diff --git a/hardware/disk/lvm2/pspec.xml b/hardware/disk/lvm2/pspec.xml index b91264e6..cf9f15d3 100644 --- a/hardware/disk/lvm2/pspec.xml +++ b/hardware/disk/lvm2/pspec.xml @@ -12,7 +12,7 @@ app:console Userland logical volume management tools LVM2 includes all of the support for handling read/write operations physical and logical volumes. - http://mirrors.kernel.org/sourceware/lvm2/LVM2.2.02.186.tgz + http://mirrors.kernel.org/sourceware/lvm2/LVM2.2.03.18.tgz libutil-linux-devel eudev-devel @@ -36,9 +36,9 @@ lvm2-2.02.166-HPPA-no-O_DIRECT.patch lvm2-2.02.184-mksh_build.patch lvm2-2.02.186-udev_remove_unsupported_option.patch - fix-stdio-usage.patch + mlockall-default-config.patch - portability.patch + @@ -57,6 +57,7 @@ /lib/udev/rules.d/10-dm.rules /lib/udev/rules.d/13-dm-disk.rules /lib/udev/rules.d/95-dm-notify.rules + /lib/udev/rules.d/69-dm-lvm.rules /usr/share/man/man8/dmsetup.8 @@ -129,6 +130,7 @@ /usr/sbin/lv* /usr/sbin/vg* /usr/sbin/pv* + /usr/libexec/lvresize_fs_helper /usr/lib/liblvm2app.so* /usr/lib/liblvm2cmd.so* /usr/lib/libdevmapper-event-lvm2.so* @@ -186,6 +188,13 @@ + + 2022-12-25 + 2.03.18 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-07-21 2.02.186 diff --git a/hardware/firmware/linux-firmware/pspec.xml b/hardware/firmware/linux-firmware/pspec.xml index 3632e120..2b545752 100644 --- a/hardware/firmware/linux-firmware/pspec.xml +++ b/hardware/firmware/linux-firmware/pspec.xml @@ -1,5 +1,5 @@ - + linux-firmware @@ -17,7 +17,7 @@ data Firmware files used by the Linux kernel linux-firmware contains different firmware files required for some devices to operate correctly. - https://mirrors.edge.kernel.org/pub/linux/kernel/firmware/linux-firmware-20220708.tar.xz + https://mirrors.edge.kernel.org/pub/linux/kernel/firmware/linux-firmware-20221109.tar.xz http://sourceforge.net/projects/pisilinux/files/source/common-fw.tar.xz http://sourceforge.net/projects/pisilinux/files/source/firmware-ipw.tar.xz http://sourceforge.net/projects/pisilinux/files/source/firmware-nonfreebox-2-tar.bz2 @@ -56,6 +56,13 @@ + + 2022-12-07 + 20221109 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-07-09 20220708 diff --git a/kernel/drivers/module-bbswitch/pspec.xml b/kernel/drivers/module-bbswitch/pspec.xml index fe15de57..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,20 @@ + + 2023-01-03 + 0.8 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-12-07 + 0.8 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-10-22 0.8 diff --git a/kernel/drivers/module-broadcom-wl/pspec.xml b/kernel/drivers/module-broadcom-wl/pspec.xml index d88d2e84..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,20 @@ + + 2023-01-03 + 6.30.223.271 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-12-07 + 6.30.223.271 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-10-22 6.30.223.271 diff --git a/kernel/drivers/module-virtualbox-guest/pspec.xml b/kernel/drivers/module-virtualbox-guest/pspec.xml index 4eea1794..4ad0015a 100644 --- a/kernel/drivers/module-virtualbox-guest/pspec.xml +++ b/kernel/drivers/module-virtualbox-guest/pspec.xml @@ -12,9 +12,9 @@ driver Kernel modules for VirtualBox guest machines 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.2.tar.xz + 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,27 @@ + + 2023-01-03 + 7.0.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-12-07 + 7.0.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-11-20 + 7.0.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-10-23 7.0.2 diff --git a/kernel/drivers/module-virtualbox/pspec.xml b/kernel/drivers/module-virtualbox/pspec.xml index a63dd1a1..e6873759 100644 --- a/kernel/drivers/module-virtualbox/pspec.xml +++ b/kernel/drivers/module-virtualbox/pspec.xml @@ -12,9 +12,9 @@ driver Kernel modules for VirtualBox This package provides the kernel support for VirtualBox. - https://sourceforge.net/projects/pisilinux/files/source/module-virtualbox-7.0.2.tar.xz + 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 8dba8213..fc528cae 100644 --- a/kernel/kernel/pspec.xml +++ b/kernel/kernel/pspec.xml @@ -33,10 +33,10 @@ - patches/linux/patch-5.15.74.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,28 @@ + + 2023-01-03 + 5.15.86 + Version bump. + security + + systemRestart + + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-12-07 + 5.15.81 + Version bump. + security + + systemRestart + + Mustafa Cinasal + muscnsl@gmail.com + 2022-10-22 5.15.74 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.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 19815adf..22a5adad 100644 --- a/kernel/tools/cpupowertools/pspec.xml +++ b/kernel/tools/cpupowertools/pspec.xml @@ -18,10 +18,10 @@ - patches/linux/patch-5.15.74.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,20 @@ + + 2023-01-03 + 5.15.86 + Version bump + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-12-07 + 5.15.81 + Version bump + Mustafa Cinasal + muscnsl@gmail.com + 2022-10-22 5.15.74 diff --git a/office/docbook/docbook-xml/actions.py b/office/docbook/docbook-xml/actions.py index 9a44009d..388eaa3f 100644 --- a/office/docbook/docbook-xml/actions.py +++ b/office/docbook/docbook-xml/actions.py @@ -37,16 +37,25 @@ def install(): pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s/ent" % version, "4.4/ent/*.ent") for version in ["4.5"]: - pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s" % version, "*.dtd") - pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s" % version, "*.mod") - pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s" % version, "docbook.cat") - pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s/ent" % version, "ent/*.ent") + pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s" % version, "4.5/*.dtd") + pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s" % version, "4.5/*.mod") + pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s" % version, "4.5/docbook.cat") + pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s/ent" % version, "4.5/ent/*.ent") for version in ["5.0"]: - pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s/dtd" % version, "docbook-5.0/dtd/*.dtd") - pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s/rng" % version, "docbook-5.0/rng/*.rng") - pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s/rng" % version, "docbook-5.0/rng/*.rnc") - pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s/xsd" % version, "docbook-5.0/xsd/*.xsd") - pisitools.insinto("/usr/share/xml/docbook/xml-dtd-%s/sch" % version, "docbook-5.0/sch/*.sch") - + pisitools.insinto("/usr/share/xml/docbook/schema/dtd/%s/" % version, "docbook-5.0/dtd/*.dtd") + pisitools.insinto("/usr/share/xml/docbook/schema/rng/%s/" % version, "docbook-5.0/rng/*.rng") + pisitools.insinto("/usr/share/xml/docbook/schema/rng/%s/" % version, "docbook-5.0/rng/*.rnc") + pisitools.insinto("/usr/share/xml/docbook/schema/xsd/%s/" % version, "docbook-5.0/xsd/*.xsd") + pisitools.insinto("/usr/share/xml/docbook/schema/sch/%s/" % version, "docbook-5.0/sch/*.sch") + + for version in ["5.1"]: + pisitools.insinto("/usr/share/xml/docbook/schema/sch/%s/" % version, "5.1/schemas/*.xml") + pisitools.insinto("/usr/share/xml/docbook/schema/rng/%s/" % version, "5.1/schemas/rng/*.rng") + pisitools.insinto("/usr/share/xml/docbook/schema/rng/%s/" % version, "5.1/schemas/rng/*.rnc") + pisitools.insinto("/usr/share/xml/docbook/schema/sch/%s/" % version, "5.1/schemas/sch/*.sch") + pisitools.insinto("/usr/share/xml/docbook/stylesheet/docbook5", "5.1/tools/db4-upgrade.xsl") + pisitools.dobin("5.1/tools/db4-entities.pl") + + shelltools.cd("docbook-5.0") pisitools.dodoc("ChangeLog", "README") diff --git a/office/docbook/docbook-xml/files/5.0/dtd/catalog.xml b/office/docbook/docbook-xml/files/5.0/dtd/catalog.xml new file mode 100644 index 00000000..4de047f6 --- /dev/null +++ b/office/docbook/docbook-xml/files/5.0/dtd/catalog.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/office/docbook/docbook-xml/files/5.0/rng/catalog.xml b/office/docbook/docbook-xml/files/5.0/rng/catalog.xml new file mode 100644 index 00000000..6e1e9b3e --- /dev/null +++ b/office/docbook/docbook-xml/files/5.0/rng/catalog.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/office/docbook/docbook-xml/files/5.0/sch/catalog.xml b/office/docbook/docbook-xml/files/5.0/sch/catalog.xml new file mode 100644 index 00000000..60985e9c --- /dev/null +++ b/office/docbook/docbook-xml/files/5.0/sch/catalog.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/office/docbook/docbook-xml/files/5.0/xsd/catalog.xml b/office/docbook/docbook-xml/files/5.0/xsd/catalog.xml new file mode 100644 index 00000000..6c4749ba --- /dev/null +++ b/office/docbook/docbook-xml/files/5.0/xsd/catalog.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/office/docbook/docbook-xml/files/5.1/rng/catalog.xml b/office/docbook/docbook-xml/files/5.1/rng/catalog.xml new file mode 100644 index 00000000..3995de79 --- /dev/null +++ b/office/docbook/docbook-xml/files/5.1/rng/catalog.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/office/docbook/docbook-xml/files/catalog.xml b/office/docbook/docbook-xml/files/catalog.xml new file mode 100644 index 00000000..84f482e8 --- /dev/null +++ b/office/docbook/docbook-xml/files/catalog.xml @@ -0,0 +1,3 @@ + + + diff --git a/office/docbook/docbook-xml/files/docbook b/office/docbook/docbook-xml/files/docbook index 5cb98147..245cc4ac 100644 --- a/office/docbook/docbook-xml/files/docbook +++ b/office/docbook/docbook-xml/files/docbook @@ -76,4 +76,15 @@ + + + + + + + + + + + diff --git a/office/docbook/docbook-xml/files/xml/catalog b/office/docbook/docbook-xml/files/xml/catalog new file mode 100644 index 00000000..14a5a956 --- /dev/null +++ b/office/docbook/docbook-xml/files/xml/catalog @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/office/docbook/docbook-xml/files/xml/docbook b/office/docbook/docbook-xml/files/xml/docbook new file mode 100644 index 00000000..6ce50bc5 --- /dev/null +++ b/office/docbook/docbook-xml/files/xml/docbook @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/office/docbook/docbook-xml/files/xml/docbook-5.0 b/office/docbook/docbook-xml/files/xml/docbook-5.0 new file mode 100644 index 00000000..2b12effc --- /dev/null +++ b/office/docbook/docbook-xml/files/xml/docbook-5.0 @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/office/docbook/docbook-xml/files/xml/docbook-5.1 b/office/docbook/docbook-xml/files/xml/docbook-5.1 new file mode 100644 index 00000000..3bd4acbd --- /dev/null +++ b/office/docbook/docbook-xml/files/xml/docbook-5.1 @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/office/docbook/docbook-xml/pspec.xml b/office/docbook/docbook-xml/pspec.xml index 5cc27dc7..bb71527b 100644 --- a/office/docbook/docbook-xml/pspec.xml +++ b/office/docbook/docbook-xml/pspec.xml @@ -17,8 +17,9 @@ https://www.oasis-open.org/docbook/xml/4.2/docbook-xml-4.2.zip https://www.oasis-open.org/docbook/xml/4.3/docbook-xml-4.3.zip https://www.oasis-open.org/docbook/xml/4.4/docbook-xml-4.4.zip - https://www.oasis-open.org/docbook/xml/4.5/docbook-xml-4.5.zip + https://www.oasis-open.org/docbook/xml/4.5/docbook-xml-4.5.zip http://www.docbook.org/xml/5.0/docbook-5.0.zip + https://docbook.org/xml/5.1/docbook-v5.1-os.zip @@ -28,19 +29,35 @@ libxml2 + /usr/bin /usr/share/doc/ /usr/share/xml /etc/xml/docbook /etc/xml/catalog + /etc/xml/docbook-5.0 + /etc/xml/docbook-5.1 - docbook - catalog - 5.0-catalog.xml + xml/docbook + xml/docbook-5.0 + xml/docbook-5.1 + xml/catalog + 5.0/dtd/catalog.xml + 5.0/rng/catalog.xml + 5.0/sch/catalog.xml + 5.0/xsd/catalog.xml + 5.1/rng/catalog.xml + + 2022-11-24 + 5.1 + Rebuild + PisiLinux Community + admin@pisilinux.org + 2020-12-09 5.0 diff --git a/pisi-index.xml b/pisi-index.xml index 668b3abc..a95778cc 100644 --- a/pisi-index.xml +++ b/pisi-index.xml @@ -754,7 +754,7 @@ Libxslt, GNOME projesi için geliştirilen XSLT C kitaplığıdır. XSLT'nin kendisi, XML oluşumunu tanımlayan bir XML dilidir. https://download.gnome.org/sources/libxslt/1.1/libxslt-1.1.37.tar.xz - libxml2-devel + libxml2-devel libgcrypt-devel python-devel @@ -764,7 +764,7 @@ libxslt-docs libxslt için belgelendirme dosyaları - libxslt + libxslt /usr/share/doc @@ -776,7 +776,7 @@ libxslt için geliştirme dosyaları libxml2-devel - libxslt + libxslt /usr/bin/*-config @@ -809,7 +809,7 @@ libgcrypt-32bit - libxslt + libxslt libxml2-32bit libgcrypt-32bit @@ -818,6 +818,13 @@ + + 2022-11-01 + 1.1.37 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-01 1.1.37 @@ -928,10 +935,10 @@ CMake, the cross-platform, open-source make system. CMake is used to control the software compilation process using simple platform and compiler independent configuration files. CMake generates native makefiles and workspaces that can be used in the compiler environment of your choice. Cmake, açık kaynak kodlu ve birden fazla platformda çalışan bir 'make' sistemidir. Yazılım derleme sürecini kontrol etmek için kullanılan CMake, derleyici bağımsız yapılandırma dosyalarının oluşturulmasını sağlar. cmake - https://github.com/Kitware/CMake/releases/download/v3.24.2/cmake-3.24.2.tar.gz + https://github.com/Kitware/CMake/releases/download/v3.24.3/cmake-3.24.3.tar.gz curl-devel - expat-devel + expat-devel libarchive-devel ncurses-devel zlib-devel @@ -963,6 +970,13 @@ + + 2022-11-11 + 3.24.3 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-14 3.24.2 @@ -1474,7 +1488,7 @@ nettle-devel attr-devel bzip2 - libxml2-devel + libxml2-devel openssl-devel xz-devel lz4-devel @@ -1513,7 +1527,7 @@ Development files for libarchive libarchive için geliştirme dosyaları - libarchive + libarchive /usr/include @@ -1522,6 +1536,13 @@ + + 2022-11-01 + 3.6.1 + Rebuild + Mustafa Cinasal + muscnsl@gmail.com + 202-07-24 3.6.1 @@ -3290,7 +3311,7 @@ python3-devel libffi-devel python-devel - glib2-devel + glib2-devel chrpath system/devel/gobject-introspection/pspec.xml @@ -3312,7 +3333,7 @@ gobject-introspection-devel Development files for gobject-introspection - gobject-introspection + gobject-introspection libffi glib2 libffi-devel @@ -3330,6 +3351,20 @@ + + 2022-11-25 + 1.74.0 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-31 + 1.74.0 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-18 1.74.0 @@ -3978,7 +4013,7 @@ Este módulo facilita una interfaz al parser XML de James Clark, expat. Como en expat, una sola instancia del parser puede analizar solamente un documento. Llamadas a parsestring después del primero de una instancia determinada morirán. mirrors://cpan/authors/id/T/TO/TODDR/XML-Parser-2.46.tar.gz - expat-devel + expat-devel perl system/devel/perl-XML-Parser/pspec.xml @@ -3996,6 +4031,13 @@ + + 2022-11-11 + 2.46 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-21 2.46 @@ -4516,9 +4558,9 @@ High productivity build system Yüksek verimli üretme sistemi Yüksek verimli üretme sistemi - https://github.com/mesonbuild/meson/releases/download/0.63.0/meson-0.63.0.tar.gz + https://github.com/mesonbuild/meson/releases/download/0.64.1/meson-0.64.1.tar.gz - python3-devel + python3-devel python3-setuptools system/devel/meson/pspec.xml @@ -4540,6 +4582,27 @@ + + 2022-11-23 + 0.64.1 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-11-11 + 0.64.0 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-22 + 0.63.3 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-07-21 0.63.0 @@ -4863,7 +4926,7 @@ Derlenmiş objeleri işlemek için gereken aletler koleksiyonu elfutils contains libraries and utilities to handle ELF objects and is a replacement for libelf. elfutils derlenmiş objeleri işlemek için gereken çeşitli araçlar içerir. - ftp://sourceware.org/pub/elfutils/0.186/elfutils-0.186.tar.bz2 + ftp://sourceware.org/pub/elfutils/0.188/elfutils-0.188.tar.bz2 bzip2 xz-devel @@ -4900,7 +4963,7 @@ xz-32bit zlib-32bit - elfutils + elfutils /usr/lib32 @@ -4910,7 +4973,7 @@ elfutils-devel Development files for elfutils - elfutils + elfutils xz-devel zstd-devel zlib-devel @@ -4922,6 +4985,13 @@ + + 2022-11-05 + 0.188 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2021-11-26 0.186 @@ -5873,11 +5943,11 @@ GNU GRUB is a Multiboot boot loader. GNU GRUB (short for GNU GRand Unified Bootloader) is a boot loader package from the GNU Project. https://ftp.gnu.org/gnu/grub/grub-2.06.tar.xz - https://ftp.gnu.org/gnu/unifont/unifont-13.0.06/unifont-13.0.06.bdf.gz - https://github.com/erkanisik1/PisiNar-Grub2-Themes/archive/refs/tags/pisinar-grub2-theme-v1.2.tar.gz + https://ftp.gnu.org/gnu/unifont/unifont-15.0.01/unifont-15.0.01.bdf.gz + https://github.com/erkanisik1/PisiNar-Grub2-Themes/archive/refs/tags/pisinar-grub2-theme-v1.3.tar.gz git - autogen + autogen-devel binutils bison flex @@ -5951,6 +6021,13 @@ + + 2022-10-26 + 2.06 + Rebuild + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-26 2.06 @@ -6514,9 +6591,24 @@ pisilinux-release os-release start-stop-daemon.8 + 01hostname + + 2022-11-20 + 3.10.1 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-01 + 3.10.1 + Rebuild.For 2.3 + Mustafa Cinasal + muscnsl@gmail.com + 2022-08-21 3.10.1 @@ -7095,7 +7187,7 @@ https://github.com/nghttp2/nghttp2/archive/refs/tags/v1.48.0.tar.gz zlib-devel - libxml2-devel + libxml2-devel python3-devel openssl-devel @@ -7115,7 +7207,7 @@ libnghttp2-devel Development files for libnghttp2 - libnghttp2 + libnghttp2 /usr/include @@ -7123,6 +7215,13 @@ + + 2022-11-01 + 1.48.0 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-08-20 1.48.0 @@ -7468,7 +7567,7 @@ X.Org Xdmcp Bibliothek LibXdmcp is the X Display Manager Control Protocol library. LibXdmcp, X Ekran Yöneticisi Denetim Protokolü kitaplığıdır. - http://xorg.freedesktop.org/archive/individual/lib/libXdmcp-1.1.3.tar.bz2 + http://xorg.freedesktop.org/archive/individual/lib/libXdmcp-1.1.4.tar.xz libxslt util-macros @@ -7493,7 +7592,7 @@ libXdmcp için geliştirme dosyaları xorg-proto - libXdmcp + libXdmcp /usr/include/X11 @@ -7508,14 +7607,25 @@ libXdmcp için 32-bit paylaşımlı kitaplıklar emul32 emul32 + + libbsd-32bit + - libXdmcp + libXdmcp + libbsd-32bit /usr/lib32 + + 2022-11-19 + 1.1.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2020-12-09 1.1.3 @@ -8570,17 +8680,17 @@ Python3, gelecek nesil üst seviye betik programlama dili. Python is an accessible, high-level, dynamically typed, interpreted programming language, designed with an emphasis on code readability. It includes an extensive standard library, and has a vast ecosystem of third-party libraries. Python3 kod okuma rahatlığı ile tasarlanmış, erişilebilir, yüksek seviyeli, dinamik, yorumlamalı programlama dilidir. Python3 kapsamlı standart kütüphanesi ile beraber gelmekte ve üçüncü parti kitaplıkların kolay bütünleştirilmesine olanak tanıyan yapısıylar en hızlı ve dinamik yaorumlamalı dillerden biri olmaktadır. - https://www.python.org/ftp/python/3.9.14/Python-3.9.14.tar.xz + https://www.python.org/ftp/python/3.9.15/Python-3.9.15.tar.xz bzip2 xz-devel gdbm-devel zlib-devel - expat-devel + expat-devel libffi-devel sqlite-devel ncurses-devel - openssl-devel + openssl-devel readline-devel mpdecimal-devel @@ -8675,7 +8785,7 @@ Python3 için geliştime dosyaları python3-devel, python3 için geliştime dosyaları içerir. - python3 + python3 /usr/include/python3.9/* @@ -8683,6 +8793,27 @@ + + 2022-11-10 + 3.9.15 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-20 + 3.9.15 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-09-30 + 3.9.14 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-12 3.9.14 @@ -9235,6 +9366,69 @@ + + + libmd + https://www.hadrons.org/software/libmd/ + + PisiLinux Community + admins@pisilinux.org + + BSD + library + system.base + Message Digest functions from BSD systems + Message Digest functions from BSD systems + Message Digest functions from BSD systems + Message Digest functions from BSD systems + libmd + https://libbsd.freedesktop.org/releases/libmd-1.0.4.tar.xz + system/base/libmd/pspec.xml + + + libmd + + /usr/lib + /usr/share + /usr/share/locale + /usr/share/man + /usr/share/doc + + + + libmd-32bit + 32-bit shared libraries for libmd + emul32 + emul32 + + libmd + + + /usr/lib32 + + + + libmd-devel + Development files for libmd + + libmd + + + /usr/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + + + + + 2022-12-04 + 1.0.4 + First release + PisiLinux Community + admins@pisilinux.org + + + libnsl @@ -9603,6 +9797,7 @@ 0001-PackageKit-Search-Bug-Fix.patch pot_file_and_ru_translation.patch + qt6-actionsapi.patch system/base/pisi/pspec.xml @@ -9650,6 +9845,13 @@ + + 2022-10-05 + 2.7.2 + Rebuild qt6 actionsapi. + Mustafa Cinasal + muscnsl@gmail.com + 2022-07-23 2.7.2 @@ -12716,7 +12918,7 @@ X.Org X11 kitaplığı X.Org X11 Bibliothek Core X11 protocol client library. - mirrors://xorg/individual/lib/libX11-1.8.1.tar.xz + mirrors://xorg/individual/lib/libX11-1.8.2.tar.xz libxcb-devel xorg-proto @@ -12744,7 +12946,7 @@ Development files for X11 library libX11 için geliştirme dosyaları - libX11 + libX11 libxcb-devel xorg-proto @@ -12766,7 +12968,7 @@ libxslt-32bit - libX11 + libX11 libxcb-32bit @@ -12774,6 +12976,13 @@ + + 2022-11-11 + 1.8.2 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-07-22 1.8.1 @@ -13036,30 +13245,66 @@ Taşınabilirlik için BSD uyumlu fonksiyonlar sağlayan bir kitaplık. This library provides useful functions commonly found on BSD systems, and lacking on others like GNU systems, thus making it easier to port projects with strong BSD origins, without needing to embed the same code over and over again on each project. GNU Linux sistemlerde bulunmayan BSD sistemlere özgü fonsiyonları barındıran bir kitaplıktır ve BSD uygulamalarının GNU Linux'a taşınmasını kolaylaştırır. - https://libbsd.freedesktop.org/releases/libbsd-0.10.0.tar.xz + https://libbsd.freedesktop.org/releases/libbsd-0.11.7.tar.xz + + libmd-devel + system/base/libbsd/pspec.xml libbsd + + libmd + /usr/lib /usr/share/doc + + libbsd-32bit + 32-bit shared libraries for libbsd + emul32 + emul32 + + libmd-32bit + + + libbsd + + + /usr/lib32 + + libbsd-devel Development files for libbsd - libbsd + libbsd /usr/include /usr/lib/pkgconfig + /usr/lib32/pkgconfig /usr/share/man/man3 /usr/share/man/man7 + + 2022-12-04 + 0.11.7 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-11-22 + 0.10.0 + Rebuild. + Pisi Linux Community + admin@pisilinux.org + 2020-12-09 0.10.0 @@ -13146,6 +13391,7 @@ gettext-0.21-gnulib-perror-tests.patch + fedora/gettext-0.21.1-disable-libtextstyle.patch system/base/gettext/pspec.xml @@ -13187,7 +13433,7 @@ gettext için geliştirme dosyaları system.devel - gettext + gettext /usr/share/aclocal @@ -13196,6 +13442,13 @@ + + 2022-10-31 + 0.21 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-07-18 0.21 @@ -14005,7 +14258,7 @@ Zamandilimi veri dosyaları ve araçları timezone includes timezone data files and tools to use them. Package contents are synchronized with glibc tree. timezone zamandilimi veri dosyaları ve bu dosyaları kullanmak için gerekli araçları içerir. Paket içeriği glibc gelişim ağacından oluşturulmaktadır. - https://data.iana.org/time-zones/releases/tzdata2019c.tar.gz + https://data.iana.org/time-zones/releases/tzdata2022e.tar.gz perl gawk @@ -14019,6 +14272,13 @@ + + 2022-10-15 + 2022e + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2020-12-09 2019c @@ -14102,7 +14362,7 @@ https://dbus.freedesktop.org/releases/dbus-python/dbus-python-1.2.18.tar.gz python-devel - dbus-devel + dbus-devel dbus-glib-devel glib2-devel @@ -14117,7 +14377,7 @@ system.devel dbus-devel - dbus-python + dbus-python /usr/include @@ -14138,6 +14398,20 @@ + + 2022-10-31 + 1.2.18 + Rebuild + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-22 + 1.2.18 + Rebuild + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-25 1.2.18 @@ -14587,11 +14861,11 @@ bzip2 gdbm-devel zlib-devel - expat-devel + expat-devel libffi-devel sqlite-devel ncurses-devel - openssl-devel + openssl-devel readline-devel glibc-devel @@ -14644,7 +14918,7 @@ python için geliştirme dosyaları system.devel - python + python /usr/include @@ -14652,6 +14926,20 @@ + + 2022-11-10 + 2.7.18 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-09-30 + 2.7.18 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-07-23 2.7.18 @@ -15268,7 +15556,7 @@ Le paquet des utilitaires pour le fichier de mot de passe Shadow regroupe les programmes nécessaires à convertir les fichiers de mots de passe traditionnels V7*NIX au format de mot passe shadow SVR4 ainsi que d'autres outils destinés à la gestion des fichiers des groupes et de mots de passe (qui fonctionnent aussi bien pour les mots de passe shadow que non-shadow). The Shadow password file utilities package includes programs necessary to convert traditional V7 *NIX password files to the SVR4 shadow password format, and additional tools to maintain password and group files (that work with both shadow and non-shadow passwords). Shadow parola dosyası yardımcı uygulamalar paketi, geleneksel V7 *nix parola dosyalarını SVR4 shadow parola biçimine dönüştüren programlar ile parola ve grup dosyalarının bakımı için ilave araçlar içerir. - https://github.com/shadow-maint/shadow/releases/download/4.12.3/shadow-4.12.3.tar.xz + https://github.com/shadow-maint/shadow/releases/download/4.13/shadow-4.13.tar.xz pisi-shadowbase.sh @@ -15310,6 +15598,13 @@ + + 2022-11-11 + 4.13 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-28 4.12.3 @@ -16475,9 +16770,9 @@ python3 gtk-doc - dbus-devel + dbus-devel glib2-devel - expat-devel + expat-devel libxml2 @@ -16510,7 +16805,7 @@ dbus-glib için geliştirme dosyaları system.devel - dbus-glib + dbus-glib dbus-devel glib2-devel @@ -16521,6 +16816,34 @@ + + 2022-11-25 + 0.112 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-11-11 + 0.112 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-31 + 0.112 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-22 + 0.112 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-25 0.112 @@ -17016,7 +17339,7 @@ XML ayrıştırıcı kütüphaneleri XML Parser Bibliotheken This is expat, the C library for parsing XML, written by James Clark. Expat is a stream oriented XML parser. This means that you register handlers with the parser prior to starting the parse. These handlers are called when the parser discovers the associated structures in the document being parsed. A start tag is an example of the kind of structures for which you may register handlers. - mirrors://sourceforge/expat/expat-2.4.9.tar.bz2 + mirrors://sourceforge/expat/expat-2.5.0.tar.xz gnuconfig glibc-devel @@ -17038,7 +17361,7 @@ expat için geliştirme dosyaları system.devel - expat + expat /usr/include @@ -17054,13 +17377,20 @@ emul32 emul32 - expat + expat /usr/lib32 + + 2022-11-11 + 2.5.0 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-21 2.4.9 @@ -17477,7 +17807,7 @@ Libxml2 est l'analyseur et la boîte à outils XML écrit en C pour le projet Gnome (mais utilisable en dehors de la plateforme Gnome). Libxml2 is the XML C parser and toolkit developed for the Gnome project (but usable outside of the Gnome platform). Libxml2, Gnome projesi için geliştirilmiş C dilinde XML ayrıştırıcısıdır. Gnome platformu olmadan da kullanılabilir. - https://download.gnome.org/sources/libxml2/2.9/libxml2-2.9.14.tar.xz + https://download.gnome.org/sources/libxml2/2.10/libxml2-2.10.3.tar.xz python-devel python3-devel @@ -17487,7 +17817,6 @@ fedora/libxml2-2.9.8-python3-unicode-errors.patch - libxml2-2.9.11-disable-fuzz-tests.patch system/base/libxml2/pspec.xml @@ -17521,7 +17850,7 @@ libxml2 için geliştirme dosyaları system.devel - libxml2 + libxml2 /usr/lib/pkgconfig @@ -17543,7 +17872,7 @@ readline-32bit - libxml2 + libxml2 xz-32bit zlib-32bit @@ -17552,6 +17881,13 @@ + + 2022-11-01 + 2.10.3 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-05-05 2.9.14 @@ -18179,9 +18515,9 @@ D-Bus fourni à la fois un daemon système (pour les événements els que l'"ajout d'un nouveau périphérique" ou "file d'impression changée") et un daemon propre à chaque session utilisateur (pour les besoins généraux de communication entre processus utilisateurs). De plus, le bus de message est construit en se basant sur un framework (cadre de développement) de passage de message de un-vers-un pouvant être utilisé par n'importe quelles applications pour communiquer directement (sans passer par le daemon de bus de message). Pour l'instant les applications pouvant communiquer doivent être situées sur le même ordinateur, mais l'option TCP/IP est disponible et le support de processus distant est prévu. D-Bus supplies both a system daemon (for events such as "new hardware device added" or "printer queue changed") and a per-user-login-session daemon (for general IPC needs among user applications). Also, the message bus is built on top of a general one-to-one message passing framework, which can be used by any two apps to communicate directly (without going through the message bus daemon). Currently the communicating applications are on one computer, but TCP/IP option is available and remote support planned. D-Bus, sistem ve kullanıcılar için olmak üzere iki tane artalan süreci (daemon) sunar. Mesaj yolu, bire bir mesaj geçiş araçları üzerine inşa edilmiştir. Bu sayede iki program birbiriyle bir mesaj yolu artalan süreci kullanmadan, direkt olarak haberleşebilir. Şu an için haberleşme araçları aynı bilgisayar üzerinde çalışabilmektedir, fakat TCP/IP ile uzaktan haberleşme de planlanmaktadır. - https://dbus.freedesktop.org/releases/dbus/dbus-1.14.0.tar.xz + https://dbus.freedesktop.org/releases/dbus/dbus-1.14.4.tar.xz - expat-devel + expat-devel libX11-devel libcap-ng-devel autoconf-archive @@ -18232,7 +18568,7 @@ dbus için geliştirme dosyaları system.devel - dbus + dbus /usr/include @@ -18257,6 +18593,20 @@ + + 2022-11-11 + 1.14.4 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-22 + 1.14.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-21 1.14.0 @@ -20289,7 +20639,7 @@ C programlama dili için glib kütüphanesi glib2 is the low-level core library that forms the basis for projects such as GTK+ and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system. glib2, GTK+ ve GNOME gibi projelerin temelini oluşturan düşük seviyeli çekirdek kütüphanedir. C için veri yapıları, taşınabilirlik katmanları ve çeşitli çalışma zamanı işlevleri için arabirimler sunar. - mirrors://gnome/glib/2.74/glib-2.74.0.tar.xz + mirrors://gnome/glib/2.74/glib-2.74.2.tar.xz multilib.diff @@ -20298,7 +20648,7 @@ ninja zlib-devel docbook-xsl - libffi-devel + libffi-devel elfutils-devel libxslt-devel libutil-linux-devel @@ -20307,6 +20657,7 @@ noisy-glib-compile-schemas.diff glib-2.68.2-skip_warnings-1.patch + 2820-str-equal-cxx.patch system/base/glib2/pspec.xml @@ -20345,7 +20696,7 @@ glib2 için geliştirme dosyaları system.devel - glib2 + glib2 libpcre2-devel zlib-devel libffi-devel @@ -20391,7 +20742,7 @@ elfutils-32bit - glib2 + glib2 libpcre2-32bit zlib-32bit libffi-32bit @@ -20413,6 +20764,27 @@ + + 2022-11-25 + 2.74.2 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-31 + 2.74.1 + Version bump + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-09-30 + 2.74.0 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-18 2.74.0 @@ -24260,7 +24632,7 @@ OpenSSL is a cryptography toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) network protocols and related cryptography standards required by them. OpenSSL, Güvenlik Soketleri Katmanı (SSL v2/v3) ve Aktarım Katmanı Güvenliği (TLSv1) ağ protokolleri ile bu protokollerin gerektirdiği şifreleme standartlarını uygulayan bir şifreleme aracıdır. OpenSSL ist ein Kryptographie Werkzeug, das die Netzwerkprotokolle Secure Sockets Layer (SSL v2/v3) und Transport Layer Security (TLS v1) sowie deren erforderliche zugehörige Kryptographie Standards implementiert. - https://www.openssl.org/source/openssl-1.1.1q.tar.gz + https://www.openssl.org/source/openssl-1.1.1s.tar.gz zlib-devel xorg-util @@ -24298,7 +24670,7 @@ openssl için geliştirme dosyaları system.devel - openssl + openssl /usr/include @@ -24317,7 +24689,7 @@ zlib-32bit - openssl + openssl zlib-32bit @@ -24325,6 +24697,13 @@ + + 2022-11-10 + 1.1.1s + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-07-07 1.1.1q @@ -25641,7 +26020,7 @@ Python kurulum araçları python3-setuptools is a collection of enhancements to the Python distutils that allow you to more easily build and distribute Python packages, especially ones that have dependencies on other packages. python3-setuptools, Python distutils'e yapılan, özellikle başka paketlere bağımlılığı olan Python paketlerini daha kolay oluşturmaya ve dağıtmaya yarayan iyileştirmeler koleksiyonudur. - https://files.pythonhosted.org/packages/dc/73/88920663229023b724a854d1ab7e3e50a1a28b63eeec399a604ba30f9242/setuptools-62.6.0.tar.gz + https://github.com/pypa/setuptools/archive/refs/tags/v65.5.0.tar.gz python3-devel python3-setuptools @@ -25661,6 +26040,13 @@ + + 2022-10-22 + 65.5.0 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-12 62.6.0 @@ -27128,8 +27514,9 @@ https://www.oasis-open.org/docbook/xml/4.2/docbook-xml-4.2.zip https://www.oasis-open.org/docbook/xml/4.3/docbook-xml-4.3.zip https://www.oasis-open.org/docbook/xml/4.4/docbook-xml-4.4.zip - https://www.oasis-open.org/docbook/xml/4.5/docbook-xml-4.5.zip + https://www.oasis-open.org/docbook/xml/4.5/docbook-xml-4.5.zip http://www.docbook.org/xml/5.0/docbook-5.0.zip + https://docbook.org/xml/5.1/docbook-v5.1-os.zip office/docbook/docbook-xml/pspec.xml @@ -27139,18 +27526,34 @@ libxml2 + /usr/bin /usr/share/doc/ /usr/share/xml /etc/xml/docbook /etc/xml/catalog + /etc/xml/docbook-5.0 + /etc/xml/docbook-5.1 - docbook - catalog - 5.0-catalog.xml + xml/docbook + xml/docbook-5.0 + xml/docbook-5.1 + xml/catalog + 5.0/dtd/catalog.xml + 5.0/rng/catalog.xml + 5.0/sch/catalog.xml + 5.0/xsd/catalog.xml + 5.1/rng/catalog.xml + + 2022-11-24 + 5.1 + Rebuild + PisiLinux Community + admin@pisilinux.org + 2020-12-09 5.0 @@ -27592,6 +27995,13 @@ + + 2022-11-11 + 1.0.7 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2020-09-11 1.0.7 @@ -27677,7 +28087,7 @@ pciutils-devel - patches/linux/patch-5.15.67.xz + patches/linux/patch-5.15.74.xz patches/aufs5/aufs5.15.41-20220620.patch patches/aufs5/aufs5-base.patch patches/aufs5/aufs5-kbuild.patch @@ -27747,6 +28157,13 @@ + + 2022-10-22 + 5.15.74 + Version bump + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-12 5.15.67 @@ -28387,7 +28804,7 @@ elfutils-devel - patches/linux/patch-5.15.67.xz + patches/linux/patch-5.15.74.xz patches/aufs5/aufs5.15.41-20220620.patch patches/aufs5/aufs5-base.patch patches/aufs5/aufs5-kbuild.patch @@ -28465,7 +28882,7 @@ kernel-module-headers includes the C header files and the necessary Kbuild files for being able to build external kernel modules. kernel-module-headers, harici çekirdek modüllerinin derlenebilmesi için gereken başlık dosyaları ve Kbuild sistemini içeren pakettir. - kernel + kernel /usr/src/linux-headers* @@ -28496,6 +28913,17 @@ + + security + 2022-10-22 + 5.15.74 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + systemRestart + + security 2022-09-12 @@ -29336,7 +29764,7 @@ Eski ve yeni optimus teknolojisine sahip dizüstü bilgisyarlarda çalışabilmektedir. https://github.com/Bumblebee-Project/bbswitch/archive/v0.8.tar.gz - kernel-module-headers + kernel-module-headers 0001-proc_ops-struct.patch @@ -29347,8 +29775,8 @@ module-bbswitch - kernel - bbswitch-common + kernel + bbswitch-common /lib/modules @@ -29371,7 +29799,7 @@ bbswitch-dkms - bbswitch-common + bbswitch-common dkms @@ -29382,6 +29810,13 @@ + + 2022-10-22 + 0.8 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-12 0.8 @@ -29882,9 +30317,9 @@ VirtualBox için çekirdek modülleri This package provides the kernel support for VirtualBox. Bu paket VirtualBox için çekirdek desteği sunar. - https://sourceforge.net/projects/pisilinux/files/source/module-virtualbox-6.1.38.tar.xz + https://sourceforge.net/projects/pisilinux/files/source/module-virtualbox-7.0.4.tar.xz - kernel-module-headers + kernel-module-headers kernel/drivers/module-virtualbox/pspec.xml @@ -29894,8 +30329,8 @@ noDelta - kernel - module-virtualbox-userspace + kernel + module-virtualbox-userspace /lib/modules @@ -29916,6 +30351,27 @@ + + 2022-11-20 + 7.0.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-23 + 7.0.2 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-22 + 6.1.38 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-16 6.1.38 @@ -30996,9 +31452,9 @@ VirtualBox misafir makineleri için çekirdek modülleri This package provides the kernel modules needed for mouse integration and shared folder support between VirtualBox host and guest systems. Bu paket VirtualBox sunucu makinesi ile misafir sistemler arası fare entegrasyonu ve paylaşımlı dizin desteği için gerekli çekirdek modüllerini içerir. - https://sourceforge.net/projects/pisilinux/files/source/module-virtualbox-guest-6.1.38.tar.xz + https://sourceforge.net/projects/pisilinux/files/source/module-virtualbox-guest-7.0.4.tar.xz - kernel-module-headers + kernel-module-headers kernel/drivers/module-virtualbox-guest/pspec.xml @@ -31008,9 +31464,9 @@ noDelta - kernel + kernel baselayout - module-virtualbox-guest-userspace + module-virtualbox-guest-userspace /lib/modules @@ -31035,6 +31491,27 @@ + + 2022-11-20 + 7.0.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-23 + 7.0.2 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-10-22 + 6.1.38 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-16 6.1.38 @@ -31776,7 +32253,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 @@ -31805,8 +32282,8 @@ noDelta - kernel - module-broadcom-wl-userspace + kernel + module-broadcom-wl-userspace /lib/modules @@ -31830,6 +32307,13 @@ + + 2022-10-22 + 6.30.223.271 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-12 6.30.223.271 diff --git a/pisi-index.xml.sha1sum b/pisi-index.xml.sha1sum index ece81fc3..94702282 100644 --- a/pisi-index.xml.sha1sum +++ b/pisi-index.xml.sha1sum @@ -1 +1 @@ -c8abc1ca50989cad6ed66122e753c1654b94ef9c \ No newline at end of file +b92442ad2d993683e857f2f25877d0f45f47b0e8 \ No newline at end of file diff --git a/pisi-index.xml.xz b/pisi-index.xml.xz index e2bb619f..4953f955 100644 Binary files a/pisi-index.xml.xz and b/pisi-index.xml.xz differ diff --git a/pisi-index.xml.xz.sha1sum b/pisi-index.xml.xz.sha1sum index 00112934..c779178e 100644 --- a/pisi-index.xml.xz.sha1sum +++ b/pisi-index.xml.xz.sha1sum @@ -1 +1 @@ -25ccac97c2c1ea82aa61aa10693a22f150e1b925 \ No newline at end of file +8690abed8f13ba5f32279dd62946e072ff3af188 \ No newline at end of file diff --git a/programming/language/python3/python3-setuptools/pspec.xml b/programming/language/python3/python3-setuptools/pspec.xml index f4c244a2..31c6689e 100644 --- a/programming/language/python3/python3-setuptools/pspec.xml +++ b/programming/language/python3/python3-setuptools/pspec.xml @@ -14,7 +14,7 @@ app:console Python setuptools python3-setuptools is a collection of enhancements to the Python distutils that allow you to more easily build and distribute Python packages, especially ones that have dependencies on other packages. - https://github.com/pypa/setuptools/archive/refs/tags/v65.5.0.tar.gz + https://github.com/pypa/setuptools/archive/refs/tags/v65.6.3.tar.gz python3-devel python3-setuptools @@ -36,6 +36,13 @@ + + 2022-12-08 + 65.6.3 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-10-22 65.5.0 diff --git a/system/base/baselayout/actions.py b/system/base/baselayout/actions.py index 9793ec68..489ff03b 100644 --- a/system/base/baselayout/actions.py +++ b/system/base/baselayout/actions.py @@ -28,9 +28,9 @@ def install(): # Dirty fix for now... (especially for flatpak) shelltools.system("mv %s/run/* %s/dev" % (get.installDIR(), get.installDIR())) - pisitools.remove("/var/lock") + # pisitools.remove("/var/lock") # shelltools.cd("%s/var" % get.installDIR()) - shelltools.system("ln -rs %s/dev/lock %s/var/lock" % (get.installDIR(), get.installDIR())) + # shelltools.system("ln -rs %s/dev/lock %s/var/lock" % (get.installDIR(), get.installDIR())) # shelltools.cd("%s/baselayout/src" % get.workDIR()) # Adjust permissions diff --git a/system/base/baselayout/pspec.xml b/system/base/baselayout/pspec.xml index 16429305..46579122 100644 --- a/system/base/baselayout/pspec.xml +++ b/system/base/baselayout/pspec.xml @@ -72,6 +72,13 @@ + + 2022-11-20 + 3.10.1 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-10-01 3.10.1 diff --git a/system/base/bash/files/fedora/bash-2.05b-pgrp_sync.patch b/system/base/bash/files/fedora/bash-2.05b-pgrp_sync.patch index bd7ded60..cc985187 100644 --- a/system/base/bash/files/fedora/bash-2.05b-pgrp_sync.patch +++ b/system/base/bash/files/fedora/bash-2.05b-pgrp_sync.patch @@ -1,11 +1,12 @@ ---- bash-2.05b/aclocal.m4.pgrp_sync 2002-06-25 14:45:43.000000000 +0100 -+++ bash-2.05b/aclocal.m4 2003-01-15 18:17:35.000000000 +0000 -@@ -1255,7 +1255,7 @@ +diff --git a/aclocal.m4 b/aclocal.m4 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -1324,7 +1324,7 @@ main() wait(&status); exit(ok ? 0 : 5); } --], bash_cv_pgrp_pipe=no,bash_cv_pgrp_pipe=yes, -+], bash_cv_pgrp_pipe=yes,bash_cv_pgrp_pipe=yes, +-]])], [bash_cv_pgrp_pipe=no], [bash_cv_pgrp_pipe=yes], ++]])], [bash_cv_pgrp_pipe=yes], [bash_cv_pgrp_pipe=yes], [AC_MSG_WARN(cannot check pgrp synchronization if cross compiling -- defaulting to no) - bash_cv_pgrp_pipe=no]) - ]) + bash_cv_pgrp_pipe=no] + )]) diff --git a/system/base/bash/files/fedora/bash-4.1-examples.patch b/system/base/bash/files/fedora/bash-4.1-examples.patch index 19159e75..43407d97 100644 --- a/system/base/bash/files/fedora/bash-4.1-examples.patch +++ b/system/base/bash/files/fedora/bash-4.1-examples.patch @@ -1,18 +1,18 @@ -diff -up bash-4.1/examples/loadables/Makefile.in.examples bash-4.1/examples/loadables/Makefile.in ---- bash-4.1/examples/loadables/Makefile.in.examples 2010-06-22 16:20:02.000000000 +0200 -+++ bash-4.1/examples/loadables/Makefile.in 2010-06-22 16:20:41.000000000 +0200 -@@ -43,7 +43,7 @@ host_os = @host_os@ - host_cpu = @host_cpu@ +diff --git a/examples/loadables/Makefile.in b/examples/loadables/Makefile.in +--- a/examples/loadables/Makefile.in ++++ b/examples/loadables/Makefile.in +@@ -59,7 +59,7 @@ host_cpu = @host_cpu@ host_vendor = @host_vendor@ + STYLE_CFLAGS = @STYLE_CFLAGS@ -CFLAGS = @CFLAGS@ -+CFLAGS = -O2 -g +++CFLAGS = -O2 -g LOCAL_CFLAGS = @LOCAL_CFLAGS@ DEFS = @DEFS@ LOCAL_DEFS = @LOCAL_DEFS@ -diff -up bash-4.1/examples/loadables/perl/Makefile.in.examples bash-4.1/examples/loadables/perl/Makefile.in ---- bash-4.1/examples/loadables/perl/Makefile.in.examples 2010-06-22 16:20:46.000000000 +0200 -+++ bash-4.1/examples/loadables/perl/Makefile.in 2010-06-22 16:21:04.000000000 +0200 +diff --git a/examples/loadables/perl/Makefile.in b/examples/loadables/perl/Makefile.in +--- a/examples/loadables/perl/Makefile.in ++++ b/examples/loadables/perl/Makefile.in @@ -42,7 +42,7 @@ SHELL = @MAKE_SHELL@ PERL5 = perl5 diff --git a/system/base/bash/files/fedora/bash-4.3-noecho.patch b/system/base/bash/files/fedora/bash-4.3-noecho.patch index f20cd6f6..b06d7f48 100644 --- a/system/base/bash/files/fedora/bash-4.3-noecho.patch +++ b/system/base/bash/files/fedora/bash-4.3-noecho.patch @@ -1,21 +1,20 @@ diff --git a/parse.y b/parse.y -index df1231d..2449fa8 100644 --- a/parse.y +++ b/parse.y -@@ -4482,6 +4482,8 @@ xparse_dolparen (base, string, indp, flags) +@@ -4255,7 +4255,8 @@ xparse_dolparen (base, string, indp, flags) + save_parser_state (&ps); save_input_line_state (&ls); - orig_eof_token = shell_eof_token; +- + /* avoid echoing every substitution again */ + echo_input_at_read = 0; #if defined (ALIAS) || defined (DPAREN_ARITHMETIC) - saved_pushed_strings = pushed_string_list; /* separate parsing context */ pushed_string_list = (STRING_SAVER *)NULL; + #endif diff --git a/subst.c b/subst.c -index 9ccbf33..8a9ee5c 100644 --- a/subst.c +++ b/subst.c -@@ -9453,6 +9453,7 @@ param_expand (string, sindex, quoted, expanded_something, +@@ -10222,6 +10222,7 @@ param_expand (string, sindex, quoted, expanded_something, WORD_LIST *list, *l; WORD_DESC *tdesc, *ret; int tflag, nullarg; @@ -23,7 +22,7 @@ index 9ccbf33..8a9ee5c 100644 /*itrace("param_expand: `%s' pflags = %d", string+*sindex, pflags);*/ zindex = *sindex; -@@ -9843,6 +9844,9 @@ arithsub: +@@ -10614,6 +10615,9 @@ arithsub: } comsub: @@ -33,7 +32,7 @@ index 9ccbf33..8a9ee5c 100644 if (pflags & PF_NOCOMSUB) /* we need zindex+1 because string[zindex] == RPAREN */ temp1 = substring (string, *sindex, zindex+1); -@@ -9855,6 +9859,7 @@ comsub: +@@ -10626,6 +10630,7 @@ comsub: } FREE (temp); temp = temp1; diff --git a/system/base/bash/files/fedora/bash-5.0-syslog-history.patch b/system/base/bash/files/fedora/bash-5.0-syslog-history.patch new file mode 100644 index 00000000..dc1ad895 --- /dev/null +++ b/system/base/bash/files/fedora/bash-5.0-syslog-history.patch @@ -0,0 +1,13 @@ +diff --git a/doc/bash.1 b/doc/bash.1 +--- a/doc/bash.1 ++++ b/doc/bash.1 +@@ -10726,6 +10726,9 @@ If set, the shell automatically closes file descriptors assigned using the + .el above) + instead of leaving them open when the command completes. + .TP 8 ++.B syslog_history ++If set, command history is logged to syslog. ++.TP 8 + .B xpg_echo + If set, the \fBecho\fP builtin expands backslash-escape sequences + by default. diff --git a/system/base/bash/files/fedora/bash-requires.patch b/system/base/bash/files/fedora/bash-requires.patch index 86d07926..674e5b94 100644 --- a/system/base/bash/files/fedora/bash-requires.patch +++ b/system/base/bash/files/fedora/bash-requires.patch @@ -1,20 +1,18 @@ diff --git a/builtins.h b/builtins.h -index dac95fd..5b7e811 100644 --- a/builtins.h +++ b/builtins.h -@@ -45,6 +45,7 @@ - #define ASSIGNMENT_BUILTIN 0x10 /* This builtin takes assignment statements. */ +@@ -46,6 +46,7 @@ #define POSIX_BUILTIN 0x20 /* This builtins is special in the Posix command search order. */ #define LOCALVAR_BUILTIN 0x40 /* This builtin creates local variables */ -+#define REQUIRES_BUILTIN 0x80 /* This builtin requires other files. */ + #define ARRAYREF_BUILTIN 0x80 /* This builtin takes array references as arguments */ ++#define REQUIRES_BUILTIN 0x100 /* This builtin requires other files. */ #define BASE_INDENT 4 diff --git a/builtins/mkbuiltins.c b/builtins/mkbuiltins.c -index e243021..0a7a0e5 100644 --- a/builtins/mkbuiltins.c +++ b/builtins/mkbuiltins.c -@@ -69,10 +69,15 @@ extern char *strcpy (); +@@ -69,11 +69,16 @@ extern char *strcpy (); #define whitespace(c) (((c) == ' ') || ((c) == '\t')) /* Flag values that builtins can have. */ @@ -25,15 +23,18 @@ index e243021..0a7a0e5 100644 #define BUILTIN_FLAG_SPECIAL 0x01 #define BUILTIN_FLAG_ASSIGNMENT 0x02 #define BUILTIN_FLAG_LOCALVAR 0x04 - #define BUILTIN_FLAG_POSIX_BUILTIN 0x08 -+#define BUILTIN_FLAG_REQUIRES 0x10 + #define BUILTIN_FLAG_POSIX_BUILTIN 0x08 + #define BUILTIN_FLAG_ARRAYREF_ARG 0x10 ++#define BUILTIN_FLAG_REQUIRES 0x20 #define BASE_INDENT 4 -@@ -173,11 +178,19 @@ char *posix_builtins[] = +@@ -189,13 +194,21 @@ char *arrayvar_builtins[] = + "typeset", "unset", "wait", /*]*/ (char *)NULL }; - +- ++ +/* The builtin commands that cause requirements on other files. */ +static char *requires_builtins[] = +{ @@ -46,36 +47,38 @@ index e243021..0a7a0e5 100644 static int is_assignment_builtin (); static int is_localvar_builtin (); static int is_posix_builtin (); + static int is_arrayvar_builtin (); +static int is_requires_builtin (); #if !defined (HAVE_RENAME) static int rename (); -@@ -831,6 +844,8 @@ builtin_handler (self, defs, arg) - new->flags |= BUILTIN_FLAG_LOCALVAR; - if (is_posix_builtin (name)) +@@ -856,6 +869,8 @@ builtin_handler (self, defs, arg) new->flags |= BUILTIN_FLAG_POSIX_BUILTIN; + if (is_arrayvar_builtin (name)) + new->flags |= BUILTIN_FLAG_ARRAYREF_ARG; + if (is_requires_builtin (name)) + new->flags |= BUILTIN_FLAG_REQUIRES; array_add ((char *)new, defs->builtins); building_builtin = 1; -@@ -1250,12 +1265,13 @@ write_builtins (defs, structfile, externfile) +@@ -1275,13 +1290,14 @@ write_builtins (defs, structfile, externfile) else fprintf (structfile, "(sh_builtin_func_t *)0x0, "); -- fprintf (structfile, "%s%s%s%s%s, %s_doc,\n", -+ fprintf (structfile, "%s%s%s%s%s%s, %s_doc,\n", +- fprintf (structfile, "%s%s%s%s%s%s, %s_doc,\n", ++ fprintf (structfile, "%s%s%s%s%s%s%s, %s_doc,\n", "BUILTIN_ENABLED | STATIC_BUILTIN", (builtin->flags & BUILTIN_FLAG_SPECIAL) ? " | SPECIAL_BUILTIN" : "", (builtin->flags & BUILTIN_FLAG_ASSIGNMENT) ? " | ASSIGNMENT_BUILTIN" : "", (builtin->flags & BUILTIN_FLAG_LOCALVAR) ? " | LOCALVAR_BUILTIN" : "", (builtin->flags & BUILTIN_FLAG_POSIX_BUILTIN) ? " | POSIX_BUILTIN" : "", + (builtin->flags & BUILTIN_FLAG_ARRAYREF_ARG) ? " | ARRAYREF_BUILTIN" : "", + (builtin->flags & BUILTIN_FLAG_REQUIRES) ? " | REQUIRES_BUILTIN" : "", document_name (builtin)); /* Don't translate short document summaries that are identical -@@ -1645,6 +1661,13 @@ is_posix_builtin (name) - return (_find_in_table (name, posix_builtins)); +@@ -1678,6 +1694,13 @@ is_arrayvar_builtin (name) + return (_find_in_table (name, arrayvar_builtins)); } +static int @@ -89,7 +92,6 @@ index e243021..0a7a0e5 100644 static int rename (from, to) diff --git a/doc/bash.1 b/doc/bash.1 -index 5af7d42..7539368 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -239,6 +239,14 @@ The shell becomes restricted (see @@ -108,10 +110,9 @@ index 5af7d42..7539368 100644 Equivalent to \fB\-v\fP. .TP diff --git a/doc/bashref.texi b/doc/bashref.texi -index 9e23f58..d02151e 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi -@@ -6554,6 +6554,13 @@ standard. @xref{Bash POSIX Mode}, for a description of the Bash +@@ -6927,6 +6927,13 @@ standard. @xref{Bash POSIX Mode}, for a description of the Bash @item --restricted Make the shell a restricted shell (@pxref{The Restricted Shell}). @@ -126,10 +127,9 @@ index 9e23f58..d02151e 100644 Equivalent to @option{-v}. Print shell input lines as they're read. diff --git a/eval.c b/eval.c -index 1d967da..f197033 100644 --- a/eval.c +++ b/eval.c -@@ -137,7 +137,8 @@ reader_loop () +@@ -138,7 +138,8 @@ reader_loop () if (read_command () == 0) { @@ -137,13 +137,12 @@ index 1d967da..f197033 100644 + + if (interactive_shell == 0 && (read_but_dont_execute && !rpm_requires)) { - set_exit_status (EXECUTION_SUCCESS); + set_exit_status (last_command_exit_value); dispose_command (global_command); diff --git a/execute_cmd.c b/execute_cmd.c -index d2555ad..397e283 100644 --- a/execute_cmd.c +++ b/execute_cmd.c -@@ -543,6 +543,8 @@ async_redirect_stdin () +@@ -561,6 +561,8 @@ async_redirect_stdin () #define DESCRIBE_PID(pid) do { if (interactive) describe_pid (pid); } while (0) @@ -152,22 +151,22 @@ index d2555ad..397e283 100644 /* Execute the command passed in COMMAND, perhaps doing it asynchronously. COMMAND is exactly what read_command () places into GLOBAL_COMMAND. ASYNCHRONOUS, if non-zero, says to do this command in the background. -@@ -574,7 +576,13 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, +@@ -592,7 +594,13 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out, if (breaking || continuing) return (last_command_exit_value); -- if (command == 0 || read_but_dont_execute) +- if (read_but_dont_execute) + if (command == 0 || (read_but_dont_execute && !rpm_requires)) + return (EXECUTION_SUCCESS); + if (rpm_requires && command->type == cm_function_def) + return last_command_exit_value = + execute_intern_function (command->value.Function_def->name, + command->value.Function_def); -+ if (read_but_dont_execute) ++ if (read_but_dont_execute) + return (last_command_exit_value); + if (command == 0) return (EXECUTION_SUCCESS); - - QUIT; -@@ -2836,7 +2844,7 @@ execute_for_command (for_command) +@@ -2883,7 +2891,7 @@ execute_for_command (for_command) save_line_number = line_number; if (check_identifier (for_command->name, 1) == 0) { @@ -177,7 +176,6 @@ index d2555ad..397e283 100644 last_command_exit_value = EX_BADUSAGE; jump_to_top_level (ERREXIT); diff --git a/execute_cmd.h b/execute_cmd.h -index 465030a..9c7fd1c 100644 --- a/execute_cmd.h +++ b/execute_cmd.h @@ -22,6 +22,9 @@ @@ -191,7 +189,6 @@ index 465030a..9c7fd1c 100644 #if defined (ARRAY_VARS) struct func_array_state diff --git a/make_cmd.c b/make_cmd.c -index 2d7ac96..ac53526 100644 --- a/make_cmd.c +++ b/make_cmd.c @@ -35,6 +35,8 @@ @@ -203,7 +200,7 @@ index 2d7ac96..ac53526 100644 #include "execute_cmd.h" #include "parser.h" #include "flags.h" -@@ -828,6 +830,30 @@ make_coproc_command (name, command) +@@ -839,6 +841,30 @@ make_coproc_command (name, command) return (make_command (cm_coproc, (SIMPLE_COM *)temp)); } @@ -234,7 +231,7 @@ index 2d7ac96..ac53526 100644 /* Reverse the word list and redirection list in the simple command has just been parsed. It seems simpler to do this here the one time then by any other method that I can think of. */ -@@ -845,6 +871,28 @@ clean_simple_command (command) +@@ -856,6 +882,28 @@ clean_simple_command (command) REVERSE_LIST (command->value.Simple->redirects, REDIRECT *); } @@ -264,10 +261,9 @@ index 2d7ac96..ac53526 100644 return (command); } diff --git a/shell.c b/shell.c -index ce8087f..7dcd000 100644 --- a/shell.c +++ b/shell.c -@@ -194,6 +194,9 @@ int have_devfd = 0; +@@ -196,6 +196,9 @@ int have_devfd = 0; /* The name of the .(shell)rc file. */ static char *bashrc_file = DEFAULT_BASHRC; @@ -277,7 +273,7 @@ index ce8087f..7dcd000 100644 /* Non-zero means to act more like the Bourne shell on startup. */ static int act_like_sh; -@@ -260,6 +263,7 @@ static const struct { +@@ -266,6 +269,7 @@ static const struct { { "protected", Int, &protected_mode, (char **)0x0 }, #endif { "rcfile", Charp, (int *)0x0, &bashrc_file }, @@ -285,9 +281,9 @@ index ce8087f..7dcd000 100644 #if defined (RESTRICTED_SHELL) { "restricted", Int, &restricted, (char **)0x0 }, #endif -@@ -502,6 +506,12 @@ main (argc, argv, env) - if (dump_translatable_strings) +@@ -510,6 +514,12 @@ main (argc, argv, env) read_but_dont_execute = 1; + #endif + if (rpm_requires) + { @@ -299,10 +295,9 @@ index ce8087f..7dcd000 100644 disable_priv_mode (); diff --git a/shell.h b/shell.h -index 8b41792..29b0efb 100644 --- a/shell.h +++ b/shell.h -@@ -99,6 +99,7 @@ extern int interactive, interactive_shell; +@@ -100,6 +100,7 @@ extern int interactive, interactive_shell; extern int startup_state; extern int reading_shell_script; extern int shell_initialized; diff --git a/system/base/bash/files/fedora/bash-tty-tests.patch b/system/base/bash/files/fedora/bash-tty-tests.patch index 93117464..ad8a50be 100644 --- a/system/base/bash/files/fedora/bash-tty-tests.patch +++ b/system/base/bash/files/fedora/bash-tty-tests.patch @@ -1,8 +1,7 @@ diff --git a/tests/exec.right b/tests/exec.right -index 0a249dd..fe8a127 100644 --- a/tests/exec.right +++ b/tests/exec.right -@@ -51,7 +51,6 @@ this is ohio-state +@@ -60,7 +60,6 @@ this is ohio-state 0 1 testb @@ -11,7 +10,6 @@ index 0a249dd..fe8a127 100644 1 1 diff --git a/tests/execscript b/tests/execscript -index 2809676..1216828 100644 --- a/tests/execscript +++ b/tests/execscript @@ -108,8 +108,6 @@ ${THIS_SH} ./exec6.sub @@ -24,26 +22,27 @@ index 2809676..1216828 100644 ${THIS_SH} ./exec10.sub diff --git a/tests/read.right b/tests/read.right -index 1144083..09cd422 100644 --- a/tests/read.right +++ b/tests/read.right -@@ -33,14 +33,6 @@ a = abcdefg +@@ -34,17 +34,6 @@ xyz a = xyz a = -xyz 123- a = abc -timeout 1: ok -- +-unset or null 1 -timeout 2: ok -- --./read2.sub: line 36: read: -3: invalid timeout specification +-unset or null 2 +-timeout 3: ok +-unset or null 3 +-./read2.sub: line 45: read: -3: invalid timeout specification -1 - +-abcde -abcde ./read3.sub: line 17: read: -1: invalid number abc - ab + defg diff --git a/tests/read.tests b/tests/read.tests -index 7384f05..43fcf8d 100644 --- a/tests/read.tests +++ b/tests/read.tests @@ -95,9 +95,6 @@ echo " foo" | { IFS=$':' ; read line; recho "$line"; } diff --git a/system/base/bash/files/official/bash52-001.patch b/system/base/bash/files/official/bash52-001.patch new file mode 100644 index 00000000..83776ec7 --- /dev/null +++ b/system/base/bash/files/official/bash52-001.patch @@ -0,0 +1,46 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-001 + +Bug-Reported-by: Emanuele Torre +Bug-Reference-ID: +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-09/msg00060.html + +Bug-Description: + +Expanding unset arrays in an arithmetic context can cause a segmentation fault. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2/subst.c 2022-08-31 17:36:46.000000000 -0400 +--- subst.c 2022-09-30 09:12:05.000000000 -0400 +*************** +*** 10858,10862 **** + t = expand_subscript_string (exp, quoted & ~(Q_ARITH|Q_DOUBLE_QUOTES)); + free (exp); +! exp = sh_backslash_quote (t, abstab, 0); + free (t); + +--- 10858,10862 ---- + t = expand_subscript_string (exp, quoted & ~(Q_ARITH|Q_DOUBLE_QUOTES)); + free (exp); +! exp = t ? sh_backslash_quote (t, abstab, 0) : savestring (""); + free (t); + +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 0 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 1 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-002.patch b/system/base/bash/files/official/bash52-002.patch new file mode 100644 index 00000000..18229c99 --- /dev/null +++ b/system/base/bash/files/official/bash52-002.patch @@ -0,0 +1,46 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-002 + +Bug-Reported-by: Kan-Ru Chen +Bug-Reference-ID: +Bug-Reference-URL: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1021109 + +Bug-Description: + +Starting bash with an invalid locale specification for LC_ALL/LANG/LC_CTYPE +can cause the shell to crash. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/lib/readline/nls.c 2022-08-15 09:38:51.000000000 -0400 +--- lib/readline/nls.c 2022-10-05 09:23:22.000000000 -0400 +*************** +*** 142,145 **** +--- 142,149 ---- + lspec = ""; + ret = setlocale (LC_CTYPE, lspec); /* ok, since it does not change locale */ ++ if (ret == 0 || *ret == 0) ++ ret = setlocale (LC_CTYPE, (char *)NULL); ++ if (ret == 0 || *ret == 0) ++ ret = RL_DEFAULT_LOCALE; + #else + ret = (lspec == 0 || *lspec == 0) ? RL_DEFAULT_LOCALE : lspec; + +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 1 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 2 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-003.patch b/system/base/bash/files/official/bash52-003.patch new file mode 100644 index 00000000..b2dc4cbc --- /dev/null +++ b/system/base/bash/files/official/bash52-003.patch @@ -0,0 +1,89 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-003 + +Bug-Reported-by: D630 +Bug-Reference-ID: +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00092.html + +Bug-Description: + +Command substitutions need to preserve newlines instead of replacing them +with semicolons, especially in the presence of multiple here-documents. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/print_cmd.c 2022-07-26 09:16:39.000000000 -0400 +--- print_cmd.c 2022-10-17 10:41:06.000000000 -0400 +*************** +*** 298,305 **** +--- 298,307 ---- + { + char c = command->value.Connection->connector; ++ int was_newline; + + s[0] = printing_comsub ? c : ';'; + s[1] = '\0'; + ++ was_newline = deferred_heredocs == 0 && was_heredoc == 0 && c == '\n'; + if (deferred_heredocs == 0) + { +*************** +*** 315,318 **** +--- 317,322 ---- + if (inside_function_def) + cprintf ("\n"); ++ else if (printing_comsub && c == '\n' && was_newline == 0) ++ cprintf ("\n"); /* preserve newlines in comsubs but don't double them */ + else + { +*************** +*** 1366,1370 **** + } + else +! newline ("}"); + + dispose_command (cmdcopy); +--- 1371,1379 ---- + } + else +! { +! /* { */ +! newline ("}"); +! was_heredoc = 0; /* not printing any here-documents now */ +! } + + dispose_command (cmdcopy); +*************** +*** 1443,1447 **** + } + else +! newline ("}"); + + result = the_printed_command; +--- 1452,1459 ---- + } + else +! { /* { */ +! newline ("}"); +! was_heredoc = 0; +! } + + result = the_printed_command; +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 2 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 3 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-004.patch b/system/base/bash/files/official/bash52-004.patch new file mode 100644 index 00000000..d0834c19 --- /dev/null +++ b/system/base/bash/files/official/bash52-004.patch @@ -0,0 +1,70 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-004 + +Bug-Reported-by: Antoine +Bug-Reference-ID: <8bd59753-05ff-9b09-2337-2c7f52ded650@glitchimini.net> +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00022.html + +Bug-Description: + +Bash needs to keep better track of nested brace expansions to avoid problems +with quoting and POSIX semantics. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/subst.c 2022-10-05 10:22:02.000000000 -0400 +--- subst.c 2022-10-06 15:19:08.000000000 -0400 +*************** +*** 1799,1802 **** +--- 1804,1810 ---- + } + ++ #define PARAMEXPNEST_MAX 32 // for now ++ static int dbstate[PARAMEXPNEST_MAX]; ++ + /* Extract a parameter expansion expression within ${ and } from STRING. + Obey the Posix.2 rules for finding the ending `}': count braces while +*************** +*** 1829,1832 **** +--- 1837,1842 ---- + return (extract_heredoc_dolbrace_string (string, sindex, quoted, flags)); + ++ dbstate[0] = dolbrace_state; ++ + pass_character = 0; + nesting_level = 1; +*************** +*** 1853,1856 **** +--- 1863,1868 ---- + if (string[i] == '$' && string[i+1] == LBRACE) + { ++ if (nesting_level < PARAMEXPNEST_MAX) ++ dbstate[nesting_level] = dolbrace_state; + nesting_level++; + i += 2; +*************** +*** 1865,1868 **** +--- 1877,1881 ---- + if (nesting_level == 0) + break; ++ dolbrace_state = (nesting_level < PARAMEXPNEST_MAX) ? dbstate[nesting_level] : dbstate[0]; /* Guess using initial state */ + i++; + continue; +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 3 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 4 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-005.patch b/system/base/bash/files/official/bash52-005.patch new file mode 100644 index 00000000..3f6a8521 --- /dev/null +++ b/system/base/bash/files/official/bash52-005.patch @@ -0,0 +1,47 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-005 + +Bug-Reported-by: Justin Wood (Callek) +Bug-Reference-ID: +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00088.html + +Bug-Description: + +Null pattern substitution replacement strings can cause a crash. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/subst.c 2022-10-05 10:22:02.000000000 -0400 +--- subst.c 2022-10-13 16:57:26.000000000 -0400 +*************** +*** 8966,8970 **** + } + else if (*string == 0 && (match_pattern (string, pat, mtype, &s, &e) != 0)) +! return ((mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2) : savestring (rep)); + + ret = (char *)xmalloc (rsize = 64); +--- 8966,8971 ---- + } + else if (*string == 0 && (match_pattern (string, pat, mtype, &s, &e) != 0)) +! return (mflags & MATCH_EXPREP) ? strcreplace (rep, '&', "", 2) +! : (rep ? savestring (rep) : savestring ("")); + + ret = (char *)xmalloc (rsize = 64); +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 4 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 5 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-006.patch b/system/base/bash/files/official/bash52-006.patch new file mode 100644 index 00000000..851cfd7b --- /dev/null +++ b/system/base/bash/files/official/bash52-006.patch @@ -0,0 +1,293 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-006 + +Bug-Reported-by: feng xiangjun +Bug-Reference-ID: +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00089.html + +Bug-Description: + +In interactive shells, interrupting the shell while entering a command +substitution can inhibit alias expansion. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/parse.y 2022-10-08 13:10:06.000000000 -0400 +--- parse.y 2022-10-14 10:03:19.000000000 -0400 +*************** +*** 3307,3310 **** +--- 3307,3312 ---- + extended_glob = global_extglob; + #endif ++ if (parser_state & (PST_CMDSUBST|PST_STRING)) ++ expand_aliases = expaliases_flag; + + parser_state = 0; +*************** +*** 4389,4392 **** +--- 4391,4395 ---- + parser_state |= PST_NOERROR; + ++ parser_state |= PST_STRING; + expand_aliases = 0; + +*************** +*** 6402,6406 **** + parser_state &= ~PST_NOEXPAND; /* parse_comsub sentinel */ + /* State flags we want to set for this run through the tokenizer. */ +! parser_state |= PST_COMPASSIGN|PST_REPARSE; + } + +--- 6405,6409 ---- + parser_state &= ~PST_NOEXPAND; /* parse_comsub sentinel */ + /* State flags we want to set for this run through the tokenizer. */ +! parser_state |= PST_COMPASSIGN|PST_REPARSE|PST_STRING; + } + +*** ../bash-20221007/parser.h 2022-08-30 11:39:56.000000000 -0400 +--- parser.h 2022-10-14 09:56:18.000000000 -0400 +*************** +*** 51,54 **** +--- 51,55 ---- + #define PST_NOEXPAND 0x400000 /* don't expand anything in read_token_word; for command substitution */ + #define PST_NOERROR 0x800000 /* don't print error messages in yyerror */ ++ #define PST_STRING 0x1000000 /* parsing a string to a command or word list */ + + /* Definition of the delimiter stack. Needed by parse.y and bashhist.c. */ +*** ../bash-20221007/builtins/shopt.def 2022-10-07 10:25:55.000000000 -0400 +--- builtins/shopt.def 2022-10-14 09:30:11.000000000 -0400 +*************** +*** 150,153 **** +--- 150,156 ---- + #endif + ++ int expaliases_flag = 0; ++ static int shopt_set_expaliases PARAMS((char *, int)); ++ + static int shopt_set_debug_mode PARAMS((char *, int)); + +*************** +*** 199,203 **** + { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL }, + { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL }, +! { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL }, + #if defined (DEBUGGER) + { "extdebug", &debugging_mode, shopt_set_debug_mode }, +--- 202,206 ---- + { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL }, + { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL }, +! { "expand_aliases", &expaliases_flag, shopt_set_expaliases }, + #if defined (DEBUGGER) + { "extdebug", &debugging_mode, shopt_set_debug_mode }, +*************** +*** 351,355 **** + allow_null_glob_expansion = glob_dot_filenames = 0; + no_exit_on_failed_exec = 0; +! expand_aliases = 0; + extended_quote = 1; + fail_glob_expansion = 0; +--- 354,358 ---- + allow_null_glob_expansion = glob_dot_filenames = 0; + no_exit_on_failed_exec = 0; +! expand_aliases = expaliases_flag = 0; + extended_quote = 1; + fail_glob_expansion = 0; +*************** +*** 632,635 **** +--- 635,647 ---- + } + ++ static int ++ shopt_set_expaliases (option_name, mode) ++ char *option_name; ++ int mode; ++ { ++ expand_aliases = expaliases_flag; ++ return 0; ++ } ++ + #if defined (READLINE) + static int +*** ../bash-20221007/builtins/common.h 2022-10-07 10:10:17.000000000 -0400 +--- builtins/common.h 2022-10-14 09:29:25.000000000 -0400 +*************** +*** 258,261 **** +--- 258,263 ---- + #endif + ++ extern int expaliases_flag; ++ + /* variables from source.def */ + extern int source_searches_cwd; +*** ../bash-20221007/execute_cmd.c 2022-10-10 10:48:54.000000000 -0400 +--- execute_cmd.c 2022-10-14 09:32:24.000000000 -0400 +*************** +*** 1537,1541 **** + aliases. */ + if (ois != interactive_shell) +! expand_aliases = 0; + } + +--- 1537,1541 ---- + aliases. */ + if (ois != interactive_shell) +! expand_aliases = expaliases_flag = 0; + } + +*** ../bash-20221007/general.c 2021-11-04 14:12:38.000000000 -0400 +--- general.c 2022-10-14 09:34:24.000000000 -0400 +*************** +*** 92,96 **** + &interactive_comments, + &source_uses_path, +! &expand_aliases, + &inherit_errexit, + &print_shift_error, +--- 92,96 ---- + &interactive_comments, + &source_uses_path, +! &expaliases_flag, + &inherit_errexit, + &print_shift_error, +*************** +*** 107,111 **** + if (on != 0) + { +! interactive_comments = source_uses_path = expand_aliases = 1; + inherit_errexit = 1; + source_searches_cwd = 0; +--- 107,112 ---- + if (on != 0) + { +! interactive_comments = source_uses_path = 1; +! expand_aliases = expaliases_flag = 1; + inherit_errexit = 1; + source_searches_cwd = 0; +*************** +*** 117,120 **** +--- 118,122 ---- + { + set_posix_options (saved_posix_vars); ++ expand_aliases = expaliases_flag; + free (saved_posix_vars); + saved_posix_vars = 0; +*************** +*** 123,127 **** + { + source_searches_cwd = 1; +! expand_aliases = interactive_shell; + print_shift_error = 0; + } +--- 125,129 ---- + { + source_searches_cwd = 1; +! expand_aliases = expaliases_flag = interactive_shell; /* XXX */ + print_shift_error = 0; + } + +*** ../bash-5.2-patched/shell.c 2022-03-04 15:13:00.000000000 -0500 +--- shell.c 2022-10-14 09:36:19.000000000 -0400 +*************** +*** 1845,1850 **** + init_interactive () + { +! expand_aliases = interactive_shell = startup_state = 1; +! interactive = 1; + #if defined (HISTORY) + if (enable_history_list == -1) +--- 1845,1850 ---- + init_interactive () + { +! expand_aliases = expaliases_flag = 1; +! interactive_shell = startup_state = interactive = 1; + #if defined (HISTORY) + if (enable_history_list == -1) +*************** +*** 1866,1870 **** + #endif /* HISTORY */ + interactive_shell = startup_state = interactive = 0; +! expand_aliases = posixly_correct; /* XXX - was 0 not posixly_correct */ + no_line_editing = 1; + #if defined (JOB_CONTROL) +--- 1866,1870 ---- + #endif /* HISTORY */ + interactive_shell = startup_state = interactive = 0; +! expand_aliases = expaliases_flag = posixly_correct; /* XXX - was 0 not posixly_correct */ + no_line_editing = 1; + #if defined (JOB_CONTROL) +*************** +*** 1883,1887 **** + #endif + init_noninteractive (); +! expand_aliases = interactive_shell = startup_state = 1; + #if defined (HISTORY) + remember_on_history = enable_history_list; /* XXX */ +--- 1883,1887 ---- + #endif + init_noninteractive (); +! expand_aliases = expaliases_flag = interactive_shell = startup_state = 1; + #if defined (HISTORY) + remember_on_history = enable_history_list; /* XXX */ +*************** +*** 2026,2030 **** + forced_interactive = interactive_shell = 0; + subshell_environment = running_in_background = 0; +! expand_aliases = 0; + bash_argv_initialized = 0; + +--- 2026,2030 ---- + forced_interactive = interactive_shell = 0; + subshell_environment = running_in_background = 0; +! expand_aliases = expaliases_flag = 0; + bash_argv_initialized = 0; + +*** ../bash-5.2-patched/y.tab.c 2022-09-23 10:18:27.000000000 -0400 +--- y.tab.c 2022-10-14 14:57:26.000000000 -0400 +*************** +*** 5618,5621 **** +--- 5618,5623 ---- + extended_glob = global_extglob; + #endif ++ if (parser_state & (PST_CMDSUBST|PST_STRING)) ++ expand_aliases = expaliases_flag; + + parser_state = 0; +*************** +*** 6700,6703 **** +--- 6702,6706 ---- + parser_state |= PST_NOERROR; + ++ parser_state |= PST_STRING; + expand_aliases = 0; + +*************** +*** 8713,8717 **** + parser_state &= ~PST_NOEXPAND; /* parse_comsub sentinel */ + /* State flags we want to set for this run through the tokenizer. */ +! parser_state |= PST_COMPASSIGN|PST_REPARSE; + } + +--- 8716,8720 ---- + parser_state &= ~PST_NOEXPAND; /* parse_comsub sentinel */ + /* State flags we want to set for this run through the tokenizer. */ +! parser_state |= PST_COMPASSIGN|PST_REPARSE|PST_STRING; + } + +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 5 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 6 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-007.patch b/system/base/bash/files/official/bash52-007.patch new file mode 100644 index 00000000..152776f4 --- /dev/null +++ b/system/base/bash/files/official/bash52-007.patch @@ -0,0 +1,262 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-007 + +Bug-Reported-by: Bruce Jerrick +Bug-Reference-ID: +Bug-Reference-URL: https://bugzilla.redhat.com/show_bug.cgi?id=2134307 + +Bug-Description: + +This patch fixes several problems with alias expansion inside command +substitutions when in POSIX mode. + +Patch (apply with `patch -p0'): + +*** /fs1/chet/scratch/bash-5.2.6/parse.y 2022-11-02 10:36:54.000000000 -0400 +--- parse.y 2022-10-24 10:53:26.000000000 -0400 +*************** +*** 3613,3616 **** +--- 3614,3618 ---- + #define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */ + #define P_DOLBRACE 0x0040 /* parsing a ${...} construct */ ++ #define P_ARITH 0x0080 /* parsing a $(( )) arithmetic expansion */ + + /* Lexical state while parsing a grouping construct or $(...). */ +*************** +*** 3911,3914 **** +--- 3914,3920 ---- + else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */ + goto parse_dollar_word; ++ else if ((flags & P_ARITH) && (tflags & LEX_WASDOL) && ch == '(') /*)*/ ++ /* $() inside $(( ))/$[ ] */ ++ goto parse_dollar_word; + #if defined (PROCESS_SUBSTITUTION) + /* XXX - technically this should only be recognized at the start of +*************** +*** 3941,3945 **** + nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags); + else if (ch == '[') /* ] */ +! nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags); + + CHECK_NESTRET_ERROR (); +--- 3947,3951 ---- + nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags); + else if (ch == '[') /* ] */ +! nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags|P_ARITH); + + CHECK_NESTRET_ERROR (); +*************** +*** 4080,4084 **** + shell_ungetc (peekc); + if (peekc == '(') /*)*/ +! return (parse_matched_pair (qc, open, close, lenp, 0)); + } + +--- 4086,4090 ---- + shell_ungetc (peekc); + if (peekc == '(') /*)*/ +! return (parse_matched_pair (qc, open, close, lenp, P_ARITH)); + } + +*************** +*** 4501,4505 **** + + exp_lineno = line_number; +! ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0); + rval = 1; + if (ttok == &matched_pair_error) +--- 4512,4516 ---- + + exp_lineno = line_number; +! ttok = parse_matched_pair (0, '(', ')', &ttoklen, P_ARITH); + rval = 1; + if (ttok == &matched_pair_error) +*************** +*** 5016,5020 **** + } + else +! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ +--- 5030,5034 ---- + } + else +! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARITH); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ +*** ../bash-5.2.6/y.tab.c 2022-11-02 10:36:54.000000000 -0400 +--- y.tab.c 2022-11-02 10:55:58.000000000 -0400 +*************** +*** 5924,5927 **** +--- 5924,5928 ---- + #define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */ + #define P_DOLBRACE 0x0040 /* parsing a ${...} construct */ ++ #define P_ARITH 0x0080 /* parsing a $(( )) arithmetic expansion */ + + /* Lexical state while parsing a grouping construct or $(...). */ +*************** +*** 6222,6225 **** +--- 6223,6229 ---- + else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */ + goto parse_dollar_word; ++ else if ((flags & P_ARITH) && (tflags & LEX_WASDOL) && ch == '(') /*)*/ ++ /* $() inside $(( ))/$[ ] */ ++ goto parse_dollar_word; + #if defined (PROCESS_SUBSTITUTION) + /* XXX - technically this should only be recognized at the start of +*************** +*** 6252,6256 **** + nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags); + else if (ch == '[') /* ] */ +! nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags); + + CHECK_NESTRET_ERROR (); +--- 6256,6260 ---- + nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags); + else if (ch == '[') /* ] */ +! nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags|P_ARITH); + + CHECK_NESTRET_ERROR (); +*************** +*** 6391,6395 **** + shell_ungetc (peekc); + if (peekc == '(') /*)*/ +! return (parse_matched_pair (qc, open, close, lenp, 0)); + } + +--- 6395,6399 ---- + shell_ungetc (peekc); + if (peekc == '(') /*)*/ +! return (parse_matched_pair (qc, open, close, lenp, P_ARITH)); + } + +*************** +*** 6812,6816 **** + + exp_lineno = line_number; +! ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0); + rval = 1; + if (ttok == &matched_pair_error) +--- 6816,6820 ---- + + exp_lineno = line_number; +! ttok = parse_matched_pair (0, '(', ')', &ttoklen, P_ARITH); + rval = 1; + if (ttok == &matched_pair_error) +*************** +*** 7327,7331 **** + } + else +! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ +--- 7331,7335 ---- + } + else +! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARITH); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ +*** /fs1/chet/scratch/bash-5.2.6/builtins/evalstring.c 2022-07-18 14:46:56.000000000 -0400 +--- builtins/evalstring.c 2022-10-18 10:57:51.000000000 -0400 +*************** +*** 432,435 **** +--- 432,437 ---- + if (parse_command () == 0) + { ++ int local_expalias, local_alflag; ++ + if ((flags & SEVAL_PARSEONLY) || (interactive_shell == 0 && read_but_dont_execute)) + { +*************** +*** 508,511 **** +--- 510,526 ---- + #endif /* ONESHOT */ + ++ /* We play tricks in the parser and command_substitute() turning ++ expand_aliases on and off depending on which parsing pass and ++ whether or not we're in posix mode. This only matters for ++ parsing, and we let the higher layers deal with that. We just ++ want to ensure that expand_aliases is set to the appropriate ++ global value when we go to execute this command, so we save ++ and restore it around the execution (we don't restore it if ++ the global value of the flag (expaliases_flag) changes). */ ++ local_expalias = expand_aliases; ++ local_alflag = expaliases_flag; ++ if (subshell_environment & SUBSHELL_COMSUB) ++ expand_aliases = expaliases_flag; ++ + /* See if this is a candidate for $( word : (char *)NULL; + if (tword) +--- 11306,11310 ---- + { + de_backslash (temp); +! tword = command_substitute (temp, quoted, PF_BACKQUOTE); + temp1 = tword ? tword->word : (char *)NULL; + if (tword) +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 6 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 7 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-008.patch b/system/base/bash/files/official/bash52-008.patch new file mode 100644 index 00000000..ff637114 --- /dev/null +++ b/system/base/bash/files/official/bash52-008.patch @@ -0,0 +1,58 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-008 + +Bug-Reported-by: Glenn Jackman +Bug-Reference-ID: +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00095.html + +Bug-Description: + +Array subscript expansion can inappropriately quote brackets if the expression +contains < or >. + +Patch (apply with `patch -p0'): + +*** ../bash-20221015/subst.c 2022-10-18 10:47:33.000000000 -0500 +--- subst.c 2022-10-20 11:41:07.000000000 -0500 +*************** +*** 3820,3823 **** +--- 3820,3827 ---- + #endif + ++ /* We don't perform process substitution in arithmetic expressions, so don't ++ bother checking for it. */ ++ #define ARITH_EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~') ++ + /* If there are any characters in STRING that require full expansion, + then call FUNC to expand STRING; otherwise just perform quote +*************** +*** 4029,4033 **** + while (string[i]) + { +! if (EXP_CHAR (string[i])) + break; + else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"') +--- 4033,4037 ---- + while (string[i]) + { +! if (ARITH_EXP_CHAR (string[i])) + break; + else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"') +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 7 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 8 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-009.patch b/system/base/bash/files/official/bash52-009.patch new file mode 100644 index 00000000..f907c8c4 --- /dev/null +++ b/system/base/bash/files/official/bash52-009.patch @@ -0,0 +1,43 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-009 + +Bug-Reported-by: Corey Hickey +Bug-Reference-ID: <134330ef-0ead-d73e-68eb-d58fc51efdba@fatooh.org> +Bug-Reference-URL: https://lists.gnu.org/archive/html/help-bash/2022-10/msg00025.html + +Bug-Description: + +Bash arithmetic expansion should allow `@' and `*' to be used as associative +array keys in expressions. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/expr.c 2022-07-11 10:03:34.000000000 -0400 +--- expr.c 2022-10-31 10:51:08.000000000 -0400 +*************** +*** 1169,1172 **** +--- 1169,1174 ---- + #if defined (ARRAY_VARS) + aflag = tflag; /* use a different variable for now */ ++ if (shell_compatibility_level > 51) ++ aflag |= AV_ATSTARKEYS; + v = (e == ']') ? array_variable_part (tok, tflag, (char **)0, (int *)0) : find_variable (tok); + #else +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 8 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 9 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-010.patch b/system/base/bash/files/official/bash52-010.patch new file mode 100644 index 00000000..b58f4a86 --- /dev/null +++ b/system/base/bash/files/official/bash52-010.patch @@ -0,0 +1,71 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-010 + +Bug-Reported-by: larsh@apache.org +Bug-Reference-ID: +Bug-Reference-URL: https://savannah.gnu.org/support/?110744 + +Bug-Description: + +Bash-5.2 checks the first 128 characters of an executable file that execve() +refuses to execute to see whether it's a binary file before trying to +execute it as a shell script. This defeats some previously-supported use +cases like "self-executing" jar files or "self-uncompressing" scripts. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/general.c 2022-11-07 10:31:42.000000000 -0500 +--- general.c 2022-11-18 14:48:45.000000000 -0500 +*************** +*** 684,687 **** +--- 684,688 ---- + { + register int i; ++ int nline; + unsigned char c; + +*************** +*** 690,702 **** + + /* Generally we check the first line for NULs. If the first line looks like +! a `#!' interpreter specifier, we just look for NULs anywhere in the +! buffer. */ +! if (sample[0] == '#' && sample[1] == '!') +! return (memchr (sample, '\0', sample_len) != NULL); + + for (i = 0; i < sample_len; i++) + { + c = sample[i]; +! if (c == '\n') + return (0); + if (c == '\0') +--- 691,701 ---- + + /* Generally we check the first line for NULs. If the first line looks like +! a `#!' interpreter specifier, we look for NULs in the first two lines. */ +! nline = (sample[0] == '#' && sample[1] == '!') ? 2 : 1; + + for (i = 0; i < sample_len; i++) + { + c = sample[i]; +! if (c == '\n' && --nline == 0) + return (0); + if (c == '\0') +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 9 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 10 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-011.patch b/system/base/bash/files/official/bash52-011.patch new file mode 100644 index 00000000..e65a50a2 --- /dev/null +++ b/system/base/bash/files/official/bash52-011.patch @@ -0,0 +1,45 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-011 + +Bug-Reported-by: Fabien Orjollet +Bug-Reference-ID: +Bug-Reference-URL: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1023776 + +Bug-Description: + +Patch (apply with `patch -p0'): + +Using timeouts and readline editing with the `read' builtin (read -e -t) can +leave the readline timeout enabled, potentially resulting in an erroneous +timeout on the next call. + +*** ../bash-5.2-patched/builtins/read.def 2022-06-02 14:23:19.000000000 -0400 +--- builtins/read.def 2022-11-10 10:27:45.000000000 -0500 +*************** +*** 168,171 **** +--- 168,174 ---- + if (read_timeout) + shtimer_clear (read_timeout); ++ #if defined (READLINE) ++ rl_clear_timeout (); ++ #endif + read_timeout = 0; + } +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 10 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 11 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-012.patch b/system/base/bash/files/official/bash52-012.patch new file mode 100644 index 00000000..2791542c --- /dev/null +++ b/system/base/bash/files/official/bash52-012.patch @@ -0,0 +1,344 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-012 + +Bug-Reported-by: Kerin Millar +Bug-Reference-ID: <20221002095107.89561bc811e549b55644df11@plushkava.net> +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00001.html + +Bug-Description: + +When running in bash compatibility mode, nested command substitutions can +leave the `extglob' option enabled. + +Patch (apply with `patch -p0'): + +*** /fs1/chet/scratch/bash-5.2.12/builtins/shopt.def 2022-11-07 10:31:42.000000000 -0500 +--- builtins/shopt.def 2022-10-14 09:30:11.000000000 -0400 +*************** +*** 150,153 **** +--- 150,158 ---- + #endif + ++ #if defined (EXTENDED_GLOB) ++ int extglob_flag = EXTGLOB_DEFAULT; ++ static int shopt_set_extglob PARAMS((char *, int)); ++ #endif ++ + int expaliases_flag = 0; + static int shopt_set_expaliases PARAMS((char *, int)); +*************** +*** 207,211 **** + #endif + #if defined (EXTENDED_GLOB) +! { "extglob", &extended_glob, (shopt_set_func_t *)NULL }, + #endif + { "extquote", &extended_quote, (shopt_set_func_t *)NULL }, +--- 212,216 ---- + #endif + #if defined (EXTENDED_GLOB) +! { "extglob", &extglob_flag, shopt_set_extglob }, + #endif + { "extquote", &extended_quote, (shopt_set_func_t *)NULL }, +*************** +*** 378,382 **** + + #if defined (EXTENDED_GLOB) +! extended_glob = EXTGLOB_DEFAULT; + #endif + +--- 383,387 ---- + + #if defined (EXTENDED_GLOB) +! extended_glob = extglob_flag = EXTGLOB_DEFAULT; + #endif + +*************** +*** 644,647 **** +--- 649,663 ---- + } + ++ #if defined (EXTENDED_GLOB) ++ static int ++ shopt_set_extglob (option_name, mode) ++ char *option_name; ++ int mode; ++ { ++ extended_glob = extglob_flag; ++ return 0; ++ } ++ #endif ++ + #if defined (READLINE) + static int +*** /fs1/chet/scratch/bash-5.2.12/builtins/common.h 2022-11-07 10:31:42.000000000 -0500 +--- builtins/common.h 2022-10-14 09:29:25.000000000 -0400 +*************** +*** 258,261 **** +--- 258,265 ---- + #endif + ++ #if defined (EXTENDED_GLOB) ++ extern int extglob_flag; ++ #endif ++ + extern int expaliases_flag; + +*** /fs1/chet/scratch/bash-5.2.12/execute_cmd.c 2022-11-07 10:31:42.000000000 -0500 +--- execute_cmd.c 2022-11-02 16:32:12.000000000 -0400 +*************** +*** 3991,4001 **** + #endif /* COND_REGEXP */ + { +- int oe; +- oe = extended_glob; + extended_glob = 1; + result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE) + ? EXECUTION_SUCCESS + : EXECUTION_FAILURE; +! extended_glob = oe; + } + if (arg1 != nullstr) +--- 4015,4023 ---- + #endif /* COND_REGEXP */ + { + extended_glob = 1; + result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE) + ? EXECUTION_SUCCESS + : EXECUTION_FAILURE; +! extended_glob = extglob_flag; + } + if (arg1 != nullstr) +*** /fs1/chet/scratch/bash-5.2.9/parse.y 2022-11-07 10:31:47.000000000 -0500 +--- parse.y 2022-11-14 11:27:22.000000000 -0500 +*************** +*** 126,130 **** + + #if defined (EXTENDED_GLOB) +! extern int extended_glob; + #endif + +--- 126,130 ---- + + #if defined (EXTENDED_GLOB) +! extern int extended_glob, extglob_flag; + #endif + +*************** +*** 3305,3309 **** + /* Reset to global value of extended glob */ + if (parser_state & (PST_EXTPAT|PST_CMDSUBST)) +! extended_glob = global_extglob; + #endif + if (parser_state & (PST_CMDSUBST|PST_STRING)) +--- 3321,3325 ---- + /* Reset to global value of extended glob */ + if (parser_state & (PST_EXTPAT|PST_CMDSUBST)) +! extended_glob = extglob_flag; + #endif + if (parser_state & (PST_CMDSUBST|PST_STRING)) +*************** +*** 4125,4132 **** + #if defined (EXTENDED_GLOB) + /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a +! conditional command and have already set global_extglob appropriately. */ + if (shell_compatibility_level <= 51 && was_extpat == 0) + { +! local_extglob = global_extglob = extended_glob; + extended_glob = 1; + } +--- 4143,4150 ---- + #if defined (EXTENDED_GLOB) + /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a +! conditional command and have already set extended_glob appropriately. */ + if (shell_compatibility_level <= 51 && was_extpat == 0) + { +! local_extglob = extended_glob; + extended_glob = 1; + } +*************** +*** 4236,4240 **** + sh_parser_state_t ps; + sh_input_line_state_t ls; +! int orig_ind, nc, sflags, start_lineno; + char *ret, *ep, *ostring; + +--- 4256,4260 ---- + sh_parser_state_t ps; + sh_input_line_state_t ls; +! int orig_ind, nc, sflags, start_lineno, local_extglob; + char *ret, *ep, *ostring; + +*************** +*** 4279,4283 **** + expand_aliases = 0; + #if defined (EXTENDED_GLOB) +! global_extglob = extended_glob; /* for reset_parser() */ + #endif + +--- 4299,4303 ---- + expand_aliases = 0; + #if defined (EXTENDED_GLOB) +! local_extglob = extended_glob; + #endif + +*************** +*** 4297,4300 **** +--- 4317,4323 ---- + restore_parser_state (&ps); + ++ #if defined (EXTENDED_GLOB) ++ extended_glob = local_extglob; ++ #endif + token_to_read = 0; + +*************** +*** 4732,4741 **** +--- 4755,4768 ---- + + /* rhs */ ++ #if defined (EXTENDED_GLOB) + local_extglob = extended_glob; + if (parser_state & PST_EXTPAT) + extended_glob = 1; ++ #endif + tok = read_token (READ); ++ #if defined (EXTENDED_GLOB) + if (parser_state & PST_EXTPAT) + extended_glob = local_extglob; ++ #endif + parser_state &= ~(PST_REGEXP|PST_EXTPAT); + +*************** +*** 4784,4788 **** + COND_COM *cexp; + +- global_extglob = extended_glob; + cexp = cond_expr (); + return (make_cond_command (cexp)); +--- 4811,4814 ---- +*** y.tab.c.save 2022-11-07 10:31:47.000000000 -0500 +--- y.tab.c 2022-11-18 15:58:03.000000000 -0500 +*************** +*** 176,180 **** + + #if defined (EXTENDED_GLOB) +! extern int extended_glob; + #endif + +--- 176,180 ---- + + #if defined (EXTENDED_GLOB) +! extern int extended_glob, extglob_flag; + #endif + +*************** +*** 5616,5620 **** + /* Reset to global value of extended glob */ + if (parser_state & (PST_EXTPAT|PST_CMDSUBST)) +! extended_glob = global_extglob; + #endif + if (parser_state & (PST_CMDSUBST|PST_STRING)) +--- 5616,5620 ---- + /* Reset to global value of extended glob */ + if (parser_state & (PST_EXTPAT|PST_CMDSUBST)) +! extended_glob = extglob_flag; + #endif + if (parser_state & (PST_CMDSUBST|PST_STRING)) +*************** +*** 6436,6443 **** + #if defined (EXTENDED_GLOB) + /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a +! conditional command and have already set global_extglob appropriately. */ + if (shell_compatibility_level <= 51 && was_extpat == 0) + { +! local_extglob = global_extglob = extended_glob; + extended_glob = 1; + } +--- 6436,6443 ---- + #if defined (EXTENDED_GLOB) + /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a +! conditional command and have already set extended_glob appropriately. */ + if (shell_compatibility_level <= 51 && was_extpat == 0) + { +! local_extglob = extended_glob; + extended_glob = 1; + } +*************** +*** 6547,6551 **** + sh_parser_state_t ps; + sh_input_line_state_t ls; +! int orig_ind, nc, sflags, start_lineno; + char *ret, *ep, *ostring; + +--- 6547,6551 ---- + sh_parser_state_t ps; + sh_input_line_state_t ls; +! int orig_ind, nc, sflags, start_lineno, local_extglob; + char *ret, *ep, *ostring; + +*************** +*** 6590,6594 **** + expand_aliases = 0; + #if defined (EXTENDED_GLOB) +! global_extglob = extended_glob; /* for reset_parser() */ + #endif + +--- 6590,6594 ---- + expand_aliases = 0; + #if defined (EXTENDED_GLOB) +! local_extglob = extended_glob; + #endif + +*************** +*** 6608,6611 **** +--- 6608,6614 ---- + restore_parser_state (&ps); + ++ #if defined (EXTENDED_GLOB) ++ extended_glob = local_extglob; ++ #endif + token_to_read = 0; + +*************** +*** 7043,7052 **** +--- 7046,7059 ---- + + /* rhs */ ++ #if defined (EXTENDED_GLOB) + local_extglob = extended_glob; + if (parser_state & PST_EXTPAT) + extended_glob = 1; ++ #endif + tok = read_token (READ); ++ #if defined (EXTENDED_GLOB) + if (parser_state & PST_EXTPAT) + extended_glob = local_extglob; ++ #endif + parser_state &= ~(PST_REGEXP|PST_EXTPAT); + +*************** +*** 7095,7099 **** + COND_COM *cexp; + +- global_extglob = extended_glob; + cexp = cond_expr (); + return (make_cond_command (cexp)); +--- 7102,7105 ---- +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 11 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 12 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-013.patch b/system/base/bash/files/official/bash52-013.patch new file mode 100644 index 00000000..3051269c --- /dev/null +++ b/system/base/bash/files/official/bash52-013.patch @@ -0,0 +1,58 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-013 + +Bug-Reported-by: Ralf Oehler +Bug-Reference-ID: <20221120140252.2fc6489b@bilbo> +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-11/msg00082.html + +Bug-Description: + +Bash can leak memory when referencing a non-existent associative array +element. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/subst.c 2022-11-05 17:27:48.000000000 -0400 +--- subst.c 2022-11-21 14:42:59.000000000 -0500 +*************** +*** 7498,7503 **** + : quote_escapes (temp); + rflags |= W_ARRAYIND; +- if (estatep) +- *estatep = es; /* structure copy */ + } + /* Note that array[*] and array[@] expanded to a quoted null string by +--- 7508,7511 ---- +*************** +*** 7508,7512 **** + rflags |= W_HASQUOTEDNULL; + +! if (estatep == 0) + flush_eltstate (&es); + } +--- 7516,7522 ---- + rflags |= W_HASQUOTEDNULL; + +! if (estatep) +! *estatep = es; /* structure copy */ +! else + flush_eltstate (&es); + } +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 12 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 13 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-014.patch b/system/base/bash/files/official/bash52-014.patch new file mode 100644 index 00000000..c6f3176b --- /dev/null +++ b/system/base/bash/files/official/bash52-014.patch @@ -0,0 +1,119 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-014 + +Bug-Reported-by: Andreas Schwab +Bug-Reference-ID: +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00076.html + +Bug-Description: + +Bash defers processing additional terminating signals when running the +EXIT trap while exiting due to a terminating signal. This patch allows the +new terminating signal to kill the shell immediately. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/execute_cmd.c 2022-11-23 17:09:18.000000000 -0500 +--- execute_cmd.c 2022-11-28 10:36:08.000000000 -0500 +*************** +*** 3625,3628 **** +--- 3649,3653 ---- + + dispose_words (es); ++ QUIT; + + if (match) +*** ../bash-5.2-patched/sig.c 2021-11-04 14:15:31.000000000 -0400 +--- sig.c 2022-12-06 09:45:11.000000000 -0500 +*************** +*** 95,98 **** +--- 95,99 ---- + + static void initialize_shell_signals PARAMS((void)); ++ static void kill_shell PARAMS((int)); + + void +*************** +*** 487,490 **** +--- 495,500 ---- + } + ++ static int handling_termsig = 0; ++ + sighandler + termsig_sighandler (sig) +*************** +*** 533,536 **** +--- 543,554 ---- + terminate_immediately = 1; + ++ /* If we are currently handling a terminating signal, we have a couple of ++ choices here. We can ignore this second terminating signal and let the ++ shell exit from the first one, or we can exit immediately by killing ++ the shell with this signal. This code implements the latter; to implement ++ the former, replace the kill_shell(sig) with return. */ ++ if (handling_termsig) ++ kill_shell (sig); /* just short-circuit now */ ++ + terminating_signal = sig; + +*************** +*** 565,572 **** + int sig; + { +- static int handling_termsig = 0; +- int i, core; +- sigset_t mask; +- + /* Simple semaphore to keep this function from being executed multiple + times. Since we no longer are running as a signal handler, we don't +--- 585,588 ---- +*************** +*** 574,578 **** + if (handling_termsig) + return; +! handling_termsig = 1; + terminating_signal = 0; /* keep macro from re-testing true. */ + +--- 590,595 ---- + if (handling_termsig) + return; +! +! handling_termsig = terminating_signal; /* for termsig_sighandler */ + terminating_signal = 0; /* keep macro from re-testing true. */ + +*************** +*** 614,617 **** +--- 631,644 ---- + run_exit_trap (); /* XXX - run exit trap possibly in signal context? */ + ++ kill_shell (sig); ++ } ++ ++ static void ++ kill_shell (sig) ++ int sig; ++ { ++ int i, core; ++ sigset_t mask; ++ + /* We don't change the set of blocked signals. If a user starts the shell + with a terminating signal blocked, we won't get here (and if by some +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 13 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 14 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/files/official/bash52-015.patch b/system/base/bash/files/official/bash52-015.patch new file mode 100644 index 00000000..740a13da --- /dev/null +++ b/system/base/bash/files/official/bash52-015.patch @@ -0,0 +1,216 @@ + BASH PATCH REPORT + ================= + +Bash-Release: 5.2 +Patch-ID: bash52-015 + +Bug-Reported-by: Frode Nordahl +Bug-Reference-ID: <20221119070714.351759-1-frode.nordahl@canonical.com> +Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-11/msg00078.html + +Bug-Description: + +There are several cases where bash is too aggressive when optimizing out forks +in subshells. For example, `eval' and traps should never be optimized. + +Patch (apply with `patch -p0'): + +*** ../bash-5.2-patched/builtins/common.h 2022-11-23 17:09:18.000000000 -0500 +--- builtins/common.h 2022-11-19 18:03:59.000000000 -0500 +*************** +*** 52,55 **** +--- 52,56 ---- + #define SEVAL_ONECMD 0x100 /* only allow a single command */ + #define SEVAL_NOHISTEXP 0x200 /* inhibit history expansion */ ++ #define SEVAL_NOOPTIMIZE 0x400 /* don't try to set optimization flags */ + + /* Flags for describe_command, shared between type.def and command.def */ +*** ../bash-5.2-patched/builtins/evalstring.c 2022-11-05 17:27:44.000000000 -0400 +--- builtins/evalstring.c 2022-11-19 18:23:21.000000000 -0500 +*************** +*** 133,138 **** + (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && + (command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) && +! ((startup_state == 2 && should_suppress_fork (command->value.Connection->second)) || +! ((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork (command->value.Connection->second, 0)))) + { + command->value.Connection->second->flags |= CMD_NO_FORK; +--- 133,138 ---- + (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && + (command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) && +! (should_suppress_fork (command->value.Connection->second) || +! ((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork (command->value.Connection->second, 0)))) + { + command->value.Connection->second->flags |= CMD_NO_FORK; +*************** +*** 291,294 **** +--- 291,295 ---- + (flags & SEVAL_RESETLINE) -> reset line_number to 1 + (flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1 ++ (flags & SEVAL_NOOPTIMIZE) -> don't try to turn on optimizing flags + */ + +*************** +*** 503,507 **** + series of connection commands is + command->value.Connection->second. */ +! else if (command->type == cm_connection && can_optimize_connection (command)) + { + command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; +--- 504,510 ---- + series of connection commands is + command->value.Connection->second. */ +! else if (command->type == cm_connection && +! (flags & SEVAL_NOOPTIMIZE) == 0 && +! can_optimize_connection (command)) + { + command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; +*** ../bash-5.2-patched/builtins/eval.def 2016-01-25 13:28:37.000000000 -0500 +--- builtins/eval.def 2022-11-19 18:04:25.000000000 -0500 +*************** +*** 54,57 **** + list = loptend; /* skip over possible `--' */ + +! return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS); + } +--- 54,57 ---- + list = loptend; /* skip over possible `--' */ + +! return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST|SEVAL_NOOPTIMIZE) : EXECUTION_SUCCESS); + } +*** ../bash-5.2-patched/trap.c 2022-08-10 08:59:45.000000000 -0400 +--- trap.c 2022-12-12 10:57:51.000000000 -0500 +*************** +*** 305,308 **** +--- 305,309 ---- + volatile int save_return_catch_flag, function_code; + procenv_t save_return_catch; ++ char *trap_command, *old_trap; + #if defined (ARRAY_VARS) + ARRAY *ps; +*************** +*** 420,423 **** +--- 421,427 ---- + else + { ++ old_trap = trap_list[sig]; ++ trap_command = savestring (old_trap); ++ + save_parser_state (&pstate); + save_subst_varlist = subst_assign_varlist; +*************** +*** 442,446 **** + + if (function_code == 0) +! x = parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE); + else + { +--- 446,451 ---- + + if (function_code == 0) +! /* XXX is x always last_command_exit_value? */ +! x = parse_and_execute (trap_command, "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE); + else + { +*************** +*** 1003,1007 **** + { + reset_parser (); +! parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE); + } + else if (code == ERREXIT) +--- 1008,1012 ---- + { + reset_parser (); +! parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE); + } + else if (code == ERREXIT) +*************** +*** 1110,1114 **** + } + +! flags = SEVAL_NONINT|SEVAL_NOHIST; + if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP) + flags |= SEVAL_RESETLINE; +--- 1115,1119 ---- + } + +! flags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE; + if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP) + flags |= SEVAL_RESETLINE; +*** ../bash-5.2-patched/parse.y 2022-11-23 17:09:18.000000000 -0500 +--- parse.y 2022-11-19 18:15:34.000000000 -0500 +*************** +*** 2828,2832 **** + last_lastarg = savestring (last_lastarg); + +! parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST); + + restore_parser_state (&ps); +--- 2844,2848 ---- + last_lastarg = savestring (last_lastarg); + +! parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE); + + restore_parser_state (&ps); +*** ../bash-5.2-patched/jobs.c 2022-07-18 10:19:56.000000000 -0400 +--- jobs.c 2022-11-19 18:10:24.000000000 -0500 +*************** +*** 4221,4225 **** + for (i = 0; i < nchild; i++) + { +! parse_and_execute (savestring (trap_command), "trap", SEVAL_NOHIST|SEVAL_RESETLINE); + } + +--- 4243,4247 ---- + for (i = 0; i < nchild; i++) + { +! parse_and_execute (savestring (trap_command), "trap", SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE); + } + +*** ../bash-5.2-patched/y.tab.c 2022-11-23 17:09:18.000000000 -0500 +--- y.tab.c 2022-11-23 17:21:17.000000000 -0500 +*************** +*** 5139,5143 **** + last_lastarg = savestring (last_lastarg); + +! parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST); + + restore_parser_state (&ps); +--- 5154,5158 ---- + last_lastarg = savestring (last_lastarg); + +! parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE); + + restore_parser_state (&ps); +*** ../bash-5.2-patched/execute_cmd.c 2022-11-05 17:27:41.000000000 -0400 +--- execute_cmd.c 2022-11-22 17:09:38.000000000 -0500 +*************** +*** 1655,1659 **** + and set CMD_TRY_OPTIMIZING for simple commands on the right side of an + and-or or `;' list to test for optimizing forks when they are executed. */ +! if (user_subshell && command->type == cm_subshell) + optimize_subshell_command (command->value.Subshell->command); + +--- 1665,1670 ---- + and set CMD_TRY_OPTIMIZING for simple commands on the right side of an + and-or or `;' list to test for optimizing forks when they are executed. */ +! if (user_subshell && command->type == cm_subshell && +! (command->flags & (CMD_TIME_PIPELINE|CMD_INVERT_RETURN)) == 0) + optimize_subshell_command (command->value.Subshell->command); + +*** ../bash-5.2/patchlevel.h 2020-06-22 14:51:03.000000000 -0400 +--- patchlevel.h 2020-10-01 11:01:28.000000000 -0400 +*************** +*** 26,30 **** + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 14 + + #endif /* _PATCHLEVEL_H_ */ +--- 26,30 ---- + looks for to find the patch level (for the sccs version string). */ + +! #define PATCHLEVEL 15 + + #endif /* _PATCHLEVEL_H_ */ diff --git a/system/base/bash/pspec.xml b/system/base/bash/pspec.xml index 21ff142b..49910177 100755 --- a/system/base/bash/pspec.xml +++ b/system/base/bash/pspec.xml @@ -12,24 +12,31 @@ app:console The standard GNU Bourne again shell Bash is the GNU Project's Bourne Again SHell, a complete implementation of the IEEE POSIX and Open Group shell specification with interactive command line editing, csh-like features such as history substitution. - mirrors://gnu/bash/bash-5.1.16.tar.gz + mirrors://gnu/bash/bash-5.2.tar.gz ncurses-devel - + official/bash52-001.patch + official/bash52-002.patch + official/bash52-003.patch + official/bash52-004.patch + official/bash52-005.patch + official/bash52-006.patch + official/bash52-007.patch + official/bash52-008.patch + official/bash52-009.patch + official/bash52-010.patch + official/bash52-011.patch + official/bash52-012.patch + official/bash52-013.patch + official/bash52-014.patch + official/bash52-015.patch - fedora/bash-2.03-paths.patch + fedora/bash-2.03-profile.patch fedora/bash-2.05a-interpreter.patch fedora/bash-2.05b-debuginfo.patch @@ -47,7 +54,7 @@ fedora/bash-4.3-memleak-lc_all.patch fedora/bash-4.3-noecho.patch fedora/bash-4.4-no-loadable-builtins.patch - fedora/bash-infotags.patch + fedora/bash-5.0-syslog-history.patch fedora/bash-requires.patch fedora/bash-setlocale.patch fedora/bash-tty-tests.patch @@ -76,6 +83,13 @@ + + 2022-12-15 + 5.2.15 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-05-05 5.1.16 diff --git a/system/base/ca-certificates/pspec.xml b/system/base/ca-certificates/pspec.xml index baa93c88..845de2e3 100644 --- a/system/base/ca-certificates/pspec.xml +++ b/system/base/ca-certificates/pspec.xml @@ -11,9 +11,10 @@ app:web Common CA certificates Common CA certificates - http://ftp.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_20210119.tar.xz + http://ftp.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_20211016.tar.xz python3 + python3-cryptography + + 2022-12-06 + 2.6.0 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-21 2.3.6 diff --git a/system/base/dbus-glib/pspec.xml b/system/base/dbus-glib/pspec.xml index b35a5c4b..33adac43 100644 --- a/system/base/dbus-glib/pspec.xml +++ b/system/base/dbus-glib/pspec.xml @@ -67,6 +67,13 @@ + + 2022-11-25 + 0.112 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-11-11 0.112 diff --git a/system/base/glib2/files/glib2.patch b/system/base/glib2/files/glib2.patch new file mode 100644 index 00000000..b88fadc0 --- /dev/null +++ b/system/base/glib2/files/glib2.patch @@ -0,0 +1,11 @@ +diff -Nuar a/glib/gthreadprivate.h b/glib/gthreadprivate.h +--- a/glib/gthreadprivate.h 2022-12-22 00:16:58.000000000 +0300 ++++ b/glib/gthreadprivate.h 2022-12-22 13:34:01.816585997 +0300 +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + #ifndef FUTEX_WAIT_PRIVATE + #define FUTEX_WAIT_PRIVATE FUTEX_WAIT diff --git a/system/base/glib2/files/multilib.diff b/system/base/glib2/files/multilib.diff index c3b4ed30..1387b866 100644 --- a/system/base/glib2/files/multilib.diff +++ b/system/base/glib2/files/multilib.diff @@ -1,8 +1,8 @@ diff --git i/gio/tests/meson.build w/gio/tests/meson.build -index 65f43e267..3bd66bf60 100644 +index 41d4e3e6c..9f8110884 100644 --- i/gio/tests/meson.build +++ w/gio/tests/meson.build -@@ -598,6 +598,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper() +@@ -838,6 +838,7 @@ if meson.can_run_host_binaries() '-r', '-b','binary', '@INPUT@', @@ -10,3 +10,18 @@ index 65f43e267..3bd66bf60 100644 '-o','@OUTPUT@']) # Rename symbol to match the one in the C file +diff --git i/glib/tests/meson.build w/glib/tests/meson.build +index db01b54b4..42a852b2b 100644 +--- i/glib/tests/meson.build ++++ w/glib/tests/meson.build +@@ -126,7 +126,9 @@ glib_tests = { + 'thread-pool' : {}, + 'thread-pool-slow' : {'suite' : ['slow']}, + 'timeout' : {}, +- 'timer' : {}, ++ 'timer' : { ++ 'suite' : ['flaky'], ++ }, + 'tree' : {}, + 'types' : {}, + 'utf8-performance' : {}, diff --git a/system/base/glib2/files/noisy-glib-compile-schemas.diff b/system/base/glib2/files/noisy-glib-compile-schemas.diff index f5f2d948..c2d7b698 100644 --- a/system/base/glib2/files/noisy-glib-compile-schemas.diff +++ b/system/base/glib2/files/noisy-glib-compile-schemas.diff @@ -1,8 +1,17 @@ -diff --git i/gio/glib-compile-schemas.c w/gio/glib-compile-schemas.c -index b8de0907248f6860..130f89b1728f7932 100644 ---- i/gio/glib-compile-schemas.c -+++ w/gio/glib-compile-schemas.c -@@ -1219,19 +1219,6 @@ parse_state_start_schema (ParseState *state, +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: "Jan Alexander Steffens (heftig)" +Date: Fri, 7 Jan 2022 18:59:10 +0000 +Subject: [PATCH] glib-compile-schemas: Remove noisy deprecation warnings + +--- + gio/glib-compile-schemas.c | 13 ------------- + 1 file changed, 13 deletions(-) + +diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c +index 326658a88b35..f61d45b9a364 100644 +--- a/gio/glib-compile-schemas.c ++++ b/gio/glib-compile-schemas.c +@@ -1234,19 +1234,6 @@ parse_state_start_schema (ParseState *state, return; } diff --git a/system/base/glib2/pspec.xml b/system/base/glib2/pspec.xml index cd30ced1..0f739d26 100644 --- a/system/base/glib2/pspec.xml +++ b/system/base/glib2/pspec.xml @@ -12,7 +12,7 @@ library A library of handy utility functions glib2 is the low-level core library that forms the basis for projects such as GTK+ and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system. - mirrors://gnome/glib/2.74/glib-2.74.1.tar.xz + mirrors://gnome/glib/2.74/glib-2.74.4.tar.xz meson ninja @@ -27,6 +27,7 @@ noisy-glib-compile-schemas.diff glib-2.68.2-skip_warnings-1.patch + glib2.patch multilib.diff @@ -140,6 +141,20 @@ + + 2022-12-22 + 2.74.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-11-25 + 2.74.2 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-10-31 2.74.1 diff --git a/system/base/help2man/pspec.xml b/system/base/help2man/pspec.xml index 19d7df0a..ab838a63 100644 --- a/system/base/help2man/pspec.xml +++ b/system/base/help2man/pspec.xml @@ -12,7 +12,7 @@ app:console GNU utility to convert program --help output to a man page Help2man is a tool which generate man page from help text of programs. - http://ftp.gnu.org/gnu/help2man/help2man-1.47.16.tar.xz + http://ftp.gnu.org/gnu/help2man/help2man-1.47.3.tar.xz perl-Locale-gettext @@ -37,6 +37,13 @@ + + 2022-12-16 + 1.47.3 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2020-12-09 1.47.16 diff --git a/system/base/libX11/files/0001-makekeys-handle-the-new-_EVDEVK-xorgproto-symbols.patch b/system/base/libX11/files/0001-makekeys-handle-the-new-_EVDEVK-xorgproto-symbols.patch deleted file mode 100644 index 55adaaec..00000000 --- a/system/base/libX11/files/0001-makekeys-handle-the-new-_EVDEVK-xorgproto-symbols.patch +++ /dev/null @@ -1,43 +0,0 @@ -From e92efc63acd7b377faa9e534f4bf52aaa86be2a9 Mon Sep 17 00:00:00 2001 -From: Peter Hutterer -Date: Tue, 27 Jul 2021 11:46:19 +1000 -Subject: [PATCH libX11] makekeys: handle the new _EVDEVK xorgproto symbols - -These keys are all defined through a macro in the form: - #define XF86XK_BrightnessAuto _EVDEVK(0x0F4) - -The _EVDEVK macro is simply an offset of 0x10081000. -Let's parse these lines correctly so those keysyms end up in our -hashtables. - -Signed-off-by: Peter Hutterer ---- - src/util/makekeys.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/src/util/makekeys.c b/src/util/makekeys.c -index e847ef4c..4896cc53 100644 ---- a/src/util/makekeys.c -+++ b/src/util/makekeys.c -@@ -78,6 +78,18 @@ parse_line(const char *buf, char *key, KeySym *val, char *prefix) - return 1; - } - -+ /* See if we can parse one of the _EVDEVK symbols */ -+ i = sscanf(buf, "#define %127s _EVDEVK(0x%lx)", key, val); -+ if (i == 2 && (tmp = strstr(key, "XK_"))) { -+ memcpy(prefix, key, (size_t)(tmp - key)); -+ prefix[tmp - key] = '\0'; -+ tmp += 3; -+ memmove(key, tmp, strlen(tmp) + 1); -+ -+ *val += 0x10081000; -+ return 1; -+ } -+ - /* Now try to catch alias (XK_foo XK_bar) definitions, and resolve them - * immediately: if the target is in the form XF86XK_foo, we need to - * canonicalise this to XF86foo before we do the lookup. */ --- -2.31.1 - diff --git a/system/base/libX11/files/176.diff b/system/base/libX11/files/176.diff new file mode 100644 index 00000000..704ec694 --- /dev/null +++ b/system/base/libX11/files/176.diff @@ -0,0 +1,189 @@ +diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h +index e20c4833c16c6d3518e4b7feb9bdbc606584bfcc..b570bd01c657f4d86f06b414a43e96da4319f729 100644 +--- a/include/X11/Xlibint.h ++++ b/include/X11/Xlibint.h +@@ -43,6 +43,10 @@ from The Open Group. + #include /* to declare xEvent */ + #include /* for configured options like XTHREADS */ + ++#ifdef XTHREADS ++#include ++#endif ++ + /* The Xlib structs are full of implicit padding to properly align members. + We can't clean that up without breaking ABI, so tell clang not to bother + complaining about it. */ +@@ -207,7 +211,10 @@ struct _XDisplay + + XIOErrorExitHandler exit_handler; + void *exit_handler_data; +- CARD32 in_ifevent; ++ CARD32 in_ifevent; ++#ifdef XTHREADS ++ xthread_t ifevent_thread; ++#endif + }; + + #define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) +diff --git a/src/ChkIfEv.c b/src/ChkIfEv.c +index b32c2d3ebcb1aad0e704a3e5dce52dc31971afd2..666366966a0e81bf413a64e015a84da1fcf5cdf0 100644 +--- a/src/ChkIfEv.c ++++ b/src/ChkIfEv.c +@@ -49,8 +49,11 @@ Bool XCheckIfEvent ( + unsigned long qe_serial = 0; + int n; /* time through count */ + +- dpy->in_ifevent++; + LockDisplay(dpy); ++#ifdef XTHREADS ++ dpy->ifevent_thread = xthread_self(); ++#endif ++ dpy->in_ifevent++; + prev = NULL; + for (n = 3; --n >= 0;) { + for (qelt = prev ? prev->next : dpy->head; +diff --git a/src/IfEvent.c b/src/IfEvent.c +index 54c37f0031b27f3d7eb629ec2ea16b615b29e734..35c592e3a54d89f1d2ac1efa40c43a04eab1c0c5 100644 +--- a/src/IfEvent.c ++++ b/src/IfEvent.c +@@ -48,8 +48,11 @@ XIfEvent ( + register _XQEvent *qelt, *prev; + unsigned long qe_serial = 0; + +- dpy->in_ifevent++; + LockDisplay(dpy); ++#ifdef XTHREADS ++ dpy->ifevent_thread = xthread_self(); ++#endif ++ dpy->in_ifevent++; + prev = NULL; + while (1) { + for (qelt = prev ? prev->next : dpy->head; +diff --git a/src/PeekIfEv.c b/src/PeekIfEv.c +index 68c028b70705968c6757c1e70a238886a94adecb..754749a77c0835c0ba3c1aa6edded15dab7fb478 100644 +--- a/src/PeekIfEv.c ++++ b/src/PeekIfEv.c +@@ -49,8 +49,11 @@ XPeekIfEvent ( + register _XQEvent *prev, *qelt; + unsigned long qe_serial = 0; + +- dpy->in_ifevent++; + LockDisplay(dpy); ++#ifdef XTHREADS ++ dpy->ifevent_thread = xthread_self(); ++#endif ++ dpy->in_ifevent++; + prev = NULL; + while (1) { + for (qelt = prev ? prev->next : dpy->head; +diff --git a/src/locking.c b/src/locking.c +index c550603e1f5d0601af3fa19c0b8486ef5b1bc30f..642cf9894268dfbbb79a104b42b4097cfd293d82 100644 +--- a/src/locking.c ++++ b/src/locking.c +@@ -240,7 +240,9 @@ static void _XUnlockDisplay( + if (lock_hist_loc >= LOCK_HIST_SIZE) + lock_hist_loc = 0; + #endif /* XTHREADS_WARN */ +- xmutex_unlock(dpy->lock->mutex); ++ ++ if (dpy->in_ifevent == 0 || dpy->ifevent_thread != xthread_self()) ++ xmutex_unlock(dpy->lock->mutex); + } + + +@@ -453,63 +455,24 @@ static void _XDisplayLockWait( + } + + static void _XLockDisplay( +- Display *dpy +- XTHREADS_FILE_LINE_ARGS +- ); +- +-static void _XIfEventLockDisplay( + Display *dpy + XTHREADS_FILE_LINE_ARGS + ) + { +- /* assert(dpy->in_ifevent); */ +-} ++ struct _XErrorThreadInfo *ti; + +-static void _XInternalLockDisplay( +- Display *dpy, +- Bool wskip +- XTHREADS_FILE_LINE_ARGS +- ); ++ if (dpy->in_ifevent && dpy->ifevent_thread == xthread_self()) ++ return; + +-static void _XIfEventInternalLockDisplay( +- Display *dpy, +- Bool wskip +- XTHREADS_FILE_LINE_ARGS +- ) +-{ +- /* assert(dpy->in_ifevent); */ +-} +- +-static void _XIfEventUnlockDisplay( +- Display *dpy +- XTHREADS_FILE_LINE_ARGS +- ) +-{ +- if (dpy->in_ifevent == 0) { +- dpy->lock_fns->lock_display = _XLockDisplay; +- dpy->lock_fns->unlock_display = _XUnlockDisplay; +- dpy->lock->internal_lock_display = _XInternalLockDisplay; +- UnlockDisplay(dpy); +- } else +- return; +-} +- +-static void _XLockDisplay( +- Display *dpy +- XTHREADS_FILE_LINE_ARGS +- ) +-{ +-#ifdef XTHREADS +- struct _XErrorThreadInfo *ti; +-#endif + #ifdef XTHREADS_WARN + _XLockDisplayWarn(dpy, file, line); + #else + xmutex_lock(dpy->lock->mutex); + #endif ++ + if (dpy->lock->locking_level > 0) +- _XDisplayLockWait(dpy); +-#ifdef XTHREADS ++ _XDisplayLockWait(dpy); ++ + /* + * Skip the two function calls below which may generate requests + * when LockDisplay is called from within _XError. +@@ -517,14 +480,9 @@ static void _XLockDisplay( + for (ti = dpy->error_threads; ti; ti = ti->next) + if (ti->error_thread == xthread_self()) + return; +-#endif ++ + _XIDHandler(dpy); + _XSeqSyncFunction(dpy); +- if (dpy->in_ifevent) { +- dpy->lock_fns->lock_display = _XIfEventLockDisplay; +- dpy->lock_fns->unlock_display = _XIfEventUnlockDisplay; +- dpy->lock->internal_lock_display = _XIfEventInternalLockDisplay; +- } + } + + /* +@@ -537,6 +495,9 @@ static void _XInternalLockDisplay( + XTHREADS_FILE_LINE_ARGS + ) + { ++ if (dpy->in_ifevent && dpy->ifevent_thread == xthread_self()) ++ return; ++ + #ifdef XTHREADS_WARN + _XLockDisplayWarn(dpy, file, line); + #else diff --git a/system/base/libX11/files/177.diff b/system/base/libX11/files/177.diff new file mode 100644 index 00000000..dfc886ff --- /dev/null +++ b/system/base/libX11/files/177.diff @@ -0,0 +1,32 @@ +diff --git a/src/PutBEvent.c b/src/PutBEvent.c +index f7b74b31deeba41a47816a53bbccf5319810ffb3..b8273e1adca11f6a7cee0199729a0908c2888937 100644 +--- a/src/PutBEvent.c ++++ b/src/PutBEvent.c +@@ -85,15 +85,20 @@ XPutBackEvent ( + int type = event->type & 0177; + + LockDisplay(dpy); +- fp = dpy->wire_vec[type]; +- if (fp == NULL) +- fp = _XEventToWire; +- ret = (*fp)(dpy, event, &wire); +- if (ret) ++ if (type == GenericEvent) ++ ret = _XPutBackEvent(dpy, event); ++ else + { +- ret = (*dpy->event_vec[type])(dpy, &lib, &wire); ++ fp = dpy->wire_vec[type]; ++ if (fp == NULL) ++ fp = _XEventToWire; ++ ret = (*fp)(dpy, event, &wire); + if (ret) +- ret = _XPutBackEvent(dpy, &lib); ++ { ++ ret = (*dpy->event_vec[type])(dpy, &lib, &wire); ++ if (ret) ++ ret = _XPutBackEvent(dpy, &lib); ++ } + } + UnlockDisplay(dpy); + return ret; diff --git a/system/base/libX11/files/fix-null-pointer.patch b/system/base/libX11/files/fix-null-pointer.patch deleted file mode 100644 index 8b37f365..00000000 --- a/system/base/libX11/files/fix-null-pointer.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur libX11-1.3.5//src/xlibi18n/ICWrap.c libX11-1.3.5.tpg//src/xlibi18n/ICWrap.c ---- libX11-1.3.5//src/xlibi18n/ICWrap.c 2010-08-10 04:59:44.000000000 +0000 -+++ libX11-1.3.5.tpg//src/xlibi18n/ICWrap.c 2010-09-17 17:11:21.000000000 +0000 -@@ -283,7 +283,7 @@ - XIMArg *args; - char *ret; - -- if (!ic->core.im) -+ if (!ic || !ic->core.im) - return (char *) NULL; - - /* diff --git a/system/base/libX11/files/fix-segfault.diff b/system/base/libX11/files/fix-segfault.diff deleted file mode 100644 index a38c0ce2..00000000 --- a/system/base/libX11/files/fix-segfault.diff +++ /dev/null @@ -1,50 +0,0 @@ -Index: libX11-1.4.99.1/src/Xrm.c -=================================================================== ---- libX11-1.4.99.1.orig/src/Xrm.c -+++ libX11-1.4.99.1/src/Xrm.c -@@ -2540,30 +2540,40 @@ Bool XrmQGetResource( - VClosureRec closure; - - if (db && *names) { -- _XLockMutex(&db->linfo); -+ if ((_XLockMutex_fn) && db->linfo.lock ) { -+ _XLockMutex(&db->linfo); -+ } - closure.type = pType; - closure.value = pValue; - table = db->table; - if (names[1]) { - if (table && !table->leaf) { - if (GetNEntry(table, names, classes, &closure)) { -- _XUnlockMutex(&db->linfo); -+ if ((_XUnlockMutex_fn) && db->linfo.lock ) { -+ _XUnlockMutex(&db->linfo); -+ } - return True; - } - } else if (table && table->hasloose && - GetLooseVEntry((LTable)table, names, classes, &closure)) { -- _XUnlockMutex (&db->linfo); -+ if ((_XUnlockMutex_fn) && db->linfo.lock ) { -+ _XUnlockMutex (&db->linfo); -+ } - return True; - } - } else { - if (table && !table->leaf) - table = table->next; - if (table && GetVEntry((LTable)table, names, classes, &closure)) { -- _XUnlockMutex(&db->linfo); -+ if ((_XUnlockMutex_fn) && db->linfo.lock ) { -+ _XUnlockMutex(&db->linfo); -+ } - return True; - } - } -- _XUnlockMutex(&db->linfo); -+ if ((_XUnlockMutex_fn) && db->linfo.lock ) { -+ _XUnlockMutex(&db->linfo); -+ } - } - *pType = NULLQUARK; - pValue->addr = (XPointer)NULL; diff --git a/system/base/libX11/files/fix_typo.diff b/system/base/libX11/files/fix_typo.diff deleted file mode 100644 index a55a9407..00000000 --- a/system/base/libX11/files/fix_typo.diff +++ /dev/null @@ -1,27 +0,0 @@ -From 5dcb40f28d59587597d2ff6e6ac64c71cfe6ff7b Mon Sep 17 00:00:00 2001 -From: James Cloos -Date: Tue, 17 Sep 2013 16:50:42 +0000 -Subject: nls/en_US.UTF-8/Compose.pre: Fix typo. - -Fix typo added in 215ce6a67863, s/actute/acute/. - -Fixes bug #69476. Reported by Jean Krohn. - -Signed-off-by: James Cloos ---- -diff --git a/nls/en_US.UTF-8/Compose.pre b/nls/en_US.UTF-8/Compose.pre -index a741332..7314d7f 100644 ---- a/nls/en_US.UTF-8/Compose.pre -+++ b/nls/en_US.UTF-8/Compose.pre -@@ -743,7 +743,7 @@ XCOMM Part 3 - : "ï" idiaeresis # LATIN SMALL LETTER I WITH DIAERESIS - : "ï" idiaeresis # LATIN SMALL LETTER I WITH DIAERESIS - : "ï" idiaeresis # LATIN SMALL LETTER I WITH DIAERESIS -- : "j́" # LATIN SMALL LETTER J U006A with COMBINING ACUTE ACCENT U0301 -+ : "j́" # LATIN SMALL LETTER J U006A with COMBINING ACUTE ACCENT U0301 - : "j́" # LATIN SMALL LETTER J U006A with COMBINING ACUTE ACCENT U0301 - : "j́" # LATIN SMALL LETTER J U006A with COMBINING ACUTE ACCENT U0301 - : "j́" # LATIN SMALL LETTER J U006A with COMBINING ACUTE ACCENT U0301 --- -cgit v0.9.0.2-2-gbebe - diff --git a/system/base/libX11/pspec.xml b/system/base/libX11/pspec.xml index 0517ad39..ba9c9db7 100644 --- a/system/base/libX11/pspec.xml +++ b/system/base/libX11/pspec.xml @@ -12,7 +12,7 @@ library X.Org X11 library Core X11 protocol client library. - mirrors://xorg/individual/lib/libX11-1.8.2.tar.xz + mirrors://xorg/individual/lib/libX11-1.8.3.tar.xz libxcb-devel xorg-proto @@ -22,9 +22,8 @@ xmlto - - + 176.diff + 177.diff @@ -76,6 +75,20 @@ + + 2022-12-19 + 1.8.3 + Rebuild + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-12-16 + 1.8.3 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-11-11 1.8.2 diff --git a/system/base/libXau/pspec.xml b/system/base/libXau/pspec.xml index 27c35c5b..1f7906ca 100644 --- a/system/base/libXau/pspec.xml +++ b/system/base/libXau/pspec.xml @@ -12,7 +12,7 @@ library X.Org Au library libXau provides functions to manage X authorization files - http://xorg.freedesktop.org/archive/individual/lib/libXau-1.0.10.tar.xz + http://xorg.freedesktop.org/archive/individual/lib/libXau-1.0.11.tar.xz visibility.patch @@ -61,6 +61,13 @@ + + 2022-12-08 + 1.0.11 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-06 1.0.10 diff --git a/system/base/libXdmcp/pspec.xml b/system/base/libXdmcp/pspec.xml index 38ef9d83..bf566b49 100644 --- a/system/base/libXdmcp/pspec.xml +++ b/system/base/libXdmcp/pspec.xml @@ -12,7 +12,7 @@ library X.Org Xdmcp library LibXdmcp is the X Display Manager Control Protocol library. - http://xorg.freedesktop.org/archive/individual/lib/libXdmcp-1.1.3.tar.bz2 + http://xorg.freedesktop.org/archive/individual/lib/libXdmcp-1.1.4.tar.xz libxslt util-macros @@ -53,11 +53,11 @@ 32-bit shared libraries for libXdmcp emul32 - + libbsd-32bit libXdmcp - + libbsd-32bit /usr/lib32 @@ -65,6 +65,13 @@ + + 2022-11-19 + 1.1.4 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2020-12-09 1.1.3 diff --git a/system/base/libbsd/pspec.xml b/system/base/libbsd/pspec.xml index a7e2fb26..6c3dc8b0 100644 --- a/system/base/libbsd/pspec.xml +++ b/system/base/libbsd/pspec.xml @@ -13,17 +13,40 @@ library Provides useful functions commonly found on BSD systems This library provides useful functions commonly found on BSD systems, and lacking on others like GNU systems, thus making it easier to port projects with strong BSD origins, without needing to embed the same code over and over again on each project. - https://libbsd.freedesktop.org/releases/libbsd-0.10.0.tar.xz + https://libbsd.freedesktop.org/releases/libbsd-0.11.7.tar.xz + + libmd-devel + libbsd + + libmd + /usr/lib /usr/share/doc + + libbsd-32bit + emul32 + 32-bit shared libraries for libbsd + emul32 + + libmd-32bit + + + libmd-32bit + libbsd + + + /usr/lib32 + + + libbsd-devel Development files for libbsd @@ -33,12 +56,27 @@ /usr/include /usr/lib/pkgconfig + /usr/lib32/pkgconfig /usr/share/man/man3 /usr/share/man/man7 + + 2022-12-04 + 0.11.7 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-11-22 + 0.10.0 + Rebuild. + Pisi Linux Community + admin@pisilinux.org + 2020-12-09 0.10.0 diff --git a/system/base/libgpg-error/pspec.xml b/system/base/libgpg-error/pspec.xml index 04831e4a..2d9a1eba 100644 --- a/system/base/libgpg-error/pspec.xml +++ b/system/base/libgpg-error/pspec.xml @@ -13,7 +13,7 @@ library Library for error values used by GnuPG components libgpg-error is a library that defines common error values for all GnuPG components. - https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.42.tar.bz2 + https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.46.tar.bz2 @@ -61,6 +61,13 @@ + + 2022-12-20 + 1.46 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2021-05-28 1.42 diff --git a/system/base/libmd/actions.py b/system/base/libmd/actions.py new file mode 100644 index 00000000..179817c5 --- /dev/null +++ b/system/base/libmd/actions.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 3. +# See the file http://www.gnu.org/licenses/gpl.txt + +from pisi.actionsapi import autotools +from pisi.actionsapi import pisitools +from pisi.actionsapi import get + +def setup(): + autotools.configure(" --enable-static=no") + +def build(): + autotools.make() + +def install(): + autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + + pisitools.dodoc("ChangeLog", "COPYING", "README*") diff --git a/system/base/libmd/pspec.xml b/system/base/libmd/pspec.xml new file mode 100644 index 00000000..132a7963 --- /dev/null +++ b/system/base/libmd/pspec.xml @@ -0,0 +1,71 @@ + + + + + libmd + https://www.hadrons.org/software/libmd/ + + PisiLinux Community + admins@pisilinux.org + + BSD + library + Message Digest functions from BSD systems + libmd + Message Digest functions from BSD systems + https://libbsd.freedesktop.org/releases/libmd-1.0.4.tar.xz + + + + + libmd + + /usr/lib + /usr/share + /usr/share/locale + /usr/share/man + /usr/share/doc + + + + + libmd-32bit + emul32 + 32-bit shared libraries for libmd + emul32 + + libmd + + + /usr/lib32 + + + + + libmd-devel + Development files for libmd + + libmd + + + /usr/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + + + + + + 2022-12-04 + 1.0.4 + First release + PisiLinux Community + admins@pisilinux.org + + + diff --git a/system/base/libmd/translations.xml b/system/base/libmd/translations.xml new file mode 100644 index 00000000..f7d1192e --- /dev/null +++ b/system/base/libmd/translations.xml @@ -0,0 +1,8 @@ + + + + libmd + Message Digest functions from BSD systems + Message Digest functions from BSD systems + + diff --git a/system/base/libnsl/actions.py b/system/base/libnsl/actions.py index 5a32a71c..cbd40866 100644 --- a/system/base/libnsl/actions.py +++ b/system/base/libnsl/actions.py @@ -19,4 +19,4 @@ def build(): def install(): autotools.rawInstall("DESTDIR=%s" % get.installDIR()) - pisitools.dodoc("AUTHORS", "ChangeLog", "COPYING", "NEWS", "README") + pisitools.dodoc("AUTHORS", "COPYING", "NEWS", "README") diff --git a/system/base/libnsl/pspec.xml b/system/base/libnsl/pspec.xml index bdf11250..88c1042f 100644 --- a/system/base/libnsl/pspec.xml +++ b/system/base/libnsl/pspec.xml @@ -12,7 +12,7 @@ library Public client interface library for NIS(YP) and NIS+ Public client interface library for NIS(YP) and NIS+ - https://github.com/thkukuk/libnsl/archive/v1.2.0/libnsl-1.2.0.tar.gz + https://github.com/thkukuk/libnsl/archive/v2.0.0/libnsl-2.0.0.tar.gz libtirpc-devel @@ -44,6 +44,13 @@ + + 2022-12-31 + 2.0.0 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-28 1.2.0 diff --git a/system/base/libpcre2/pspec.xml b/system/base/libpcre2/pspec.xml index 24da5a6a..b20126a1 100644 --- a/system/base/libpcre2/pspec.xml +++ b/system/base/libpcre2/pspec.xml @@ -12,7 +12,7 @@ library Perl-compatible regular expression library The PCRE (Perl Compatible Regular Expressions) library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5. - https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.40/pcre2-10.40.tar.bz2 + https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.41/pcre2-10.41.tar.bz2 readline-devel @@ -71,6 +71,13 @@ + + 2022-12-07 + 10.41 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-08-23 10.40 diff --git a/system/base/libtirpc/pspec.xml b/system/base/libtirpc/pspec.xml index e219106c..422e5f0a 100644 --- a/system/base/libtirpc/pspec.xml +++ b/system/base/libtirpc/pspec.xml @@ -12,7 +12,7 @@ library Transport Independent RPC library Transport Independent RPC library - https://sourceforge.net/projects/libtirpc/files/libtirpc/1.3.2/libtirpc-1.3.2.tar.bz2 + https://sourceforge.net/projects/libtirpc/files/libtirpc/1.3.3/libtirpc-1.3.3.tar.bz2 mit-kerberos-devel e2fsprogs-devel @@ -49,6 +49,13 @@ + + 2022-12-04 + 1.3.3 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-28 1.3.2 diff --git a/system/base/mit-kerberos/pspec.xml b/system/base/mit-kerberos/pspec.xml index 8db059db..0a3f4a7a 100644 --- a/system/base/mit-kerberos/pspec.xml +++ b/system/base/mit-kerberos/pspec.xml @@ -13,7 +13,7 @@ app:console MIT Kerberos Library Kerberos is a network authentication protocol. It is designed to provide strong authentication for client/server applications by using secret-key cryptography. - http://web.mit.edu/kerberos/dist/krb5/1.20/krb5-1.20.tar.gz + https://kerberos.org/dist/krb5/1.20/krb5-1.20.1.tar.gz python3 keyutils @@ -76,6 +76,13 @@ + + 2022-12-06 + 1.20.1 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-09-26 1.20 diff --git a/system/base/pam/pspec.xml b/system/base/pam/pspec.xml index 5e45e5e9..c9437ccf 100644 --- a/system/base/pam/pspec.xml +++ b/system/base/pam/pspec.xml @@ -19,8 +19,9 @@ dlopen-test.sh - libnsl-devel + libnsl-devel audit-devel + libtirpc-devel bzip2 @@ -129,6 +129,13 @@ + + 2022-12-08 + 3.9.16 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-11-10 3.9.15 diff --git a/system/base/sqlite/actions.py b/system/base/sqlite/actions.py index e8826905..ade05edf 100644 --- a/system/base/sqlite/actions.py +++ b/system/base/sqlite/actions.py @@ -64,9 +64,9 @@ def install(): pisitools.dodoc("README*") - shelltools.cd("%s/sqlite-doc-3390000" % get.workDIR()) + shelltools.cd("%s/sqlite-doc-3400100" % get.workDIR()) - pisitools.insinto("/usr/share/doc/sqlite", "../sqlite-doc-3390000/*") + pisitools.insinto("/usr/share/doc/sqlite", "../sqlite-doc-3400100/*") """ # fix permissions and remove obsolete files; https://bugs.archlinux.org/task/24605 shelltools.system("find %s -type f -perm 755 -exec ls -lha {} \;" % get.installDIR()) diff --git a/system/base/sqlite/pspec.xml b/system/base/sqlite/pspec.xml index c486e627..61f993c9 100644 --- a/system/base/sqlite/pspec.xml +++ b/system/base/sqlite/pspec.xml @@ -14,8 +14,8 @@ app:console An SQL Database Engine in a C Library SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine. Supports databases up to 2 terabytes in size. - https://sqlite.org/2022/sqlite-autoconf-3390000.tar.gz - https://sqlite.org/2022/sqlite-doc-3390000.zip + https://www.sqlite.org/2022/sqlite-autoconf-3400100.tar.gz + https://www.sqlite.org/2022/sqlite-doc-3400100.zip readline-devel @@ -105,6 +105,13 @@ --> + + 2022-12-30 + 3.40.1 + Version bump + Mustafa Cinasal + muscnsl@gmail.com + 2022-06-26 3.39.0 diff --git a/system/devel/gobject-introspection/pspec.xml b/system/devel/gobject-introspection/pspec.xml index 3d9c2aa9..57000462 100644 --- a/system/devel/gobject-introspection/pspec.xml +++ b/system/devel/gobject-introspection/pspec.xml @@ -18,11 +18,11 @@ meson - python3-devel + python3-devel libffi-devel python-devel - glib2-devel + glib2-devel chrpath @@ -65,6 +65,27 @@ + + 2022-12-21 + 1.74.0 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-12-08 + 1.74.0 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-11-25 + 1.74.0 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2022-10-31 1.74.0 diff --git a/system/devel/libarchive/actions.py b/system/devel/libarchive/actions.py index 6274cf96..c03980cf 100644 --- a/system/devel/libarchive/actions.py +++ b/system/devel/libarchive/actions.py @@ -28,5 +28,7 @@ def build(): def install(): autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + + pisitools.dosed("%s/usr/lib/pkgconfig/libarchive.pc" % get.installDIR(), "iconv", "") - pisitools.dodoc("COPYING", "NEWS") + pisitools.dodoc("COPYING","NEWS") diff --git a/system/devel/libmpc/pspec.xml b/system/devel/libmpc/pspec.xml index 7d7af5f1..94deeb3e 100644 --- a/system/devel/libmpc/pspec.xml +++ b/system/devel/libmpc/pspec.xml @@ -12,10 +12,10 @@ library High precision and correct rounding library libmpc is a library for arithmetic of complex numbers with arbitrarily high precision and correct rounding. - ftp://ftp.gnu.org/gnu/mpc/mpc-1.2.0.tar.gz + ftp://ftp.gnu.org/gnu/mpc/mpc-1.3.1.tar.gz gmp-devel - mpfr-devel + mpfr-devel @@ -44,6 +44,13 @@ + + 2022-12-20 + 1.3.1 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2021-05-19 1.2.0 diff --git a/system/devel/meson/actions.py b/system/devel/meson/actions.py index 2e1a45ad..3a19069c 100755 --- a/system/devel/meson/actions.py +++ b/system/devel/meson/actions.py @@ -16,7 +16,7 @@ def install(): pythonmodules.install(pyVer="3") pisitools.insinto("/usr/share/vim/vimfiles", "data/syntax-highlighting/vim/*") - #pisitools.insinto("/usr/share/emacs/site-lisp", "data/syntax-highlighting/emacs/*") + # pisitools.insinto("/usr/share/emacs/site-lisp", "data/syntax-highlighting/emacs/*") pisitools.insinto("/usr/share/zsh/site-functions", "data/shell-completions/zsh/*") pisitools.insinto("/usr/share/bash-completion/completions", "data/shell-completions/bash/*") pisitools.remove("/usr/share/vim/vimfiles/README") diff --git a/system/devel/meson/pspec.xml b/system/devel/meson/pspec.xml index 0c1c9d29..ba700f71 100644 --- a/system/devel/meson/pspec.xml +++ b/system/devel/meson/pspec.xml @@ -12,7 +12,7 @@ app:console High productivity build system Yüksek verimli üretme sistemi - https://github.com/mesonbuild/meson/releases/download/0.64.0/meson-0.64.0.tar.gz + https://github.com/mesonbuild/meson/releases/download/1.0.0/meson-1.0.0.tar.gz python3-devel python3-setuptools @@ -38,6 +38,20 @@ + + 2022-12-24 + 1.0.0 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + + + 2022-11-23 + 0.64.1 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2022-11-11 0.64.0 diff --git a/system/devel/mpfr/pspec.xml b/system/devel/mpfr/pspec.xml index bf55128c..db704bea 100644 --- a/system/devel/mpfr/pspec.xml +++ b/system/devel/mpfr/pspec.xml @@ -13,7 +13,7 @@ library Multiple precision floating point library The MPFR library is a C library for multiple-precision floating-point computations with exact rounding (also called correct rounding). It is based on the GMP multiple-precision library. - https://ftp.gnu.org/gnu/mpfr/mpfr-4.1.0.tar.xz + https://ftp.gnu.org/gnu/mpfr/mpfr-4.1.1.tar.xz gmp-devel @@ -49,6 +49,13 @@ + + 2022-12-20 + 4.1.1 + Version bump. + Mustafa Cinasal + muscnsl@gmail.com + 2021-05-19 4.1.0 diff --git a/system/devel/xorg-util/files/host-defaults.patch b/system/devel/xorg-util/files/host-defaults.patch index 5cbe2a9f..66b5e53a 100644 --- a/system/devel/xorg-util/files/host-defaults.patch +++ b/system/devel/xorg-util/files/host-defaults.patch @@ -1,7 +1,7 @@ -Index: work/xorg-cf-files-1.0.6/host.def +Index: work/xorg-cf-files-1.0.7/host.def =================================================================== --- /dev/null -+++ work/xorg-cf-files-1.0.6/host.def ++++ work/xorg-cf-files-1.0.7/host.def @@ -0,0 +1,14 @@ +#define FSUseSyslog YES +#define BuildRman NO diff --git a/system/devel/xorg-util/pspec.xml b/system/devel/xorg-util/pspec.xml index 3cd8b681..555a6d53 100644 --- a/system/devel/xorg-util/pspec.xml +++ b/system/devel/xorg-util/pspec.xml @@ -13,10 +13,10 @@ X.Org utilities xorg-util contains some Xorg X11 command-line utilities, but more importantly, X11 configuration and rule files. mirrors://xorg/individual/util/gccmakedep-1.0.3.tar.bz2 - mirrors://xorg/individual/util/imake-1.0.8.tar.bz2 - mirrors://xorg/individual/util/lndir-1.0.3.tar.bz2 - mirrors://xorg/individual/util/makedepend-1.0.6.tar.bz2 - mirrors://xorg/individual/util/xorg-cf-files-1.0.6.tar.bz2 + mirrors://xorg/individual/util/imake-1.0.9.tar.xz + mirrors://xorg/individual/util/lndir-1.0.4.tar.xz + mirrors://xorg/individual/util/makedepend-1.0.8.tar.xz + mirrors://xorg/individual/util/xorg-cf-files-1.0.7.tar.bz2 xorg-proto util-macros @@ -36,6 +36,13 @@ + + 2022-12-12 + 7.6 + Rebuild. + Mustafa Cinasal + muscnsl@gmail.com + 2020-12-09 7.6