From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> To: linux-staging@lists.linux.dev Cc: linux-kernel@vger.kernel.org, patches@lists.linux.dev, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Hans de Goede <hdegoede@redhat.com>, Martin Kaiser <martin@kaiser.cx>, Larry Finger <Larry.Finger@lwfinger.net>, Phillip Potter <phil@philpotter.co.uk>, Pavel Skripkin <paskripkin@gmail.com> Subject: [PATCH] staging: r8188eu: delete driver Date: Wed, 8 Mar 2023 14:19:34 +0100 [thread overview] Message-ID: <20230308131934.380395-1-gregkh@linuxfoundation.org> (raw) Now that the same hardware that the r8188eu driver supported is supported by the real wireless driver rtl8xxxu, the r8188eu driver can be deleted. Also the rtl8xxxu driver supports way more devices, and is a fraction of the overall size, making this a much better overall solution. Thanks to the r8188eu developers and maintainers and reviewers over the years, your work allowed Linux users to use their hardware before the real driver was implemented properly. Reported-by: Hans de Goede <hdegoede@redhat.com> Cc: Martin Kaiser <martin@kaiser.cx> Cc: Larry Finger <Larry.Finger@lwfinger.net> Cc: Phillip Potter <phil@philpotter.co.uk> Cc: Pavel Skripkin <paskripkin@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- MAINTAINERS | 7 - drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/r8188eu/Kconfig | 16 - drivers/staging/r8188eu/Makefile | 48 - drivers/staging/r8188eu/TODO | 16 - drivers/staging/r8188eu/core/rtw_ap.c | 1181 --- drivers/staging/r8188eu/core/rtw_br_ext.c | 658 -- drivers/staging/r8188eu/core/rtw_cmd.c | 1529 ---- drivers/staging/r8188eu/core/rtw_efuse.c | 74 - drivers/staging/r8188eu/core/rtw_fw.c | 335 - drivers/staging/r8188eu/core/rtw_ieee80211.c | 1150 --- drivers/staging/r8188eu/core/rtw_ioctl_set.c | 479 - drivers/staging/r8188eu/core/rtw_iol.c | 160 - drivers/staging/r8188eu/core/rtw_led.c | 255 - drivers/staging/r8188eu/core/rtw_mlme.c | 2067 ----- drivers/staging/r8188eu/core/rtw_mlme_ext.c | 7817 ----------------- drivers/staging/r8188eu/core/rtw_p2p.c | 1918 ---- drivers/staging/r8188eu/core/rtw_pwrctrl.c | 445 - drivers/staging/r8188eu/core/rtw_recv.c | 2010 ----- drivers/staging/r8188eu/core/rtw_rf.c | 29 - drivers/staging/r8188eu/core/rtw_security.c | 1374 --- drivers/staging/r8188eu/core/rtw_sta_mgt.c | 490 -- drivers/staging/r8188eu/core/rtw_wlan_util.c | 1551 ---- drivers/staging/r8188eu/core/rtw_xmit.c | 2179 ----- .../r8188eu/hal/Hal8188ERateAdaptive.c | 654 -- .../staging/r8188eu/hal/HalHWImg8188E_BB.c | 733 -- .../staging/r8188eu/hal/HalHWImg8188E_MAC.c | 212 - .../staging/r8188eu/hal/HalHWImg8188E_RF.c | 269 - drivers/staging/r8188eu/hal/HalPhyRf_8188e.c | 900 -- drivers/staging/r8188eu/hal/HalPwrSeqCmd.c | 149 - drivers/staging/r8188eu/hal/hal_com.c | 139 - drivers/staging/r8188eu/hal/hal_intf.c | 50 - drivers/staging/r8188eu/hal/odm.c | 821 -- drivers/staging/r8188eu/hal/odm_HWConfig.c | 349 - drivers/staging/r8188eu/hal/odm_RTL8188E.c | 264 - drivers/staging/r8188eu/hal/rtl8188e_cmd.c | 694 -- drivers/staging/r8188eu/hal/rtl8188e_dm.c | 146 - .../staging/r8188eu/hal/rtl8188e_hal_init.c | 922 -- drivers/staging/r8188eu/hal/rtl8188e_phycfg.c | 705 -- drivers/staging/r8188eu/hal/rtl8188e_rf6052.c | 405 - drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c | 161 - drivers/staging/r8188eu/hal/rtl8188eu_xmit.c | 627 -- drivers/staging/r8188eu/hal/usb_halinit.c | 1069 --- drivers/staging/r8188eu/hal/usb_ops_linux.c | 476 - .../staging/r8188eu/include/Hal8188EPhyCfg.h | 97 - .../staging/r8188eu/include/Hal8188EPhyReg.h | 1072 --- .../r8188eu/include/Hal8188ERateAdaptive.h | 49 - .../r8188eu/include/HalHWImg8188E_BB.h | 27 - .../r8188eu/include/HalHWImg8188E_MAC.h | 12 - .../r8188eu/include/HalHWImg8188E_RF.h | 13 - .../staging/r8188eu/include/HalPhyRf_8188e.h | 36 - .../staging/r8188eu/include/HalPwrSeqCmd.h | 18 - drivers/staging/r8188eu/include/HalVerDef.h | 42 - drivers/staging/r8188eu/include/drv_types.h | 224 - drivers/staging/r8188eu/include/hal_com.h | 146 - drivers/staging/r8188eu/include/hal_intf.h | 44 - drivers/staging/r8188eu/include/ieee80211.h | 817 -- drivers/staging/r8188eu/include/odm.h | 416 - .../staging/r8188eu/include/odm_HWConfig.h | 69 - .../staging/r8188eu/include/odm_RTL8188E.h | 35 - .../r8188eu/include/odm_RegDefine11N.h | 47 - drivers/staging/r8188eu/include/osdep_intf.h | 30 - .../staging/r8188eu/include/osdep_service.h | 153 - .../staging/r8188eu/include/rtl8188e_cmd.h | 90 - drivers/staging/r8188eu/include/rtl8188e_dm.h | 28 - .../staging/r8188eu/include/rtl8188e_hal.h | 181 - .../staging/r8188eu/include/rtl8188e_recv.h | 40 - drivers/staging/r8188eu/include/rtl8188e_rf.h | 18 - .../staging/r8188eu/include/rtl8188e_spec.h | 1142 --- .../staging/r8188eu/include/rtl8188e_xmit.h | 130 - drivers/staging/r8188eu/include/rtw_ap.h | 34 - drivers/staging/r8188eu/include/rtw_br_ext.h | 43 - drivers/staging/r8188eu/include/rtw_cmd.h | 925 -- drivers/staging/r8188eu/include/rtw_eeprom.h | 15 - drivers/staging/r8188eu/include/rtw_efuse.h | 11 - drivers/staging/r8188eu/include/rtw_event.h | 97 - drivers/staging/r8188eu/include/rtw_fw.h | 17 - drivers/staging/r8188eu/include/rtw_ht.h | 28 - drivers/staging/r8188eu/include/rtw_io.h | 33 - drivers/staging/r8188eu/include/rtw_ioctl.h | 13 - .../staging/r8188eu/include/rtw_ioctl_set.h | 25 - drivers/staging/r8188eu/include/rtw_iol.h | 55 - drivers/staging/r8188eu/include/rtw_led.h | 57 - drivers/staging/r8188eu/include/rtw_mlme.h | 574 -- .../staging/r8188eu/include/rtw_mlme_ext.h | 753 -- drivers/staging/r8188eu/include/rtw_p2p.h | 118 - drivers/staging/r8188eu/include/rtw_pwrctrl.h | 111 - drivers/staging/r8188eu/include/rtw_recv.h | 347 - drivers/staging/r8188eu/include/rtw_rf.h | 80 - .../staging/r8188eu/include/rtw_security.h | 231 - drivers/staging/r8188eu/include/rtw_xmit.h | 334 - drivers/staging/r8188eu/include/sta_info.h | 313 - drivers/staging/r8188eu/include/usb_ops.h | 57 - drivers/staging/r8188eu/include/usb_osintf.h | 21 - drivers/staging/r8188eu/include/wifi.h | 773 -- drivers/staging/r8188eu/include/wlan_bssdef.h | 272 - drivers/staging/r8188eu/os_dep/ioctl_linux.c | 3775 -------- drivers/staging/r8188eu/os_dep/os_intfs.c | 807 -- .../staging/r8188eu/os_dep/osdep_service.c | 227 - drivers/staging/r8188eu/os_dep/usb_intf.c | 445 - .../staging/r8188eu/os_dep/usb_ops_linux.c | 136 - 102 files changed, 51239 deletions(-) delete mode 100644 drivers/staging/r8188eu/Kconfig delete mode 100644 drivers/staging/r8188eu/Makefile delete mode 100644 drivers/staging/r8188eu/TODO delete mode 100644 drivers/staging/r8188eu/core/rtw_ap.c delete mode 100644 drivers/staging/r8188eu/core/rtw_br_ext.c delete mode 100644 drivers/staging/r8188eu/core/rtw_cmd.c delete mode 100644 drivers/staging/r8188eu/core/rtw_efuse.c delete mode 100644 drivers/staging/r8188eu/core/rtw_fw.c delete mode 100644 drivers/staging/r8188eu/core/rtw_ieee80211.c delete mode 100644 drivers/staging/r8188eu/core/rtw_ioctl_set.c delete mode 100644 drivers/staging/r8188eu/core/rtw_iol.c delete mode 100644 drivers/staging/r8188eu/core/rtw_led.c delete mode 100644 drivers/staging/r8188eu/core/rtw_mlme.c delete mode 100644 drivers/staging/r8188eu/core/rtw_mlme_ext.c delete mode 100644 drivers/staging/r8188eu/core/rtw_p2p.c delete mode 100644 drivers/staging/r8188eu/core/rtw_pwrctrl.c delete mode 100644 drivers/staging/r8188eu/core/rtw_recv.c delete mode 100644 drivers/staging/r8188eu/core/rtw_rf.c delete mode 100644 drivers/staging/r8188eu/core/rtw_security.c delete mode 100644 drivers/staging/r8188eu/core/rtw_sta_mgt.c delete mode 100644 drivers/staging/r8188eu/core/rtw_wlan_util.c delete mode 100644 drivers/staging/r8188eu/core/rtw_xmit.c delete mode 100644 drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c delete mode 100644 drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c delete mode 100644 drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c delete mode 100644 drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c delete mode 100644 drivers/staging/r8188eu/hal/HalPhyRf_8188e.c delete mode 100644 drivers/staging/r8188eu/hal/HalPwrSeqCmd.c delete mode 100644 drivers/staging/r8188eu/hal/hal_com.c delete mode 100644 drivers/staging/r8188eu/hal/hal_intf.c delete mode 100644 drivers/staging/r8188eu/hal/odm.c delete mode 100644 drivers/staging/r8188eu/hal/odm_HWConfig.c delete mode 100644 drivers/staging/r8188eu/hal/odm_RTL8188E.c delete mode 100644 drivers/staging/r8188eu/hal/rtl8188e_cmd.c delete mode 100644 drivers/staging/r8188eu/hal/rtl8188e_dm.c delete mode 100644 drivers/staging/r8188eu/hal/rtl8188e_hal_init.c delete mode 100644 drivers/staging/r8188eu/hal/rtl8188e_phycfg.c delete mode 100644 drivers/staging/r8188eu/hal/rtl8188e_rf6052.c delete mode 100644 drivers/staging/r8188eu/hal/rtl8188e_rxdesc.c delete mode 100644 drivers/staging/r8188eu/hal/rtl8188eu_xmit.c delete mode 100644 drivers/staging/r8188eu/hal/usb_halinit.c delete mode 100644 drivers/staging/r8188eu/hal/usb_ops_linux.c delete mode 100644 drivers/staging/r8188eu/include/Hal8188EPhyCfg.h delete mode 100644 drivers/staging/r8188eu/include/Hal8188EPhyReg.h delete mode 100644 drivers/staging/r8188eu/include/Hal8188ERateAdaptive.h delete mode 100644 drivers/staging/r8188eu/include/HalHWImg8188E_BB.h delete mode 100644 drivers/staging/r8188eu/include/HalHWImg8188E_MAC.h delete mode 100644 drivers/staging/r8188eu/include/HalHWImg8188E_RF.h delete mode 100644 drivers/staging/r8188eu/include/HalPhyRf_8188e.h delete mode 100644 drivers/staging/r8188eu/include/HalPwrSeqCmd.h delete mode 100644 drivers/staging/r8188eu/include/HalVerDef.h delete mode 100644 drivers/staging/r8188eu/include/drv_types.h delete mode 100644 drivers/staging/r8188eu/include/hal_com.h delete mode 100644 drivers/staging/r8188eu/include/hal_intf.h delete mode 100644 drivers/staging/r8188eu/include/ieee80211.h delete mode 100644 drivers/staging/r8188eu/include/odm.h delete mode 100644 drivers/staging/r8188eu/include/odm_HWConfig.h delete mode 100644 drivers/staging/r8188eu/include/odm_RTL8188E.h delete mode 100644 drivers/staging/r8188eu/include/odm_RegDefine11N.h delete mode 100644 drivers/staging/r8188eu/include/osdep_intf.h delete mode 100644 drivers/staging/r8188eu/include/osdep_service.h delete mode 100644 drivers/staging/r8188eu/include/rtl8188e_cmd.h delete mode 100644 drivers/staging/r8188eu/include/rtl8188e_dm.h delete mode 100644 drivers/staging/r8188eu/include/rtl8188e_hal.h delete mode 100644 drivers/staging/r8188eu/include/rtl8188e_recv.h delete mode 100644 drivers/staging/r8188eu/include/rtl8188e_rf.h delete mode 100644 drivers/staging/r8188eu/include/rtl8188e_spec.h delete mode 100644 drivers/staging/r8188eu/include/rtl8188e_xmit.h delete mode 100644 drivers/staging/r8188eu/include/rtw_ap.h delete mode 100644 drivers/staging/r8188eu/include/rtw_br_ext.h delete mode 100644 drivers/staging/r8188eu/include/rtw_cmd.h delete mode 100644 drivers/staging/r8188eu/include/rtw_eeprom.h delete mode 100644 drivers/staging/r8188eu/include/rtw_efuse.h delete mode 100644 drivers/staging/r8188eu/include/rtw_event.h delete mode 100644 drivers/staging/r8188eu/include/rtw_fw.h delete mode 100644 drivers/staging/r8188eu/include/rtw_ht.h delete mode 100644 drivers/staging/r8188eu/include/rtw_io.h delete mode 100644 drivers/staging/r8188eu/include/rtw_ioctl.h delete mode 100644 drivers/staging/r8188eu/include/rtw_ioctl_set.h delete mode 100644 drivers/staging/r8188eu/include/rtw_iol.h delete mode 100644 drivers/staging/r8188eu/include/rtw_led.h delete mode 100644 drivers/staging/r8188eu/include/rtw_mlme.h delete mode 100644 drivers/staging/r8188eu/include/rtw_mlme_ext.h delete mode 100644 drivers/staging/r8188eu/include/rtw_p2p.h delete mode 100644 drivers/staging/r8188eu/include/rtw_pwrctrl.h delete mode 100644 drivers/staging/r8188eu/include/rtw_recv.h delete mode 100644 drivers/staging/r8188eu/include/rtw_rf.h delete mode 100644 drivers/staging/r8188eu/include/rtw_security.h delete mode 100644 drivers/staging/r8188eu/include/rtw_xmit.h delete mode 100644 drivers/staging/r8188eu/include/sta_info.h delete mode 100644 drivers/staging/r8188eu/include/usb_ops.h delete mode 100644 drivers/staging/r8188eu/include/usb_osintf.h delete mode 100644 drivers/staging/r8188eu/include/wifi.h delete mode 100644 drivers/staging/r8188eu/include/wlan_bssdef.h delete mode 100644 drivers/staging/r8188eu/os_dep/ioctl_linux.c delete mode 100644 drivers/staging/r8188eu/os_dep/os_intfs.c delete mode 100644 drivers/staging/r8188eu/os_dep/osdep_service.c delete mode 100644 drivers/staging/r8188eu/os_dep/usb_intf.c delete mode 100644 drivers/staging/r8188eu/os_dep/usb_ops_linux.c diff --git a/MAINTAINERS b/MAINTAINERS index 8d5bc223f305..93c5fa40c772 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19863,13 +19863,6 @@ S: Maintained W: http://wiki.laptop.org/go/DCON F: drivers/staging/olpc_dcon/ -STAGING - REALTEK RTL8188EU DRIVERS -M: Larry Finger <Larry.Finger@lwfinger.net> -M: Phillip Potter <phil@philpotter.co.uk> -R: Pavel Skripkin <paskripkin@gmail.com> -S: Supported -F: drivers/staging/r8188eu/ - STAGING - REALTEK RTL8712U DRIVERS M: Larry Finger <Larry.Finger@lwfinger.net> M: Florian Schilhabel <florian.c.schilhabel@googlemail.com>. diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 5cfabd5376cc..f9aef39cac2e 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -36,8 +36,6 @@ source "drivers/staging/rtl8723bs/Kconfig" source "drivers/staging/rtl8712/Kconfig" -source "drivers/staging/r8188eu/Kconfig" - source "drivers/staging/rts5208/Kconfig" source "drivers/staging/octeon/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index f8c3aa9c2418..ffa70dda481d 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_RTL8723BS) += rtl8723bs/ obj-$(CONFIG_R8712U) += rtl8712/ -obj-$(CONFIG_R8188EU) += r8188eu/ obj-$(CONFIG_RTS5208) += rts5208/ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ diff --git a/drivers/staging/r8188eu/Kconfig b/drivers/staging/r8188eu/Kconfig deleted file mode 100644 index f5fe423530f0..000000000000 --- a/drivers/staging/r8188eu/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# 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. - diff --git a/drivers/staging/r8188eu/Makefile b/drivers/staging/r8188eu/Makefile deleted file mode 100644 index fd494c2299e6..000000000000 --- a/drivers/staging/r8188eu/Makefile +++ /dev/null @@ -1,48 +0,0 @@ - -r8188eu-y = \ - hal/HalHWImg8188E_MAC.o \ - hal/HalHWImg8188E_BB.o \ - hal/HalHWImg8188E_RF.o \ - hal/HalPhyRf_8188e.o \ - hal/HalPwrSeqCmd.o \ - hal/Hal8188ERateAdaptive.o \ - hal/hal_intf.o \ - hal/hal_com.o \ - hal/odm.o \ - hal/odm_HWConfig.o \ - hal/odm_RTL8188E.o \ - hal/rtl8188e_cmd.o \ - hal/rtl8188e_dm.o \ - hal/rtl8188e_hal_init.o \ - hal/rtl8188e_phycfg.o \ - hal/rtl8188e_rf6052.o \ - hal/rtl8188e_rxdesc.o \ - hal/rtl8188eu_xmit.o \ - hal/usb_halinit.o \ - hal/usb_ops_linux.o \ - os_dep/ioctl_linux.o \ - os_dep/os_intfs.o \ - os_dep/osdep_service.o \ - os_dep/usb_intf.o \ - os_dep/usb_ops_linux.o \ - core/rtw_ap.o \ - core/rtw_br_ext.o \ - core/rtw_cmd.o \ - core/rtw_efuse.o \ - core/rtw_fw.o \ - core/rtw_ieee80211.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_pwrctrl.o \ - core/rtw_p2p.o \ - core/rtw_recv.o \ - core/rtw_rf.o \ - core/rtw_security.o \ - core/rtw_sta_mgt.o \ - core/rtw_wlan_util.o \ - core/rtw_xmit.o - -obj-$(CONFIG_R8188EU) := r8188eu.o diff --git a/drivers/staging/r8188eu/TODO b/drivers/staging/r8188eu/TODO deleted file mode 100644 index ab9d5d145b3b..000000000000 --- a/drivers/staging/r8188eu/TODO +++ /dev/null @@ -1,16 +0,0 @@ -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 deleted file mode 100644 index e0ca4b6e17cc..000000000000 --- a/drivers/staging/r8188eu/core/rtw_ap.c +++ /dev/null @@ -1,1181 +0,0 @@ -// 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" -#include "../include/rtl8188e_cmd.h" - -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; - 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; - - /* update TIM IE */ - - 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; - - tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap); - - 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--; - - 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--; - - 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)) { - 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) { - psta->expire_to = pstapriv->expire_to; - psta->keep_alive_trycnt = 0; - continue; - } else if (psta->keep_alive_trycnt <= 3) { - psta->expire_to = 1; - continue; - } - - psta->keep_alive_trycnt = 0; - - 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; - 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) { - 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); - - /* bitmap[0:27] = tx_rate_bitmap */ - /* bitmap[28:31]= Rate Adaptive id */ - /* arg[0:4] = macid */ - /* arg[5] = Short GI */ - rtl8188e_Add_RateATid(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; - } -} - -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 */ - rtl8188e_SetHalODMVar(padapter, psta, true); - - { - u8 arg = 0; - - arg = psta->mac_id & 0x1f; - arg |= BIT(7); - tx_ra_bitmap |= ((raid << 28) & 0xf0000000); - - /* bitmap[0:27] = tx_rate_bitmap */ - /* bitmap[28:31]= Rate Adaptive id */ - /* arg[0:4] = macid */ - /* arg[5] = Short GI */ - rtl8188e_Add_RateATid(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); - } -} - -/* 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; - - /* ap mode */ - rtl8188e_SetHalODMVar(padapter, 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_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; - - 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_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; - - 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_vendor_spec_ie(struct adapter *padapter, u8 *oui) -{ - if (!memcmp(WPS_OUI, oui, 4)) - update_bcn_wps_ie(padapter); -} - -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 _TIM_IE_: - update_BCNTIM(padapter); - break; - case _ERPINFO_IE_: - update_bcn_erpinfo_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 following 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; - - 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++; - } - - return op_mode_changes; -} - -void associated_clients_update(struct adapter *padapter, u8 updated) -{ - /* update associated 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); - - 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++; - } - } - - 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++; - } - } - } else { - if (!psta->no_ht_set) { - psta->no_ht_set = 1; - 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 associated stations cap. */ - associated_clients_update(padapter, 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 associated stations cap. */ - - return beacon_updated; -} - -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); - - wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL); -} - -static 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); - - wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL); -} - -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; -} - -void rtw_sta_flush(struct adapter *padapter) -{ - struct list_head *phead, *plist; - 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; - - 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); -} - -/* 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); -} - -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); - - 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); -} diff --git a/drivers/staging/r8188eu/core/rtw_br_ext.c b/drivers/staging/r8188eu/core/rtw_br_ext.c deleted file mode 100644 index a7c67014dde0..000000000000 --- a/drivers/staging/r8188eu/core/rtw_br_ext.c +++ /dev/null @@ -1,658 +0,0 @@ -// 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" - -#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 tag_len, tag_type; - - start_ptr = (unsigned char *)ph->tag; - cur_ptr = (unsigned char *)ph->tag; - while ((cur_ptr - start_ptr) < ntohs(ph->length)) { - /* prevent un-alignment access */ - tag_type = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]); - tag_len = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]); - if (tag_type == type) - return cur_ptr; - cur_ptr = cur_ptr + TAG_HDR_LEN + tag_len; - } - 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 = be16_to_cpu(tag->tag_len) + TAG_HDR_LEN; - if (skb_tailroom(skb) < data_len) - 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 int __nat25_has_expired(struct nat25_network_db_entry *fdb) -{ - if (time_before_eq(fdb->ageing_timer, jiffies - NAT25_AGEING_TIME * HZ)) - return 1; - - return 0; -} - -static void __nat25_generate_ipv4_network_addr(unsigned char *addr, - unsigned int *ip_addr) -{ - memset(addr, 0, MAX_NETWORK_ADDR_LEN); - - addr[0] = NAT25_IPV4; - memcpy(addr + 7, (unsigned char *)ip_addr, 4); -} - -static void __nat25_generate_pppoe_network_addr(unsigned char *addr, - unsigned char *ac_mac, __be16 *sid) -{ - memset(addr, 0, MAX_NETWORK_ADDR_LEN); - - addr[0] = NAT25_PPPOE; - memcpy(addr + 1, (unsigned char *)sid, 2); - memcpy(addr + 3, (unsigned char *)ac_mac, 6); -} - -static void __nat25_generate_ipv6_network_addr(unsigned char *addr, - unsigned int *ip_addr) -{ - memset(addr, 0, MAX_NETWORK_ADDR_LEN); - - addr[0] = NAT25_IPV6; - memcpy(addr + 1, (unsigned char *)ip_addr, 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) { - 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) { - 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) { - 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) { - 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) { - memcpy(mac, replace_mac, 6); - return 1; - } - } - } - return 0; -} - -static int __nat25_network_hash(unsigned char *addr) -{ - if (addr[0] == NAT25_IPV4) { - unsigned long x; - - x = addr[7] ^ addr[8] ^ addr[9] ^ addr[10]; - - return x & (NAT25_HASH_SIZE - 1); - } else if (addr[0] == NAT25_IPX) { - unsigned long x; - - x = addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ - addr[6] ^ addr[7] ^ addr[8] ^ addr[9] ^ addr[10]; - - return x & (NAT25_HASH_SIZE - 1); - } else if (addr[0] == NAT25_APPLE) { - unsigned long x; - - x = addr[1] ^ addr[2] ^ addr[3]; - - return x & (NAT25_HASH_SIZE - 1); - } else if (addr[0] == NAT25_PPPOE) { - unsigned long x; - - x = addr[0] ^ addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ - addr[5] ^ addr[6] ^ addr[7] ^ addr[8]; - - return x & (NAT25_HASH_SIZE - 1); - } else if (addr[0] == NAT25_IPV6) { - unsigned long x; - - x = addr[1] ^ addr[2] ^ addr[3] ^ addr[4] ^ addr[5] ^ addr[6] ^ - addr[7] ^ addr[8] ^ addr[9] ^ addr[10] ^ addr[11] ^ addr[12] ^ - addr[13] ^ addr[14] ^ addr[15] ^ addr[16]; - - return x & (NAT25_HASH_SIZE - 1); - } else { - unsigned long x = 0; - int i; - - for (i = 0; i < MAX_NETWORK_ADDR_LEN; i++) - x ^= addr[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 *mac_addr, unsigned char *addr) -{ - struct nat25_network_db_entry *db; - int hash; - - spin_lock_bh(&priv->br_ext_lock); - hash = __nat25_network_hash(addr); - db = priv->nethash[hash]; - while (db) { - if (!memcmp(db->networkAddr, addr, MAX_NETWORK_ADDR_LEN)) { - memcpy(db->macAddr, mac_addr, 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, addr, MAX_NETWORK_ADDR_LEN); - memcpy(db->macAddr, mac_addr, 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); -} - -/* - * 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(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 addr[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)) - 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); - __nat25_generate_ipv4_network_addr(addr, &tmp); - /* record source IP address and , source mac address into db */ - __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr); - 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 != htons(ETH_P_IP)) - return -1; - - switch (method) { - case NAT25_CHECK: - return 0; /* skb_copy for all ARP frame */ - case NAT25_INSERT: - /* 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(addr, sender); - __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr); - 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); - __be16 *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)) - 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) - 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 = (__be16 *)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; - } else { /* not add relay tag */ - if (priv->pppoe_connection_in_progress && - memcmp(skb->data + ETH_ALEN, - priv->pppoe_addr, - ETH_ALEN)) - 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 */ - __nat25_generate_pppoe_network_addr(addr, skb->data, &ph->sid); - - __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr); - - 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)) - return -1; - - switch (method) { - case NAT25_CHECK: - if (skb->data[0] & 1) - return 0; - return -1; - case NAT25_INSERT: - 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(addr, (unsigned int *)&iph->saddr); - __nat25_db_network_insert(priv, skb->data + ETH_ALEN, addr); - - 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, - be16_to_cpu(iph->payload_len), - IPPROTO_ICMPV6, - csum_partial((__u8 *)hdr, - be16_to_cpu(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 == htons(ETH_P_IP)) { /* IP */ - struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); - - if (iph->protocol == IPPROTO_UDP) { /* UDP */ - struct udphdr *udph = (void *)iph + (iph->ihl << 2); - - if ((udph->source == htons(CLIENT_PORT)) && - (udph->dest == htons(SERVER_PORT))) { /* DHCP request */ - struct dhcpMessage *dhcph = (void *)udph + sizeof(struct udphdr); - u32 cookie = be32_to_cpu(dhcph->cookie); - - if (cookie == DHCP_MAGIC) { /* match magic word */ - if (!(dhcph->flags & htons(BROADCAST_FLAG))) { - /* if not broadcast */ - register int sum = 0; - - /* 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 *ip_addr) -{ - unsigned char addr[MAX_NETWORK_ADDR_LEN]; - struct nat25_network_db_entry *db; - int hash; - - __nat25_generate_ipv4_network_addr(addr, (unsigned int *)ip_addr); - hash = __nat25_network_hash(addr); - db = priv->nethash[hash]; - while (db) { - if (!memcmp(db->networkAddr, addr, 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 deleted file mode 100644 index ca9e3d4ee7f4..000000000000 --- a/drivers/staging/r8188eu/core/rtw_cmd.c +++ /dev/null @@ -1,1529 +0,0 @@ -// 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/rtw_br_ext.h" -#include "../include/rtw_mlme_ext.h" -#include "../include/rtl8188e_dm.h" - -/* Caller and the rtw_cmd_thread can protect cmd_q by spin_lock. - * No irqsave is necessary. - */ - -static void c2h_wk_callback(struct work_struct *work); - -void rtw_free_evt_priv(struct evt_priv *pevtpriv) -{ - cancel_work_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); - } -} - -int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) -{ - init_completion(&pcmdpriv->enqueue_cmd); - /* sema_init(&(pcmdpriv->cmd_done_sema), 0); */ - init_completion(&pcmdpriv->start_cmd_thread); - init_completion(&pcmdpriv->stop_cmd_thread); - - rtw_init_queue(&pcmdpriv->cmd_queue); - - /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ - - pcmdpriv->cmd_allocated_buf = kzalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ, - GFP_KERNEL); - - if (!pcmdpriv->cmd_allocated_buf) - return -ENOMEM; - - 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) { - kfree(pcmdpriv->cmd_allocated_buf); - return -ENOMEM; - } - - pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((size_t)(pcmdpriv->rsp_allocated_buf) & 3); - - pcmdpriv->cmd_done_cnt = 0; - pcmdpriv->rsp_cnt = 0; - - return 0; -} - -int rtw_init_evt_priv(struct evt_priv *pevtpriv) -{ - /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ - atomic_set(&pevtpriv->event_seq, 0); - - INIT_WORK(&pevtpriv->c2h_wk, c2h_wk_callback); - pevtpriv->c2h_wk_alive = false; - pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN + 1); - if (!pevtpriv->c2h_queue) - return -ENOMEM; - - return 0; -} - -void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) -{ - if (pcmdpriv) { - kfree(pcmdpriv->cmd_allocated_buf); - kfree(pcmdpriv->rsp_allocated_buf); - } -} - -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 */ - - 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) -{ - unsigned long flags; - struct adapter *padapter = pcmdpriv->padapter; - - if (!cmd_obj) - return _FAIL; - - cmd_obj->padapter = padapter; - - if (rtw_cmd_filter(pcmdpriv, cmd_obj) == _FAIL) { - rtw_free_cmd_obj(cmd_obj); - return _FAIL; - } - - spin_lock_irqsave(&pcmdpriv->cmd_queue.lock, flags); - list_add_tail(&cmd_obj->list, &pcmdpriv->cmd_queue.queue); - spin_unlock_irqrestore(&pcmdpriv->cmd_queue.lock, flags); - - complete(&pcmdpriv->enqueue_cmd); - return _SUCCESS; -} - -struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv) -{ - struct cmd_obj *obj; - struct __queue *queue = &pcmdpriv->cmd_queue; - 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); - list_del_init(&obj->list); - } - - spin_unlock_irqrestore(&queue->lock, flags); - - return obj; -} - -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; - - pcmdbuf = pcmdpriv->cmd_buf; - - pcmdpriv->cmdthd_running = true; - complete(&pcmdpriv->start_cmd_thread); - - while (1) { - wait_for_completion(&pcmdpriv->enqueue_cmd); - -_next: - if (padapter->bDriverStopped || - padapter->bSurpriseRemoved) - break; - - pcmd = rtw_dequeue_cmd(pcmdpriv); - if (!pcmd) - continue; - - if (rtw_cmd_filter(pcmdpriv, pcmd) == _FAIL) { - pcmd->res = H2C_DROPPED; - goto post_process; - } - - pcmd->cmdsz = round_up(pcmd->cmdsz, 4); - - 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; - } - } 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 consider 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; - - rtw_free_cmd_obj(pcmd); - } while (1); - - complete(&pcmdpriv->stop_cmd_thread); - - return 0; -} - -/* 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) -{ - 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(*ph2c), GFP_ATOMIC); - if (!ph2c) - return _FAIL; - - psurveyPara = kzalloc(sizeof(*psurveyPara), 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++; - } - } - } - - 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; -} - -int rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset) -{ - struct cmd_obj *ph2c; - struct setdatarate_parm *pbsetdataratepara; - struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - - ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return -ENOMEM; - - pbsetdataratepara = kzalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC); - if (!pbsetdataratepara) { - kfree(ph2c); - return -ENOMEM; - } - - init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); - pbsetdataratepara->mac_id = 5; - memcpy(pbsetdataratepara->datarates, rateset, NumRates); - if (rtw_enqueue_cmd(pcmdpriv, ph2c) == _FAIL) - return -EPERM; - - return 0; -} - -void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) -{ - - - kfree(pcmd->parmbuf); - kfree(pcmd); -} - -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(*pcmd), 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_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(*pcmd), 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 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; - - 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 (disconnect_hdl(padapter, (u8 *)param) != H2C_SUCCESS) - 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(*ph2c), GFP_KERNEL); - if (!ph2c) { - res = false; - goto exit; - } - psetop = kzalloc(sizeof(*psetop), 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(*ph2c), GFP_KERNEL); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - psetstakey_para = kzalloc(sizeof(*psetstakey_para), GFP_KERNEL); - if (!psetstakey_para) { - kfree(ph2c); - res = _FAIL; - goto exit; - } - - psetstakey_rsp = kzalloc(sizeof(*psetstakey_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(*ph2c), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - psetstakey_para = kzalloc(sizeof(*psetstakey_para), - GFP_ATOMIC); - if (!psetstakey_para) { - kfree(ph2c); - res = _FAIL; - goto exit; - } - - psetstakey_rsp = kzalloc(sizeof(*psetstakey_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_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(*ph2c), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - paddbareq_parm = kzalloc(sizeof(*paddbareq_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)); - - /* 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(*ph2c), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_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_chplan_cmd(struct adapter *padapter, u8 chplan) -{ - 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(*setChannelPlan_param), - GFP_KERNEL); - if (!setChannelPlan_param) { - res = _FAIL; - goto exit; - } - setChannelPlan_param->channel_plan = chplan; - - /* need enqueue, prepare cmd_obj and enqueue */ - pcmdobj = kzalloc(sizeof(*pcmdobj), 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); - - /* do something based on res... */ - if (res == _SUCCESS) - padapter->mlmepriv.ChannelPlan = chplan; - -exit: - - return res; -} - -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 rtl8188e_sreset_xmit_status_check(struct adapter *padapter) -{ - u32 txdma_status; - int res; - - res = rtw_read32(padapter, REG_TXDMA_STATUS, &txdma_status); - if (res) - return; - - if (txdma_status != 0x00) - rtw_write32(padapter, REG_TXDMA_STATUS, txdma_status); - /* total xmit irp = 4 */ -} - -static void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf) -{ - struct mlme_priv *pmlmepriv; - - padapter = (struct adapter *)pbuf; - pmlmepriv = &padapter->mlmepriv; - - if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) - expire_timeout_chk(padapter); - - rtl8188e_sreset_xmit_status_check(padapter); - - linked_status_chk(padapter); - traffic_status_watchdog(padapter); - - rtl8188e_HalDmWatchDog(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; - rtl8188e_set_FwJoinBssReport_cmd(padapter, mstatus); - break; - case LPS_CTRL_DISCONNECT: - mstatus = 0;/* disconnect */ - LPS_Leave(padapter); - rtl8188e_set_FwJoinBssReport_cmd(padapter, mstatus); - break; - case LPS_CTRL_SPECIAL_PACKET: - 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(*ph2c), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_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) -{ - struct hal_data_8188e *haldata = &padapter->haldata; - struct odm_dm_struct *odmpriv = &haldata->odmpriv; - - ODM_RA_Set_TxRPT_Time(odmpriv, 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(*ph2c), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_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) -{ - struct hal_data_8188e *haldata = &padapter->haldata; - - /* switch current antenna to optimum antenna */ - if (haldata->CurAntenna != antenna) { - ODM_UpdateRxIdleAnt_88E(&haldata->odmpriv, antenna == 2 ? MAIN_ANT : AUX_ANT); - haldata->CurAntenna = antenna; - } -} - -static bool rtw_antenna_diversity(struct adapter *adapter) -{ - struct hal_data_8188e *haldata = &adapter->haldata; - - return haldata->AntDivCfg != 0; -} - -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 res = _SUCCESS; - - if (!rtw_antenna_diversity(padapter)) - return res; - - if (enqueue) { - ph2c = kzalloc(sizeof(*ph2c), GFP_KERNEL); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_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; -} - -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(*ph2c), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_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 type. */ - 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; -} - -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(*ppscmd), GFP_ATOMIC); - if (!ppscmd) { - res = _FAIL; - goto exit; - } - - pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_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; -} - -static bool rtw_is_hi_queue_empty(struct adapter *adapter) -{ - int res; - u32 reg; - - res = rtw_read32(adapter, REG_HGQ_INFORMATION, ®); - if (res) - return false; - - return (reg & 0x0000ff00) == 0; -} - -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) { - bool val = rtw_is_hi_queue_empty(padapter); - - while (!val) { - msleep(100); - - cnt++; - - if (cnt > 10) - break; - - val = rtw_is_hi_queue_empty(padapter); - } - - 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); - } - } -} - -void 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; - - ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - return; - - pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_cmd_parm), GFP_ATOMIC); - if (!pdrvextra_cmd_parm) { - kfree(ph2c); - return; - } - - 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)); - - rtw_enqueue_cmd(pcmdpriv, ph2c); -} - -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(*ph2c), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - pdrvextra_cmd_parm = kzalloc(sizeof(*pdrvextra_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; -} - -/* C2H event format: - * Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID - * BITS [127:120] [119:16] [15:8] [7:4] [3:0] - */ -static 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; - - ret = rtw_read8(adapter, REG_C2HEVT_CLEAR, &trigger); - if (ret) - return _FAIL; - - 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); - - ret = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL, buf); - if (ret) { - ret = _FAIL; - goto clear_evt; - } - - ret = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1, buf + 1); - if (ret) { - ret = _FAIL; - goto clear_evt; - } - /* Read the content */ - for (i = 0; i < c2h_evt->plen; i++) { - ret = rtw_read8(adapter, REG_C2HEVT_MSG_NORMAL + - sizeof(*c2h_evt) + i, c2h_evt->payload + i); - if (ret) { - ret = _FAIL; - goto clear_evt; - } - } - - 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. - */ - rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); -exit: - return ret; -} - -static void c2h_evt_hdl(struct adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter) -{ - u8 buf[16]; - - if (!c2h_evt) - c2h_evt_read(adapter, buf); -} - -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; - - evtpriv->c2h_wk_alive = true; - - while (!rtw_cbuf_empty(evtpriv->c2h_queue)) { - c2h_evt = (struct c2h_evt_hdr *)rtw_cbuf_pop(evtpriv->c2h_queue); - if (c2h_evt) { - /* This C2H event is read, clear it */ - rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); - } 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; - } - - /* Enqueue into cmd_thread for others */ - rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt); - } - - 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); - break; - case POWER_SAVING_CTRL_WK_CID: - rtw_ps_processor(padapter); - 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; - 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; - case CHECK_HIQ_WK_CID: - rtw_chk_hi_queue_hdl(padapter); - break; - 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_SUCCESS) { - /* TODO: cancel timer and do timeout handler directly... */ - _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; - } - - /* 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_SUCCESS) { - /* TODO: cancel timer and do timeout handler directly... */ - _set_timer(&pmlmepriv->assoc_timer, 1); - } - - rtw_free_cmd_obj(pcmd); -} - -void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) -{ - 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); - - del_timer_sync(&pmlmepriv->assoc_timer); - - 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_efuse.c b/drivers/staging/r8188eu/core/rtw_efuse.c deleted file mode 100644 index df9534dd25cb..000000000000 --- a/drivers/staging/r8188eu/core/rtw_efuse.c +++ /dev/null @@ -1,74 +0,0 @@ -// 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" -#include "../include/rtl8188e_hal.h" - -/* */ -/* 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) -{ - u32 value32; - u8 readbyte; - u16 retry; - int res; - - /* Write Address */ - rtw_write8(Adapter, EFUSE_CTRL + 1, (_offset & 0xff)); - res = rtw_read8(Adapter, EFUSE_CTRL + 2, &readbyte); - if (res) - return; - - rtw_write8(Adapter, EFUSE_CTRL + 2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); - - /* Write bit 32 0 */ - res = rtw_read8(Adapter, EFUSE_CTRL + 3, &readbyte); - if (res) - return; - - rtw_write8(Adapter, EFUSE_CTRL + 3, (readbyte & 0x7f)); - - /* Check bit 32 read-ready */ - res = rtw_read32(Adapter, EFUSE_CTRL, &value32); - if (res) - return; - - for (retry = 0; retry < 10000; retry++) { - res = rtw_read32(Adapter, EFUSE_CTRL, &value32); - if (res) - continue; - - if (((value32 >> 24) & 0xff) & 0x80) - break; - } - - /* 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); - res = rtw_read32(Adapter, EFUSE_CTRL, &value32); - if (res) - return; - - *pbuf = (u8)(value32 & 0xff); - - /* FIXME: return an error to caller */ -} diff --git a/drivers/staging/r8188eu/core/rtw_fw.c b/drivers/staging/r8188eu/core/rtw_fw.c deleted file mode 100644 index 1e4baf74ecd5..000000000000 --- a/drivers/staging/r8188eu/core/rtw_fw.c +++ /dev/null @@ -1,335 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#include <linux/firmware.h> -#include "../include/rtw_fw.h" - -#define MAX_REG_BLOCK_SIZE 196 -#define FW_8188E_START_ADDRESS 0x1000 -#define MAX_PAGE_SIZE 4096 - -#define IS_FW_HEADER_EXIST(_fwhdr) \ - ((le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x92C0 || \ - (le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x88C0 || \ - (le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x2300 || \ - (le16_to_cpu(_fwhdr->signature) & 0xFFF0) == 0x88E0) - -struct rt_firmware_hdr { - __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 */ - u8 rsvd1; - 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; - __le32 svnidx; /* The SVN entry index */ - __le32 rsvd3; - __le32 rsvd4; - __le32 rsvd5; -}; - -static_assert(sizeof(struct rt_firmware_hdr) == 32); - -static void fw_download_enable(struct adapter *padapter, bool enable) -{ - u8 tmp; - int res; - - if (enable) { - /* MCU firmware download enable. */ - res = rtw_read8(padapter, REG_MCUFWDL, &tmp); - if (res) - return; - - rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01); - - /* 8051 reset */ - res = rtw_read8(padapter, REG_MCUFWDL + 2, &tmp); - if (res) - return; - - rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7); - } else { - /* MCU firmware download disable. */ - res = rtw_read8(padapter, REG_MCUFWDL, &tmp); - if (res) - return; - - rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe); - - /* Reserved for fw extension. */ - rtw_write8(padapter, REG_MCUFWDL + 1, 0x00); - } -} - -static int block_write(struct adapter *padapter, u8 *buffer, u32 size) -{ - int ret = _SUCCESS; - u32 blocks, block_size, remain; - u32 i, offset, addr; - u8 *data; - - block_size = MAX_REG_BLOCK_SIZE; - - blocks = size / block_size; - remain = size % block_size; - - for (i = 0; i < blocks; i++) { - addr = FW_8188E_START_ADDRESS + i * block_size; - data = buffer + i * block_size; - - if (rtw_writeN(padapter, addr, block_size, data)) - return _FAIL; - } - - if (remain) { - offset = blocks * block_size; - block_size = 8; - - blocks = remain / block_size; - remain = remain % block_size; - - for (i = 0; i < blocks; i++) { - addr = FW_8188E_START_ADDRESS + offset + i * block_size; - data = buffer + offset + i * block_size; - - if (rtw_writeN(padapter, addr, block_size, data)) - return _FAIL; - } - } - - if (remain) { - offset += blocks * block_size; - - /* block size 1 */ - blocks = remain; - - for (i = 0; i < blocks; i++) { - addr = FW_8188E_START_ADDRESS + offset + i; - data = buffer + offset + i; - - ret = rtw_write8(padapter, addr, *data); - if (ret == _FAIL) - goto exit; - } - } - -exit: - return ret; -} - -static int page_write(struct adapter *padapter, u32 page, u8 *buffer, u32 size) -{ - u8 value8; - u8 u8Page = (u8)(page & 0x07); - int res; - - res = rtw_read8(padapter, REG_MCUFWDL + 2, &value8); - if (res) - return _FAIL; - - value8 = (value8 & 0xF8) | u8Page; - rtw_write8(padapter, REG_MCUFWDL + 2, value8); - - return block_write(padapter, buffer, size); -} - -static int write_fw(struct adapter *padapter, u8 *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; - - pageNums = size / MAX_PAGE_SIZE; - remainSize = size % MAX_PAGE_SIZE; - - for (page = 0; page < pageNums; page++) { - offset = page * MAX_PAGE_SIZE; - ret = page_write(padapter, page, buffer + offset, MAX_PAGE_SIZE); - - if (ret == _FAIL) - goto exit; - } - if (remainSize) { - offset = pageNums * MAX_PAGE_SIZE; - page = pageNums; - ret = page_write(padapter, page, buffer + offset, remainSize); - - if (ret == _FAIL) - goto exit; - } -exit: - return ret; -} - -void rtw_reset_8051(struct adapter *padapter) -{ - u8 val8; - int res; - - res = rtw_read8(padapter, REG_SYS_FUNC_EN + 1, &val8); - if (res) - return; - - rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 & (~BIT(2))); - rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val8 | (BIT(2))); -} - -static int fw_free_to_go(struct adapter *padapter) -{ - u32 counter = 0; - u32 value32; - int res; - - /* polling CheckSum report */ - do { - res = rtw_read32(padapter, REG_MCUFWDL, &value32); - if (res) - continue; - - if (value32 & FWDL_CHKSUM_RPT) - break; - } while (counter++ < POLLING_READY_TIMEOUT_COUNT); - - if (counter >= POLLING_READY_TIMEOUT_COUNT) - return _FAIL; - - res = rtw_read32(padapter, REG_MCUFWDL, &value32); - if (res) - return _FAIL; - - value32 |= MCUFWDL_RDY; - value32 &= ~WINTINI_RDY; - rtw_write32(padapter, REG_MCUFWDL, value32); - - rtw_reset_8051(padapter); - - /* polling for FW ready */ - counter = 0; - do { - res = rtw_read32(padapter, REG_MCUFWDL, &value32); - if (!res && value32 & WINTINI_RDY) - return _SUCCESS; - - udelay(5); - } while (counter++ < POLLING_READY_TIMEOUT_COUNT); - - return _FAIL; -} - -static int load_firmware(struct rt_firmware *rtfw, struct device *device) -{ - int ret = _SUCCESS; - const struct firmware *fw; - const char *fw_name = FW_RTL8188EU; - int err = request_firmware(&fw, fw_name, device); - - if (err) { - pr_err("Request firmware failed with error 0x%x\n", err); - ret = _FAIL; - goto exit; - } - if (!fw) { - pr_err("Firmware %s not available\n", fw_name); - ret = _FAIL; - goto exit; - } - - rtfw->data = kmemdup(fw->data, fw->size, GFP_KERNEL); - if (!rtfw->data) { - pr_err("Failed to allocate rtfw->data\n"); - ret = _FAIL; - goto exit; - } - rtfw->size = fw->size; - -exit: - release_firmware(fw); - return ret; -} - -int rtl8188e_firmware_download(struct adapter *padapter) -{ - int ret = _SUCCESS; - u8 reg; - unsigned long fwdl_timeout; - struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - struct device *device = dvobj_to_dev(dvobj); - struct rt_firmware_hdr *fwhdr = NULL; - u8 *fw_data; - u32 fw_size; - - if (!dvobj->firmware.data) - ret = load_firmware(&dvobj->firmware, device); - if (ret == _FAIL) { - dvobj->firmware.data = NULL; - goto exit; - } - fw_data = dvobj->firmware.data; - fw_size = dvobj->firmware.size; - - fwhdr = (struct rt_firmware_hdr *)dvobj->firmware.data; - - if (IS_FW_HEADER_EXIST(fwhdr)) { - dev_info_once(device, "Firmware Version %d, SubVersion %d, Signature 0x%x\n", - le16_to_cpu(fwhdr->version), fwhdr->subversion, - le16_to_cpu(fwhdr->signature)); - - fw_data = fw_data + sizeof(struct rt_firmware_hdr); - fw_size = fw_size - sizeof(struct rt_firmware_hdr); - } - - /* 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. */ - ret = rtw_read8(padapter, REG_MCUFWDL, ®); - if (ret) { - ret = _FAIL; - goto exit; - } - - if (reg & RAM_DL_SEL) { /* 8051 RAM code */ - rtw_write8(padapter, REG_MCUFWDL, 0x00); - rtw_reset_8051(padapter); - } - - fw_download_enable(padapter, true); - fwdl_timeout = jiffies + msecs_to_jiffies(500); - do { - /* reset the FWDL chksum */ - ret = rtw_read8(padapter, REG_MCUFWDL, ®); - if (ret) { - ret = _FAIL; - continue; - } - - rtw_write8(padapter, REG_MCUFWDL, reg | FWDL_CHKSUM_RPT); - - ret = write_fw(padapter, fw_data, fw_size); - if (ret == _SUCCESS) - break; - } while (!time_after(jiffies, fwdl_timeout)); - - fw_download_enable(padapter, false); - if (ret != _SUCCESS) - goto exit; - - ret = fw_free_to_go(padapter); - if (ret != _SUCCESS) - goto exit; - -exit: - return ret; -} diff --git a/drivers/staging/r8188eu/core/rtw_ieee80211.c b/drivers/staging/r8188eu/core/rtw_ieee80211.c deleted file mode 100644 index bc8543ea2e66..000000000000 --- a/drivers/staging/r8188eu/core/rtw_ieee80211.c +++ /dev/null @@ -1,1150 +0,0 @@ -// 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; -} - -bool 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; -} - -bool 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; - /* 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; -} - -/*---------------------------------------------------------------------------- -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; - } - tmp = *(p + 1); - p += (tmp + 2); - i += (tmp + 2); - if (i >= limit) - break; - } - - return NULL; -} - -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; - } - *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; - } - 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; - } - 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) - 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) - 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: - return -1; - } - break; - case 4: - /* Wi-Fi Protected Setup (WPS) IE */ - elems->wps_ie = pos; - elems->wps_ie_len = elen; - break; - default: - 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: - return -1; - } - break; - default: - 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) - 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++; - 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 && mac_pton(rtw_initmac, mac)) { - /* Users specify the mac address */ - ether_addr_copy(mac_addr, mac); - } else { - /* Use the mac address stored in the Efuse */ - ether_addr_copy(mac, mac_addr); - } - - if (is_broadcast_ether_addr(mac) || is_zero_ether_addr(mac)) - eth_random_addr(mac_addr); -} - -/** - * 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; - } - 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; - } - 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; - } - } -} - -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 (rtw_parse_wpa_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { - 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 (rtw_parse_wpa2_ie(pbuf, wpa_ielen + 2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { - 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 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char *MCS_rate) -{ - u16 max_rate = 0; - - 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; -} diff --git a/drivers/staging/r8188eu/core/rtw_ioctl_set.c b/drivers/staging/r8188eu/core/rtw_ioctl_set.c deleted file mode 100644 index 785c0dba508f..000000000000 --- a/drivers/staging/r8188eu/core/rtw_ioctl_set.c +++ /dev/null @@ -1,479 +0,0 @@ -// 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" - -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); - if (ret != _SUCCESS) - pmlmepriv->to_join = false; - } else { - pmlmepriv->to_join = false; - ret = _FAIL; - } - - return ret; - } 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; - - 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) - return false; - - 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); - if (ret != _SUCCESS) - pmlmepriv->to_join = false; - } else { - ret = _FAIL; - pmlmepriv->to_join = false; - } - } - } - } - - 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; - - 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); - - 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; - - if (!padapter->hw_init_completed) { - status = _FAIL; - goto exit; - } - - spin_lock_bh(&pmlmepriv->lock); - - 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); - - if (*pold_state == Ndis802_11APMode) { - /* change to other mode from Ndis802_11APMode */ - cur_network->join_res = -1; - - stop_ap_mode(padapter); - } - - 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 checked 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); - break; - case Ndis802_11AutoUnknown: - case Ndis802_11InfrastructureMax: - break; - } - spin_unlock_bh(&pmlmepriv->lock); - } - - return true; -} - -void 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); -} - -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 { - spin_lock_bh(&pmlmepriv->lock); - - res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num); - - 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; -} - -/* -* 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 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0; - u16 mcs_rate = 0; - u32 ht_ielen = 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; - - max_rate = rtw_mcs_rate(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; -} diff --git a/drivers/staging/r8188eu/core/rtw_iol.c b/drivers/staging/r8188eu/core/rtw_iol.c deleted file mode 100644 index 31e196ccd899..000000000000 --- a/drivers/staging/r8188eu/core/rtw_iol.c +++ /dev/null @@ -1,160 +0,0 @@ -// 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) - return NULL; - - xmitbuf = rtw_alloc_xmitbuf(pxmitpriv); - if (!xmitbuf) { - rtw_free_xmitframe(pxmitpriv, xmit_frame); - return NULL; - } - - 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; - - 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) - 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 (adapter->registrypriv.fw_iol == 1) - return true; - - if ((adapter->registrypriv.fw_iol == 2) && - (adapter_to_dvobj(adapter)->pusbdev->speed != USB_SPEED_HIGH)) - return true; - - return false; -} - -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; -} diff --git a/drivers/staging/r8188eu/core/rtw_led.c b/drivers/staging/r8188eu/core/rtw_led.c deleted file mode 100644 index 48725ce9d369..000000000000 --- a/drivers/staging/r8188eu/core/rtw_led.c +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2012 Realtek Corporation. */ - -#include "../include/drv_types.h" -#include "../include/rtw_led.h" -#include "../include/rtl8188e_spec.h" - -#define LED_BLINK_NO_LINK_INTVL msecs_to_jiffies(1000) -#define LED_BLINK_LINK_INTVL msecs_to_jiffies(500) -#define LED_BLINK_SCAN_INTVL msecs_to_jiffies(180) -#define LED_BLINK_FASTER_INTVL msecs_to_jiffies(50) -#define LED_BLINK_WPS_SUCESS_INTVL msecs_to_jiffies(5000) - -#define IS_LED_WPS_BLINKING(l) \ - ((l)->CurrLedState == LED_BLINK_WPS || \ - (l)->CurrLedState == LED_BLINK_WPS_STOP || \ - (l)->bLedWPSBlinkInProgress) - -static void ResetLedStatus(struct led_priv *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->bLedScanBlinkInProgress = false; -} - -static void SwLedOn(struct led_priv *pLed) -{ - struct adapter *padapter = container_of(pLed, struct adapter, ledpriv); - - if (padapter->bDriverStopped) - return; - - if (rtw_write8(padapter, REG_LEDCFG2, BIT(5)) != _SUCCESS) - return; - - pLed->bLedOn = true; -} - -static void SwLedOff(struct led_priv *pLed) -{ - struct adapter *padapter = container_of(pLed, struct adapter, ledpriv); - - if (padapter->bDriverStopped) - return; - - if (rtw_write8(padapter, REG_LEDCFG2, BIT(5) | BIT(3)) != _SUCCESS) - return; - - pLed->bLedOn = false; -} - -static void blink_work(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct led_priv *pLed = container_of(dwork, struct led_priv, blink_work); - struct adapter *padapter = container_of(pLed, struct adapter, ledpriv); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) { - SwLedOff(pLed); - ResetLedStatus(pLed); - return; - } - - if (pLed->bLedOn) - SwLedOff(pLed); - else - SwLedOn(pLed); - - switch (pLed->CurrLedState) { - case LED_BLINK_SLOWLY: - schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL); - break; - case LED_BLINK_NORMAL: - schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); - break; - case LED_BLINK_SCAN: - case LED_BLINK_TXRX: - pLed->BlinkTimes--; - if (pLed->BlinkTimes == 0) { - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - pLed->CurrLedState = LED_BLINK_NORMAL; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); - } else { - pLed->CurrLedState = LED_BLINK_SLOWLY; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL); - } - pLed->bLedBlinkInProgress = false; - pLed->bLedScanBlinkInProgress = false; - } else { - schedule_delayed_work(&pLed->blink_work, - pLed->CurrLedState == LED_BLINK_SCAN ? - LED_BLINK_SCAN_INTVL : LED_BLINK_FASTER_INTVL); - } - break; - case LED_BLINK_WPS: - schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL); - break; - case LED_BLINK_WPS_STOP: /* WPS success */ - if (!pLed->bLedOn) { - pLed->CurrLedState = LED_BLINK_NORMAL; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); - - pLed->bLedWPSBlinkInProgress = false; - } else { - schedule_delayed_work(&pLed->blink_work, LED_BLINK_WPS_SUCESS_INTVL); - } - break; - default: - break; - } -} - -void rtl8188eu_InitSwLeds(struct adapter *padapter) -{ - struct led_priv *pledpriv = &padapter->ledpriv; - - ResetLedStatus(pledpriv); - INIT_DELAYED_WORK(&pledpriv->blink_work, blink_work); -} - -void rtl8188eu_DeInitSwLeds(struct adapter *padapter) -{ - struct led_priv *ledpriv = &padapter->ledpriv; - - cancel_delayed_work_sync(&ledpriv->blink_work); - ResetLedStatus(ledpriv); - SwLedOff(ledpriv); -} - -void rtw_led_control(struct adapter *padapter, enum LED_CTL_MODE LedAction) -{ - struct led_priv *pLed = &padapter->ledpriv; - struct registry_priv *registry_par; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - if (!padapter->hw_init_completed) - return; - - if (!pLed->bRegUseLed) - return; - - registry_par = &padapter->registrypriv; - if (!registry_par->led_enable) - return; - - switch (LedAction) { - case LED_CTL_START_TO_LINK: - case LED_CTL_NO_LINK: - if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) - return; - - cancel_delayed_work(&pLed->blink_work); - - pLed->bLedBlinkInProgress = false; - - pLed->CurrLedState = LED_BLINK_SLOWLY; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL); - break; - case LED_CTL_LINK: - if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) - return; - - cancel_delayed_work(&pLed->blink_work); - - pLed->bLedBlinkInProgress = false; - - pLed->CurrLedState = LED_BLINK_NORMAL; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_LINK_INTVL); - break; - case LED_CTL_SITE_SURVEY: - if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) - return; - - if (pLed->bLedScanBlinkInProgress) - return; - - if (IS_LED_WPS_BLINKING(pLed)) - return; - - cancel_delayed_work(&pLed->blink_work); - - pLed->bLedBlinkInProgress = false; - pLed->bLedScanBlinkInProgress = true; - - pLed->CurrLedState = LED_BLINK_SCAN; - pLed->BlinkTimes = 24; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL); - break; - case LED_CTL_TX: - case LED_CTL_RX: - if (pLed->bLedBlinkInProgress) - return; - - if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed)) - return; - - cancel_delayed_work(&pLed->blink_work); - - pLed->bLedBlinkInProgress = true; - - pLed->CurrLedState = LED_BLINK_TXRX; - pLed->BlinkTimes = 2; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_FASTER_INTVL); - break; - case LED_CTL_START_WPS: /* wait until xinpin finish */ - if (pLed->bLedWPSBlinkInProgress) - return; - - cancel_delayed_work(&pLed->blink_work); - - pLed->bLedBlinkInProgress = false; - pLed->bLedScanBlinkInProgress = false; - pLed->bLedWPSBlinkInProgress = true; - pLed->CurrLedState = LED_BLINK_WPS; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_SCAN_INTVL); - break; - case LED_CTL_STOP_WPS: - cancel_delayed_work(&pLed->blink_work); - - pLed->bLedBlinkInProgress = false; - pLed->bLedScanBlinkInProgress = false; - pLed->bLedWPSBlinkInProgress = true; - - pLed->CurrLedState = LED_BLINK_WPS_STOP; - if (pLed->bLedOn) { - schedule_delayed_work(&pLed->blink_work, LED_BLINK_WPS_SUCESS_INTVL); - } else { - schedule_delayed_work(&pLed->blink_work, 0); - } - break; - case LED_CTL_STOP_WPS_FAIL: - cancel_delayed_work(&pLed->blink_work); - pLed->bLedWPSBlinkInProgress = false; - pLed->CurrLedState = LED_BLINK_SLOWLY; - schedule_delayed_work(&pLed->blink_work, LED_BLINK_NO_LINK_INTVL); - break; - case LED_CTL_POWER_OFF: - pLed->CurrLedState = RTW_LED_OFF; - pLed->bLedBlinkInProgress = false; - pLed->bLedWPSBlinkInProgress = false; - pLed->bLedScanBlinkInProgress = false; - cancel_delayed_work(&pLed->blink_work); - SwLedOff(pLed); - break; - default: - break; - } -} diff --git a/drivers/staging/r8188eu/core/rtw_mlme.c b/drivers/staging/r8188eu/core/rtw_mlme.c deleted file mode 100644 index fb7d0e161fdd..000000000000 --- a/drivers/staging/r8188eu/core/rtw_mlme.c +++ /dev/null @@ -1,2067 +0,0 @@ -// 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/hal_intf.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" -#include "../include/rtl8188e_dm.h" - -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; -} - -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); - 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); -} - -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); -} - -/* - return the wlan_network with the matching addr - - Shall be called 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_beacon_interval_from_ie(u8 *ie) -{ - return ie + 8; -} - -static void rtw_join_timeout_handler(struct timer_list *t) -{ - struct adapter *adapter = from_timer(adapter, t, mlmepriv.assoc_timer); - - _rtw_join_timeout_handler(adapter); -} - -static 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); - - rtw_dynamic_check_timer_handlder(adapter); - _set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000); -} - -static 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); -} - -int rtw_init_mlme_priv(struct adapter *padapter)/* struct mlme_priv *pmlmepriv) */ -{ - int i; - u8 *pbuf; - struct wlan_network *pnetwork; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - - /* 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) - return -ENOMEM; - - 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_init_mlme_timer(padapter); - - return 0; -} - -void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) -{ - rtw_free_mlme_priv_ie_data(pmlmepriv); - vfree(pmlmepriv->free_bss_buf); -} - -struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) -{ - 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; -} - -static 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--; -} - -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 called 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; - - AntDivCompare8188E(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); - } - -} - -u8 rtw_current_antenna(struct adapter *adapter) -{ - struct hal_data_8188e *haldata = &adapter->haldata; - - return haldata->CurAntenna; -} - -/* -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; - - target->PhyInfo.Optimum_antenna = rtw_current_antenna(adapter); - - 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; - target->PhyInfo.Optimum_antenna = rtw_current_antenna(adapter); - 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) -{ - - rtw_wlan_bssid_ex_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO); - 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 bool 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)) - 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); -} - -static void rtw_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); -} - -void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) -{ - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - 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)) - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); - - spin_unlock_bh(&pmlmepriv->lock); - - del_timer_sync(&pmlmepriv->scan_to_timer); - - 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); - - 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 (s_ret == _SUCCESS) { - _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT); - } else { - if (rtw_to_roaming(adapter) != 0) { - if (--pmlmepriv->to_roaming == 0 || - rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1) != _SUCCESS) { - 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_xmit_schedule(adapter); -} - -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; - -} - -static struct rt_pmkid_list backup_pmkid[NUM_PMKID_CACHE]; - -static void rtw_reset_securitypriv(struct adapter *adapter) -{ - u8 backup_index; - u8 backup_counter; - u32 backup_time; - - 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. */ - 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; - } -} - -/* -*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_indicate_wx_assoc_event(padapter); - netif_carrier_on(padapter->pnetdev); - if (padapter->pid[2] != 0) - rtw_signal_process(padapter->pid[2], SIGALRM); - } - - pmlmepriv->to_roaming = 0; -} - -/* -*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)) { - /* Do it first for tx broadcast pkt after disconnection issue! */ - netif_carrier_off(padapter->pnetdev); - - rtw_indicate_wx_disassoc_event(padapter); - rtw_reset_securitypriv(padapter); - - _clr_fwstate_(pmlmepriv, _FW_LINKED); - rtw_led_control(padapter, LED_CTL_NO_LINK); - } - 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) -{ - indicate_wx_scan_complete_event(padapter); -} - -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 */ - psta->aid = pnetwork->join_res; - psta->mac_id = 0; - /* sta mode */ - rtl8188e_SetHalODMVar(padapter, 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)); - } - /* 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 transmitted. */ - 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; - - /* 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_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) -{ - 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; - - 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); - } - - spin_unlock_bh(&pmlmepriv->lock); - /* s5. Cancel assoc_timer */ - del_timer_sync(&pmlmepriv->assoc_timer); - spin_lock_bh(&pmlmepriv->lock); - } 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_xmit_schedule(adapter); -} - -void rtw_set_max_rpt_macid(struct adapter *adapter, u8 macid) -{ - rtw_write8(adapter, REG_TX_RPT_CTRL + 1, macid + 1); -} - -static u8 search_max_mac_id(struct adapter *padapter) -{ - u8 mac_id; - u8 aid; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct sta_priv *pstapriv = &padapter->stapriv; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - - 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 { - /* 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_set_max_rpt_macid(adapter, macid); - - /* MACID|OPMODE:1 connect */ - media_status_rpt = (u16)((psta->mac_id << 8) | mstatus); - rtl8188e_set_FwMediaStatus_cmd(adapter, 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 (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr); - if (psta) - rtw_indicate_sta_assoc_event(adapter, psta); - return; - } - /* 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; - - /* for ad-hoc mode */ - rtl8188e_SetHalODMVar(adapter, 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; - - 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 */ - rtl8188e_set_FwMediaStatus_cmd(adapter, 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)); - - 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/failure 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; - - if (adapter->bDriverStopped || adapter->bSurpriseRemoved) - return; - - spin_lock_irq(&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 */ - do_join_r = rtw_do_join(adapter); - if (do_join_r != _SUCCESS) - continue; - break; - } else { - rtw_indicate_disconnect(adapter); - break; - } - } - } else { - rtw_indicate_disconnect(adapter); - free_scanqueue(pmlmepriv);/* */ - } - spin_unlock_irq(&pmlmepriv->lock); - -} - -/* -* rtw_scan_timeout_handler - Timeout/Failure handler for CMD SiteSurvey -* @adapter: pointer to struct adapter structure -*/ -void rtw_scan_timeout_handler (struct adapter *adapter) -{ - struct mlme_priv *pmlmepriv = &adapter->mlmepriv; - - spin_lock_bh(&pmlmepriv->lock); - _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); - spin_unlock_bh(&pmlmepriv->lock); - rtw_indicate_scan_done(adapter); -} - -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) { - 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) { - struct wifidirect_info *pwdinfo = &adapter->wdinfo; - if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) { - /* 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); - unsigned long scan_res_expire; - - /* 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; - - scan_res_expire = competitor->last_scanned + msecs_to_jiffies(RTW_SCAN_RESULT_EXPIRE); - if (rtw_to_roaming(adapter) > 0) { - if (time_after(jiffies, scan_res_expire) || - !is_same_ess(&competitor->network, &pmlmepriv->cur_network.network)) - goto exit; - } - - if (!*candidate || (*candidate)->network.Rssi < competitor->network.Rssi) { - *candidate = competitor; - updated = true; - } - -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; - - 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); - pmlmepriv->pscanned = pmlmepriv->pscanned->next; - rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork); - } - if (!candidate) { - ret = _FAIL; - goto exit; - } - - /* check for situation of _FW_LINKED */ - if (check_fwstate(pmlmepriv, _FW_LINKED)) { - rtw_disassoc_cmd(adapter, 0, true); - rtw_indicate_disconnect(adapter); - rtw_free_assoc_resources(adapter, 0); - } - - 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(*pcmd), GFP_KERNEL); - if (!pcmd) { - res = _FAIL; /* try again */ - goto exit; - } - - psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_KERNEL); - if (!psetauthparm) { - kfree(pcmd); - res = _FAIL; - goto exit; - } - 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(*pcmd), GFP_KERNEL); - if (!pcmd) { - res = _FAIL; /* try again */ - goto exit; - } - psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_KERNEL); - if (!psetkeyparm) { - kfree(pcmd); - res = _FAIL; - goto exit; - } - - 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); - - 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: - kfree(psetkeyparm); - kfree(pcmd); - 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; -} - -/* */ -/* 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 *p = &Adapter->securitypriv; - int i; - - for (i = 0; i < NUM_PMKID_CACHE; i++) - if (p->PMKIDList[i].bUsed && !memcmp(p->PMKIDList[i].Bssid, bssid, ETH_ALEN)) - return i; - return -1; -} - -/* */ -/* 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; -} - -static 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_ATOMIC); - 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); - } -} - -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; - - 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); */ - -} - -static void rtw_set_threshold(struct adapter *adapter) -{ - struct mlme_priv *mlmepriv = &adapter->mlmepriv; - struct ht_priv *htpriv = &mlmepriv->htpriv; - - if (htpriv->ht_option && adapter->registrypriv.wifi_spec != 1) { - /* validate usb rx aggregation, use init value. */ - rtw_write8(adapter, REG_RXDMA_AGG_PG_TH, USB_RXAGG_PAGE_COUNT); - } else { - /* invalidate usb rx aggregation */ - rtw_write8(adapter, REG_RXDMA_AGG_PG_TH, 1); - } -} - -/* the function is at passive_level */ -void rtw_joinbss_reset(struct adapter *padapter) -{ - 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 */ - - rtw_set_threshold(padapter); -} - -/* 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; - 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; - - 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); - - /* - AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k - AMPDU_para [4:2]:Min MPDU Start Spacing - */ - - ht_capie.ampdu_params_info = (MAX_AMPDU_FACTOR_64K & 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; - - /* 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; - - /* update the MCS rates */ - for (i = 0; i < 16; i++) - pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[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; - - /* 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 (issued == 0) { - 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 (rtw_to_roaming(padapter) > 0) { - 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 (do_join_r == _SUCCESS) { - break; - } else { - pmlmepriv->to_roaming--; - - if (pmlmepriv->to_roaming > 0) { - continue; - } else { - 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 deleted file mode 100644 index dc181e491b34..000000000000 --- a/drivers/staging/r8188eu/core/rtw_mlme_ext.c +++ /dev/null @@ -1,7817 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2012 Realtek Corporation. */ - -#define _RTW_MLME_EXT_C_ - -#include <linux/ieee80211.h> -#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/rtl8188e_xmit.h" -#include "../include/rtl8188e_dm.h" - -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_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 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 */ - {0x00}, /* 0x13 */ - {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, */ - {0x00}, /* 0x1F, */ - /* 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 combination 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 ((padapter->registrypriv.ht_enable == 0) && (o->inc == 8)) - continue; - - if (((padapter->registrypriv.cbw40_enable & BIT(1)) == 0) && - ((o->bw == BW40MINUS) || (o->bw == BW40PLUS))) - 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) - return chanset_size; - - if (padapter->registrypriv.wireless_mode & WIRELESS_11G) { - b2_4GBand = true; - if (ChannelPlan == RT_CHANNEL_DOMAIN_REALTEK_DEFINE) - 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 ((ChannelPlan == RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN) ||/* Channel 1~11 is active, and 12~14 is passive */ - (ChannelPlan == RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G)) { - 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 (ChannelPlan == RT_CHANNEL_DOMAIN_WORLD_WIDE_13 || - Index2G == RT_CHANNEL_DOMAIN_2G_WORLD) {/* 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; -} - -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 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); -} - -void init_mlme_ext_priv(struct adapter *padapter) -{ - 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); - - init_mlme_ap_info(padapter); - - 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; -} - -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 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; -} - -static void correct_TSF(struct adapter *padapter) -{ - u8 reg; - int res; - u64 tsf; - struct mlme_ext_priv *pmlmeext = &padapter->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)) - rtw_stop_tx_beacon(padapter); - - /* disable related TSF function */ - res = rtw_read8(padapter, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(padapter, REG_BCN_CTRL, reg & (~BIT(3))); - - rtw_write32(padapter, REG_TSFTR, tsf); - rtw_write32(padapter, REG_TSFTR + 4, tsf >> 32); - - /* enable related TSF function */ - res = rtw_read8(padapter, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(padapter, REG_BCN_CTRL, reg | BIT(3)); - - if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || - ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) - rtw_resume_tx_beacon(padapter); -} - -/**************************************************************************** - -Following are the callback functions for each subtype of the management frames - -*****************************************************************************/ - -static void 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; - - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - - 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 */ - 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; - } - } - } - - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) - return; - - if (!check_fwstate(pmlmepriv, _FW_LINKED) && - !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) - return; - - 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; - -_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); - } -} - -static void OnProbeRsp(struct adapter *padapter, struct recv_frame *precv_frame) -{ - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - u8 *pframe = precv_frame->rx_data; - - 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; - } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) { - if (pwdinfo->nego_req_info.benable) { - 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) { - 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); - } - } - } - if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { - report_survey_event(padapter, precv_frame); - return; - } -} - -static void OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - 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; - u8 *ie_ptr; - u32 ie_len; - - ie_ptr = (u8 *)&mgmt->u.beacon.variable; - if (precv_frame->len < offsetof(struct ieee80211_mgmt, u.beacon.variable)) - return; - ie_len = precv_frame->len - offsetof(struct ieee80211_mgmt, u.beacon.variable); - - if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { - report_survey_event(padapter, precv_frame); - return; - } - - if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) - return; - - 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) - return; - - 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 ieee80211_hdr_3addr), len - sizeof(struct ieee80211_hdr_3addr)); - - pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp); - - /* start auth */ - start_clnt_auth(padapter); - - return; - } - - if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { - psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (!psta) - return; - - if (rtw_check_bcn_info(padapter, pframe, len) != _SUCCESS) { - receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0); - return; - } - /* 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, ie_ptr, ie_len, psta); - process_p2p_ps_ie(padapter, ie_ptr, ie_len); - } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) { - psta = rtw_get_stainfo(pstapriv, mgmt->sa); - 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, ie_ptr, ie_len, psta); - } else { - /* allocate a new CAM entry for IBSS station */ - cam_idx = allocate_fw_sta_entry(padapter); - if (cam_idx == NUM_STA) - return; - - /* get supported rate */ - if (update_sta_support_rate(padapter, ie_ptr, ie_len, cam_idx) == _FAIL) { - pmlmeinfo->FW_sta_info[cam_idx].status = 0; - return; - } - - pmlmeext->TSFValue = le64_to_cpu(mgmt->u.beacon.timestamp); - - report_add_sta_event(padapter, mgmt->sa, cam_idx); - } - } -} - -static void OnAuth(struct adapter *padapter, struct recv_frame *precv_frame) -{ - 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; - - 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)); - - 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 */ - - 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 */ - pstat = rtw_alloc_stainfo(pstapriv, sa); - if (!pstat) { - 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) { - 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 { - 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... */ - - 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) { - 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 { - status = _STATS_CHALLENGE_FAIL_; - goto auth_fail; - } - } else { - status = _STATS_OUT_OF_AUTH_SEQ_; - goto auth_fail; - } - } - - /* Now, we are going to issue_auth... */ - pstat->auth_seq = seq + 1; - - issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_)); - - if (pstat->state & WIFI_FW_AUTH_SUCCESS) - pstat->auth_seq = 0; - - return; - -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); - - issue_auth(padapter, pstat, (unsigned short)status); -} - -static void OnAuthClient(struct adapter *padapter, struct recv_frame *precv_frame) -{ - unsigned int seq, len, status, offset; - unsigned char *p; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; - u8 *pframe = precv_frame->rx_data; - uint pkt_len = precv_frame->len; - - /* check A1 matches or not */ - if (memcmp(myid(&padapter->eeprompriv), ieee80211_get_DA(hdr), ETH_ALEN)) - return; - - if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) - return; - - offset = ieee80211_has_protected(hdr->frame_control) ? 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) { - 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); - return; - } - - 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) - return; - - 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; - } else { - /* open system */ - start_clnt_assoc(padapter); - } - } else if (seq == 4) { - if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) - start_clnt_assoc(padapter); - } -} - -static void UpdateBrateTbl(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; - } - } -} - -static 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; - } - } -} - -static void OnAssocReq(struct adapter *padapter, struct recv_frame *precv_frame) -{ - u16 capab_info; - struct rtw_ieee802_11_elems elems; - struct sta_info *pstat; - unsigned char *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; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - u8 p2p_status_code = P2P_STATUS_SUCCESS; - u8 *p2pie; - u32 p2pielen = 0; - - if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) - return; - - frame_type = GetFrameSubType(pframe); - if (frame_type == WIFI_ASSOCREQ) - ie_offset = _ASOCREQ_IE_OFFSET_; - else /* WIFI_REASSOCREQ */ - ie_offset = _REASOCREQ_IE_OFFSET_; - - if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) - return; - - 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); - - /* 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) { - 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 (status != _STATS_SUCCESSFUL_) - 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) { - /* 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 (status != _STATS_SUCCESSFUL_) - goto OnAssocReqFail; - - pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); - if (!wpa_ie) { - if (elems.wps_ie) - 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 - 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) { - - status = _STATS_UNABLE_HANDLE_STA_; - - goto OnAssocReqFail; - } - } - } - } else { - int copy_len; - - if (psecuritypriv->wpa_psk == 0) { - - status = WLAN_STATUS_INVALID_IE; - - goto OnAssocReqFail; - } - - if (elems.wps_ie) { - 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; - } - - 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; - - 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; - - /* 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) { - 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; - - status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; - - goto OnAssocReqFail; - } else { - pstapriv->sta_aid[pstat->aid - 1] = pstat; - } - } - - 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) && (status == _STATS_SUCCESSFUL_)) { - /* 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 */ - rtw_indicate_sta_assoc_event(padapter, pstat); - - /* 3-(1) report sta add event */ - report_add_sta_event(padapter, pstat->hwaddr, pstat->aid); - } - - return; - -asoc_class2_error: - - issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status); - - return; - -OnAssocReqFail: - - pstat->aid = 0; - if (frame_type == WIFI_ASSOCREQ) - issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); - else - issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); - - return; -} - -static void OnAssocRsp(struct adapter *padapter, struct recv_frame *precv_frame) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - uint i; - int res; - 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); */ - u8 *pframe = precv_frame->rx_data; - uint pkt_len = precv_frame->len; - - /* check A1 matches or not */ - if (memcmp(myid(&padapter->eeprompriv), mgmt->da, ETH_ALEN)) - return; - - if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE))) - return; - - if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) - return; - - _cancel_timer_ex(&pmlmeext->link_timer); - - if (le16_to_cpu(mgmt->u.assoc_resp.status_code) > 0) { - pmlmeinfo->state = WIFI_FW_NULL_STATE; - res = -4; - goto report_assoc_result; - } - - pmlmeinfo->capability = le16_to_cpu(mgmt->u.assoc_resp.capab_info); - - /* set slot time */ - pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20; - - pmlmeinfo->aid = le16_to_cpu(mgmt->u.assoc_resp.aid) & 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 = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 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(pmlmeinfo->network.SupportedRates); - -report_assoc_result: - report_join_res(padapter, res); -} - -static void OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - unsigned short reason; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - - if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) - return; - - if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { - _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); - _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); - } - - reason = le16_to_cpu(mgmt->u.disassoc.reason_code); - - if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - struct sta_info *psta; - struct sta_priv *pstapriv = &padapter->stapriv; - u8 updated = 0; - - psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (!psta) - return; - - 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); - } else { - bool ignore_received_deauth = false; - - /* 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 | WIFI_FW_ASSOC_STATE)) { - if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) { - ignore_received_deauth = true; - } else if (reason == WLAN_REASON_PREV_AUTH_NOT_VALID) { - // TODO: 802.11r - ignore_received_deauth = true; - } - } - - if (!ignore_received_deauth) - receive_disconnect(padapter, mgmt->bssid, reason); - - pmlmepriv->LinkDetectInfo.bBusyTraffic = false; - } -} - -static void OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - u16 reason; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - struct sta_info *psta; - struct sta_priv *pstapriv = &padapter->stapriv; - u8 updated = 0; - - if (memcmp(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) - return; - - if (pwdinfo->rx_invitereq_info.scan_op_ch_only) { - _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey); - _set_timer(&pwdinfo->reset_ch_sitesurvey, 10); - } - - reason = le16_to_cpu(mgmt->u.disassoc.reason_code); - - if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) { - receive_disconnect(padapter, mgmt->bssid, reason); - pmlmepriv->LinkDetectInfo.bBusyTraffic = false; - return; - } - - psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (!psta) - return; - - 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); -} - -static void OnAction_back(struct adapter *padapter, struct recv_frame *precv_frame) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - struct sta_info *psta = NULL; - struct recv_reorder_ctrl *preorder_ctrl; - unsigned short tid; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - struct sta_priv *pstapriv = &padapter->stapriv; - - if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE) - if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) - return; - - psta = rtw_get_stainfo(pstapriv, mgmt->sa); - if (!psta) - return; - - if (!pmlmeinfo->HT_enable) - return; - /* All union members start with an action code, it's ok to use addba_req. */ - switch (mgmt->u.action.u.addba_req.action_code) { - case WLAN_ACTION_ADDBA_REQ: - tid = u16_get_bits(le16_to_cpu(mgmt->u.action.u.addba_req.capab), - IEEE80211_ADDBA_PARAM_TID_MASK); - preorder_ctrl = &psta->recvreorder_ctrl[tid]; - preorder_ctrl->indicate_seq = 0xffff; - preorder_ctrl->enable = pmlmeinfo->bAcceptAddbaReq; - issue_action_BA(padapter, mgmt->sa, WLAN_ACTION_ADDBA_RESP, - pmlmeinfo->bAcceptAddbaReq ? - WLAN_STATUS_SUCCESS : WLAN_STATUS_REQUEST_DECLINED, mgmt); - break; - case WLAN_ACTION_ADDBA_RESP: - tid = u16_get_bits(le16_to_cpu(mgmt->u.action.u.addba_resp.capab), - IEEE80211_ADDBA_PARAM_TID_MASK); - if (mgmt->u.action.u.addba_resp.status == 0) { /* successful */ - psta->htpriv.agg_enable_bitmap |= BIT(tid); - psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); - } else { - psta->htpriv.agg_enable_bitmap &= ~BIT(tid); - } - break; - case WLAN_ACTION_DELBA: - tid = u16_get_bits(le16_to_cpu(mgmt->u.action.u.delba.params), - IEEE80211_DELBA_PARAM_TID_MASK); - if (u16_get_bits(le16_to_cpu(mgmt->u.action.u.delba.params), - IEEE80211_DELBA_PARAM_INITIATOR_MASK) == WLAN_BACK_RECIPIENT) { - psta->htpriv.agg_enable_bitmap &= ~BIT(tid); - psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); - } else { - preorder_ctrl = &psta->recvreorder_ctrl[tid]; - preorder_ctrl->enable = false; - preorder_ctrl->indicate_seq = 0xffff; - } - /* todo: how to notify the host while receiving DELETE BA */ - break; - default: - break; - } -} - -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 = 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 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 negotiation 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 = 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 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 negotiation 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 = 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 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 negotiation 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 = 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 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 = 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 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 = 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 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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; - - for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) { - if (!memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) { - match_result = 1; - 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 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 ieee80211_hdr *)pframe; - - mac = myid(&padapter->eeprompriv); - - fctrl = &pwlanhdr->frame_control; - *(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 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); -} - -inline void issue_probereq_p2p(struct adapter *padapter) -{ - struct xmit_frame *pmgntframe; - struct pkt_attrib *pattrib; - unsigned char *pframe; - struct ieee80211_hdr *pwlanhdr; - __le16 *fctrl; - unsigned char *mac; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - 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) - 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 ieee80211_hdr *)pframe; - - mac = myid(&padapter->eeprompriv); - - fctrl = &pwlanhdr->frame_control; - *(fctrl) = 0; - - 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 */ - eth_broadcast_addr(pwlanhdr->addr1); - eth_broadcast_addr(pwlanhdr->addr3); - } - - memcpy(pwlanhdr->addr2, mac, ETH_ALEN); - - SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - SetFrameSubType(pframe, WIFI_PROBEREQ); - - pframe += sizeof(struct ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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; - - dump_mgntframe(padapter, pmgntframe); -} - -static s32 rtw_action_public_decache(struct recv_frame *recv_frame, u8 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 ((seq_ctrl == mlmeext->action_public_rxseq) && - (token == mlmeext->action_public_dialog_token)) - return _FAIL; - } - - mlmeext->action_public_rxseq = seq_ctrl; - 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; - 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 }; - - frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); - - dialogToken = frame_body[7]; - - if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL) - return _FAIL; - - _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 ieee80211_hdr_3addr); - - switch (frame_body[6]) { /* OUI Subtype */ - case P2P_GO_NEGO_REQ: - 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)); - } - - /* 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: - 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 (result == P2P_STATUS_SUCCESS) { - 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); - } - break; - case P2P_GO_NEGO_CONF: - result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len); - if (result == P2P_STATUS_SUCCESS) { - 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. */ - - 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 (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 { - 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 { - status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; - } - } - } else { - status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE; - } - - 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; - - _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) { - 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: - 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?? */ - /* 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; - } - - return _SUCCESS; -} - -static void on_action_public(struct adapter *padapter, struct recv_frame *precv_frame) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - u8 *frame_body = (u8 *)&mgmt->u; - - /* All members of the action enum start with action_code. */ - if (mgmt->u.action.u.s1g.action_code == WLAN_PUB_ACTION_VENDOR_SPECIFIC) { - if (!memcmp(frame_body + 2, P2P_OUI, 4)) - on_action_public_p2p(precv_frame); - } else { - rtw_action_public_decache(precv_frame, frame_body[2]); - } -} - -static void OnAction_p2p(struct adapter *padapter, struct recv_frame *precv_frame) -{ - u8 *frame_body; - u8 OUI_Subtype; - u8 *pframe = precv_frame->rx_data; - uint len = precv_frame->len; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - - frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); - - if (be32_to_cpu(*((__be32 *)(frame_body + 1))) != P2POUI) - return; - - len -= sizeof(struct ieee80211_hdr_3addr); - OUI_Subtype = frame_body[5]; - - if (OUI_Subtype == P2P_PRESENCE_REQUEST) - process_p2p_presence_req(pwdinfo, pframe, len); -} - -static void OnAction(struct adapter *padapter, struct recv_frame *precv_frame) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - - if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da)) - return; - - switch (mgmt->u.action.category) { - case WLAN_CATEGORY_BACK: - OnAction_back(padapter, precv_frame); - break; - case WLAN_CATEGORY_PUBLIC: - on_action_public(padapter, precv_frame); - break; - case RTW_WLAN_CATEGORY_P2P: - OnAction_p2p(padapter, precv_frame); - break; - } -} - -struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) -{ - struct xmit_frame *pmgntframe; - struct xmit_buf *pxmitbuf; - - pmgntframe = rtw_alloc_xmitframe(pxmitpriv); - if (!pmgntframe) - return NULL; - - pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv); - if (!pxmitbuf) { - 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; -} - -void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame) -{ - mlme_handler mlme_sta_tbl[] = { - OnAssocReq, - OnAssocRsp, - OnAssocReq, - OnAssocRsp, - OnProbeReq, - OnProbeRsp, - NULL, - NULL, - OnBeacon, - NULL, - OnDisassoc, - OnAuthClient, - OnDeAuth, - OnAction, - }; - int index; - mlme_handler fct; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; - struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, hdr->addr2); - - if (!ieee80211_is_mgmt(hdr->frame_control)) - return; - - /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ - if (memcmp(hdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN) && - !is_broadcast_ether_addr(hdr->addr1)) - return; - - index = (le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE) >> 4; - if (index >= ARRAY_SIZE(mlme_sta_tbl)) - return; - fct = mlme_sta_tbl[index]; - - if (psta) { - if (ieee80211_has_retry(hdr->frame_control)) { - if (precv_frame->attrib.seq_num == psta->RxMgmtFrameSeqNum) - /* drop the duplicate management frame */ - return; - } - psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num; - } - - if (ieee80211_is_auth(hdr->frame_control)) { - if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) - fct = OnAuth; - else - fct = OnAuthClient; - } - - if (fct) - fct(padapter, precv_frame); -} - -/**************************************************************************** - -Following are some TX functions for WiFi MLME - -*****************************************************************************/ - -void update_mgnt_tx_rate(struct adapter *padapter, u8 rate) -{ - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - - pmlmeext->tx_rate = 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) -{ - rtl8188eu_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 = rtl8188eu_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; - - mutex_lock(&pxmitpriv->ack_tx_mutex); - pxmitpriv->ack_tx = true; - - pmgntframe->ack_report = 1; - if (rtl8188eu_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) { - ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms); - } - - pxmitpriv->ack_tx = false; - mutex_unlock(&pxmitpriv->ack_tx_mutex); - - 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 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; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - - pmgntframe = alloc_mgtxmitframe(pxmitpriv); - if (!pmgntframe) - return; - spin_lock_bh(&pmlmepriv->bcn_update_lock); - - /* 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(fctrl) = 0; - - eth_broadcast_addr(pwlanhdr->addr1); - 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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); - - if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { - /* 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 { - 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 ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, - pattrib->pktlen - sizeof(struct 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); - } - - if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) { - u32 len; - len = build_beacon_p2p_ie(pwdinfo, pframe); - - pframe += len; - pattrib->pktlen += len; - } - - 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: - - pmlmepriv->update_bcn = false; - - spin_unlock_bh(&pmlmepriv->bcn_update_lock); - - if ((pattrib->pktlen + TXDESC_SIZE) > 512) - return; - - pattrib->last_txcmdsz = pattrib->pktlen; - - 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 ieee80211_hdr *pwlanhdr; - __le16 *fctrl; - unsigned char *mac, *bssid; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - u8 *pwps_ie; - uint wps_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 *cur_network = &pmlmeinfo->network; - unsigned int rate_len; - 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 ieee80211_hdr *)pframe; - - mac = myid(&padapter->eeprompriv); - bssid = cur_network->MacAddress; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = pattrib->hdrlen; - pframe += pattrib->hdrlen; - - if (cur_network->IELength > MAX_IE_SZ) - return; - - 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 { - /* 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 */ - } - - 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; - } - - 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 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; - - 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 ieee80211_hdr *)pframe; - - mac = myid(&padapter->eeprompriv); - - fctrl = &pwlanhdr->frame_control; - *(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 */ - eth_broadcast_addr(pwlanhdr->addr1); - eth_broadcast_addr(pwlanhdr->addr3); - } - - memcpy(pwlanhdr->addr2, mac, ETH_ALEN); - - SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - SetFrameSubType(pframe, WIFI_PROBEREQ); - - pframe += sizeof(struct ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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); -} - -void issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da) -{ - int i; - - for (i = 0; i < 3; i++) { - if (_issue_probereq(padapter, pssid, da, true) == _FAIL) - msleep(1); - else - break; - } -} - -/* if psta == NULL, indicate 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 ieee80211_hdr *pwlanhdr; - __le16 *fctrl; - unsigned int val32; - u16 val16; - __le16 le_val16; - 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(fctrl) = 0; - - SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - SetFrameSubType(pframe, WIFI_AUTH); - - pframe += sizeof(struct ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); - - if (psta) {/* for 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); - } 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 ieee80211_hdr_3addr); - - pattrib->encrypt = _WEP40_; - - pattrib->icv_len = 4; - - pattrib->pktlen += pattrib->icv_len; - } - } - - pattrib->last_txcmdsz = pattrib->pktlen; - - rtw_wep_encrypt(padapter, pmgntframe); - dump_mgntframe(padapter, pmgntframe); -} - -void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type) -{ - struct xmit_frame *pmgntframe; - struct 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; - 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 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; - } - - 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; - } - pattrib->last_txcmdsz = pattrib->pktlen; - dump_mgntframe(padapter, pmgntframe); -} - -void issue_assocreq(struct adapter *padapter) -{ - int ret = _FAIL; - struct xmit_frame *pmgntframe; - struct pkt_attrib *pattrib; - unsigned char *pframe, *p; - struct ieee80211_hdr *pwlanhdr; - __le16 *fctrl; - __le16 le_tmp; - unsigned int i, j, ie_len, index = 0; - unsigned char 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; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - u8 p2pie[255] = { 0x00 }; - u16 p2pielen = 0; - - 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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; - - /* 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 supported by STA */ - bssrate[index++] = pmlmeinfo->network.SupportedRates[i]; - } - - bssrate_len = index; - - 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); - - 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); - - 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 vendor extension information 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); - - 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); - } - - 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 true, this function should 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 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 should 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; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - - /* da == NULL, assume 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; - } -exit: - return ret; -} - -/* when wait_ack is true, this function should 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 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; - - 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(fctrl) = 0; - - if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) - SetFrDs(fctrl); - else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) - SetToDs(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 ieee80211_qos_hdr); - pattrib->pktlen = sizeof(struct ieee80211_qos_hdr); - - 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 should 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; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - - /* da == NULL, assume 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; - } -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 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; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - - 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); - } - - 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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) -{ - 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; - - 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; - } -exit: - return ret; -} - -void issue_action_BA(struct adapter *padapter, unsigned char *raddr, u8 action, - u16 status, struct ieee80211_mgmt *mgmt_req) -{ - u16 start_seq; - u16 BA_starting_seqctrl = 0; - struct xmit_frame *pmgntframe; - struct pkt_attrib *pattrib; - 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; - struct ieee80211_mgmt *mgmt; - u16 capab, params; - - 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); - - mgmt = (struct ieee80211_mgmt *)(pmgntframe->buf_addr + TXDESC_OFFSET); - - mgmt->frame_control = cpu_to_le16(IEEE80211_STYPE_ACTION | IEEE80211_FTYPE_MGMT); - - memcpy(mgmt->da, raddr, ETH_ALEN); - memcpy(mgmt->sa, myid(&padapter->eeprompriv), ETH_ALEN); - memcpy(mgmt->bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); - - mgmt->seq_ctrl = cpu_to_le16(pmlmeext->mgnt_seq); - pmlmeext->mgnt_seq++; - - mgmt->u.action.category = WLAN_CATEGORY_BACK; - - switch (action) { - case WLAN_ACTION_ADDBA_REQ: - mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ; - do { - pmlmeinfo->dialogToken++; - } while (pmlmeinfo->dialogToken == 0); - mgmt->u.action.u.addba_req.dialog_token = pmlmeinfo->dialogToken; - - /* immediate ack & 64 buffer size */ - capab = u16_encode_bits(64, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); - capab |= u16_encode_bits(1, IEEE80211_ADDBA_PARAM_POLICY_MASK); - capab |= u16_encode_bits(status, IEEE80211_ADDBA_PARAM_TID_MASK); - mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab); - - mgmt->u.action.u.addba_req.timeout = cpu_to_le16(5000); /* 5 ms */ - - psta = rtw_get_stainfo(pstapriv, raddr); - if (psta) { - start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07] & 0xfff) + 1; - - psta->BA_starting_seqctrl[status & 0x07] = start_seq; - - BA_starting_seqctrl = start_seq << 4; - } - mgmt->u.action.u.addba_req.start_seq_num = cpu_to_le16(BA_starting_seqctrl); - - pattrib->pktlen = offsetofend(struct ieee80211_mgmt, - u.action.u.addba_req.start_seq_num); - break; - case WLAN_ACTION_ADDBA_RESP: - mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; - mgmt->u.action.u.addba_resp.dialog_token = mgmt_req->u.action.u.addba_req.dialog_token; - mgmt->u.action.u.addba_resp.status = cpu_to_le16(status); - capab = le16_to_cpu(mgmt_req->u.action.u.addba_req.capab) & 0x3f; - capab |= u16_encode_bits(64, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK); - capab |= u16_encode_bits(pregpriv->ampdu_amsdu, IEEE80211_ADDBA_PARAM_AMSDU_MASK); - mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab); - mgmt->u.action.u.addba_resp.timeout = mgmt_req->u.action.u.addba_req.timeout; - pattrib->pktlen = offsetofend(struct ieee80211_mgmt, u.action.u.addba_resp.timeout); - break; - case WLAN_ACTION_DELBA: - mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA; - mgmt->u.action.u.delba.params = cpu_to_le16((status & 0x1F) << 3); - params = u16_encode_bits((status & 0x1), IEEE80211_DELBA_PARAM_INITIATOR_MASK); - params |= u16_encode_bits((status >> 1) & 0xF, IEEE80211_DELBA_PARAM_TID_MASK); - mgmt->u.action.u.delba.params = cpu_to_le16(params); - mgmt->u.action.u.delba.reason_code = cpu_to_le16(WLAN_STATUS_REQUEST_DECLINED); - pattrib->pktlen = offsetofend(struct ieee80211_mgmt, u.action.u.delba.reason_code); - 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 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; - - category = 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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) { - issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, - (((tid << 1) | initiator) & 0x1F), NULL); - 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)) { - issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, - (((tid << 1) | initiator) & 0x1F), NULL); - psta->htpriv.agg_enable_bitmap &= ~BIT(tid); - psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); - } - } - } - - return _SUCCESS; -} - -unsigned int send_beacon(struct adapter *padapter) -{ - bool bxmitok = false; - int issue = 0; - int poll = 0; - - clear_beacon_valid_bit(padapter); - - do { - issue_beacon(padapter, 100); - issue++; - do { - yield(); - bxmitok = get_beacon_valid_bit(padapter); - poll++; - } while ((poll % 10) != 0 && !bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); - } while (!bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); - - if (padapter->bSurpriseRemoved || padapter->bDriverStopped || !bxmitok) - return _FAIL; - - return _SUCCESS; -} - -bool get_beacon_valid_bit(struct adapter *adapter) -{ - int res; - u8 reg; - - res = rtw_read8(adapter, REG_TDECTRL + 2, ®); - if (res) - return false; - - /* BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2 */ - return BIT(0) & reg; -} - -void clear_beacon_valid_bit(struct adapter *adapter) -{ - int res; - u8 reg; - - res = rtw_read8(adapter, REG_TDECTRL + 2, ®); - if (res) - return; - - /* BIT(16) of REG_TDECTRL = BIT(0) of REG_TDECTRL+2, write 1 to clear, Clear by sw */ - rtw_write8(adapter, REG_TDECTRL + 2, reg | BIT(0)); -} - -void rtw_resume_tx_beacon(struct adapter *adapt) -{ - struct hal_data_8188e *haldata = &adapt->haldata; - - /* 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); -} - -void rtw_stop_tx_beacon(struct adapter *adapt) -{ - struct hal_data_8188e *haldata = &adapt->haldata; - - /* 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 rtw_set_opmode(struct adapter *adapter, u8 mode) -{ - u8 val8; - int res; - - /* disable Port0 TSF update */ - res = rtw_read8(adapter, REG_BCN_CTRL, &val8); - if (res) - return; - - rtw_write8(adapter, REG_BCN_CTRL, val8 | BIT(4)); - - /* set net_type */ - res = rtw_read8(adapter, MSR, &val8); - if (res) - return; - - val8 &= 0x0c; - val8 |= mode; - rtw_write8(adapter, MSR, val8); - - if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) { - rtw_stop_tx_beacon(adapter); - - rtw_write8(adapter, REG_BCN_CTRL, 0x19);/* disable atim wnd */ - } else if (mode == _HW_STATE_ADHOC_) { - rtw_resume_tx_beacon(adapter); - rtw_write8(adapter, REG_BCN_CTRL, 0x1a); - } else if (mode == _HW_STATE_AP_) { - rtw_resume_tx_beacon(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 */ - res = rtw_read8(adapter, REG_MBID_NUM, &val8); - if (res) - return; - - rtw_write8(adapter, REG_MBID_NUM, val8 | 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 */ - res = rtw_read8(adapter, REG_BCN_CTRL_1, &val8); - if (res) - return; - - rtw_write8(adapter, REG_BCN_CTRL_1, val8 | BIT(0)); - } -} - -/**************************************************************************** - -Following are some utility functions for WiFi MLME - -*****************************************************************************/ - -static void rtw_set_initial_gain(struct adapter *adapter, u8 gain) -{ - struct hal_data_8188e *haldata = &adapter->haldata; - struct odm_dm_struct *odmpriv = &haldata->odmpriv; - struct rtw_dig *digtable = &odmpriv->DM_DigTable; - - if (gain == 0xff) { - /* restore rx gain */ - ODM_Write_DIG(odmpriv, digtable->BackupIGValue); - } else { - digtable->BackupIGValue = digtable->CurIGValue; - ODM_Write_DIG(odmpriv, gain); - } -} - -void rtw_mlme_under_site_survey(struct adapter *adapter) -{ - /* config RCR to receive different BSSID & not to receive data frame */ - - int res; - u8 reg; - u32 v; - - res = rtw_read32(adapter, REG_RCR, &v); - if (res) - return; - - v &= ~(RCR_CBSSID_BCN); - rtw_write32(adapter, REG_RCR, v); - /* reject all data frame */ - rtw_write16(adapter, REG_RXFLTMAP2, 0x00); - - /* disable update TSF */ - res = rtw_read8(adapter, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(adapter, REG_BCN_CTRL, reg | BIT(4)); -} - -void rtw_mlme_site_survey_done(struct adapter *adapter) -{ - struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - u32 reg32; - int res; - u8 reg; - - if ((r8188eu_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 */ - res = rtw_read8(adapter, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(adapter, REG_BCN_CTRL, reg & (~BIT(4))); - } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) { - rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF); - /* enable update TSF */ - res = rtw_read8(adapter, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(adapter, REG_BCN_CTRL, reg & (~BIT(4))); - } - - res = rtw_read32(adapter, REG_RCR, ®32); - if (res) - return; - - rtw_write32(adapter, REG_RCR, reg32 | RCR_CBSSID_BCN); -} - -void site_survey(struct adapter *padapter) -{ - unsigned char survey_channel = 0; - enum rt_scan_type ScanType = SCAN_PASSIVE; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - 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 { - 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) { - 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... */ - if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || - rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)) { - issue_probereq_p2p(padapter); - issue_probereq_p2p(padapter); - issue_probereq_p2p(padapter); - } else { - 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. */ - 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; - - /* restore RX GAIN */ - rtw_set_initial_gain(padapter, 0xff); - /* 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 { - /* 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 selects a better one to do connection. */ - if (AntDivBeforeLink8188E(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; - } - 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); - - pmlmeext->sitesurvey_res.state = SCAN_COMPLETE; - - /* switch back to the original channel */ - - 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); - - /* config MSR */ - Set_MSR(padapter, (pmlmeinfo->state & 0x3)); - - /* restore RX GAIN */ - rtw_set_initial_gain(padapter, 0xff); - /* turn on dynamic functions */ - Restore_DM_Func_Flag(padapter); - /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */ - - if (r8188eu_is_client_associated_to_ap(padapter)) - issue_nulldata(padapter, NULL, 0, 3, 500); - - rtw_mlme_site_survey_done(padapter); - - 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) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)precv_frame->rx_data; - int i; - u32 len; - u8 *p; - u16 val16; - 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 ieee80211_hdr_3addr); - - if (len > MAX_IE_SZ) - return _FAIL; - - memset(bssid, 0, sizeof(struct wlan_bssid_ex)); - - if (ieee80211_is_beacon(mgmt->frame_control)) { - bssid->Reserved[0] = 1; - ie_offset = _BEACON_IE_OFFSET_; - } else if (ieee80211_is_probe_req(mgmt->frame_control)) { - ie_offset = _PROBEREQ_IE_OFFSET_; - bssid->Reserved[0] = 2; - } else if (ieee80211_is_probe_resp(mgmt->frame_control)) { - 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 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 */ - bssid->PhyInfo.Optimum_antenna = rtw_current_antenna(padapter); - - /* checking SSID */ - p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset); - if (!p) - return _FAIL; - - if (*(p + 1)) { - if (len > NDIS_802_11_LENGTH_SSID) - 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) - 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)) - return _FAIL; - memcpy(bssid->SupportedRates + i, (p + 2), len); - } - - 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; -} - -static void rtw_set_bssid(struct adapter *adapter, u8 *bssid) -{ - int i; - - for (i = 0; i < ETH_ALEN; i++) - rtw_write8(adapter, REG_BSSID + i, bssid[i]); -} - -static void mlme_join(struct adapter *adapter, int type) -{ - struct mlme_priv *mlmepriv = &adapter->mlmepriv; - u8 retry_limit = 0x30, reg; - u32 reg32; - int res; - - switch (type) { - case 0: - /* prepare to join */ - /* enable to rx data frame, accept all data frame */ - rtw_write16(adapter, REG_RXFLTMAP2, 0xFFFF); - - res = rtw_read32(adapter, REG_RCR, ®32); - if (res) - return; - - rtw_write32(adapter, REG_RCR, - reg32 | RCR_CBSSID_DATA | RCR_CBSSID_BCN); - - if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) { - retry_limit = 48; - } else { - /* ad-hoc mode */ - retry_limit = 0x7; - } - break; - case 1: - /* joinbss_event call back when join res < 0 */ - rtw_write16(adapter, REG_RXFLTMAP2, 0x00); - break; - case 2: - /* sta add event call back */ - /* enable update TSF */ - res = rtw_read8(adapter, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(adapter, REG_BCN_CTRL, reg & (~BIT(4))); - - if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) - retry_limit = 0x7; - break; - default: - break; - } - - rtw_write16(adapter, REG_RL, - retry_limit << RETRY_LIMIT_SHORT_SHIFT | retry_limit << RETRY_LIMIT_LONG_SHIFT); -} - -void start_create_ibss(struct adapter *padapter) -{ - unsigned short caps; - 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); - - /* update capability */ - caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); - update_capinfo(padapter, caps); - if (caps & cap_IBSS) {/* adhoc master */ - rtw_write8(padapter, REG_SECCFG, 0xcf); - - /* 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_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress); - mlme_join(padapter, 0); - - report_join_res(padapter, 1); - pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; - rtw_indicate_connect(padapter); - } - } else { - 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); - - /* update 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_write8(padapter, REG_SECCFG, 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); - - rtw_write8(padapter, REG_SECCFG, 0xcf); - - /* 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); - - 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); -} - -void 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; - - 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); - } - } -} - -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(*pcmd_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(*pcmd_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; - - 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(*pcmd_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; - - 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; - - 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(*pcmd_obj), GFP_ATOMIC); - if (!pcmd_obj) - return; - - cmdsz = (sizeof(struct stadel_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 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; - - 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(*pcmd_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; - - 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; -} - -static void rtw_reset_dm_func_flag(struct adapter *adapter) -{ - struct hal_data_8188e *haldata = &adapter->haldata; - struct dm_priv *dmpriv = &haldata->dmpriv; - struct odm_dm_struct *odmpriv = &haldata->odmpriv; - - odmpriv->SupportAbility = dmpriv->InitODMFlag; -} - -static void rtw_clear_dm_func_flag(struct adapter *adapter) -{ - struct hal_data_8188e *haldata = &adapter->haldata; - struct odm_dm_struct *odmpriv = &haldata->odmpriv; - - odmpriv->SupportAbility = 0; -} - -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; - u16 media_status; - - if (join_res < 0) { - mlme_join(padapter, 1); - rtw_set_bssid(padapter, null_addr); - - /* restore to initial setting. */ - update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); - - return; - } - - 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 */ - rtw_reset_dm_func_flag(padapter); - - /* update IOT-releated issue */ - update_IOT_info(padapter); - - rtw_set_basic_rate(padapter, cur_network->SupportedRates); - - /* BCN interval */ - rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval); - - /* update 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_set_max_rpt_macid(padapter, psta->mac_id); - - media_status = (psta->mac_id << 8) | 1; /* MACID|OPMODE: 1 means connect */ - rtl8188e_set_FwMediaStatus_cmd(padapter, media_status); - } - - mlme_join(padapter, 2); - - if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) { - /* correcting TSF */ - correct_TSF(padapter); - } - rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0); -} - -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; - - 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); - - /* 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; - } - mlme_join(padapter, 2); - } - - 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); -} - -static void mlme_disconnect(struct adapter *adapter) -{ - int res; - u8 reg; - - /* 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 */ - - res = rtw_read8(adapter, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(adapter, REG_BCN_CTRL, reg | BIT(4)); -} - -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 (r8188eu_is_client_associated_to_ap(padapter) || r8188eu_is_ibss_empty(padapter)) { - mlme_disconnect(padapter); - rtw_set_bssid(padapter, 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 - -*****************************************************************************/ -static u8 chk_ap_is_alive(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; -} - -static int rtl8188e_sreset_linked_status_check(struct adapter *padapter) -{ - u32 rx_dma_status; - int res; - u8 reg; - - res = rtw_read32(padapter, REG_RXDMA_STATUS, &rx_dma_status); - if (res) - return res; - - if (rx_dma_status != 0x00) - rtw_write32(padapter, REG_RXDMA_STATUS, rx_dma_status); - - return rtw_read8(padapter, REG_FMETHR, ®); -} - -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; - - rtl8188e_sreset_linked_status_check(padapter); - - if (r8188eu_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; - is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE); - - if (!chk_ap_is_alive(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); - - 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) { - 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 (r8188eu_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 (psta == NULL) - 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; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - - /* 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) { - 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; - } else { - pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num; - } - - pmlmeext->scan_abort = false;/* reset */ - } - - ph2c = kzalloc(sizeof(*ph2c), GFP_ATOMIC); - if (!ph2c) - goto exit_survey_timer_hdl; - - psurveyPara = kzalloc(sizeof(*psurveyPara), 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) { - 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; - } - - 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; - } - - 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_set_opmode(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) { - if (pmlmeinfo->state == WIFI_FW_AP_STATE) { - /* todo: */ - return H2C_SUCCESS; - } - } - - /* 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); - rtw_clear_dm_func_flag(padapter); - - /* cancel link timer */ - _cancel_timer_ex(&pmlmeext->link_timer); - - /* clear CAM */ - flush_all_cam_entry(padapter); - - memcpy(pnetwork, pbuf, offsetof(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) -{ - 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_); - - mlme_disconnect(padapter); - } - - 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, offsetof(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; - } - } - } - 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_set_bssid(padapter, pmlmeinfo->network.MacAddress); - mlme_join(padapter, 0); - - /* 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; - int res; - - if (r8188eu_is_client_associated_to_ap(padapter)) - issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100); - - mlme_disconnect(padapter); - rtw_set_bssid(padapter, 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 */ - res = rtw_read8(padapter, REG_BCN_CTRL, &val8); - if (res) - return H2C_DROPPED; - - rtw_write8(padapter, REG_BCN_CTRL, val8 & (~(EN_BCN_FUNCTION | EN_TXBCN_RPT))); - } - - /* 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; - u32 i; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - - if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) { - /* for first time sitesurvey_cmd */ - - 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 (r8188eu_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); - rtw_clear_dm_func_flag(padapter); - - /* config the initial gain under scanning, need to write the BB registers */ - if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) - rtw_set_initial_gain(padapter, 0x1e); - else - rtw_set_initial_gain(padapter, 0x28); - - - /* set MSR to no link state */ - Set_MSR(padapter, _HW_STATE_NOLINK_); - - rtw_mlme_under_site_survey(padapter); - - 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; - - 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; - - 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)); - - if ((psta->mac_id < 1) || (psta->mac_id > (NUM_STA - 4))) - return H2C_REJECTED; - - cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */ - - write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); - - return H2C_SUCCESS_RSP; - } else { - 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, WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid, NULL); - _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(*ph2c), GFP_ATOMIC); - if (!ph2c) { - res = _FAIL; - goto exit; - } - - ptxBeacon_parm = kzalloc(sizeof(*ptxBeacon_parm), 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); - } - -_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) { - return H2C_PARAMETERS_ERROR; - } 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 (rtl8188eu_hal_xmit(padapter, pxmitframe)) - rtw_xmit_complete(padapter, pxmitframe); - spin_lock_bh(&psta_bmc->sleep_q.lock); - } - spin_unlock_bh(&psta_bmc->sleep_q.lock); - } - } - 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; - - 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_p2p.c b/drivers/staging/r8188eu/core/rtw_p2p.c deleted file mode 100644 index 93d3c9c4399c..000000000000 --- a/drivers/staging/r8188eu/core/rtw_p2p.c +++ /dev/null @@ -1,1918 +0,0 @@ -// 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" - -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; - - 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 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; - - 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 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 = 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; - - 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 = 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 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 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; - - 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_hdr_3addr); - pattrib->pktlen = sizeof(struct 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 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) - status_code = P2P_STATUS_FAIL_INVALID_PARAM; - - 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)) { - 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)) { - 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 (be16_to_cpu(*(__be16 *)pattr_content) == WPS_ATTR_DEVICE_NAME) { - 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 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; -} - -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 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); - } - } - 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 { - 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) { - 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)) { - 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) { - 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; - else - /* Take first channel of ch_list_inclusioned as operating channel */ - pwdinfo->operating_channel = ch_list_inclusioned[0]; - } - } - } - - /* 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)) { - 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) { - if (attr_content == P2P_STATUS_SUCCESS) { - /* Do nothing. */ - } else { - if (attr_content == P2P_STATUS_FAIL_INFO_UNAVAILABLE) { - 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)) { - 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)) - 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)) { - - 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) { - 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; - else - /* Take first channel of ch_list_inclusioned as operating channel */ - pwdinfo->operating_channel = ch_list_inclusioned[0]; - } - } - } - - /* 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) { - result = attr_content; - - if (attr_content == P2P_STATUS_SUCCESS) { - del_timer_sync(&pwdinfo->restore_p2p_state_timer); - - /* 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)) { - 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)) - 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 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; - - set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); - rtw_mlme_under_site_survey(padapter); - issue_probereq_p2p(padapter); - _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; - - set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); - rtw_mlme_under_site_survey(padapter); - issue_probereq_p2p(padapter); - _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; - - set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20); - rtw_mlme_under_site_survey(padapter); - issue_probereq_p2p(padapter); - _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 *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; - - p2p_ie = rtw_get_p2p_ie(IEs, IELength, 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, IELength - (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; - - rtl8188e_set_p2p_ps_offload_cmd(padapter, 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_set_firmware_ps_mode(padapter, pwrpriv->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; - rtw_set_firmware_ps_mode(padapter, pwrpriv->pwr_mode); - } - } - rtl8188e_set_p2p_ps_offload_cmd(padapter, 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; - rtl8188e_set_p2p_ps_offload_cmd(padapter, 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; - - /* 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; - - /* 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); */ - /* _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); - } - - 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; -} - -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) -{ - 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); -} - -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)); - 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; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - - if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) { - /* leave IPS/Autosuspend */ - ret = rtw_pwr_wakeup(padapter); - if (ret) - return ret; - - /* 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); - - } else if (role == P2P_ROLE_DISABLE) { - ret = rtw_pwr_wakeup(padapter); - if (ret) - return ret; - - /* 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)); - } - - /* Restore to initial setting. */ - update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode); - } - - return 0; -} diff --git a/drivers/staging/r8188eu/core/rtw_pwrctrl.c b/drivers/staging/r8188eu/core/rtw_pwrctrl.c deleted file mode 100644 index 051cdcb11ff5..000000000000 --- a/drivers/staging/r8188eu/core/rtw_pwrctrl.c +++ /dev/null @@ -1,445 +0,0 @@ -// 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" - -static void ips_enter(struct adapter *padapter) -{ - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - struct xmit_priv *pxmit_priv = &padapter->xmitpriv; - - if (pxmit_priv->free_xmitbuf_cnt != NR_XMITBUFF || - pxmit_priv->free_xmit_extbuf_cnt != NR_XMIT_EXTBUFF) - return; - - mutex_lock(&pwrpriv->lock); - - pwrpriv->bips_processing = true; - - /* syn ips_mode with request */ - pwrpriv->ips_mode = pwrpriv->ips_mode_req; - - pwrpriv->ips_enter_cnts++; - pwrpriv->bpower_saving = true; - - if (pwrpriv->ips_mode == IPS_LEVEL_2) - pwrpriv->bkeepfwalive = true; - - rtw_ips_pwr_down(padapter); - pwrpriv->rf_pwrstate = rf_off; - - pwrpriv->bips_processing = false; - - mutex_unlock(&pwrpriv->lock); -} - -static 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; - - mutex_lock(&pwrpriv->lock); - - if ((pwrpriv->rf_pwrstate == rf_off) && (!pwrpriv->bips_processing)) { - pwrpriv->bips_processing = true; - pwrpriv->ips_leave_cnts++; - - result = rtw_ips_pwr_up(padapter); - if (result == _SUCCESS) { - pwrpriv->rf_pwrstate = rf_on; - } - - if ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_)) { - 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); - } - } - } - - pwrpriv->bips_processing = false; - - pwrpriv->bkeepfwalive = false; - pwrpriv->bpower_saving = false; - } - - mutex_unlock(&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; - struct wifidirect_info *pwdinfo = &adapter->wdinfo; - bool ret = false; - - if (time_after_eq(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) || - !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) - goto exit; - - /* consider buddy, if exist */ - if (buddy) { - struct mlme_priv *b_pmlmepriv = &buddy->mlmepriv; - struct wifidirect_info *b_pwdinfo = &buddy->wdinfo; - - 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) || - !rtw_p2p_chk_state(b_pwdinfo, P2P_STATE_NONE)) - goto exit; - } - ret = true; - -exit: - return ret; -} - -void rtw_ps_processor(struct adapter *padapter) -{ - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - - pwrpriv->ps_processing = true; - - if (pwrpriv->bips_processing) - goto exit; - - if (pwrpriv->ips_mode_req == IPS_NONE) - goto exit; - - if (!rtw_pwr_unassociated_idle(padapter)) - goto exit; - - if (pwrpriv->rf_pwrstate == rf_on) - 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); -} - -static bool 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) - return false; - return true; -} - -void rtw_set_firmware_ps_mode(struct adapter *adapter, u8 mode) -{ - struct hal_data_8188e *haldata = &adapter->haldata; - struct odm_dm_struct *odmpriv = &haldata->odmpriv; - - /* Force leave RF low power mode for 1T1R to prevent - * conflicting setting in firmware power saving sequence. - */ - if (mode != PS_MODE_ACTIVE) - ODM_RF_Saving(odmpriv, true); - rtl8188e_set_FwPwrMode_cmd(adapter, mode); -} - -void rtw_set_ps_mode(struct adapter *padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode) -{ - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - struct wifidirect_info *pwdinfo = &padapter->wdinfo; - - if (ps_mode > PM_Card_Disable) - return; - - if (pwrpriv->pwr_mode == ps_mode) { - if (ps_mode == PS_MODE_ACTIVE) - return; - - if ((pwrpriv->smart_ps == smart_ps) && - (pwrpriv->bcn_ant_mode == bcn_ant_mode)) - return; - } - - if (ps_mode == PS_MODE_ACTIVE) { - if (pwdinfo->opp_ps == 0) { - pwrpriv->pwr_mode = ps_mode; - rtw_set_firmware_ps_mode(padapter, ps_mode); - pwrpriv->bFwCurrentInPSMode = false; - } - } else { - if (PS_RDY_CHECK(padapter)) { - pwrpriv->bFwCurrentInPSMode = true; - pwrpriv->pwr_mode = ps_mode; - pwrpriv->smart_ps = smart_ps; - pwrpriv->bcn_ant_mode = bcn_ant_mode; - rtw_set_firmware_ps_mode(padapter, ps_mode); - - /* Set CTWindow after LPS */ - if (pwdinfo->opp_ps == 1) - p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 0); - } - } -} - -static bool lps_rf_on(struct adapter *adapter) -{ - int res; - u32 reg; - - /* 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. */ - return true; - } - - res = rtw_read32(adapter, REG_RCR, ®); - if (res) - return false; - - if (reg & 0x00070000) - return false; - - return true; -} - -/* - * Return: - * 0: Leave OK - * -1: Timeout - * -2: Other error - */ -static s32 LPS_RF_ON_check(struct adapter *padapter, u32 delay_ms) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(delay_ms); - s32 err = 0; - - while (1) { - if (lps_rf_on(padapter)) - break; - - if (padapter->bSurpriseRemoved) { - err = -2; - break; - } - - if (time_after(jiffies, timeout)) { - err = -1; - break; - } - mdelay(1); - } - - 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; - /* 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; - - mutex_init(&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->bInSuspend = false; - pwrctrlpriv->bkeepfwalive = false; - - pwrctrlpriv->LpsIdleCount = 0; - pwrctrlpriv->power_mgnt = padapter->registrypriv.power_mgnt;/* PS_MODE_MIN; */ - pwrctrlpriv->bLeisurePs = pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE; - - pwrctrlpriv->bFwCurrentInPSMode = false; - - pwrctrlpriv->pwr_mode = PS_MODE_ACTIVE; - pwrctrlpriv->smart_ps = padapter->registrypriv.smart_ps; - pwrctrlpriv->bcn_ant_mode = 0; - - timer_setup(&pwrctrlpriv->pwr_state_check_timer, pwr_state_check_handler, 0); -} - -/* Wake the NIC up from: 1)IPS 2)USB autosuspend */ -int rtw_pwr_wakeup(struct adapter *padapter) -{ - struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - unsigned long timeout = jiffies + msecs_to_jiffies(3000); - unsigned long deny_time; - int ret; - - while (pwrpriv->ps_processing && time_before(jiffies, timeout)) - msleep(10); - - /* I think this should be check in IPS, LPS, autosuspend functions... */ - /* Below goto is a success path taken for already linked devices */ - ret = 0; - if (check_fwstate(pmlmepriv, _FW_LINKED)) - goto exit; - - if (pwrpriv->rf_pwrstate == rf_off && ips_leave(padapter) == _FAIL) { - ret = -ENOMEM; - goto exit; - } - - if (padapter->bDriverStopped || !padapter->bup || !padapter->hw_init_completed) { - ret = -EBUSY; - goto exit; - } - -exit: - deny_time = jiffies + msecs_to_jiffies(RTW_PWR_STATE_CHK_INTERVAL); - if (time_before(pwrpriv->ips_deny_time, deny_time)) - pwrpriv->ips_deny_time = deny_time; - 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 (mode == PS_MODE_ACTIVE) - LeaveAllPowerSaveMode(padapter); - else - pwrctrlpriv->LpsIdleCount = 2; - pwrctrlpriv->power_mgnt = mode; - pwrctrlpriv->bLeisurePs = pwrctrlpriv->power_mgnt != PS_MODE_ACTIVE; - } - } 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); - return 0; - } else if (mode == IPS_NONE) { - rtw_ips_mode_req(pwrctrlpriv, mode); - if ((padapter->bSurpriseRemoved == 0) && 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 deleted file mode 100644 index fc7568cf948b..000000000000 --- a/drivers/staging/r8188eu/core/rtw_recv.c +++ /dev/null @@ -1,2010 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2012 Realtek Corporation. */ - -#define _RTW_RECV_C_ - -#include <linux/ieee80211.h> -#include "../include/osdep_service.h" -#include "../include/drv_types.h" -#include "../include/usb_ops.h" -#include "../include/wifi.h" -#include "../include/rtl8188e_recv.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 -}; - -static void rtw_signal_stat_timer_hdl(struct timer_list *t); - -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); - -} - -static int rtl8188eu_init_recv_priv(struct adapter *padapter) -{ - struct recv_priv *precvpriv = &padapter->recvpriv; - int i, err = 0; - 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) - return -ENOMEM; - - precvpriv->precv_buf = (u8 *)ALIGN((size_t)(precvpriv->pallocated_recv_buf), 4); - - precvbuf = (struct recv_buf *)precvpriv->precv_buf; - - for (i = 0; i < NR_RECVBUFF; i++) { - precvbuf->pskb = NULL; - precvbuf->reuse = false; - precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL); - if (!precvbuf->purb) { - err = -ENOMEM; - break; - } - 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; - } - } - - return err; -} - -int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter) -{ - int i; - struct recv_frame *precvframe; - int err; - - 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; - - precvpriv->pallocated_frame_buf = vzalloc(NR_RECVFRAME * sizeof(struct recv_frame) + RXFRAME_ALIGN_SZ); - if (!precvpriv->pallocated_frame_buf) - return -ENOMEM; - - precvpriv->precv_frame_buf = (u8 *)ALIGN((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); - - precvframe->pkt = NULL; - - precvframe->len = 0; - - precvframe->adapter = padapter; - precvframe++; - } - precvpriv->rx_pending_cnt = 1; - - err = rtl8188eu_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); - - return err; -} - -static 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++) { - usb_free_urb(precvbuf->purb); - precvbuf++; - } - - kfree(precvpriv->pallocated_recv_buf); - - skb_queue_purge(&precvpriv->rx_skb_queue); - - skb_queue_purge(&precvpriv->free_recv_skb_queue); -} - -void _rtw_free_recv_priv(struct recv_priv *precvpriv) -{ - struct adapter *padapter = precvpriv->adapter; - - rtw_free_uc_swdec_pending_queue(padapter); - - vfree(precvpriv->pallocated_frame_buf); - - rtl8188eu_free_recv_priv(padapter); - _cancel_timer_ex(&precvpriv->signal_stat_timer); -} - -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; -} - -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 && (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); - cnt++; - } - - return cnt; -} - -static 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); -} - -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; - 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)); - - 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) { - 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, precv_frame); - break; - case _TKIP_: - res = rtw_tkip_decrypt(padapter, precv_frame); - break; - case _AES_: - res = rtw_aes_decrypt(padapter, 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; -} - -static void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame) -{ - 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); - } - } -} - -static void process_wmmps_data(struct adapter *padapter, struct recv_frame *precv_frame) -{ - 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); - } - } - } -} - -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; - } -} - -static int sta2sta_data_frame(struct adapter *adapter, - struct recv_frame *precv_frame, struct sta_info **psta) -{ - 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)) { - 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) - 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 ieee80211_hdr *hdr = (struct ieee80211_hdr *)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 (is_zero_ether_addr(pattrib->bssid) || is_zero_ether_addr(mybssid) || - (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { - if (!bmcast) - 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 (ieee80211_is_nullfunc(hdr->frame_control)) { - /* We count the nullfunc frame, but we'll not pass it on to higher layers. */ - 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->src, GetAddr2Ptr(ptr), 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) - 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; - __le16 fc = *(__le16 *)ptr; - 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) { - 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 (ieee80211_is_data_qos(fc)) - 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; - } - issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); - ret = RTW_RX_HANDLED; - goto exit; - } - -exit: - - return ret; -} - -static void validate_recv_ctrl_frame(struct adapter *padapter, - struct recv_frame *precv_frame) -{ - struct rx_pkt_attrib *pattrib = &precv_frame->attrib; - struct sta_priv *pstapriv = &padapter->stapriv; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; - struct ieee80211_pspoll *pspoll = (struct ieee80211_pspoll *)hdr; - u8 wmmps_ac; - struct sta_info *psta; - - /* receive the frames that ra(a1) is my address */ - if (memcmp(hdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN)) - return; - - /* only handle ps-poll */ - if (!ieee80211_is_pspoll(hdr->frame_control)) - return; - - psta = rtw_get_stainfo(pstapriv, hdr->addr2); - if (!psta || psta->aid != (le16_to_cpu(pspoll->aid) & 0x3FFF)) - return; - - /* 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; - - if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { - 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; - - if (psta->sleepq_len == 0) { - pstapriv->tim_bitmap &= ~BIT(psta->aid); - - /* update 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) - /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */ - issue_nulldata(padapter, psta->hwaddr, 0, 0, 0); - else - psta->sleepq_len = 0; - - pstapriv->tim_bitmap &= ~BIT(psta->aid); - - /* update BCN for TIM IE */ - /* update_BCNTIM(padapter); */ - update_beacon(padapter, _TIM_IE_, NULL, false); - } - } - spin_unlock_bh(&pxmitpriv->lock); - } -} - -struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame); - -static void validate_recv_mgnt_frame(struct adapter *padapter, - struct recv_frame *precv_frame) -{ - struct sta_info *psta; - struct ieee80211_hdr *hdr; - - precv_frame = recvframe_chk_defrag(padapter, precv_frame); - if (!precv_frame) - return; - - hdr = (struct ieee80211_hdr *)precv_frame->rx_data; - psta = rtw_get_stainfo(&padapter->stapriv, hdr->addr2); - if (psta) { - psta->sta_stats.rx_mgnt_pkts++; - if (ieee80211_is_beacon(hdr->frame_control)) - psta->sta_stats.rx_beacon_pkts++; - else if (ieee80211_is_probe_req(hdr->frame_control)) - psta->sta_stats.rx_probereq_pkts++; - else if (ieee80211_is_probe_resp(hdr->frame_control)) { - if (!memcmp(padapter->eeprompriv.mac_addr, hdr->addr1, ETH_ALEN)) - psta->sta_stats.rx_probersp_pkts++; - else if (is_broadcast_mac_addr(hdr->addr1) || is_multicast_mac_addr(hdr->addr1)) - psta->sta_stats.rx_probersp_bm_pkts++; - else - psta->sta_stats.rx_probersp_uo_pkts++; - } - } - - mgt_dispatcher(padapter, precv_frame); -} - -static int validate_recv_data_frame(struct adapter *adapter, - struct recv_frame *precv_frame) -{ - struct sta_info *psta = NULL; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; - struct rx_pkt_attrib *pattrib = &precv_frame->attrib; - struct security_priv *psecuritypriv = &adapter->securitypriv; - int ret; - - memcpy(pattrib->dst, ieee80211_get_DA(hdr), ETH_ALEN); - memcpy(pattrib->src, ieee80211_get_SA(hdr), ETH_ALEN); - - /* address4 is used only if both to_ds and from_ds are set */ - if (ieee80211_has_a4(hdr->frame_control)) - return _FAIL; - - memcpy(pattrib->ra, hdr->addr1, ETH_ALEN); - memcpy(pattrib->ta, hdr->addr2, ETH_ALEN); - - if (ieee80211_has_fromds(hdr->frame_control)) { - memcpy(pattrib->bssid, hdr->addr2, ETH_ALEN); - ret = ap2sta_data_frame(adapter, precv_frame, &psta); - } else if (ieee80211_has_tods(hdr->frame_control)) { - memcpy(pattrib->bssid, hdr->addr1, ETH_ALEN); - ret = sta2ap_data_frame(adapter, precv_frame, &psta); - } else { - memcpy(pattrib->bssid, hdr->addr3, ETH_ALEN); - ret = sta2sta_data_frame(adapter, precv_frame, &psta); - } - - if (ret == _FAIL || ret == RTW_RX_HANDLED) - return ret; - - if (!psta) - return _FAIL; - - precv_frame->psta = psta; - - pattrib->amsdu = 0; - pattrib->ack_policy = 0; - /* parsing QC field */ - if (pattrib->qos) { - struct ieee80211_qos_hdr *qos_hdr = (struct ieee80211_qos_hdr *)hdr; - - pattrib->priority = ieee80211_get_tid(hdr); - pattrib->ack_policy = GetAckpolicy(&qos_hdr->qos_ctrl); - pattrib->amsdu = GetAMsdu(&qos_hdr->qos_ctrl); - pattrib->hdrlen = sizeof(*qos_hdr); - - if (pattrib->priority != 0 && pattrib->priority != 3) - adapter->recvpriv.bIsAnyNonBEPkts = true; - } else { - pattrib->priority = 0; - pattrib->hdrlen = 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, ieee80211_has_retry(hdr->frame_control), - &psta->sta_recvpriv.rxcache) == _FAIL) - return _FAIL; - - 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; - } - - return _SUCCESS; -} - -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. */ - - int retval = _FAIL; - struct rx_pkt_attrib *pattrib = &precv_frame->attrib; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)precv_frame->rx_data; - 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++; - } - - if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_VERS)) != 0) - return _FAIL; - - pattrib->frag_num = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; - pattrib->seq_num = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); - - pattrib->pw_save = ieee80211_has_pm(hdr->frame_control); - pattrib->mfrag = ieee80211_has_morefrags(hdr->frame_control); - pattrib->mdata = ieee80211_has_moredata(hdr->frame_control); - pattrib->privacy = ieee80211_has_protected(hdr->frame_control); - pattrib->order = ieee80211_has_order(hdr->frame_control); - - /* We return _SUCCESS only for data frames. */ - if (ieee80211_is_mgmt(hdr->frame_control)) - validate_recv_mgnt_frame(adapter, precv_frame); - else if (ieee80211_is_ctl(hdr->frame_control)) - validate_recv_ctrl_frame(adapter, precv_frame); - else if (ieee80211_is_data(hdr->frame_control)) { - rtw_led_control(adapter, LED_CTL_RX); - pattrib->qos = ieee80211_is_data_qos(hdr->frame_control); - retval = validate_recv_data_frame(adapter, precv_frame); - if (retval == _FAIL) { - struct recv_priv *precvpriv = &adapter->recvpriv; - - precvpriv->rx_drop++; - } - } - - 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 = precvframe->rx_data; /* 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); - if (!ptr) - return _FAIL; - memcpy(ptr, get_rxmem(precvframe), 24); - ptr += 24; - } else { - ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); - if (!ptr) - return _FAIL; - } - - 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) { - __le16 fc = *(__le16 *)pfhdr->rx_data; - - if (ieee80211_is_data(fc)) { - 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; - struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT]; - - struct recv_priv *precvpriv = &padapter->recvpriv; - struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue; - - 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) - 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); - skb_put_data(sub_skb, 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 { - break; - } - } - - subframes[nr_subframes++] = sub_skb; - - if (nr_subframes >= MAX_SUBFRAME_COUNT) - 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 _SUCCESS; -} - -static bool 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; -} - -static bool 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 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; -} - -static bool 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) { - 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 __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; - - /* 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 */ - - 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; - - while ((pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) - 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); - 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: - - return ret; -} - -static 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 acquired, 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 acquired, 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 deleted file mode 100644 index 2d2f0fc4c942..000000000000 --- a/drivers/staging/r8188eu/core/rtw_rf.c +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#include "../include/drv_types.h" - -static const u32 ch_freq_map[] = { - 2412, - 2417, - 2422, - 2427, - 2432, - 2437, - 2442, - 2447, - 2452, - 2457, - 2462, - 2467, - 2472, - 2484 -}; - -u32 rtw_ch2freq(u32 channel) -{ - if (channel == 0 || channel > ARRAY_SIZE(ch_freq_map)) - return 2412; - - return ch_freq_map[channel - 1]; -} diff --git a/drivers/staging/r8188eu/core/rtw_security.c b/drivers/staging/r8188eu/core/rtw_security.c deleted file mode 100644 index 780019ce1b98..000000000000 --- a/drivers/staging/r8188eu/core/rtw_security.c +++ /dev/null @@ -1,1374 +0,0 @@ -// 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 ===== */ - -/* - Need to consider the fragment situation -*/ -void rtw_wep_encrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) -{ /* exclude ICV */ - union { - __le32 f0; - u8 f1[4]; - } crc; - - int curfragnum, length; - u32 keylength; - - u8 *pframe, *payload, *iv; /* wepkey */ - u8 wepkey[16]; - u8 hw_hdr_offset = 0; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct arc4_ctx *ctx = &psecuritypriv->xmit_arc4_ctx; - - if (!pxmitframe->buf_addr) - return; - - hw_hdr_offset = TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ; - pframe = 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)); - - arc4_setkey(ctx, wepkey, 3 + keylength); - arc4_crypt(ctx, payload, payload, length); - arc4_crypt(ctx, 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)); - arc4_setkey(ctx, wepkey, 3 + keylength); - arc4_crypt(ctx, payload, payload, length); - arc4_crypt(ctx, payload + length, crc.f1, 4); - - pframe += pxmitpriv->frag_len; - pframe = PTR_ALIGN(pframe, 4); - } - } - } - -} - -void rtw_wep_decrypt(struct adapter *padapter, struct recv_frame *precvframe) -{ - /* exclude ICV */ - int length; - u32 keylength; - u8 *pframe, *payload, *iv, wepkey[16]; - u8 keyindex; - struct rx_pkt_attrib *prxattrib = &precvframe->attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct arc4_ctx *ctx = &psecuritypriv->recv_arc4_ctx; - - pframe = 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 = precvframe->len - prxattrib->hdrlen - prxattrib->iv_len; - - payload = pframe + prxattrib->iv_len + prxattrib->hdrlen; - - /* decrypt payload include icv */ - arc4_setkey(ctx, wepkey, 3 + keylength); - arc4_crypt(ctx, 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, struct xmit_frame *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; - int curfragnum, length; - - u8 *pframe, *payload, *iv, *prwskey; - union pn48 dot11txpn; - struct sta_info *stainfo; - struct pkt_attrib *pattrib = &pxmitframe->attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - struct arc4_ctx *ctx = &psecuritypriv->xmit_arc4_ctx; - u32 res = _SUCCESS; - - if (!pxmitframe->buf_addr) - return _FAIL; - - hw_hdr_offset = TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ; - pframe = 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)); - - arc4_setkey(ctx, rc4key, 16); - arc4_crypt(ctx, payload, payload, length); - arc4_crypt(ctx, 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)); - - arc4_setkey(ctx, rc4key, 16); - arc4_crypt(ctx, payload, payload, length); - arc4_crypt(ctx, payload + length, crc.f1, 4); - - pframe += pxmitpriv->frag_len; - pframe = PTR_ALIGN(pframe, 4); - } - } - } else { - res = _FAIL; - } - } - - return res; -} - -/* The hlen isn't include the IV */ -u32 rtw_tkip_decrypt(struct adapter *padapter, struct recv_frame *precvframe) -{ /* exclude ICV */ - u16 pnl; - u32 pnh; - u8 rc4key[16]; - u8 ttkey[16]; - union { - __le32 f0; - u8 f1[4]; - } crc; - int length; - - u8 *pframe, *payload, *iv, *prwskey; - union pn48 dot11txpn; - struct sta_info *stainfo; - struct rx_pkt_attrib *prxattrib = &precvframe->attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct arc4_ctx *ctx = &psecuritypriv->recv_arc4_ctx; - u32 res = _SUCCESS; - - pframe = 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; - 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 = 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 */ - - arc4_setkey(ctx, rc4key, 16); - arc4_crypt(ctx, 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 void 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]; -} - -u32 rtw_aes_encrypt(struct adapter *padapter, struct xmit_frame *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 = &pxmitframe->attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - -/* uint offset = 0; */ - u32 res = _SUCCESS; - - if (!pxmitframe->buf_addr) - return _FAIL; - - hw_hdr_offset = TXDESC_SIZE + pxmitframe->pkt_offset * PACKET_OFFSET_SZ; - pframe = 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 = PTR_ALIGN(pframe, 4); - } - } - } 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]) - res = _FAIL; - } - - return res; -} - -u32 rtw_aes_decrypt(struct adapter *padapter, struct recv_frame *precvframe) -{ /* exclude ICV */ - /* Intermediate Buffers */ - int length; - u8 *pframe, *prwskey; /* *payload,*iv */ - struct sta_info *stainfo; - struct rx_pkt_attrib *prxattrib = &precvframe->attrib; - struct security_priv *psecuritypriv = &padapter->securitypriv; - u32 res = _SUCCESS; - - pframe = 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; - goto exit; - } - prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey; - if (psecuritypriv->dot118021XGrpKeyid != prxattrib->key_index) { - res = _FAIL; - goto exit; - } - } else { - prwskey = &stainfo->dot118021x_UncstKey.skey[0]; - } - length = precvframe->len - prxattrib->hdrlen - prxattrib->iv_len; - res = aes_decipher(prwskey, prxattrib->hdrlen, pframe, length); - } else { - res = _FAIL; - } - } - -exit: - return res; -} diff --git a/drivers/staging/r8188eu/core/rtw_sta_mgt.c b/drivers/staging/r8188eu/core/rtw_sta_mgt.c deleted file mode 100644 index e1ae1859686e..000000000000 --- a/drivers/staging/r8188eu/core/rtw_sta_mgt.c +++ /dev/null @@ -1,490 +0,0 @@ -// 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/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); - - 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; - - 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; - - psta->under_exist_checking = 0; - - psta->keep_alive_trycnt = 0; -} - -int _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 -ENOMEM; - - 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++; - } - - 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; - - return 0; -} - -inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta) -{ - return (((u8 *)sta) - stapriv->pstainfo_buf) / sizeof(struct sta_info); -} - -inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset) -{ - return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info)); -} - -void _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); - /*===============================*/ - - vfree(pstapriv->pallocated_stainfo_buf); - } -} - -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); -} - -static void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl) -{ - timer_setup(&preorder_ctrl->reordering_ctrl_timer, _rtw_reordering_ctrl_timeout_handler, 0); -} - -static void _addba_timer_hdl(struct timer_list *t) -{ - struct sta_info *psta = from_timer(psta, t, addba_retry_timer); - - addba_timer_hdl(psta); -} - -static void init_addba_retry_timer(struct adapter *padapter, struct sta_info *psta) -{ - timer_setup(&psta->addba_retry_timer, _addba_timer_hdl, 0); -} - -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 */ -void 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) - return; - - pfree_sta_queue = &pstapriv->free_sta_queue; - - pstaxmitpriv = &psta->sta_xmitpriv; - - spin_lock_bh(&pxmitpriv->lock); - - rtw_free_xmitframe_list(pxmitpriv, get_list_head(&psta->sleep_q)); - psta->sleepq_len = 0; - - rtw_free_xmitframe_list(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending); - - list_del_init(&pstaxmitpriv->vo_q.tx_pending); - - rtw_free_xmitframe_list(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending); - - list_del_init(&pstaxmitpriv->vi_q.tx_pending); - - rtw_free_xmitframe_list(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending); - - list_del_init(&pstaxmitpriv->bk_q.tx_pending); - - rtw_free_xmitframe_list(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)) - rtl8188e_SetHalODMVar(padapter, psta, false); - - 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; - - 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); -} - -/* 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 sta_info *ploop, *psta = NULL; - u32 index; - u8 *addr; - u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - if (!hwaddr) - return NULL; - - if (is_multicast_ether_addr(hwaddr)) - addr = bc_addr; - else - addr = hwaddr; - - index = wifi_mac_hash(addr); - - spin_lock_bh(&pstapriv->sta_hash_lock); - - list_for_each_entry(ploop, &pstapriv->sta_hash[index], hash_list) { - if (!memcmp(ploop->hwaddr, addr, ETH_ALEN)) { - psta = ploop; - break; - } - } - - 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; - 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; - else if (pacl_list->mode == 2)/* deny unless in accept list */ - res = match; - else - res = true; - - return res; -} diff --git a/drivers/staging/r8188eu/core/rtw_wlan_util.c b/drivers/staging/r8188eu/core/rtw_wlan_util.c deleted file mode 100644 index f1ebb5358cb9..000000000000 --- a/drivers/staging/r8188eu/core/rtw_wlan_util.c +++ /dev/null @@ -1,1551 +0,0 @@ -// 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 -}; - -bool 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; -} - -bool 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 bool 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 Save_DM_Func_Flag(struct adapter *padapter) -{ - struct hal_data_8188e *haldata = &padapter->haldata; - struct odm_dm_struct *odmpriv = &haldata->odmpriv; - - odmpriv->BK_SupportAbility = odmpriv->SupportAbility; -} - -void Restore_DM_Func_Flag(struct adapter *padapter) -{ - struct hal_data_8188e *haldata = &padapter->haldata; - struct odm_dm_struct *odmpriv = &haldata->odmpriv; - - odmpriv->SupportAbility = odmpriv->BK_SupportAbility; -} - -void Set_MSR(struct adapter *padapter, u8 type) -{ - u8 val8; - int res; - - res = rtw_read8(padapter, MSR, &val8); - if (res) - return; - - val8 &= 0x0c; - val8 |= type; - rtw_write8(padapter, MSR, val8); -} - -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 void rtw_set_oper_bw(struct adapter *adapter, u8 bw) -{ - adapter->mlmeextpriv.oper_bwmode = bw; -} - -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); - PHY_SwChnl8188E(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); - - PHY_SetBWMode8188E(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 ((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); - - PHY_SwChnl8188E(padapter, center_ch); /* set center channel */ - SetBWMode(padapter, bwmode, channel_offset); -} - -__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); -} - -bool r8188eu_is_client_associated_to_ap(struct adapter *padapter) -{ - struct mlme_ext_priv *pmlmeext; - struct mlme_ext_info *pmlmeinfo; - - if (!padapter) - return false; - - pmlmeext = &padapter->mlmeextpriv; - pmlmeinfo = &pmlmeext->mlmext_info; - - if ((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)) - return true; - - return false; -} - -bool r8188eu_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; - - return false; -} - -bool r8188eu_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 false; - } - 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 invalidate_cam_all(struct adapter *padapter) -{ - rtw_write32(padapter, RWCAM, BIT(31) | BIT(30)); -} - -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_write32(padapter, WCAMI, cam_val[0]); - rtw_write32(padapter, RWCAM, CAM_POLLINIG | CAM_WRITE | cam_val[1]); - } -} - -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_write32(padapter, RWCAM, BIT(31) | BIT(30)); - - 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; -} - -static void set_acm_ctrl(struct adapter *adapter, u8 acm_mask) -{ - u8 acmctrl; - int res = rtw_read8(adapter, REG_ACMHWCTRL, &acmctrl); - - if (res) - return; - - if (acm_mask > 1) - acmctrl = acmctrl | 0x1; - - if (acm_mask & BIT(3)) - acmctrl |= ACMHW_VOQEN; - else - acmctrl &= (~ACMHW_VOQEN); - - if (acm_mask & BIT(2)) - acmctrl |= ACMHW_VIQEN; - else - acmctrl &= (~ACMHW_VIQEN); - - if (acm_mask & BIT(1)) - acmctrl |= ACMHW_BEQEN; - else - acmctrl &= (~ACMHW_BEQEN); - - rtw_write8(adapter, REG_ACMHWCTRL, acmctrl); -} - -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; - struct hal_data_8188e *haldata = &padapter->haldata; - - 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: - haldata->AcParam_BE = acParm; - rtw_write32(padapter, REG_EDCA_BE_PARAM, acParm); - acm_mask |= (ACM ? BIT(1) : 0); - edca[XMIT_BE_QUEUE] = acParm; - break; - case 0x1: - rtw_write32(padapter, REG_EDCA_BK_PARAM, acParm); - edca[XMIT_BK_QUEUE] = acParm; - break; - case 0x2: - rtw_write32(padapter, REG_EDCA_VI_PARAM, acParm); - acm_mask |= (ACM ? BIT(2) : 0); - edca[XMIT_VI_QUEUE] = acParm; - break; - case 0x3: - rtw_write32(padapter, REG_EDCA_VO_PARAM, acParm); - acm_mask |= (ACM ? BIT(3) : 0); - edca[XMIT_VO_QUEUE] = acParm; - break; - } - } - - if (padapter->registrypriv.acm_method == 1) - set_acm_ctrl(padapter, 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, 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) { - swap(edca[i], edca[j]); - swap(inx[i], inx[j]); - - change_inx = false; - } - } - } - } - - for (i = 0; i < 4; i++) - pxmitpriv->wmm_para_seq[i] = inx[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 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 */ - max_AMPDU_len = min(pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3, - pIE->data[i] & 0x3); - - min_MPDU_spacing = max(pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c, - pIE->data[i] & 0x1c); - - pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para = max_AMPDU_len | min_MPDU_spacing; - } - } - - /* update the MCS rates */ - for (i = 0; i < 16; i++) - pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[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); -} - -static void set_min_ampdu_spacing(struct adapter *adapter, u8 spacing) -{ - u8 sec_spacing; - int res; - - if (spacing <= 7) { - switch (adapter->securitypriv.dot11PrivacyAlgrthm) { - case _NO_PRIVACY_: - case _AES_: - sec_spacing = 0; - break; - case _WEP40_: - case _WEP104_: - case _TKIP_: - case _TKIP_WTMIC_: - sec_spacing = 6; - break; - default: - sec_spacing = 7; - break; - } - - if (spacing < sec_spacing) - spacing = sec_spacing; - - res = rtw_read8(adapter, REG_AMPDU_MIN_SPACE, &sec_spacing); - if (res) - return; - - rtw_write8(adapter, REG_AMPDU_MIN_SPACE, - (sec_spacing & 0xf8) | spacing); - } -} - -static void set_ampdu_factor(struct adapter *adapter, u8 factor) -{ - u8 RegToSet_Normal[4] = {0x41, 0xa8, 0x72, 0xb9}; - u8 FactorToSet; - u8 *pRegToSet; - u8 index = 0; - - pRegToSet = RegToSet_Normal; /* 0xb972a841; */ - FactorToSet = factor; - 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]); - } - } -} - -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; - - 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; - - set_min_ampdu_spacing(padapter, min_MPDU_spacing); - - set_ampdu_factor(padapter, 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) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)pframe; - unsigned int len; - unsigned char *p; - unsigned short val16; - 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 (!r8188eu_is_client_associated_to_ap(Adapter)) - return true; - - len = packet_len - sizeof(struct ieee80211_hdr_3addr); - - if (len > MAX_IE_SZ) - return _FAIL; - - if (memcmp(cur_network->network.MacAddress, pbssid, 6)) - return true; - - bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC); - if (!bssid) - return _FAIL; - - if (ieee80211_is_beacon(mgmt->frame_control)) - 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 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))) { - /* 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 */ - bcn_channel = Adapter->mlmeextpriv.cur_channel; - } - if (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) - hidden_ssid = true; - else - hidden_ssid = false; - - if (p && (!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) { - /* not hidden ssid */ - if (bssid->Ssid.Ssid[0] != '\0' && bssid->Ssid.SsidLength != 0) - 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) - 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) - 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) - goto _mismatch; - - if (is_8021x != cur_network->BcnInfo.is_8021x) - goto _mismatch; - } - - kfree(bssid); - - return _SUCCESS; - -_mismatch: - kfree(bssid); - - return _FAIL; -} - -void update_beacon_info(struct adapter *padapter, u8 *ie_ptr, uint ie_len, struct sta_info *psta) -{ - unsigned int i; - struct ndis_802_11_var_ie *pIE; - - for (i = 0; i < ie_len;) { - pIE = (struct ndis_802_11_var_ie *)(ie_ptr + 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); - } -} - -bool 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; - } -} - -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); -} - -void rtw_set_basic_rate(struct adapter *adapter, u8 *rates) -{ - u16 BrateCfg = 0; - u8 RateIndex = 0; - int res; - u8 reg; - - /* 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, rates, &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; - - 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); - res = rtw_read8(adapter, REG_RRSR + 2, ®); - if (res) - return; - - rtw_write8(adapter, REG_RRSR + 2, reg & 0xf0); - - /* Set RTS initial rate */ - while (BrateCfg > 0x1) { - BrateCfg = (BrateCfg >> 1); - RateIndex++; - } - /* Ziv - Check */ - rtw_write8(adapter, REG_INIRTS_RATE_SEL, RateIndex); -} - -/* 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]; - 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; - 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_set_basic_rate(padapter, 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))) { - return HT_IOT_PEER_ATHEROS; - } else if ((!memcmp(pIE->data, BROADCOM_OUI1, 3)) || - (!memcmp(pIE->data, BROADCOM_OUI2, 3))) { - return HT_IOT_PEER_BROADCOM; - } else if (!memcmp(pIE->data, MARVELL_OUI, 3)) { - return HT_IOT_PEER_MARVELL; - } else if (!memcmp(pIE->data, RALINK_OUI, 3)) { - if (!ralink_vendor_flag) { - ralink_vendor_flag = 1; - } else { - return HT_IOT_PEER_RALINK; - } - } else if (!memcmp(pIE->data, CISCO_OUI, 3)) { - return HT_IOT_PEER_CISCO; - } else if (!memcmp(pIE->data, REALTEK_OUI, 3)) { - return HT_IOT_PEER_REALTEK; - } else if (!memcmp(pIE->data, AIRGOCAP_OUI, 3)) { - return HT_IOT_PEER_AIRGO; - } else if (!memcmp(pIE->data, EPIGRAM_OUI, 3)) { - epigram_vendor_flag = 1; - if (ralink_vendor_flag) - return HT_IOT_PEER_TENDA; - } else { - break; - } - break; - - default: - break; - } - i += (pIE->Length + 2); - } - - if (ralink_vendor_flag && !epigram_vendor_flag) - return HT_IOT_PEER_RALINK; - else if (ralink_vendor_flag && epigram_vendor_flag) - return HT_IOT_PEER_TENDA; - else - 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; - break; - case HT_IOT_PEER_REALTEK: - /* rtw_write16(padapter, 0x4cc, 0xffff); */ - /* rtw_write16(padapter, 0x546, 0x01c0); */ - break; - default: - pmlmeinfo->turboMode_cts2self = 0; - pmlmeinfo->turboMode_rtsen = 1; - break; - } -} - -static void set_ack_preamble(struct adapter *adapter, bool short_preamble) -{ - struct hal_data_8188e *haldata = &adapter->haldata; - u8 val8; - - /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */ - val8 = haldata->nCur40MhzPrimeSC << 5; - if (short_preamble) - val8 |= 0x80; - - rtw_write8(adapter, REG_RRSR + 2, val8); -}; - -static void set_slot_time(struct adapter *adapter, u8 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, slot_time); - - if (pmlmeinfo->WMM_enable == 0) { - if (pmlmeext->cur_wireless_mode == WIRELESS_11B) - aSifsTime = 10; - else - aSifsTime = 16; - - u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime); - - /* <Roger_EXP> 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); - } -} - -void update_capinfo(struct adapter *Adapter, u16 updateCap) -{ - struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - - /* 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 */ - pmlmeinfo->preamble_mode = PREAMBLE_SHORT; - set_ack_preamble(Adapter, true); - } - } else { /* Long Preamble */ - if (pmlmeinfo->preamble_mode != PREAMBLE_LONG) { /* PREAMBLE_SHORT or PREAMBLE_AUTO */ - pmlmeinfo->preamble_mode = PREAMBLE_LONG; - set_ack_preamble(Adapter, false); - } - } - - 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; - } - } - - set_slot_time(Adapter, pmlmeinfo->slotTime); -} - -void update_wireless_mode(struct adapter *padapter) -{ - int ratelen, network_type = 0; - 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; - - /* RESP_SIFS for CCK */ - rtw_write8(padapter, REG_R2T_SIFS, 0x08); - rtw_write8(padapter, REG_R2T_SIFS + 1, 0x08); - /* RESP_SIFS for OFDM */ - rtw_write8(padapter, REG_T2T_SIFS, 0x0a); - rtw_write8(padapter, REG_T2T_SIFS + 1, 0x0a); - - 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 beacon_timing_control(struct adapter *padapter) -{ - SetBeaconRelatedRegisters8188EUsb(padapter); -} - -static struct adapter *pbuddy_padapter; - -void rtw_handle_dualmac(struct adapter *adapter, bool init) -{ - if (init) { - if (!pbuddy_padapter) { - pbuddy_padapter = adapter; - } else { - adapter->pbuddy_adapter = pbuddy_padapter; - pbuddy_padapter->pbuddy_adapter = adapter; - /* clear global value */ - pbuddy_padapter = NULL; - } - } else { - pbuddy_padapter = NULL; - } -} diff --git a/drivers/staging/r8188eu/core/rtw_xmit.c b/drivers/staging/r8188eu/core/rtw_xmit.c deleted file mode 100644 index df88b3e29e77..000000000000 --- a/drivers/staging/r8188eu/core/rtw_xmit.c +++ /dev/null @@ -1,2179 +0,0 @@ -// 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" -#include "../include/rtl8188e_xmit.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); - INIT_LIST_HEAD(&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); -} - -static int rtw_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitbuf, - u32 alloc_sz) -{ - pxmitbuf->pallocated_buf = kzalloc(alloc_sz, GFP_KERNEL); - if (!pxmitbuf->pallocated_buf) - return -ENOMEM; - - pxmitbuf->pbuf = (u8 *)ALIGN((size_t)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ); - - pxmitbuf->pxmit_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!pxmitbuf->pxmit_urb) { - kfree(pxmitbuf->pallocated_buf); - return -ENOMEM; - } - - return 0; -} - -static void rtw_xmit_resource_free(struct adapter *padapter, struct xmit_buf *pxmitbuf, - u32 free_sz) -{ - usb_free_urb(pxmitbuf->pxmit_urb); - kfree(pxmitbuf->pallocated_buf); -} - -int _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) -{ - int i; - struct xmit_buf *pxmitbuf; - struct xmit_frame *pxframe; - 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); - - /* - * Please insert all the queue initializaiton using rtw_init_queue below - */ - - pxmitpriv->adapter = padapter; - - INIT_LIST_HEAD(&pxmitpriv->be_pending); - INIT_LIST_HEAD(&pxmitpriv->bk_pending); - INIT_LIST_HEAD(&pxmitpriv->vi_pending); - INIT_LIST_HEAD(&pxmitpriv->vo_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; - goto exit; - } - pxmitpriv->pxmit_frame_buf = (u8 *)ALIGN((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) - goto free_frame_buf; - - pxmitpriv->pxmitbuf = (u8 *)ALIGN((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. */ - if (rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) { - msleep(10); - if (rtw_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ))) - goto free_xmitbuf; - } - - pxmitbuf->high_queue = false; - - 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) - goto free_xmitbuf; - - pxmitpriv->pxmit_extbuf = (u8 *)ALIGN((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; - - if (rtw_xmit_resource_alloc(padapter, pxmitbuf, max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)) - goto free_xmit_extbuf; - - list_add_tail(&pxmitbuf->list, &pxmitpriv->free_xmit_extbuf_queue.queue); - pxmitbuf++; - } - - pxmitpriv->free_xmit_extbuf_cnt = num_xmit_extbuf; - - if (rtw_alloc_hwxmits(padapter)) - goto free_xmit_extbuf; - - for (i = 0; i < 4; i++) - pxmitpriv->wmm_para_seq[i] = i; - - pxmitpriv->ack_tx = false; - mutex_init(&pxmitpriv->ack_tx_mutex); - rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0); - - tasklet_init(&pxmitpriv->xmit_tasklet, rtl8188eu_xmit_tasklet, (unsigned long)padapter); - - return 0; - -free_xmit_extbuf: - pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf; - while (i--) { - rtw_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)); - pxmitbuf++; - } - vfree(pxmitpriv->pallocated_xmit_extbuf); - i = NR_XMITBUFF; -free_xmitbuf: - pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; - while (i--) { - rtw_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ)); - pxmitbuf++; - } - vfree(pxmitpriv->pallocated_xmitbuf); -free_frame_buf: - vfree(pxmitpriv->pallocated_frame_buf); -exit: - return -ENOMEM; -} - -static void rtw_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_xmit_complete(struct adapter *padapter, struct xmit_frame *pxframe) -{ - if (pxframe->pkt) - rtw_pkt_complete(padapter, pxframe->pkt); - pxframe->pkt = NULL; -} - -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_xmit_complete(padapter, pxmitframe); - - pxmitframe++; - } - - for (i = 0; i < NR_XMITBUFF; i++) { - rtw_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_xmit_resource_free(padapter, pxmitbuf, (max_xmit_extbuf_size + XMITBUF_ALIGN_SZ)); - pxmitbuf++; - } - - vfree(pxmitpriv->pallocated_xmit_extbuf); - - kfree(pxmitpriv->hwxmits); - - mutex_destroy(&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: - break; - } - - return change_priority; -} - -static 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; -} - -static uint rtw_remainder_len(struct pkt_file *pfile) -{ - return pfile->buf_len - ((size_t)(pfile->cur_addr) - - (size_t)(pfile->buf_start)); -} - -static uint rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen) -{ - uint len; - - len = min(rtw_remainder_len(pfile), 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; -} - -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 = IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA; -} - -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 (pattrib->ether_type == ETH_P_IP) { - /* 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 (((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; - } - } - } - - /* 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; - 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 = IEEE80211_FTYPE_DATA; - 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; - - 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 = PTR_ALIGN(payload, 4); - - 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 void xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmitframe) -{ - struct pkt_attrib *pattrib = &pxmitframe->attrib; - - if (!pattrib->bswenc) - return; - - switch (pattrib->encrypt) { - case _WEP40_: - case _WEP104_: - rtw_wep_encrypt(padapter, pxmitframe); - break; - case _TKIP_: - rtw_tkip_encrypt(padapter, pxmitframe); - break; - case _AES_: - rtw_aes_encrypt(padapter, pxmitframe); - break; - default: - break; - } -} - -s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib) -{ - u16 *qc; - - struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct qos_priv *pqospriv = &pmlmepriv->qospriv; - bool qos_option; - __le16 *fctrl = &pwlanhdr->frame_control; - - 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 & IEEE80211_FTYPE_DATA)) - return _SUCCESS; - - 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); - qos_option = pqospriv->qos_option; - } 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); - qos_option = psta->qos_option; - } 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); - qos_option = psta->qos_option; - } else { - return _FAIL; - } - - 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 */ - } - } - } - - return _SUCCESS; -} - -s32 rtw_txframes_pending(struct adapter *padapter) -{ - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - return (!list_empty(&pxmitpriv->be_pending) || - !list_empty(&pxmitpriv->bk_pending) || - !list_empty(&pxmitpriv->vi_pending) || - !list_empty(&pxmitpriv->vo_pending)); -} - -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; -} - -/* - * 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; - 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) - 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) { - 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) { - 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 broadcast/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 || pktfile.pkt_len == 0) { - 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; - } - - mem_start = PTR_ALIGN(pframe, 4) + hw_hdr_offset; - memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen); - } - - if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) { - 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_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) - 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; - - 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) - 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) - 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)) - goto out; - - phead = get_list_head(pfree_xmit_queue); - plist = phead->next; - pxframe = container_of(plist, struct xmit_frame, list); - list_del_init(&pxframe->list); - - 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; - -out: - 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_pkt_complete(padapter, pndis_pkt); - -exit: - - return _SUCCESS; -} - -void rtw_free_xmitframe_list(struct xmit_priv *pxmitpriv, struct list_head *xframe_list) -{ - struct xmit_frame *pxmitframe, *tmp_xmitframe; - - list_for_each_entry_safe(pxmitframe, tmp_xmitframe, xframe_list, list) - rtw_free_xmitframe(pxmitpriv, pxmitframe); -} - -struct xmit_frame *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i) -{ - struct hw_xmit *phwxmit; - struct tx_servq *ptxservq, *tmp_txservq; - struct list_head *xframe_list; - struct xmit_frame *pxmitframe = NULL; - struct adapter *padapter = pxmitpriv->adapter; - struct registry_priv *pregpriv = &padapter->registrypriv; - int i, inx[] = { 0, 1, 2, 3 }; - - if (pregpriv->wifi_spec == 1) { - for (i = 0; i < ARRAY_SIZE(inx); i++) - inx[i] = pxmitpriv->wmm_para_seq[i]; - } - - spin_lock_bh(&pxmitpriv->lock); - - for (i = 0; i < HWXMIT_ENTRY; i++) { - phwxmit = phwxmit_i + inx[i]; - list_for_each_entry_safe(ptxservq, tmp_txservq, phwxmit->sta_list, tx_pending) { - xframe_list = &ptxservq->sta_pending; - if (list_empty(xframe_list)) - continue; - - pxmitframe = container_of(xframe_list->next, struct xmit_frame, list); - list_del_init(&pxmitframe->list); - - phwxmit->accnt--; - ptxservq->qcnt--; - - /* Remove sta node when there are no pending packets. */ - if (list_empty(xframe_list)) - list_del_init(&ptxservq->tx_pending); - - goto exit; - } - } -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; - 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, phwxmits[ac_index].sta_list); - - list_add_tail(&pxmitframe->list, &ptxservq->sta_pending); - ptxservq->qcnt++; - phwxmits[ac_index].accnt++; -exit: - - return res; -} - -int rtw_alloc_hwxmits(struct adapter *padapter) -{ - struct hw_xmit *hwxmits; - struct xmit_priv *pxmitpriv = &padapter->xmitpriv; - - pxmitpriv->hwxmits = kcalloc(HWXMIT_ENTRY, sizeof(struct hw_xmit), GFP_KERNEL); - if (!pxmitpriv->hwxmits) - return -ENOMEM; - - hwxmits = pxmitpriv->hwxmits; - - hwxmits[0].sta_list = &pxmitpriv->vo_pending; - hwxmits[1].sta_list = &pxmitpriv->vi_pending; - hwxmits[2].sta_list = &pxmitpriv->be_pending; - hwxmits[3].sta_list = &pxmitpriv->bk_pending; - - return 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 + ETH_ALEN, padapter->br_mac, ETH_ALEN) && - *((__be16 *)(skb->data + ETH_ALEN * 2)) != htons(ETH_P_8021Q) && - *((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_IP) && - !memcmp(padapter->scdb_mac, skb->data + ETH_ALEN, ETH_ALEN) && padapter->scdb_entry) { - memcpy(skb->data + ETH_ALEN, GET_MY_HWADDR(padapter), ETH_ALEN); - padapter->scdb_entry->ageing_timer = jiffies; - spin_unlock_bh(&padapter->br_ext_lock); - } else { - if (*((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_8021Q)) { - is_vlan_tag = 1; - vlan_hdr = *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)); - for (i = 0; i < 6; i++) - *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + ETH_ALEN * 2 - 2 - i * 2)); - skb_pull(skb, 4); - } - if (!memcmp(skb->data + ETH_ALEN, padapter->br_mac, ETH_ALEN) && - (*((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_IP))) - memcpy(padapter->br_ip, skb->data + WLAN_ETHHDR_LEN + 12, 4); - - if (*((__be16 *)(skb->data + ETH_ALEN * 2)) == htons(ETH_P_IP)) { - if (memcmp(padapter->scdb_mac, skb->data + ETH_ALEN, ETH_ALEN)) { - padapter->scdb_entry = (struct nat25_network_db_entry *)scdb_findEntry(padapter, - skb->data + WLAN_ETHHDR_LEN + 12); - if (padapter->scdb_entry) { - memcpy(padapter->scdb_mac, skb->data + ETH_ALEN, ETH_ALEN); - 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, ETH_ALEN); - 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 + ETH_ALEN * 2)) = htons(ETH_P_8021Q); - *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)) = vlan_hdr; - } - - newskb = skb_copy(skb, GFP_ATOMIC); - if (!newskb) - return -1; - dev_kfree_skb_any(skb); - - *pskb = skb = newskb; - if (is_vlan_tag) { - vlan_hdr = *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)); - for (i = 0; i < 6; i++) - *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2 - i * 2)) = *((unsigned short *)(skb->data + ETH_ALEN * 2 - 2 - i * 2)); - skb_pull(skb, 4); - } - } - - res = skb_linearize(skb); - if (res < 0) - return -1; - - res = nat25_db_handle(padapter, skb, NAT25_INSERT); - if (res < 0) { - if (res == -2) - return -1; - - return 0; - } - } - - memcpy(skb->data + ETH_ALEN, GET_MY_HWADDR(padapter), ETH_ALEN); - - 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 + ETH_ALEN * 2)) = htons(ETH_P_8021Q); - *((unsigned short *)(skb->data + ETH_ALEN * 2 + 2)) = vlan_hdr; - } - } - - /* check if SA is equal to our MAC */ - if (memcmp(skb->data + ETH_ALEN, GET_MY_HWADDR(padapter), ETH_ALEN)) - 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; -} - -/* - * 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; - s32 res; - - pxmitframe = rtw_alloc_xmitframe(pxmitpriv); - if (!pxmitframe) - return -1; - - if (rcu_access_pointer(padapter->pnetdev->rx_handler_data) && - 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); - - pxmitframe->attrib.qsel = pxmitframe->attrib.priority; - - 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); - - if (!rtl8188eu_hal_xmit(padapter, pxmitframe)) - return 1; - - return 0; -} - -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); - /* tx bc/mc packets after update bcn */ - update_beacon(padapter, _TIM_IE_, NULL, false); - - 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) { - /* update 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 list_head *phead) -{ - struct list_head *plist; - u8 ac_index; - struct tx_servq *ptxservq; - struct pkt_attrib *pattrib; - struct xmit_frame *pxmitframe; - struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits; - - 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 (rtl8188eu_hal_xmit(padapter, pxmitframe)) - rtw_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 (rtl8188eu_hal_xmit(padapter, pxmitframe)) - rtw_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 (rtl8188eu_hal_xmit(padapter, pxmitframe)) - rtw_xmit_complete(padapter, pxmitframe); - - if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) { - pstapriv->tim_bitmap &= ~BIT(psta->aid); - - /* update BCN for TIM IE */ - update_beacon(padapter, _TIM_IE_, NULL, false); - } - } - - spin_unlock_bh(&psta->sleep_q.lock); -} - -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; - else - status = sctx->status; - - if (status == RTW_SCTX_DONE_SUCCESS) - ret = _SUCCESS; - - return ret; -} - -void rtw_sctx_done_err(struct submit_ctx **sctx, int status) -{ - if (*sctx) { - (*sctx)->status = status; - complete(&((*sctx)->done)); - *sctx = NULL; - } -} - -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); -} - -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) { - pxmitpriv->tx_drop++; - dev_kfree_skb_any(newskb); - } else { - pxmitpriv->tx_pkts++; - } - } else { - 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; -} - -netdev_tx_t 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 NETDEV_TX_OK; -} diff --git a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c b/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c deleted file mode 100644 index 1e04de3a6622..000000000000 --- a/drivers/staging/r8188eu/hal/Hal8188ERateAdaptive.c +++ /dev/null @@ -1,654 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) Realtek Semiconductor Corp. */ - -#include "../include/drv_types.h" - -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, /* SS<TH */ - 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x13, 0x15, - 9, 9, 9, 9, 0x0c, 0x0e, 0x11, 0x13} - }; - -static u8 RETRY_PENALTY_UP_IDX[RATESIZE] = { - 0x0c, 0x0d, 0x0d, 0x0f, 0x0d, 0x0e, - 0x0f, 0x0f, 0x10, 0x12, 0x13, 0x14, /* SS>TH */ - 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; - int res; - - 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: - res = rtw_read32(dm_odm->Adapter, REG_ARFR0, &MaskFromReg); - if (res) - return res; - - pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; - break; - case 13: - res = rtw_read32(dm_odm->Adapter, REG_ARFR1, &MaskFromReg); - if (res) - return res; - - pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; - break; - case 14: - res = rtw_read32(dm_odm->Adapter, REG_ARFR2, &MaskFromReg); - if (res) - return res; - - pRaInfo->RAUseRate = (pRaInfo->RateMask) & MaskFromReg; - break; - case 15: - res = rtw_read32(dm_odm->Adapter, REG_ARFR3, &MaskFromReg); - if (res) - return res; - - 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; - } -} - -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 >= ODM_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 >= ODM_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 >= ODM_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 >= ODM_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 >= ODM_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) -{ - rtw_write16(dm_odm->Adapter, 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 >= ODM_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] = le16_to_cpup((__le16 *)pBuffer); - pRAInfo->RTY[1] = pBuffer[2]; - pRAInfo->RTY[2] = pBuffer[3]; - pRAInfo->RTY[3] = pBuffer[4]; - pRAInfo->RTY[4] = pBuffer[5]; - pRAInfo->DROP = pBuffer[6]; - 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 deleted file mode 100644 index 23b7205722b5..000000000000 --- a/drivers/staging/r8188eu/hal/HalHWImg8188E_BB.c +++ /dev/null @@ -1,733 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#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 _interface = (hex & 0x0000FF00) >> 8; - u32 _platform = (hex & 0x00FF0000) >> 16; - u32 cond = condition; - - if (condition == 0xCDCDCDCD) - return true; - - 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, -}; - -static void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data) -{ - rtl8188e_PHY_SetBBReg(pDM_Odm->Adapter, Addr, Bitmask, Data); - /* Add 1us delay between BB/RF register setting. */ - udelay(1); -} - -int ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *dm_odm) -{ - u32 hex = 0; - u32 i = 0; - u32 arraylen = ARRAY_SIZE(array_agc_tab_1t_8188e); - 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; - - hex += ODM_ITRF_USB << 8; - hex += ODM_CE << 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 -ENOMEM; - } - } - - 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 (!rtl8188e_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { - printk("~~~ %s IOL_exec_cmds Failed !!!\n", __func__); - return -1; - } - } - return 0; -} - -/****************************************************************************** -* 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, -}; - -static void odm_ConfigBB_PHY_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data) -{ - if (Addr == 0xfe) { - msleep(50); - } else if (Addr == 0xfd) { - mdelay(5); - } else if (Addr == 0xfc) { - mdelay(1); - } else if (Addr == 0xfb) { - udelay(50); - } else if (Addr == 0xfa) { - udelay(5); - } else if (Addr == 0xf9) { - udelay(1); - } else { - if (Addr == 0xa24) - pDM_Odm->RFCalibrateInfo.RegA24 = Data; - rtl8188e_PHY_SetBBReg(pDM_Odm->Adapter, Addr, Bitmask, Data); - - /* Add 1us delay between BB/RF register setting. */ - udelay(1); - } -} - -int ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *dm_odm) -{ - u32 hex = 0; - u32 i = 0; - u32 arraylen = ARRAY_SIZE(array_phy_reg_1t_8188e); - 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; - hex += ODM_ITRF_USB << 8; - hex += ODM_CE << 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 -ENOMEM; - } - } - - 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 (!rtl8188e_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { - pr_info("~~~ IOL Config %s Failed !!!\n", __func__); - return -1; - } - } - return 0; -} - -/****************************************************************************** -* 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, - -}; - -static void odm_ConfigBB_PHY_REG_PG_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, - u32 Data) -{ - if (Addr == 0xfe) - msleep(50); - else if (Addr == 0xfd) - mdelay(5); - else if (Addr == 0xfc) - mdelay(1); - else if (Addr == 0xfb) - udelay(50); - else if (Addr == 0xfa) - udelay(5); - else if (Addr == 0xf9) - udelay(1); - else - storePwrIndexDiffRateOffset(pDM_Odm->Adapter, Addr, Bitmask, Data); -} - -void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm) -{ - u32 hex; - u32 i = 0; - u32 arraylen = ARRAY_SIZE(array_phy_reg_pg_8188e); - u32 *array = array_phy_reg_pg_8188e; - - hex = ODM_ITRF_USB << 8; - hex += (ODM_CE << 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 deleted file mode 100644 index da71867bcca3..000000000000 --- a/drivers/staging/r8188eu/hal/HalHWImg8188E_MAC.c +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#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, -}; - -static void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data) -{ - rtw_write8(pDM_Odm->Adapter, Addr, Data); -} - -int 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; - u32 array_len = ARRAY_SIZE(array_MAC_REG_8188E); - 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; - hex += ODM_ITRF_USB << 8; - hex += ODM_CE << 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 -ENOMEM; - } - } - - 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 (!rtl8188e_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { - pr_info("~~~ MAC IOL_exec_cmds Failed !!!\n"); - return -1; - } - } - return 0; -} diff --git a/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c b/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c deleted file mode 100644 index a4c3d3d149f7..000000000000 --- a/drivers/staging/r8188eu/hal/HalHWImg8188E_RF.c +++ /dev/null @@ -1,269 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#include "../include/rtw_iol.h" - -static bool CheckCondition(const u32 Condition, const u32 Hex) -{ - u32 _interface = (Hex & 0x0000FF00) >> 8; - u32 _platform = (Hex & 0x00FF0000) >> 16; - u32 cond = Condition; - - if (Condition == 0xCDCDCDCD) - return true; - - 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, -}; - -static void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, - u32 Data, u32 RegAddr) -{ - if (Addr == 0xffe) { - msleep(50); - } else if (Addr == 0xfd) { - mdelay(5); - } else if (Addr == 0xfc) { - mdelay(1); - } else if (Addr == 0xfb) { - udelay(50); - } else if (Addr == 0xfa) { - udelay(5); - } else if (Addr == 0xf9) { - udelay(1); - } else { - rtl8188e_PHY_SetRFReg(pDM_Odm->Adapter, RegAddr, bRFRegOffsetMask, Data); - /* Add 1us delay between BB/RF register setting. */ - udelay(1); - } -} - -static 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, Addr | maskforPhySet); -} - -int 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; - u32 ArrayLen = ARRAY_SIZE(Array_RadioA_1T_8188E); - 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; - - hex += ODM_ITRF_USB << 8; - hex += ODM_CE << 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 -ENOMEM; - } - } - - 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 (!rtl8188e_IOL_exec_cmds_sync(pDM_Odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { - pr_info("~~~ IOL Config %s Failed !!!\n", __func__); - return -1; - } - } - return 0; -} diff --git a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c b/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c deleted file mode 100644 index 26e710ef5134..000000000000 --- a/drivers/staging/r8188eu/hal/HalPhyRf_8188e.c +++ /dev/null @@ -1,900 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#include "../include/drv_types.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 according 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 = &Adapter->haldata; - u8 ThermalValue = 0, delta, delta_LCK, delta_IQK, offset; - u8 ThermalValue_AVG_count = 0; - u32 ThermalValue_AVG = 0; - s32 ele_D, TempCCk; - s8 OFDM_index, CCK_index = 0; - s8 OFDM_index_old = 0, CCK_index_old = 0; - u32 i = 0, j = 0; - - u8 OFDM_min_index = 6; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */ - 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); - - /* <Kordan> RFCalibrateInfo.RegA24 will be initialized when ODM HW configuring, but MP configures with para files. */ - dm_odm->RFCalibrateInfo.RegA24 = 0x090e1317; - - ThermalValue = (u8)rtl8188e_PHY_QueryRFReg(Adapter, RF_T_METER_88E, 0xfc00); /* 0x42: RF Reg[15:10] 88E */ - - if (ThermalValue) { - /* Query OFDM path A default setting */ - ele_D = rtl8188e_PHY_QueryBBReg(Adapter, 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 = (u8)i; - dm_odm->BbSwingIdxOfdmBase = (u8)i; - break; - } - } - - /* Query CCK default setting From 0xa24 */ - TempCCk = dm_odm->RFCalibrateInfo.RegA24; - - for (i = 0; i < CCK_TABLE_SIZE; i++) { - if (memcmp((void *)&TempCCk, (void *)&cck_swing_table[i][2], 4)) { - 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; - - dm_odm->RFCalibrateInfo.OFDM_index = OFDM_index_old; - 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; - OFDM_index = dm_odm->RFCalibrateInfo.OFDM_index + OFDM_index_mapping[j][offset]; - CCK_index = dm_odm->RFCalibrateInfo.CCK_index + OFDM_index_mapping[j][offset]; - - if (OFDM_index > OFDM_TABLE_SIZE_92D - 1) - OFDM_index = OFDM_TABLE_SIZE_92D - 1; - else if (OFDM_index < OFDM_min_index) - OFDM_index = 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; - - /* Revse TX power table. */ - dm_odm->BbSwingIdxOfdm = (u8)OFDM_index; - 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 (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; - } -} - -/* 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) -{ - u32 regeac, regE94, regE9C; - u8 result = 0x00; - - /* 1 Tx IQK */ - /* path-A IQK setting */ - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c); - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c); - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x8214032a); - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000); - - /* LO calibration setting */ - rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x00462911); - - /* One shot, path A LOK & IQK */ - rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); - rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); - - /* delay x ms */ - /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */ - mdelay(IQK_DELAY_TIME_88E); - - /* Check failed */ - regeac = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord); - regE94 = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord); - regE9C = rtl8188e_PHY_QueryBBReg(adapt, 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) -{ - u32 regeac, regE94, regE9C, regEA4, u4tmp; - u8 result = 0x00; - - /* 1 Get TXIMR setting */ - /* modify RXIQK mode table */ - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000); - rtl8188e_PHY_SetRFReg(adapt, RF_WE_LUT, bRFRegOffsetMask, 0x800a0); - rtl8188e_PHY_SetRFReg(adapt, RF_RCK_OS, bRFRegOffsetMask, 0x30000); - rtl8188e_PHY_SetRFReg(adapt, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); - rtl8188e_PHY_SetRFReg(adapt, RF_TXPA_G2, bRFRegOffsetMask, 0xf117B); - - /* PA,PAD off */ - rtl8188e_PHY_SetRFReg(adapt, 0xdf, bRFRegOffsetMask, 0x980); - rtl8188e_PHY_SetRFReg(adapt, 0x56, bRFRegOffsetMask, 0x51000); - - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000); - - /* IQK setting */ - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK, bMaskDWord, 0x01007c00); - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK, bMaskDWord, 0x81004800); - - /* path-A IQK setting */ - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x10008c1c); - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x30008c1c); - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c1f); - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160000); - - /* LO calibration setting */ - rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); - - /* One shot, path A LOK & IQK */ - rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); - rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); - - /* delay x ms */ - mdelay(IQK_DELAY_TIME_88E); - - /* Check failed */ - regeac = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord); - regE94 = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord); - regE9C = rtl8188e_PHY_QueryBBReg(adapt, 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); - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK, bMaskDWord, u4tmp); - - /* 1 RX IQK */ - /* modify RXIQK mode table */ - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000); - rtl8188e_PHY_SetRFReg(adapt, RF_WE_LUT, bRFRegOffsetMask, 0x800a0); - rtl8188e_PHY_SetRFReg(adapt, RF_RCK_OS, bRFRegOffsetMask, 0x30000); - rtl8188e_PHY_SetRFReg(adapt, RF_TXPA_G1, bRFRegOffsetMask, 0x0000f); - rtl8188e_PHY_SetRFReg(adapt, RF_TXPA_G2, bRFRegOffsetMask, 0xf7ffa); - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000); - - /* IQK setting */ - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK, bMaskDWord, 0x01004800); - - /* path-A IQK setting */ - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x38008c1c); - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x18008c1c); - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_PI_A, bMaskDWord, 0x82160c05); - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_PI_A, bMaskDWord, 0x28160c1f); - - /* LO calibration setting */ - rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Rsp, bMaskDWord, 0x0046a911); - - /* One shot, path A LOK & IQK */ - rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf9000000); - rtl8188e_PHY_SetBBReg(adapt, rIQK_AGC_Pts, bMaskDWord, 0xf8000000); - - /* delay x ms */ - /* PlatformStallExecution(IQK_DELAY_TIME_88E*1000); */ - mdelay(IQK_DELAY_TIME_88E); - - /* Check failed */ - regeac = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord); - regE94 = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord); - regE9C = rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord); - regEA4 = rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord); - - /* reload RF 0xdf */ - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x00000000); - rtl8188e_PHY_SetRFReg(adapt, 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 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; - - if (final_candidate == 0xFF) { - return; - } else if (iqkok) { - Oldval_0 = (rtl8188e_PHY_QueryBBReg(adapt, rOFDM0_XATxIQImbalance, bMaskDWord) >> 22) & 0x3FF; - - X = result[final_candidate][0]; - if ((X & 0x00000200) != 0) - X = X | 0xFFFFFC00; - TX0_A = (X * Oldval_0) >> 8; - rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XATxIQImbalance, 0x3FF, TX0_A); - - rtl8188e_PHY_SetBBReg(adapt, 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; - rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XCTxAFE, 0xF0000000, ((TX0_C & 0x3C0) >> 6)); - rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XATxIQImbalance, 0x003F0000, (TX0_C & 0x3F)); - - rtl8188e_PHY_SetBBReg(adapt, rOFDM0_ECCAThreshold, BIT(29), ((Y * Oldval_0 >> 7) & 0x1)); - - if (txonly) - return; - - reg = result[final_candidate][2]; - rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XARxIQImbalance, 0x3FF, reg); - - reg = result[final_candidate][3] & 0x3F; - rtl8188e_PHY_SetBBReg(adapt, rOFDM0_XARxIQImbalance, 0xFC00, reg); - - reg = (result[final_candidate][3] >> 6) & 0xF; - rtl8188e_PHY_SetBBReg(adapt, rOFDM0_RxIQExtAnta, 0xF0000000, reg); - } -} - -void _PHY_SaveADDARegisters(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegisterNum) -{ - u32 i; - - for (i = 0; i < RegisterNum; i++) { - ADDABackup[i] = rtl8188e_PHY_QueryBBReg(adapt, ADDAReg[i], bMaskDWord); - } -} - -/* FIXME: return an error to caller */ -static void _PHY_SaveMACRegisters( - struct adapter *adapt, - u32 *MACReg, - u32 *MACBackup - ) -{ - u32 i; - int res; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) { - u8 reg; - - res = rtw_read8(adapt, MACReg[i], ®); - if (res) - return; - - MACBackup[i] = reg; - } - - res = rtw_read32(adapt, MACReg[i], MACBackup + i); - (void)res; -} - -static void reload_adda_reg(struct adapter *adapt, u32 *ADDAReg, u32 *ADDABackup, u32 RegiesterNum) -{ - u32 i; - - for (i = 0; i < RegiesterNum; i++) - rtl8188e_PHY_SetBBReg(adapt, ADDAReg[i], bMaskDWord, ADDABackup[i]); -} - -static void -_PHY_ReloadMACRegisters( - struct adapter *adapt, - u32 *MACReg, - u32 *MACBackup - ) -{ - u32 i; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) - rtw_write8(adapt, MACReg[i], (u8)MACBackup[i]); - - rtw_write32(adapt, MACReg[i], MACBackup[i]); -} - -static void -_PHY_PathADDAOn( - struct adapter *adapt, - u32 *ADDAReg) -{ - u32 i; - - rtl8188e_PHY_SetBBReg(adapt, ADDAReg[0], bMaskDWord, 0x0b1b25a0); - - for (i = 1; i < IQK_ADDA_REG_NUM; i++) - rtl8188e_PHY_SetBBReg(adapt, ADDAReg[i], bMaskDWord, 0x0bdb25a0); -} - -void -_PHY_MACSettingCalibration( - struct adapter *adapt, - u32 *MACReg, - u32 *MACBackup - ) -{ - u32 i = 0; - - rtw_write8(adapt, MACReg[i], 0x3F); - - for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) - rtw_write8(adapt, MACReg[i], (u8)(MACBackup[i] & (~BIT(3)))); - - rtw_write8(adapt, MACReg[i], (u8)(MACBackup[i] & (~BIT(5)))); -} - -static void _PHY_PIModeSwitch( - struct adapter *adapt, - bool PIMode - ) -{ - u32 mode; - - mode = PIMode ? 0x01000100 : 0x01000000; - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XA_HSSIParameter1, bMaskDWord, mode); - rtl8188e_PHY_SetBBReg(adapt, 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; - u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ - bool result = true; - s32 tmp1 = 0, tmp2 = 0; - - 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 = abs(tmp1 - tmp2); - - 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) -{ - struct hal_data_8188e *pHalData = &adapt->haldata; - struct odm_dm_struct *dm_odm = &pHalData->odmpriv; - u32 i; - u8 PathAOK; - 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 = 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); - if (t == 0) - dm_odm->RFCalibrateInfo.bRfPiEnable = (u8)rtl8188e_PHY_QueryBBReg(adapt, 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 */ - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_RFMOD, BIT(24), 0x00); - rtl8188e_PHY_SetBBReg(adapt, rOFDM0_TRxPathEnable, bMaskDWord, 0x03a05600); - rtl8188e_PHY_SetBBReg(adapt, rOFDM0_TRMuxPar, bMaskDWord, 0x000800e4); - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XCD_RFInterfaceSW, bMaskDWord, 0x22204000); - - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(10), 0x01); - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XAB_RFInterfaceSW, BIT(26), 0x01); - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XA_RFInterfaceOE, BIT(10), 0x00); - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XB_RFInterfaceOE, BIT(10), 0x00); - - /* MAC settings */ - _PHY_MACSettingCalibration(adapt, IQK_MAC_REG, dm_odm->RFCalibrateInfo.IQK_MAC_backup); - - /* Page B init */ - /* AP or IQK */ - rtl8188e_PHY_SetBBReg(adapt, rConfig_AntA, bMaskDWord, 0x0f600000); - - - /* IQ calibration setting */ - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_IQK, bMaskDWord, 0x80800000); - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK, bMaskDWord, 0x01007c00); - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK, bMaskDWord, 0x81004800); - - for (i = 0; i < retryCount; i++) { - PathAOK = phy_PathA_IQK_8188E(adapt); - if (PathAOK == 0x01) { - result[t][0] = (rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_Before_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; - result[t][1] = (rtl8188e_PHY_QueryBBReg(adapt, rTx_Power_After_IQK_A, bMaskDWord) & 0x3FF0000) >> 16; - break; - } - } - - for (i = 0; i < retryCount; i++) { - PathAOK = phy_PathA_RxIQK(adapt); - if (PathAOK == 0x03) { - result[t][2] = (rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_Before_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16; - result[t][3] = (rtl8188e_PHY_QueryBBReg(adapt, rRx_Power_After_IQK_A_2, bMaskDWord) & 0x3FF0000) >> 16; - break; - } - } - - /* Back to BB mode, load original value */ - rtl8188e_PHY_SetBBReg(adapt, 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 */ - rtl8188e_PHY_SetBBReg(adapt, rFPGA0_XA_LSSIParameter, bMaskDWord, 0x00032ed3); - - /* load 0xe30 IQC default value */ - rtl8188e_PHY_SetBBReg(adapt, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00); - rtl8188e_PHY_SetBBReg(adapt, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00); - } -} - -static void phy_LCCalibrate_8188E(struct adapter *adapt) -{ - u8 tmpreg; - u32 RF_Amode = 0, LC_Cal; - int res; - - /* Check continuous TX and Packet TX */ - res = rtw_read8(adapt, 0xd03, &tmpreg); - if (res) - return; - - if ((tmpreg & 0x70) != 0) /* Deal with contisuous TX case */ - rtw_write8(adapt, 0xd03, tmpreg & 0x8F); /* disable all continuous TX */ - else /* Deal with Packet TX case */ - rtw_write8(adapt, REG_TXPAUSE, 0xFF); /* block all queues */ - - if ((tmpreg & 0x70) != 0) { - /* 1. Read original RF mode */ - /* Path-A */ - RF_Amode = rtl8188e_PHY_QueryRFReg(adapt, RF_AC, bMask12Bits); - - /* 2. Set RF mode = standby mode */ - /* Path-A */ - rtl8188e_PHY_SetRFReg(adapt, RF_AC, bMask12Bits, (RF_Amode & 0x8FFFF) | 0x10000); - } - - /* 3. Read RF reg18 */ - LC_Cal = rtl8188e_PHY_QueryRFReg(adapt, RF_CHNLBW, bMask12Bits); - - /* 4. Set LC calibration begin bit15 */ - rtl8188e_PHY_SetRFReg(adapt, RF_CHNLBW, bMask12Bits, LC_Cal | 0x08000); - - msleep(100); - - /* Restore original situation */ - if ((tmpreg & 0x70) != 0) { - /* Deal with continuous TX case */ - /* Path-A */ - rtw_write8(adapt, 0xd03, tmpreg); - rtl8188e_PHY_SetRFReg(adapt, RF_AC, bMask12Bits, RF_Amode); - } else { - /* Deal with Packet TX case */ - rtw_write8(adapt, REG_TXPAUSE, 0x00); - } -} - -void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery) -{ - struct hal_data_8188e *pHalData = &adapt->haldata; - struct odm_dm_struct *dm_odm = &pHalData->odmpriv; - s32 result[4][8]; /* last is final result */ - u8 i, final_candidate; - bool pathaok; - s32 RegE94, RegE9C, RegEA4, RegEB4, RegEBC; - bool is12simular, is13simular, is23simular; - 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}; - - 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; - is12simular = false; - is23simular = false; - is13simular = false; - - for (i = 0; i < 3; i++) { - phy_IQCalibrate_8188E(adapt, result, i); - - 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]; - } - - 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; - pathaok = 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)); - - _PHY_SaveADDARegisters(adapt, IQK_BB_REG_92C, dm_odm->RFCalibrateInfo.IQK_BB_backup_recover, 9); -} - -void PHY_LCCalibrate_8188E(struct adapter *adapt) -{ - u32 timeout = 2000, timecount = 0; - struct hal_data_8188e *pHalData = &adapt->haldata; - struct odm_dm_struct *dm_odm = &pHalData->odmpriv; - - while (*dm_odm->pbScanInProcess && timecount < timeout) { - mdelay(50); - timecount += 50; - } - - phy_LCCalibrate_8188E(adapt); -} diff --git a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c b/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c deleted file mode 100644 index 6c0b1368383d..000000000000 --- a/drivers/staging/r8188eu/hal/HalPwrSeqCmd.c +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#include "../include/HalPwrSeqCmd.h" - -#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 (in us) */ - /* msk: N/A */ - /* value: N/A */ - -struct wl_pwr_cfg { - u16 offset; - u8 cmd:4; - u8 msk; - u8 value; -}; - -#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset -#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 - -static struct wl_pwr_cfg rtl8188E_power_on_flow[] = { - { 0x0006, PWR_CMD_POLLING, BIT(1), BIT(1) }, - { 0x0002, PWR_CMD_WRITE, BIT(0) | BIT(1), 0 }, /* reset BB */ - { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */ - { 0x0005, PWR_CMD_WRITE, BIT(7), 0 }, /* disable HWPDN (control by DRV)*/ - { 0x0005, PWR_CMD_WRITE, BIT(4) | BIT(3), 0 }, /* disable WL suspend*/ - { 0x0005, PWR_CMD_WRITE, BIT(0), BIT(0) }, - { 0x0005, PWR_CMD_POLLING, BIT(0), 0 }, - { 0x0023, PWR_CMD_WRITE, BIT(4), 0 }, -}; - -static struct wl_pwr_cfg rtl8188E_card_disable_flow[] = { - { 0x001F, PWR_CMD_WRITE, 0xFF, 0 }, /* turn off RF */ - { 0x0023, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* LDO Sleep mode */ - { 0x0005, PWR_CMD_WRITE, BIT(1), BIT(1) }, /* turn off MAC by HW state machine */ - { 0x0005, PWR_CMD_POLLING, BIT(1), 0 }, - { 0x0026, PWR_CMD_WRITE, BIT(7), BIT(7) }, /* schmitt trigger */ - { 0x0005, PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) }, /* enable WL suspend */ - { 0x0007, PWR_CMD_WRITE, 0xFF, 0 }, /* enable bandgap mbias in suspend */ - { 0x0041, PWR_CMD_WRITE, BIT(4), 0 }, /* Clear SIC_EN register */ - { 0xfe10, PWR_CMD_WRITE, BIT(4), BIT(4) }, /* Set USB suspend enable local register */ -}; - -/* This is used by driver for LPSRadioOff Procedure, not for FW LPS Step */ -static struct wl_pwr_cfg rtl8188E_enter_lps_flow[] = { - { 0x0522, PWR_CMD_WRITE, 0xFF, 0x7F },/* Tx Pause */ - { 0x05F8, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */ - { 0x05F9, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */ - { 0x05FA, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */ - { 0x05FB, PWR_CMD_POLLING, 0xFF, 0 }, /* Should be zero if no packet is transmitted */ - { 0x0002, PWR_CMD_WRITE, BIT(0), 0 }, /* CCK and OFDM are disabled, clocks are gated */ - { 0x0002, PWR_CMD_DELAY, 0, 0 }, - { 0x0100, PWR_CMD_WRITE, 0xFF, 0x3F }, /* Reset MAC TRX */ - { 0x0101, PWR_CMD_WRITE, BIT(1), 0 }, /* check if removed later */ - { 0x0553, PWR_CMD_WRITE, BIT(5), BIT(5) }, /* Respond TxOK to scheduler */ -}; - -u8 HalPwrSeqCmdParsing(struct adapter *padapter, enum r8188eu_pwr_seq seq) -{ - struct wl_pwr_cfg pwrcfgcmd = {0}; - struct wl_pwr_cfg *pwrseqcmd; - u8 poll_bit = false; - u8 idx, num_steps; - u8 value = 0; - u32 offset = 0; - u32 poll_count = 0; /* polling autoload done. */ - u32 max_poll_count = 5000; - int res; - - switch (seq) { - case PWR_ON_FLOW: - pwrseqcmd = rtl8188E_power_on_flow; - num_steps = ARRAY_SIZE(rtl8188E_power_on_flow); - break; - case DISABLE_FLOW: - pwrseqcmd = rtl8188E_card_disable_flow; - num_steps = ARRAY_SIZE(rtl8188E_card_disable_flow); - break; - case LPS_ENTER_FLOW: - pwrseqcmd = rtl8188E_enter_lps_flow; - num_steps = ARRAY_SIZE(rtl8188E_enter_lps_flow); - break; - default: - return false; - } - - for (idx = 0; idx < num_steps; idx++) { - pwrcfgcmd = pwrseqcmd[idx]; - - switch (GET_PWR_CFG_CMD(pwrcfgcmd)) { - case PWR_CMD_WRITE: - offset = GET_PWR_CFG_OFFSET(pwrcfgcmd); - - /* Read the value from system register */ - res = rtw_read8(padapter, offset, &value); - if (res) - return false; - - 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 { - res = rtw_read8(padapter, offset, &value); - if (res) - return false; - - 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) - return false; - } while (!poll_bit); - break; - case PWR_CMD_DELAY: - udelay(GET_PWR_CFG_OFFSET(pwrcfgcmd)); - break; - default: - break; - } - } - return true; -} diff --git a/drivers/staging/r8188eu/hal/hal_com.c b/drivers/staging/r8188eu/hal/hal_com.c deleted file mode 100644 index 33967eb3c0d0..000000000000 --- a/drivers/staging/r8188eu/hal/hal_com.c +++ /dev/null @@ -1,139 +0,0 @@ -// 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_ - -#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; - } - } - } -} diff --git a/drivers/staging/r8188eu/hal/hal_intf.c b/drivers/staging/r8188eu/hal/hal_intf.c deleted file mode 100644 index 13790e32f11c..000000000000 --- a/drivers/staging/r8188eu/hal/hal_intf.c +++ /dev/null @@ -1,50 +0,0 @@ -// 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" - -uint rtw_hal_init(struct adapter *adapt) -{ - adapt->hw_init_completed = false; - - if (rtl8188eu_hal_init(adapt) != _SUCCESS) - return _FAIL; - - adapt->hw_init_completed = true; - - if (adapt->registrypriv.notch_filter == 1) - hal_notch_filter_8188e(adapt, 1); - - return _SUCCESS; -} - -uint rtw_hal_deinit(struct adapter *adapt) -{ - uint status = _SUCCESS; - - status = rtl8188eu_hal_deinit(adapt); - - if (status == _SUCCESS) - adapt->hw_init_completed = false; - - return status; -} - -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)) { - struct sta_info *psta = NULL; - struct sta_priv *pstapriv = &adapt->stapriv; - if (mac_id >= 2) - psta = pstapriv->sta_aid[(mac_id - 1) - 1]; - if (psta) - add_RATid(adapt, psta, 0);/* todo: based on rssi_level*/ - } else { - UpdateHalRAMask8188EUsb(adapt, mac_id, rssi_level); - } -} diff --git a/drivers/staging/r8188eu/hal/odm.c b/drivers/staging/r8188eu/hal/odm.c deleted file mode 100644 index 94f9b125d860..000000000000 --- a/drivers/staging/r8188eu/hal/odm.c +++ /dev/null @@ -1,821 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#include "../include/drv_types.h" - -/* 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 cck_swing_table[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 */ -}; - -#define RxDefaultAnt1 0x65a9 -#define RxDefaultAnt2 0x569a - -static void odm_DIGInit(struct odm_dm_struct *pDM_Odm) -{ - struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; - struct adapter *adapter = pDM_Odm->Adapter; - - pDM_DigTable->CurIGValue = (u8)rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_IGI_A_11N, ODM_BIT_IGI_11N); - pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC; - pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC; - 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->bMediaConnect_0 = false; - - /* To Initialize pDM_Odm->bDMInitialGainEnable == false to avoid DIG error */ - pDM_Odm->bDMInitialGainEnable = true; -} - -static 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->pbScanInProcess) - return; - - /* add by Neil Chen to avoid PSD is processing */ - if (!pDM_Odm->bDMInitialGainEnable) - return; - - 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 */ - 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 */ - /* 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->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 (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; -} - -static void odm_CommonInfoSelfInit(struct odm_dm_struct *pDM_Odm) -{ - struct adapter *adapter = pDM_Odm->Adapter; - - pDM_Odm->bCckHighPower = (bool)rtl8188e_PHY_QueryBBReg(adapter, 0x824, BIT(9)); - pDM_Odm->RFPathRxEnable = (u8)rtl8188e_PHY_QueryBBReg(adapter, 0xc04, 0x0F); -} - -static void odm_CommonInfoSelfUpdate(struct odm_dm_struct *pDM_Odm) -{ - u8 EntryCnt = 0; - u8 i; - struct sta_info *pEntry; - - if (*pDM_Odm->pBandWidth == HT_CHANNEL_WIDTH_40) { - 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 void odm_RateAdaptiveMaskInit(struct odm_dm_struct *pDM_Odm) -{ - struct odm_rate_adapt *pOdmRA = &pDM_Odm->RateAdaptive; - - pOdmRA->RATRState = DM_RATR_STA_INIT; - pOdmRA->HighRSSIThresh = 50; - pOdmRA->LowRSSIThresh = 20; -} - -static void odm_RefreshRateAdaptiveMask(struct odm_dm_struct *pDM_Odm) -{ - u8 i; - struct adapter *pAdapter = pDM_Odm->Adapter; - - if (pAdapter->bDriverStopped) - 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); - } - } -} - -static void odm_DynamicBBPowerSavingInit(struct odm_dm_struct *pDM_Odm) -{ - struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable; - - pDM_PSTable->pre_rf_state = RF_MAX; - pDM_PSTable->cur_rf_state = RF_MAX; - pDM_PSTable->initialize = 0; -} - -static void odm_FalseAlarmCounterStatistics(struct odm_dm_struct *pDM_Odm) -{ - u32 ret_value; - struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; - struct adapter *adapter = pDM_Odm->Adapter; - - /* hold ofdm counter */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); /* hold page C counter */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); /* hold page D counter */ - - ret_value = rtl8188e_PHY_QueryBBReg(adapter, 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 = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_OFDM_FA_TYPE2_11N, bMaskDWord); - FalseAlmCnt->Cnt_OFDM_CCA = (ret_value & 0xffff); - FalseAlmCnt->Cnt_Parity_Fail = ((ret_value & 0xffff0000) >> 16); - ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_OFDM_FA_TYPE3_11N, bMaskDWord); - FalseAlmCnt->Cnt_Rate_Illegal = (ret_value & 0xffff); - FalseAlmCnt->Cnt_Crc8_fail = ((ret_value & 0xffff0000) >> 16); - ret_value = rtl8188e_PHY_QueryBBReg(adapter, 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; - - ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_SC_CNT_11N, bMaskDWord); - FalseAlmCnt->Cnt_BW_LSC = (ret_value & 0xffff); - FalseAlmCnt->Cnt_BW_USC = ((ret_value & 0xffff0000) >> 16); - - /* hold cck counter */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_FA_RST_11N, BIT(12), 1); - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_FA_RST_11N, BIT(14), 1); - - ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_CCK_FA_LSB_11N, bMaskByte0); - FalseAlmCnt->Cnt_Cck_fail = ret_value; - ret_value = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_CCK_FA_MSB_11N, bMaskByte3); - FalseAlmCnt->Cnt_Cck_fail += (ret_value & 0xff) << 8; - - ret_value = rtl8188e_PHY_QueryBBReg(adapter, 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; -} - -static void odm_CCKPacketDetectionThresh(struct odm_dm_struct *pDM_Odm) -{ - u8 CurCCK_CCAThres; - struct false_alarm_stats *FalseAlmCnt = &pDM_Odm->FalseAlmCnt; - - 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); -} - -static void FindMinimumRSSI(struct adapter *pAdapter) -{ - struct hal_data_8188e *pHalData = &pAdapter->haldata; - 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; - - pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB; -} - -static void odm_RSSIMonitorCheck(struct odm_dm_struct *pDM_Odm) -{ - struct adapter *Adapter = pDM_Odm->Adapter; - struct hal_data_8188e *pHalData = &Adapter->haldata; - 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; - - if (!(pDM_Odm->SupportAbility & ODM_BB_RSSI_MONITOR)) - return; - - 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) && - !is_broadcast_ether_addr(psta->hwaddr) && - 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 (tmpEntryMinPWDB != 0xff) /* If associated entry is found */ - pdmpriv->EntryMinUndecoratedSmoothedPWDB = tmpEntryMinPWDB; - else - pdmpriv->EntryMinUndecoratedSmoothedPWDB = 0; - - FindMinimumRSSI(Adapter); - pHalData->odmpriv.RSSI_Min = pdmpriv->MinUndecoratedPWDBForDM; -} - -static void odm_TXPowerTrackingThermalMeterInit(struct odm_dm_struct *pDM_Odm) -{ - pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = true; -} - -static void odm_InitHybridAntDiv(struct odm_dm_struct *pDM_Odm) -{ - if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) - return; - - ODM_AntennaDiversityInit_88E(pDM_Odm); -} - -static void odm_HwAntDiv(struct odm_dm_struct *pDM_Odm) -{ - if (!(pDM_Odm->SupportAbility & ODM_BB_ANT_DIV)) - return; - - ODM_AntennaDiversity_88E(pDM_Odm); -} - -static 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; -} - -static void odm_EdcaTurboCheck(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 = &Adapter->haldata; - 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; -} - -/* 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); - - odm_DynamicBBPowerSavingInit(pDM_Odm); - odm_TXPowerTrackingThermalMeterInit(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); -} - -/* 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_CommonInfoSelfUpdate(pDM_Odm); - odm_FalseAlarmCounterStatistics(pDM_Odm); - odm_RSSIMonitorCheck(pDM_Odm); - - odm_DIG(pDM_Odm); - odm_CCKPacketDetectionThresh(pDM_Odm); - - if (*pDM_Odm->pbPowerSaving) - return; - - odm_RefreshRateAdaptiveMask(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); - - ODM_TXPowerTrackingCheck(pDM_Odm); - odm_EdcaTurboCheck(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_MP_TEST_CHIP: - pDM_Odm->bIsMPChip = (u8)Value; - break; - case ODM_CMNINFO_RF_ANTENNA_TYPE: - pDM_Odm->AntDivType = (u8)Value; - break; - 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_Write_DIG(struct odm_dm_struct *pDM_Odm, u8 CurrentIGI) -{ - struct rtw_dig *pDM_DigTable = &pDM_Odm->DM_DigTable; - struct adapter *adapter = pDM_Odm->Adapter; - - if (pDM_DigTable->CurIGValue != CurrentIGI) { - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_IGI_A_11N, ODM_BIT_IGI_11N, CurrentIGI); - pDM_DigTable->CurIGValue = CurrentIGI; - } -} - -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 */ - rtw_write8(pDM_Odm->Adapter, ODM_REG_CCK_CCA_11N, CurCCK_CCAThres); - pDM_DigTable->CurCCK_CCAThres = CurCCK_CCAThres; -} - -void ODM_RF_Saving(struct odm_dm_struct *pDM_Odm, u8 bForceInNormal) -{ - struct rtl_ps *pDM_PSTable = &pDM_Odm->DM_PSTable; - struct adapter *adapter = pDM_Odm->Adapter; - u8 Rssi_Up_bound = 30; - u8 Rssi_Low_bound = 25; - - if (pDM_PSTable->initialize == 0) { - pDM_PSTable->reg_874 = (rtl8188e_PHY_QueryBBReg(adapter, 0x874, bMaskDWord) & 0x1CC000) >> 14; - pDM_PSTable->reg_c70 = (rtl8188e_PHY_QueryBBReg(adapter, 0xc70, bMaskDWord) & BIT(3)) >> 3; - pDM_PSTable->reg_85c = (rtl8188e_PHY_QueryBBReg(adapter, 0x85c, bMaskDWord) & 0xFF000000) >> 24; - pDM_PSTable->reg_a74 = (rtl8188e_PHY_QueryBBReg(adapter, 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) { - rtl8188e_PHY_SetBBReg(adapter, 0x874, 0x1C0000, 0x2); /* Reg874[20:18]=3'b010 */ - rtl8188e_PHY_SetBBReg(adapter, 0xc70, BIT(3), 0); /* RegC70[3]=1'b0 */ - rtl8188e_PHY_SetBBReg(adapter, 0x85c, 0xFF000000, 0x63); /* Reg85C[31:24]=0x63 */ - rtl8188e_PHY_SetBBReg(adapter, 0x874, 0xC000, 0x2); /* Reg874[15:14]=2'b10 */ - rtl8188e_PHY_SetBBReg(adapter, 0xa74, 0xF000, 0x3); /* RegA75[7:4]=0x3 */ - rtl8188e_PHY_SetBBReg(adapter, 0x818, BIT(28), 0x0); /* Reg818[28]=1'b0 */ - rtl8188e_PHY_SetBBReg(adapter, 0x818, BIT(28), 0x1); /* Reg818[28]=1'b1 */ - } else { - rtl8188e_PHY_SetBBReg(adapter, 0x874, 0x1CC000, pDM_PSTable->reg_874); - rtl8188e_PHY_SetBBReg(adapter, 0xc70, BIT(3), pDM_PSTable->reg_c70); - rtl8188e_PHY_SetBBReg(adapter, 0x85c, 0xFF000000, pDM_PSTable->reg_85c); - rtl8188e_PHY_SetBBReg(adapter, 0xa74, 0xF000, pDM_PSTable->reg_a74); - rtl8188e_PHY_SetBBReg(adapter, 0x818, BIT(28), 0x0); - } - pDM_PSTable->pre_rf_state = pDM_PSTable->cur_rf_state; - } -} - -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 (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 == HT_CHANNEL_WIDTH_40) - rate_bitmap = 0x000ff015; - else - rate_bitmap = 0x000ff005; - } - break; - default: - /* case WIRELESS_11_24N: */ - rate_bitmap = 0x0fffffff; - break; - } - - return rate_bitmap; -} - -/* 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; -} - -void ODM_TXPowerTrackingCheck(struct odm_dm_struct *pDM_Odm) -{ - struct adapter *Adapter = pDM_Odm->Adapter; - - if (!pDM_Odm->RFCalibrateInfo.TM_Trigger) { /* at least delay 1 sec */ - rtl8188e_PHY_SetRFReg(Adapter, 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; - } -} diff --git a/drivers/staging/r8188eu/hal/odm_HWConfig.c b/drivers/staging/r8188eu/hal/odm_HWConfig.c deleted file mode 100644 index 38f357e8aeda..000000000000 --- a/drivers/staging/r8188eu/hal/odm_HWConfig.c +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#include "../include/drv_types.h" - -static u8 odm_query_rxpwrpercentage(s8 antpower) -{ - if ((antpower <= -100) || (antpower >= 20)) - return 0; - else if (antpower >= 0) - return 100; - else - return 100 + antpower; -} - -static s32 odm_signal_scale_mapping(struct odm_dm_struct *dm_odm, s32 currsig) -{ - s32 retsig; - - 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 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 phy_info *pPhyInfo, - u8 *pPhyStatus, - struct odm_per_pkt_info *pPktinfo, - struct adapter *adapt) -{ - u8 i, Max_spatial_stream; - s8 rx_pwr[4], rx_pwr_all = 0; - u8 EVM, PWDB_ALL = 0; - 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; - - if (isCCKrate) { - u8 cck_agc_rpt; - - /* (1)Hardware does not provide RSSI for CCK */ - /* (2)PWDB, Average PWDB calculated 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 */ - 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_query_rxpwrpercentage(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; - } - - pPhyInfo->RxPWDBAll = PWDB_ALL; - pPhyInfo->recvpower = rx_pwr_all; - /* (3) Get Signal Quality (EVM) */ - if (pPktinfo->bPacketMatchBSSID) { - u8 SQ, SQ_rpt; - - if (pPhyInfo->RxPWDBAll > 40) { - 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; - } - } else { /* is OFDM rate */ - /* (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_query_rxpwrpercentage(rx_pwr[i]); - total_rssi += RSSI; - - pPhyInfo->RxMIMOSignalStrength[i] = (u8)RSSI; - - /* Get Rx snr value in DB */ - dm_odm->PhyDbgInfo.RxSNRdB[i] = (s32)(pPhyStaRpt->path_rxsnr[i] / 2); - } - /* (2)PWDB, Average PWDB calculated by hardware (for rate adaptive) */ - rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f) - 110; - - PWDB_ALL = odm_query_rxpwrpercentage(rx_pwr_all); - - pPhyInfo->RxPWDBAll = PWDB_ALL; - pPhyInfo->RxPower = rx_pwr_all; - pPhyInfo->recvpower = rx_pwr_all; - - /* (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); - } - } - } - /* 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_signal_scale_mapping(dm_odm, PWDB_ALL));/* PWDB_ALL; */ - } else { - if (rf_rx_num != 0) - pPhyInfo->SignalStrength = (u8)(odm_signal_scale_mapping(dm_odm, total_rssi /= rf_rx_num)); - } - - /* 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; -} - -static void odm_Process_RSSIForDM(struct odm_dm_struct *dm_odm, - struct phy_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; - u8 antsel_tr_mux; - struct fast_ant_train *pDM_FatTable = &dm_odm->DM_FatTable; - - 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; - - /* Smart Antenna Debug Message------------------ */ - 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 */ -void ODM_PhyStatusQuery(struct odm_dm_struct *dm_odm, - struct phy_info *pPhyInfo, - u8 *pPhyStatus, - struct odm_per_pkt_info *pPktinfo, - struct adapter *adapt) -{ - odm_RxPhyStatus92CSeries_Parsing(dm_odm, pPhyInfo, pPhyStatus, pPktinfo, adapt); - odm_Process_RSSIForDM(dm_odm, pPhyInfo, pPktinfo); -} diff --git a/drivers/staging/r8188eu/hal/odm_RTL8188E.c b/drivers/staging/r8188eu/hal/odm_RTL8188E.c deleted file mode 100644 index f3f4074d4316..000000000000 --- a/drivers/staging/r8188eu/hal/odm_RTL8188E.c +++ /dev/null @@ -1,264 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#include "../include/drv_types.h" - -static void odm_RX_HWAntDivInit(struct odm_dm_struct *dm_odm) -{ - struct adapter *adapter = dm_odm->Adapter; - u32 value32; - - /* MAC Setting */ - value32 = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord); - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */ - /* Pin Settings */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0 antsel antselb by HW */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0); /* Reg864[10]=1'b0 antsel2 by HW */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_LNA_SWITCH_11N, BIT(22), 1); /* Regb2c[22]=1'b0 disable CS/CG switch */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* Regb2c[31]=1'b1 output at CG only */ - /* OFDM Settings */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTDIV_PARA1_11N, bMaskDWord, 0x000000a0); - /* CCK Settings */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */ - ODM_UpdateRxIdleAnt_88E(dm_odm, MAIN_ANT); - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANT_MAPPING1_11N, 0xFFFF, 0x0201); /* antenna mapping table */ -} - -static void odm_TRX_HWAntDivInit(struct odm_dm_struct *dm_odm) -{ - struct adapter *adapter = dm_odm->Adapter; - u32 value32; - - /* MAC Setting */ - value32 = rtl8188e_PHY_QueryBBReg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord); - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTSEL_PIN_11N, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */ - /* Pin Settings */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_PIN_CTRL_11N, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0 antsel antselb by HW */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(10), 0); /* Reg864[10]=1'b0 antsel2 by HW */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_LNA_SWITCH_11N, BIT(22), 0); /* Regb2c[22]=1'b0 disable CS/CG switch */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_LNA_SWITCH_11N, BIT(31), 1); /* Regb2c[31]=1'b1 output at CG only */ - /* OFDM Settings */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTDIV_PARA1_11N, bMaskDWord, 0x000000a0); - /* CCK Settings */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_BB_PWR_SAV4_11N, BIT(7), 1); /* Fix CCK PHY status report issue */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_ANTDIV_PARA2_11N, BIT(4), 1); /* CCK complete HW AntDiv within 64 samples */ - /* Tx Settings */ - rtl8188e_PHY_SetBBReg(adapter, 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 */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_DEFUALT_A_11N, BIT(10) | BIT(9) | BIT(8), 1); /* Reg858[10:8]=3'b001 */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_DEFUALT_A_11N, BIT(13) | BIT(12) | BIT(11), 2); /* Reg858[13:11]=3'b010 */ - } else { /* MPchip */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANT_MAPPING1_11N, bMaskDWord, 0x0201); /* Reg914=3'b010, Reg915=3'b001 */ - } -} - -static void odm_FastAntTrainingInit(struct odm_dm_struct *dm_odm) -{ - struct adapter *adapter = dm_odm->Adapter; - u32 value32; - - /* MAC Setting */ - value32 = rtl8188e_PHY_QueryBBReg(adapter, 0x4c, bMaskDWord); - rtl8188e_PHY_SetBBReg(adapter, 0x4c, bMaskDWord, value32 | (BIT(23) | BIT(25))); /* Reg4C[25]=1, Reg4C[23]=1 for pin output */ - value32 = rtl8188e_PHY_QueryBBReg(adapter, 0x7B4, bMaskDWord); - rtl8188e_PHY_SetBBReg(adapter, 0x7b4, bMaskDWord, value32 | (BIT(16) | BIT(17))); /* Reg7B4[16]=1 enable antenna training, Reg7B4[17]=1 enable A2 match */ - - /* Match MAC ADDR */ - rtl8188e_PHY_SetBBReg(adapter, 0x7b4, 0xFFFF, 0); - rtl8188e_PHY_SetBBReg(adapter, 0x7b0, bMaskDWord, 0); - - rtl8188e_PHY_SetBBReg(adapter, 0x870, BIT(9) | BIT(8), 0);/* Reg870[8]=1'b0, Reg870[9]=1'b0 antsel antselb by HW */ - rtl8188e_PHY_SetBBReg(adapter, 0x864, BIT(10), 0); /* Reg864[10]=1'b0 antsel2 by HW */ - rtl8188e_PHY_SetBBReg(adapter, 0xb2c, BIT(22), 0); /* Regb2c[22]=1'b0 disable CS/CG switch */ - rtl8188e_PHY_SetBBReg(adapter, 0xb2c, BIT(31), 1); /* Regb2c[31]=1'b1 output at CG only */ - rtl8188e_PHY_SetBBReg(adapter, 0xca4, bMaskDWord, 0x000000a0); - - if (!dm_odm->bIsMPChip) { /* testchip */ - rtl8188e_PHY_SetBBReg(adapter, 0x858, BIT(10) | BIT(9) | BIT(8), 1); /* Reg858[10:8]=3'b001 */ - rtl8188e_PHY_SetBBReg(adapter, 0x858, BIT(13) | BIT(12) | BIT(11), 2); /* Reg858[13:11]=3'b010 */ - } else { /* MPchip */ - rtl8188e_PHY_SetBBReg(adapter, 0x914, bMaskByte0, 1); - rtl8188e_PHY_SetBBReg(adapter, 0x914, bMaskByte1, 2); - } - - /* Default Ant Setting when no fast training */ - rtl8188e_PHY_SetBBReg(adapter, 0x80c, BIT(21), 1); /* Reg80c[21]=1'b1 from TX Info */ - rtl8188e_PHY_SetBBReg(adapter, 0x864, BIT(5) | BIT(4) | BIT(3), 0); /* Default RX */ - rtl8188e_PHY_SetBBReg(adapter, 0x864, BIT(8) | BIT(7) | BIT(6), 1); /* Optional RX */ - - /* Enter Training state */ - rtl8188e_PHY_SetBBReg(adapter, 0x864, BIT(2) | BIT(1) | BIT(0), 1); - rtl8188e_PHY_SetBBReg(adapter, 0xc50, BIT(7), 1); /* RegC50[7]=1'b1 enable HW AntDiv */ -} - -void ODM_AntennaDiversityInit_88E(struct odm_dm_struct *dm_odm) -{ - 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; - struct adapter *adapter = dm_odm->Adapter; - 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) { - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), DefaultAnt); /* Default RX */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(8) | BIT(7) | BIT(6), OptionalAnt); /* Optional RX */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_ANTSEL_CTRL_11N, BIT(14) | BIT(13) | BIT(12), DefaultAnt); /* Default TX */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RESP_TX_11N, BIT(6) | BIT(7), DefaultAnt); /* Resp Tx */ - } else if (dm_odm->AntDivType == CGCS_RX_HW_ANTDIV) { - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_RX_ANT_CTRL_11N, BIT(5) | BIT(4) | BIT(3), DefaultAnt); /* Default RX */ - rtl8188e_PHY_SetBBReg(adapter, 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 Calculate 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 = max(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 = min(Main_RSSI, Aux_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; - struct adapter *adapter = dm_odm->Adapter; - - if (!(dm_odm->SupportAbility & ODM_BB_ANT_DIV)) - return; - if (!dm_odm->bLinked) { - if (dm_fat_tbl->bBecomeLinked) { - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_IGI_A_11N, BIT(7), 0); /* RegC50[7]=1'b1 enable HW AntDiv */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_ANTDIV_PARA1_11N, BIT(15), 0); /* Enable CCK AntDiv */ - if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) - rtl8188e_PHY_SetBBReg(adapter, 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 */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_IGI_A_11N, BIT(7), 1); /* RegC50[7]=1'b1 enable HW AntDiv */ - rtl8188e_PHY_SetBBReg(adapter, ODM_REG_CCK_ANTDIV_PARA1_11N, BIT(15), 1); /* Enable CCK AntDiv */ - if (dm_odm->AntDivType == CG_TRX_HW_ANTDIV) - rtl8188e_PHY_SetBBReg(adapter, 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); -} diff --git a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c b/drivers/staging/r8188eu/hal/rtl8188e_cmd.c deleted file mode 100644 index 788904d4655c..000000000000 --- a/drivers/staging/r8188eu/hal/rtl8188e_cmd.c +++ /dev/null @@ -1,694 +0,0 @@ -// 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/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, reg; - int retry_cnts = 100; - int res; - - u8 valid; - - do { - res = rtw_read8(adapt, REG_HMETFR, ®); - if (res) - continue; - - valid = reg & 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 = &adapt->haldata; - u8 cmd_idx, ext_cmd_len; - u32 h2c_cmd = 0; - u32 h2c_cmd_ex = 0; - - if (!adapt->bFWReady) - return _FAIL; - - if (!pCmdBuffer || CmdLen > RTL88E_MAX_CMD_LEN || adapt->bSurpriseRemoved) - return _FAIL; - - /* 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)) - return _FAIL; - - *(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--)); - - return _SUCCESS; -} - -u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask) -{ - u8 buf[3]; - u8 res = _SUCCESS; - struct hal_data_8188e *haldata = &adapt->haldata; - - 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 { - 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 = &pAdapter->haldata; - - 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 */ - - 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, u16 mstatus_rpt) -{ - __le16 mst_rpt = cpu_to_le16(mstatus_rpt); - - 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 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; - - pwlanhdr = (struct ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(fctrl) = 0; - - eth_broadcast_addr(pwlanhdr->addr1); - 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 ieee80211_hdr_3addr); - pktlen = sizeof(struct 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) - return; - - *pLength = pktlen; -} - -static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength) -{ - struct ieee80211_hdr *pwlanhdr; - struct mlme_ext_priv *pmlmeext = &adapt->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; - __le16 *fctrl; - - pwlanhdr = (struct ieee80211_hdr *)pframe; - - /* Frame control. */ - fctrl = &pwlanhdr->frame_control; - *(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 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 ieee80211_hdr *)pframe; - - fctrl = &pwlanhdr->frame_control; - *(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 ieee80211_qos_hdr *pwlanqoshdr; - - SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); - - pwlanqoshdr = (struct ieee80211_qos_hdr *)pframe; - SetPriority(&pwlanqoshdr->qos_ctrl, AC); - SetEOSP(&pwlanqoshdr->qos_ctrl, bEosp); - - pktlen = sizeof(struct ieee80211_qos_hdr); - } else { - SetFrameSubType(pframe, WIFI_DATA_NULL); - - pktlen = sizeof(struct ieee80211_qos_hdr); - } - - *pLength = pktlen; -} - -static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u8 *StaAddr, bool bHideSSID) -{ - struct 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 ieee80211_hdr *)pframe; - - mac = myid(&adapt->eeprompriv); - bssid = cur_network->MacAddress; - - fctrl = &pwlanhdr->frame_control; - *(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 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 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; - - ReservedPagePacket = kzalloc(1000, GFP_KERNEL); - if (!ReservedPagePacket) - return; - - 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; - - 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); - - rtl8188eu_mgnt_xmit(adapt, pmgntframe); - - 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 = &adapt->haldata; - 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; - u8 reg; - int res; - - 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. */ - res = rtw_read8(adapt, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(adapt, REG_BCN_CTRL, reg & (~BIT(3))); - - res = rtw_read8(adapt, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(adapt, REG_BCN_CTRL, reg | BIT(4)); - - if (haldata->RegFwHwTxQCtrl & BIT(6)) - 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_bit(adapt); - DLBcnCount = 0; - poll = 0; - do { - /* download rsvd page. */ - SetFwRsvdPagePkt(adapt, false); - DLBcnCount++; - do { - yield(); - /* mdelay(10); */ - /* check rsvd page download OK. */ - bcn_valid = get_beacon_valid_bit(adapt); - poll++; - } while (!bcn_valid && (poll % 10) != 0 && !adapt->bSurpriseRemoved && !adapt->bDriverStopped); - } while (!bcn_valid && DLBcnCount <= 100 && !adapt->bSurpriseRemoved && !adapt->bDriverStopped); - - /* */ - /* 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 */ - res = rtw_read8(adapt, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(adapt, REG_BCN_CTRL, reg | BIT(3)); - - res = rtw_read8(adapt, REG_BCN_CTRL, ®); - if (res) - return; - - rtw_write8(adapt, REG_BCN_CTRL, reg & (~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) - clear_beacon_valid_bit(adapt); - - /* 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) -{ - struct hal_data_8188e *haldata = &adapt->haldata; - 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: - memset(p2p_ps_offload, 0, 1); - break; - case P2P_PS_ENABLE: - /* 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: - p2p_ps_offload->discovery = 1; - break; - case P2P_PS_SCAN_DONE: - 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); -} diff --git a/drivers/staging/r8188eu/hal/rtl8188e_dm.c b/drivers/staging/r8188eu/hal/rtl8188e_dm.c deleted file mode 100644 index 0399872c4546..000000000000 --- a/drivers/staging/r8188eu/hal/rtl8188e_dm.c +++ /dev/null @@ -1,146 +0,0 @@ -// 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" - -/* Initialize GPIO setting registers */ -static void dm_InitGPIOSetting(struct adapter *Adapter) -{ - u8 tmp1byte; - int res; - - res = rtw_read8(Adapter, REG_GPIO_MUXCFG, &tmp1byte); - if (res) - return; - - tmp1byte &= (GPIOSEL_GPIO | ~GPIOSEL_ENBT); - - rtw_write8(Adapter, REG_GPIO_MUXCFG, tmp1byte); -} - -/* */ -/* functions */ -/* */ -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 = &Adapter->haldata; - struct odm_dm_struct *dm_odm = &hal_data->odmpriv; - struct dm_priv *pdmpriv = &hal_data->dmpriv; - int i; - - pdmpriv->InitODMFlag = ODM_BB_RSSI_MONITOR; - if (hal_data->AntDivCfg) - pdmpriv->InitODMFlag |= ODM_BB_ANT_DIV; - - dm_odm->SupportAbility = pdmpriv->InitODMFlag; - - dm_odm->pWirelessMode = &pmlmeext->cur_wireless_mode; - dm_odm->pSecChOffset = &hal_data->nCur40MhzPrimeSC; - dm_odm->pBandWidth = &hal_data->CurrentChannelBW; - dm_odm->pChannel = &hal_data->CurrentChannel; - dm_odm->pbScanInProcess = &pmlmepriv->bScanInProcess; - dm_odm->pbPowerSaving = &pwrctrlpriv->bpower_saving; - - ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType); - - for (i = 0; i < NUM_STA; i++) - dm_odm->pODM_StaInfo[i] = NULL; -} - -void rtl8188e_InitHalDm(struct adapter *Adapter) -{ - struct hal_data_8188e *hal_data = &Adapter->haldata; - struct odm_dm_struct *dm_odm = &hal_data->odmpriv; - - dm_InitGPIOSetting(Adapter); - Update_ODM_ComInfo_88E(Adapter); - ODM_DMInit(dm_odm); -} - -void rtl8188e_HalDmWatchDog(struct adapter *Adapter) -{ - u8 hw_init_completed = Adapter->hw_init_completed; - struct hal_data_8188e *hal_data = &Adapter->haldata; - struct mlme_priv *pmlmepriv = &Adapter->mlmepriv; - u8 bLinked = false; - - if (!hw_init_completed) - return; - - 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; - } - - hal_data->odmpriv.bLinked = bLinked; - ODM_DMWatchdog(&hal_data->odmpriv); -} - -void rtl8188e_init_dm_priv(struct adapter *Adapter) -{ - struct hal_data_8188e *hal_data = &Adapter->haldata; - struct dm_priv *pdmpriv = &hal_data->dmpriv; - struct odm_dm_struct *dm_odm = &hal_data->odmpriv; - - memset(pdmpriv, 0, sizeof(struct dm_priv)); - memset(dm_odm, 0, sizeof(*dm_odm)); - - dm_odm->Adapter = Adapter; - ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_MP_TEST_CHIP, IS_NORMAL_CHIP(hal_data->VersionID)); - ODM_CmnInfoInit(dm_odm, ODM_CMNINFO_RF_ANTENNA_TYPE, hal_data->TRxAntDivType); -} - -/* 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 = &Adapter->haldata; - - 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 = &Adapter->haldata; - 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 deleted file mode 100644 index 73855bca76fe..000000000000 --- a/drivers/staging/r8188eu/hal/rtl8188e_hal_init.c +++ /dev/null @@ -1,922 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright(c) 2007 - 2011 Realtek Corporation. */ - -#define _HAL_INIT_C_ - -#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" -#include "../include/rtw_fw.h" - -static void iol_mode_enable(struct adapter *padapter, u8 enable) -{ - u8 reg_0xf0 = 0; - int res; - - if (enable) { - /* Enable initial offload */ - res = rtw_read8(padapter, REG_SYS_CFG, ®_0xf0); - if (res) - return; - - rtw_write8(padapter, REG_SYS_CFG, reg_0xf0 | SW_OFFLOAD_EN); - - if (!padapter->bFWReady) - rtw_reset_8051(padapter); - - } else { - /* disable initial offload */ - res = rtw_read8(padapter, REG_SYS_CFG, ®_0xf0); - if (res) - return; - - 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; - unsigned long timeout; - int res; - - control = control & 0x0f; - res = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88); - if (res) - return _FAIL; - - rtw_write8(padapter, REG_HMEBOX_E0, reg_0x88 | control); - - timeout = jiffies + msecs_to_jiffies(1000); - - do { - res = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88); - if (res) - continue; - - if (!(reg_0x88 & control)) - break; - - } while (time_before(jiffies, timeout)); - - res = rtw_read8(padapter, REG_HMEBOX_E0, ®_0x88); - if (res) - return _FAIL; - - 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 _size_byte, u8 *pbuf) -{ - u8 *efuseTbl = NULL; - u8 rtemp8; - u16 eFuse_Addr = 0; - u8 offset, wren; - u16 i, j; - u16 **eFuseWord = NULL; - u8 u1temp = 0; - - efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL); - if (!efuseTbl) - goto exit; - - eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16)); - if (!eFuseWord) - 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_Addr++; - } else { - 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++; - eFuseWord[offset][i] = (rtemp8 & 0xff); - if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) - break; - rtemp8 = *(phymap + eFuse_Addr); - eFuse_Addr++; - 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_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!!! */ - /* */ - memcpy(pbuf, efuseTbl, _size_byte); - -exit: - kfree(efuseTbl); - kfree(eFuseWord); -} - -/* FIXME: add error handling in callers */ -static int efuse_read_phymap_from_txpktbuf( - struct adapter *adapter, - u8 *content, /* buffer to store efuse physical map */ - u16 *size /* for efuse content: the max byte to read. will update to byte read */ - ) -{ - unsigned long timeout; - __le32 lo32 = 0, hi32 = 0; - u16 len = 0, count = 0; - int i = 0, res; - u16 limit = *size; - u8 reg; - u8 *pos = content; - u32 reg32; - - rtw_write8(adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); - - while (1) { - rtw_write16(adapter, REG_PKTBUF_DBG_ADDR, i); - - rtw_write8(adapter, REG_TXPKTBUF_DBG, 0); - timeout = jiffies + msecs_to_jiffies(1000); - do { - res = rtw_read8(adapter, REG_TXPKTBUF_DBG, ®); - if (res) - continue; - - if (reg) - break; - - msleep(1); - } while (time_before(jiffies, timeout)); - - /* data from EEPROM needs to be in LE */ - res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_L, ®32); - if (res) - return res; - - lo32 = cpu_to_le32(reg32); - - res = rtw_read32(adapter, REG_PKTBUF_DBG_DATA_H, ®32); - if (res) - return res; - - hi32 = cpu_to_le32(reg32); - - if (i == 0) { - u16 reg; - - /* 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. - */ - res = rtw_read16(adapter, REG_PKTBUF_DBG_DATA_L, ®); - if (res) - return res; - - len = le32_to_cpu(lo32) & 0x0000ffff; - - limit = (len - 2 < limit) ? len - 2 : limit; - - 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); - *size = count; - - return 0; -} - -static s32 iol_read_efuse(struct adapter *padapter, u16 size_byte, u8 *logical_map) -{ - s32 status = _FAIL; - u8 physical_map[512]; - u16 size = 512; - - rtw_write8(padapter, REG_TDECTRL + 1, 0); - 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, physical_map, &size); - efuse_phymap_to_logical(physical_map, size_byte, logical_map); - return status; -} - -s32 rtl8188e_iol_efuse_patch(struct adapter *padapter) -{ - s32 result = _SUCCESS; - - 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; -} - -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 rtl8188e_EfusePowerSwitch(struct adapter *pAdapter, u8 PwrState) -{ - u16 tmpV16; - int res; - - if (PwrState) { - rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); - - /* 1.2V Power: From VDDON with Power Cut(0x0000h[15]), default valid */ - res = rtw_read16(pAdapter, REG_SYS_ISO_CTRL, &tmpV16); - if (res) - return; - - if (!(tmpV16 & PWC_EV12V)) { - tmpV16 |= PWC_EV12V; - rtw_write16(pAdapter, REG_SYS_ISO_CTRL, tmpV16); - } - /* Reset: 0x0000h[28], default valid */ - res = rtw_read16(pAdapter, REG_SYS_FUNC_EN, &tmpV16); - if (res) - return; - - 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 */ - res = rtw_read16(pAdapter, REG_SYS_CLKR, &tmpV16); - if (res) - return; - - if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) { - tmpV16 |= (LOADER_CLK_EN | ANA8M); - rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16); - } - } else { - rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); - } -} - -static void Hal_EfuseReadEFuse88E(struct adapter *Adapter, - u16 _offset, - u16 _size_byte, - u8 *pbuf) -{ - 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 */ - goto exit; - - efuseTbl = kzalloc(EFUSE_MAP_LEN_88E, GFP_KERNEL); - if (!efuseTbl) - goto exit; - - eFuseWord = rtw_malloc2d(EFUSE_MAX_SECTION_88E, EFUSE_MAX_WORD_UNIT, sizeof(u16)); - if (!eFuseWord) - 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); - if (*rtemp8 != 0xFF) { - efuse_utilized++; - eFuse_Addr++; - } else { - 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); - - if ((*rtemp8 & 0x0F) == 0x0F) { - eFuse_Addr++; - ReadEFuseByte(Adapter, eFuse_Addr, rtemp8); - - 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); - eFuse_Addr++; - efuse_utilized++; - eFuseWord[offset][i] = (*rtemp8 & 0xff); - if (eFuse_Addr >= EFUSE_REAL_CONTENT_LEN_88E) - break; - ReadEFuseByte(Adapter, eFuse_Addr, rtemp8); - 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); - - 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]; - -exit: - kfree(efuseTbl); - kfree(eFuseWord); -} - -void rtl8188e_ReadEFuse(struct adapter *Adapter, u16 _size_byte, u8 *pbuf) -{ - int ret = _FAIL; - if (rtw_IOL_applied(Adapter)) { - rtl8188eu_InitPowerOn(Adapter); - - iol_mode_enable(Adapter, 1); - ret = iol_read_efuse(Adapter, _size_byte, pbuf); - iol_mode_enable(Adapter, 0); - - if (_SUCCESS == ret) - return; - } - - Hal_EfuseReadEFuse88E(Adapter, 0, _size_byte, pbuf); -} - -static void dump_chip_info(struct adapter *adapter, struct HAL_VERSION chip_vers) -{ - struct net_device *netdev = adapter->pnetdev; - char *cut = NULL; - char buf[25]; - - switch (chip_vers.CUTVersion) { - case A_CUT_VERSION: - cut = "A_CUT"; - break; - case B_CUT_VERSION: - cut = "B_CUT"; - break; - case C_CUT_VERSION: - cut = "C_CUT"; - break; - case D_CUT_VERSION: - cut = "D_CUT"; - break; - case E_CUT_VERSION: - cut = "E_CUT"; - break; - default: - snprintf(buf, sizeof(buf), "UNKNOWN_CUT(%d)", chip_vers.CUTVersion); - cut = buf; - break; - } - - netdev_dbg(netdev, "Chip Version Info: CHIP_8188E_%s_%s_%s_1T1R_RomVer(%d)\n", - IS_NORMAL_CHIP(chip_vers) ? "Normal_Chip" : "Test_Chip", - IS_CHIP_VENDOR_TSMC(chip_vers) ? "TSMC" : "UMC", - cut, 0); -} - -void rtl8188e_read_chip_version(struct adapter *padapter) -{ - u32 value32; - struct HAL_VERSION ChipVersion; - struct hal_data_8188e *pHalData = &padapter->haldata; - int res; - - res = rtw_read32(padapter, REG_SYS_CFG, &value32); - if (res) - return; - - ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP); - - 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) */ - - dump_chip_info(padapter, ChipVersion); - - pHalData->VersionID = ChipVersion; -} - -void rtl8188e_SetHalODMVar(struct adapter *Adapter, void *pValue1, bool bSet) -{ - struct hal_data_8188e *pHalData = &Adapter->haldata; - struct odm_dm_struct *podmpriv = &pHalData->odmpriv; - struct sta_info *psta = (struct sta_info *)pValue1; - - if (bSet) { - podmpriv->pODM_StaInfo[psta->mac_id] = psta; - ODM_RAInfo_Init(podmpriv, psta->mac_id); - } else { - podmpriv->pODM_StaInfo[psta->mac_id] = NULL; - } -} - -void hal_notch_filter_8188e(struct adapter *adapter, bool enable) -{ - int res; - u8 reg; - - res = rtw_read8(adapter, rOFDM0_RxDSP + 1, ®); - if (res) - return; - - if (enable) - rtw_write8(adapter, rOFDM0_RxDSP + 1, reg | BIT(1)); - else - rtw_write8(adapter, rOFDM0_RxDSP + 1, reg & ~BIT(1)); -} - -/* */ -/* */ -/* LLT R/W/Init function */ -/* */ -/* */ -static s32 _LLTWrite(struct adapter *padapter, u32 address, u32 data) -{ - s32 count; - u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); - u16 LLTReg = REG_LLT_INIT; - int res; - - rtw_write32(padapter, LLTReg, value); - - /* polling */ - for (count = 0; count <= POLLING_LLT_THRESHOLD; count++) { - res = rtw_read32(padapter, LLTReg, &value); - if (res) - continue; - - if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) - break; - } - - return count > POLLING_LLT_THRESHOLD ? _FAIL : _SUCCESS; -} - -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_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo) -{ - struct eeprom_priv *pEEPROM = &padapter->eeprompriv; - struct net_device *netdev = padapter->pnetdev; - 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; - } - - netdev_dbg(netdev, "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.bSupportRemoteWakeup = false; - else - /* hw power down mode selection , 0:rf-off / 1:power down */ - - /* 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; -} - -void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool AutoLoadFail) -{ - struct hal_data_8188e *pHalData = &padapter->haldata; - struct txpowerinfo24g pwrInfo24G; - u8 ch, group; - u8 TxCount; - - Hal_ReadPowerValueFromPROM_8188E(&pwrInfo24G, PROMContent, AutoLoadFail); - - for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { - hal_get_chnl_group_88e(ch, &group); - - pHalData->Index24G_CCK_Base[ch] = pwrInfo24G.IndexCCK_Base[0][group]; - if (ch == 14) - pHalData->Index24G_BW40_Base[ch] = pwrInfo24G.IndexBW40_Base[0][4]; - else - pHalData->Index24G_BW40_Base[ch] = pwrInfo24G.IndexBW40_Base[0][group]; - } - for (TxCount = 0; TxCount < MAX_TX_COUNT; TxCount++) { - pHalData->OFDM_24G_Diff[TxCount] = pwrInfo24G.OFDM_Diff[0][TxCount]; - pHalData->BW20_24G_Diff[TxCount] = pwrInfo24G.BW20_Diff[0][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; - } -} - -void Hal_EfuseParseXtal_8188E(struct adapter *pAdapter, u8 *hwinfo, bool AutoLoadFail) -{ - struct hal_data_8188e *pHalData = &pAdapter->haldata; - - 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; - } -} - -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); -} - -void Hal_ReadAntennaDiversity88E(struct adapter *pAdapter, u8 *PROMContent, bool AutoLoadFail) -{ - struct hal_data_8188e *pHalData = &pAdapter->haldata; - 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; - } -} - -void Hal_ReadThermalMeter_88E(struct adapter *Adapter, u8 *PROMContent, bool AutoloadFail) -{ - struct hal_data_8188e *pHalData = &Adapter->haldata; - - /* 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->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_88E; -} diff --git a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c deleted file mode 100644 index f4edf4a8f5c2..000000000000 --- a/drivers/staging/r8188eu/hal/rtl8188e_phycfg.c +++ /dev/null @@ -1,705 +0,0 @@ -// 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" - -/* */ -/* 1. BB register R/W API */ -/* */ - -/* Get shifted position of the bit mask */ -static u32 phy_calculate_bit_shift(u32 bitmask) -{ - u32 i = ffs(bitmask); - - return i ? i - 1 : 32; -} - -/** -* 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; - int res; - - res = rtw_read32(Adapter, RegAddr, &OriginalValue); - if (res) - return 0; - - BitShift = phy_calculate_bit_shift(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; - int res; - - if (BitMask != bMaskDWord) { /* if not "double word" write */ - res = rtw_read32(Adapter, RegAddr, &OriginalValue); - if (res) - return; - - BitShift = phy_calculate_bit_shift(BitMask); - Data = ((OriginalValue & (~BitMask)) | (Data << BitShift)); - } - - rtw_write32(Adapter, RegAddr, Data); -} - -/* */ -/* 2. RF register R/W API */ -/* */ -/** -* Function: phy_RFSerialRead -* -* Overview: Read register from RF chips -* -* Input: -* struct adapter *Adapter, -* 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, - u32 Offset - ) -{ - u32 retValue = 0; - struct hal_data_8188e *pHalData = &Adapter->haldata; - struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef; - 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 = rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord); - tmplong2 = tmplong; - - tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset << 23) | bLSSIReadEdge; /* T65 RF */ - - rtl8188e_PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong & (~bLSSIReadEdge)); - udelay(10);/* PlatformStallExecution(10); */ - - rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2); - udelay(100);/* PlatformStallExecution(100); */ - - udelay(10);/* PlatformStallExecution(10); */ - - RfPiEnable = (u8)rtl8188e_PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter1, BIT(8)); - - if (RfPiEnable) { /* Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF */ - retValue = rtl8188e_PHY_QueryBBReg(Adapter, pPhyReg->rfLSSIReadBackPi, bLSSIReadBackData); - } else { /* Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF */ - retValue = rtl8188e_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, - u32 Offset, - u32 Data - ) -{ - u32 DataAndAddr = 0; - struct hal_data_8188e *pHalData = &Adapter->haldata; - struct bb_reg_def *pPhyReg = &pHalData->PHYRegDef; - 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 */ - /* */ - rtl8188e_PHY_SetBBReg(Adapter, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); -} - -/** -* Function: PHY_QueryRFReg -* -* Overview: Query "Specific bits" to RF register (page 8~) -* -* Input: -* struct adapter *Adapter, -* 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, u32 RegAddr, u32 BitMask) -{ - u32 Original_Value, Readback_Value, BitShift; - - Original_Value = phy_RFSerialRead(Adapter, RegAddr); - - BitShift = phy_calculate_bit_shift(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, -* 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, - u32 RegAddr, - u32 BitMask, - u32 Data - ) -{ - u32 Original_Value, BitShift; - - /* RF data is 12 bits only */ - if (BitMask != bRFRegOffsetMask) { - Original_Value = phy_RFSerialRead(Adapter, RegAddr); - BitShift = phy_calculate_bit_shift(BitMask); - Data = ((Original_Value & (~BitMask)) | (Data << BitShift)); - } - - phy_RFSerialWrite(Adapter, 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. - * - *---------------------------------------------------------------------------*/ -int PHY_MACConfig8188E(struct adapter *Adapter) -{ - struct hal_data_8188e *pHalData = &Adapter->haldata; - int err; - - /* */ - /* Config MAC */ - /* */ - err = ODM_ReadAndConfig_MAC_REG_8188E(&pHalData->odmpriv); - - /* 2010.07.13 AMPDU aggregation number B */ - rtw_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); - - return err; -} - -/** -* 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 = &Adapter->haldata; - - /* RF Interface Sowrtware Control */ - pHalData->PHYRegDef.rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 LSBs if read 32-bit from 0x870 */ - - /* RF Interface Readback Value */ - pHalData->PHYRegDef.rfintfi = rFPGA0_XAB_RFInterfaceRB; /* 16 LSBs if read 32-bit from 0x8E0 */ - - /* RF Interface Output (and Enable) */ - pHalData->PHYRegDef.rfintfo = rFPGA0_XA_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x860 */ - - /* RF Interface (Output and) Enable */ - pHalData->PHYRegDef.rfintfe = rFPGA0_XA_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ - - /* Addr of LSSI. Write RF register by driver */ - pHalData->PHYRegDef.rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */ - - /* RF parameter */ - pHalData->PHYRegDef.rfLSSI_Select = rFPGA0_XAB_RFParameter; /* BB Band Select */ - - /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ - pHalData->PHYRegDef.rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ - - /* Transceiver A~D HSSI Parameter-1 */ - pHalData->PHYRegDef.rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; /* wire control parameter1 */ - - /* Transceiver A~D HSSI Parameter-2 */ - pHalData->PHYRegDef.rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; /* wire control parameter2 */ - - /* RF switch Control */ - pHalData->PHYRegDef.rfSwitchControl = rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */ - - /* AGC control 1 */ - pHalData->PHYRegDef.rfAGCControl1 = rOFDM0_XAAGCCore1; - - /* AGC control 2 */ - pHalData->PHYRegDef.rfAGCControl2 = rOFDM0_XAAGCCore2; - - /* RX AFE control 1 */ - pHalData->PHYRegDef.rfRxIQImbalance = rOFDM0_XARxIQImbalance; - - /* RX AFE control 1 */ - pHalData->PHYRegDef.rfRxAFE = rOFDM0_XARxAFE; - - /* Tx AFE control 1 */ - pHalData->PHYRegDef.rfTxIQImbalance = rOFDM0_XATxIQImbalance; - - /* Tx AFE control 2 */ - pHalData->PHYRegDef.rfTxAFE = rOFDM0_XATxAFE; - - /* Transceiver LSSI Readback SI mode */ - pHalData->PHYRegDef.rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; - - /* Transceiver LSSI Readback PI mode */ - pHalData->PHYRegDef.rfLSSIReadBackPi = TransceiverA_HSPI_Readback; -} - -void storePwrIndexDiffRateOffset(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data) -{ - struct hal_data_8188e *pHalData = &Adapter->haldata; - - 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; - 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; -} - -static int phy_BB8188E_Config_ParaFile(struct adapter *Adapter) -{ - struct eeprom_priv *pEEPROM = &Adapter->eeprompriv; - struct hal_data_8188e *pHalData = &Adapter->haldata; - int err; - - /* */ - /* 1. Read PHY_REG.TXT BB INIT!! */ - /* We will separate as 88C / 92C according to chip version */ - /* */ - err = ODM_ReadAndConfig_PHY_REG_1T_8188E(&pHalData->odmpriv); - if (err) - return err; - - /* 2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */ - if (!pEEPROM->bautoload_fail_flag) { - pHalData->pwrGroupCnt = 0; - ODM_ReadAndConfig_PHY_REG_PG_8188E(&pHalData->odmpriv); - } - - /* 3. BB AGC table Initialization */ - err = ODM_ReadAndConfig_AGC_TAB_1T_8188E(&pHalData->odmpriv); - if (err) - return err; - - return 0; -} - -int -PHY_BBConfig8188E( - struct adapter *Adapter - ) -{ - struct hal_data_8188e *pHalData = &Adapter->haldata; - u16 RegVal; - u8 CrystalCap; - int err; - - phy_InitBBRFRegisterDefinition(Adapter); - - /* Enable BB and RF */ - err = rtw_read16(Adapter, REG_SYS_FUNC_EN, &RegVal); - if (err) - return err; - - 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 */ - err = phy_BB8188E_Config_ParaFile(Adapter); - - /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */ - CrystalCap = pHalData->CrystalCap & 0x3F; - rtl8188e_PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, 0x7ff800, (CrystalCap | (CrystalCap << 6))); - - return err; -} - -static void getTxPowerIndex88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel, - u8 *ofdmPowerLevel, u8 *BW20PowerLevel, - u8 *BW40PowerLevel) -{ - struct hal_data_8188e *pHalData = &Adapter->haldata; - u8 index = (channel - 1); - - /* 1. CCK */ - cckPowerLevel[RF_PATH_A] = pHalData->Index24G_CCK_Base[index]; - /* 2. OFDM */ - ofdmPowerLevel[RF_PATH_A] = pHalData->Index24G_BW40_Base[index] + - pHalData->OFDM_24G_Diff[RF_PATH_A];