qcacld-3.0: Move sta_info from array based to hash based
Currently in hdd_adapter, the variable sta_info is an array of
hdd_station_info structured indexed by the sta_id. As sta_id is no
longer used this array based implementation becomes unnecessary.
Move the sta_info implementation to a hash table implementation.
Change-Id: I7d6fe04b7e0ab22615d431de9a10a4ad38ed65ba
CRs-Fixed: 2514280
diff --git a/Kbuild b/Kbuild
index 8fa2d1e..cbff722 100644
--- a/Kbuild
+++ b/Kbuild
@@ -77,6 +77,7 @@
$(HDD_SRC_DIR)/wlan_hdd_regulatory.o \
$(HDD_SRC_DIR)/wlan_hdd_scan.o \
$(HDD_SRC_DIR)/wlan_hdd_softap_tx_rx.o \
+ $(HDD_SRC_DIR)/wlan_hdd_sta_info.o \
$(HDD_SRC_DIR)/wlan_hdd_stats.o \
$(HDD_SRC_DIR)/wlan_hdd_trace.o \
$(HDD_SRC_DIR)/wlan_hdd_tx_rx.o \
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h
index b5e0a10..6baab17 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_api.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h
@@ -555,7 +555,7 @@
bool value);
/**
- * wlan_mlme_is_sap_bcast_deauth_enabled() - get the enable/disable value
+ * wlan_mlme_get_sap_bcast_deauth_enabled() - get the enable/disable value
* for broadcast deauth in sap
* @psoc: pointer to psoc object
* @value: Value that needs to get from the caller
@@ -563,8 +563,8 @@
* Return: QDF Status
*/
QDF_STATUS
-wlan_mlme_is_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc,
- bool *value);
+wlan_mlme_get_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc,
+ bool *value);
/**
* wlan_mlme_get_sap_allow_all_channels() - get the value of sap allow all
diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
index 7a070b6..0ed2480 100644
--- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
+++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h
@@ -1421,7 +1421,7 @@
}
/**
- * ucfg_mlme_is_sap_bcast_deauth_enabled() - get the sap bcast deauth
+ * ucfg_mlme_get_sap_bcast_deauth_enabled() - get the sap bcast deauth
* enabled value
* @psoc: pointer to psoc object
* @value: Value that needs to be get from the caller
@@ -1431,10 +1431,10 @@
* Return: QDF Status
*/
static inline QDF_STATUS
-ucfg_mlme_is_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc,
- bool *value)
+ucfg_mlme_get_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc,
+ bool *value)
{
- return wlan_mlme_is_sap_bcast_deauth_enabled(psoc, value);
+ return wlan_mlme_get_sap_bcast_deauth_enabled(psoc, value);
}
/**
diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c
index b9431ee..334074c 100644
--- a/components/mlme/dispatcher/src/wlan_mlme_api.c
+++ b/components/mlme/dispatcher/src/wlan_mlme_api.c
@@ -1716,8 +1716,8 @@
}
QDF_STATUS
-wlan_mlme_is_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc,
- bool *value)
+wlan_mlme_get_sap_bcast_deauth_enabled(struct wlan_objmgr_psoc *psoc,
+ bool *value)
{
struct wlan_mlme_psoc_obj *mlme_obj;
diff --git a/core/hdd/inc/qc_sap_ioctl.h b/core/hdd/inc/qc_sap_ioctl.h
index f5d04b7..7226536 100644
--- a/core/hdd/inc/qc_sap_ioctl.h
+++ b/core/hdd/inc/qc_sap_ioctl.h
@@ -226,7 +226,7 @@
QCSAP_PARAM_CHAN_WIDTH,
QCSAP_PARAM_SET_TXRX_STATS,
QCASAP_SET_11AX_RATE,
- QCASAP_SET_PEER_RATE,
+ QCASAP_SET_PEER_RATE, /* Not Supported */
QCASAP_PARAM_DCM,
QCASAP_PARAM_RANGE_EXT,
QCSAP_SET_DEFAULT_AMPDU,
diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h
index 2aa5bc7..e625240 100644
--- a/core/hdd/inc/wlan_hdd_assoc.h
+++ b/core/hdd/inc/wlan_hdd_assoc.h
@@ -388,8 +388,17 @@
const uint8_t numBss);
#endif /* FEATURE_WLAN_ESE */
+/**
+ * hdd_change_peer_state() - change peer state
+ * @adapter: HDD adapter
+ * @peer_mac_addr: Peer MAC address
+ * @sta_state: peer state
+ * @roam_synch_in_progress: roam synch in progress
+ *
+ * Return: QDF status
+ */
QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter,
- uint8_t sta_id,
+ uint8_t *peer_mac_addr,
enum ol_txrx_peer_state sta_state,
bool roam_synch_in_progress);
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h
index da5af95..8895830 100644
--- a/core/hdd/inc/wlan_hdd_main.h
+++ b/core/hdd/inc/wlan_hdd_main.h
@@ -112,6 +112,8 @@
#include "qdf_periodic_work.h"
#endif
+#include "wlan_hdd_sta_info.h"
+
/*
* Preprocessor definitions and constants
*/
@@ -881,135 +883,6 @@
};
/**
- * struct dhcp_phase - Per Peer DHCP Phases
- * @DHCP_PHASE_ACK: upon receiving DHCP_ACK/NAK message in REQUEST phase or
- * DHCP_DELINE message in OFFER phase
- * @DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase
- * @DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase
- * @DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase or
- * ACK phase (Renewal process)
- */
-enum dhcp_phase {
- DHCP_PHASE_ACK,
- DHCP_PHASE_DISCOVER,
- DHCP_PHASE_OFFER,
- DHCP_PHASE_REQUEST
-};
-
-/**
- * struct dhcp_nego_status - Per Peer DHCP Negotiation Status
- * @DHCP_NEGO_STOP: when the peer is in ACK phase or client disassociated
- * @DHCP_NEGO_IN_PROGRESS: when the peer is in DISCOVER or REQUEST
- * (Renewal process) phase
- */
-enum dhcp_nego_status {
- DHCP_NEGO_STOP,
- DHCP_NEGO_IN_PROGRESS
-};
-
-/**
- * struct hdd_station_info - Per station structure kept in HDD for
- * multiple station support for SoftAP
- * @in_use: Is the station entry in use?
- * @sta_id: Station ID reported back from HAL (through SAP).
- * Broadcast uses station ID zero by default.
- * @sta_type: Type of station i.e. p2p client or infrastructure station
- * @sta_mac: MAC address of the station
- * @peer_state: Current Station state so HDD knows how to deal with packet
- * queue. Most recent states used to change TLSHIM STA state.
- * @is_qos_enabled: Track QoS status of station
- * @is_deauth_in_progress: The station entry for which Deauth is in progress
- * @nss: Number of spatial streams supported
- * @rate_flags: Rate Flags for this connection
- * @ecsa_capable: Extended CSA capabilities
- * @max_phy_rate: Calcuated maximum phy rate based on mode, nss, mcs etc.
- * @tx_packets: Packets send to current station
- * @tx_bytes: Bytes send to current station
- * @rx_packets: Packets received from current station
- * @rx_bytes: Bytes received from current station
- * @last_tx_rx_ts: Last tx/rx timestamp with current station
- * @assoc_ts: Current station association timestamp
- * @tx_rate: Tx rate with current station reported from F/W
- * @rx_rate: Rx rate with current station reported from F/W
- * @ampdu: Ampdu enable or not of the station
- * @sgi_enable: Short GI enable or not of the station
- * @tx_stbc: Tx Space-time block coding enable/disable
- * @rx_stbc: Rx Space-time block coding enable/disable
- * @ch_width: Channel Width of the connection
- * @mode: Mode of the connection
- * @max_supp_idx: Max supported rate index of the station
- * @max_ext_idx: Max extended supported rate index of the station
- * @max_mcs_idx: Max supported mcs index of the station
- * @rx_mcs_map: VHT Rx mcs map
- * @tx_mcs_map: VHT Tx mcs map
- * @freq : Frequency of the current station
- * @dot11_mode: 802.11 Mode of the connection
- * @ht_present: HT caps present or not in the current station
- * @vht_present: VHT caps present or not in the current station
- * @ht_caps: HT capabilities of current station
- * @vht_caps: VHT capabilities of current station
- * @reason_code: Disconnection reason code for current station
- * @rssi: RSSI of the current station reported from F/W
- * @capability: Capability information of current station
- * @support_mode: Max supported mode of a station currently
- * connected to sap
- * @rx_retry_cnt: Number of rx retries received from current station
- * Currently this feature is not supported from FW
- * @rx_mc_bc_cnt: Multicast broadcast packet count received from
- * current station
- * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt
- * feature or not, if first bit is 1 it indicates that FW supports this
- * feature, if it is 0 it indicates FW doesn't support this feature
- */
-struct hdd_station_info {
- bool in_use;
- uint8_t sta_id;
- eStationType sta_type;
- struct qdf_mac_addr sta_mac;
- enum ol_txrx_peer_state peer_state;
- bool is_qos_enabled;
- bool is_deauth_in_progress;
- uint8_t nss;
- uint32_t rate_flags;
- uint8_t ecsa_capable;
- uint32_t max_phy_rate;
- uint32_t tx_packets;
- uint64_t tx_bytes;
- uint32_t rx_packets;
- uint64_t rx_bytes;
- qdf_time_t last_tx_rx_ts;
- qdf_time_t assoc_ts;
- qdf_time_t disassoc_ts;
- uint32_t tx_rate;
- uint32_t rx_rate;
- bool ampdu;
- bool sgi_enable;
- bool tx_stbc;
- bool rx_stbc;
- tSirMacHTChannelWidth ch_width;
- uint8_t mode;
- uint8_t max_supp_idx;
- uint8_t max_ext_idx;
- uint8_t max_mcs_idx;
- uint8_t rx_mcs_map;
- uint8_t tx_mcs_map;
- uint32_t freq;
- uint8_t dot11_mode;
- bool ht_present;
- bool vht_present;
- struct ieee80211_ht_cap ht_caps;
- struct ieee80211_vht_cap vht_caps;
- uint32_t reason_code;
- int8_t rssi;
- enum dhcp_phase dhcp_phase;
- enum dhcp_nego_status dhcp_nego_status;
- uint16_t capability;
- uint8_t support_mode;
- uint32_t rx_retry_cnt;
- uint32_t rx_mc_bc_cnt;
-};
-
-/**
* struct hdd_ap_ctx - SAP/P2PGO specific information
* @hostapd_state: state control information
* @dfs_cac_block_tx: Is data tramsmission blocked due to DFS CAC?
@@ -1264,10 +1137,14 @@
/** Multiple station supports */
/** Per-station structure */
- spinlock_t sta_info_lock; /* To protect access to station Info */
+
+ /* TODO: Will be removed as a part of next phase of clean up */
struct hdd_station_info sta_info[WLAN_MAX_STA_COUNT];
struct hdd_station_info cache_sta_info[WLAN_MAX_STA_COUNT];
+ /* TODO: _list from name will be removed after clean up */
+ struct hdd_sta_info_obj sta_info_list;
+ struct hdd_sta_info_obj cache_sta_info_list;
#ifdef FEATURE_WLAN_WAPI
struct hdd_wapi_info wapi_info;
diff --git a/core/hdd/inc/wlan_hdd_softap_tx_rx.h b/core/hdd/inc/wlan_hdd_softap_tx_rx.h
index c110a7a..39b05c6 100644
--- a/core/hdd/inc/wlan_hdd_softap_tx_rx.h
+++ b/core/hdd/inc/wlan_hdd_softap_tx_rx.h
@@ -70,10 +70,9 @@
* hdd_softap_init_tx_rx() - Initialize Tx/Rx module
* @adapter: pointer to adapter context
*
- * Return: QDF_STATUS_E_FAILURE if any errors encountered,
- * QDF_STATUS_SUCCESS otherwise
+ * Return: None
*/
-QDF_STATUS hdd_softap_init_tx_rx(struct hdd_adapter *adapter);
+void hdd_softap_init_tx_rx(struct hdd_adapter *adapter);
/**
* hdd_softap_deinit_tx_rx() - Deinitialize Tx/Rx module
@@ -87,28 +86,15 @@
/**
* hdd_softap_init_tx_rx_sta() - Initialize Tx/Rx for a softap station
* @adapter: pointer to adapter context
- * @sta_id: Station ID to initialize
* @sta_mac: pointer to the MAC address of the station
*
* Return: QDF_STATUS_E_FAILURE if any errors encountered,
* QDF_STATUS_SUCCESS otherwise
*/
QDF_STATUS hdd_softap_init_tx_rx_sta(struct hdd_adapter *adapter,
- uint8_t sta_id,
struct qdf_mac_addr *sta_mac);
/**
- * hdd_softap_deinit_tx_rx_sta() - Deinitialize Tx/Rx for a softap station
- * @adapter: pointer to adapter context
- * @sta_id: Station ID to deinitialize
- *
- * Return: QDF_STATUS_E_FAILURE if any errors encountered,
- * QDF_STATUS_SUCCESS otherwise
- */
-QDF_STATUS hdd_softap_deinit_tx_rx_sta(struct hdd_adapter *adapter,
- uint8_t sta_id);
-
-/**
* hdd_softap_rx_packet_cbk() - Receive packet handler
* @adapter_context: pointer to HDD adapter
* @rx_buf: pointer to rx qdf_nbuf chain
@@ -125,14 +111,12 @@
/**
* hdd_softap_deregister_sta() - Deregister a STA with the Data Path
* @adapter: pointer to adapter context
- * @sta_id: Station ID to deregister
- * @mac_addr: Peer mac address
+ * @sta_info: pointer to HDD station info structure
*
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
*/
QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter,
- uint8_t sta_id,
- struct qdf_mac_addr mac_addr);
+ struct hdd_station_info *sta_info);
/**
* hdd_softap_register_sta() - Register a SoftAP STA
@@ -182,20 +166,6 @@
struct qdf_mac_addr *sta_mac,
enum ol_txrx_peer_state state);
-/**
- * hdd_softap_get_sta_id() - Find station ID from MAC address
- * @adapter: pointer to adapter context
- * @sta_mac: MAC address of the destination
- * @sta_id: Station ID associated with the MAC address
- *
- * Return: QDF_STATUS_SUCCESS if a match was found, in which case
- * @sta_id is populated, QDF_STATUS_E_FAILURE if a match is
- * not found
- */
-QDF_STATUS hdd_softap_get_sta_id(struct hdd_adapter *adapter,
- struct qdf_mac_addr *sta_mac,
- uint8_t *sta_id);
-
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
/**
* hdd_softap_tx_resume_timer_expired_handler() - TX Q resume timer handler
@@ -235,20 +205,39 @@
/**
* hdd_post_dhcp_ind() - Send DHCP START/STOP indication to FW
* @adapter: pointer to hdd adapter
- * @sta_id: peer station ID
+ * @mac_addr: mac address
* @type: WMA message type
*
* Return: error number
*/
int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
- uint8_t sta_id, uint16_t type);
+ uint8_t *mac_addr, uint16_t type);
/**
- * hdd_softap_inspect_dhcp_packet() - Inspect DHCP packet
+ * hdd_softap_inspect_dhcp_packet() - Inspect DHCP packet
* @adapter: pointer to hdd adapter
* @skb: pointer to OS packet (sk_buff)
* @dir: direction
*
+ * Inspect the Tx/Rx frame, and send DHCP START/STOP notification to the FW
+ * through WMI message, during DHCP based IP address acquisition phase.
+ *
+ * - Send DHCP_START notification to FW when SAP gets DHCP Discovery
+ * - Send DHCP_STOP notification to FW when SAP sends DHCP ACK/NAK
+ *
+ * DHCP subtypes are determined by a status octet in the DHCP Message type
+ * option (option code 53 (0x35)).
+ *
+ * Each peer will be in one of 4 DHCP phases, starts from QDF_DHCP_PHASE_ACK,
+ * and transitioned per DHCP message type as it arrives.
+ *
+ * - QDF_DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase
+ * - QDF_DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase
+ * - QDF_DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase
+ * or ACK phase (Renewal process)
+ * - QDF_DHCP_PHASE_ACK : upon receiving DHCP_ACK/NAK message in REQUEST phase
+ * or DHCP_DELINE message in OFFER phase
+ *
* Return: error number
*/
int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
@@ -257,7 +246,7 @@
#else
static inline
int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
- uint8_t sta_id, uint16_t type)
+ uint8_t *mac_addr, uint16_t type)
{
return 0;
}
diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c
index 744fcad..fd810be 100644
--- a/core/hdd/src/wlan_hdd_assoc.c
+++ b/core/hdd/src/wlan_hdd_assoc.c
@@ -69,6 +69,7 @@
#include <wlan_cfg80211_crypto.h>
#include <wlan_crypto_global_api.h>
#include "wlan_blm_ucfg_api.h"
+#include "wlan_hdd_sta_info.h"
/* These are needed to recognize WPA and RSN suite types */
#define HDD_WPA_OUI_SIZE 4
@@ -1935,47 +1936,29 @@
complete(&adapter->sta_authorized_event);
}
-/**
- * hdd_change_peer_state() - change peer state
- * @adapter: HDD adapter
- * @sta_state: peer state
- * @roam_synch_in_progress: roam synch in progress
- *
- * Return: QDF status
- */
QDF_STATUS hdd_change_peer_state(struct hdd_adapter *adapter,
- uint8_t sta_id,
+ uint8_t *peer_mac,
enum ol_txrx_peer_state sta_state,
bool roam_synch_in_progress)
{
QDF_STATUS err;
- uint8_t *peer_mac_addr;
void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
void *soc = cds_get_context(QDF_MODULE_ID_SOC);
void *peer;
+ /* Will be removed as a part of clean up */
+ uint8_t sta_id;
if (!pdev) {
hdd_err("Failed to get txrx context");
return QDF_STATUS_E_FAULT;
}
- if (sta_id >= WLAN_MAX_STA_COUNT) {
- hdd_err("Invalid sta id: %d", sta_id);
- return QDF_STATUS_E_INVAL;
- }
-
- peer = cdp_peer_find_by_local_id(soc,
- (struct cdp_pdev *)pdev, sta_id);
+ peer = cdp_peer_find_by_addr(soc, (struct cdp_pdev *)pdev,
+ peer_mac, &sta_id);
if (!peer)
return QDF_STATUS_E_FAULT;
- peer_mac_addr = cdp_peer_get_peer_mac_addr(soc, peer);
- if (!peer_mac_addr) {
- hdd_err("peer mac addr is NULL");
- return QDF_STATUS_E_FAULT;
- }
-
- err = cdp_peer_state_update(soc, pdev, peer_mac_addr, sta_state);
+ err = cdp_peer_state_update(soc, pdev, peer_mac, sta_state);
if (err != QDF_STATUS_SUCCESS) {
hdd_err("peer state update failed");
return QDF_STATUS_E_FAULT;
@@ -1994,7 +1977,8 @@
INIT_COMPLETION(adapter->sta_authorized_event);
#endif
- err = sme_set_peer_authorized(peer_mac_addr,
+ err = sme_set_peer_authorized(
+ peer_mac,
hdd_set_peer_authorized_event,
adapter->vdev_id);
if (err != QDF_STATUS_SUCCESS) {
@@ -2062,6 +2046,32 @@
}
/**
+ * hdd_conn_change_peer_state() - Change the state of the peer
+ * @adapter: pointer to adapter
+ * @roam_info: pointer to roam info
+ * @mac_addr: peer mac address
+ *
+ * Return: QDF_STATUS enumeration
+ */
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static QDF_STATUS hdd_conn_change_peer_state(struct hdd_adapter *adapter,
+ struct csr_roam_info *roam_info,
+ uint8_t *mac_addr)
+{
+ return hdd_change_peer_state(adapter, mac_addr, OL_TXRX_PEER_STATE_AUTH,
+ roam_info->roamSynchInProgress);
+}
+#else
+static QDF_STATUS hdd_conn_change_peer_state(struct hdd_adapter *adapter,
+ struct csr_roam_info *roam_info,
+ uint8_t *mac_addr)
+{
+ return hdd_change_peer_state(adapter, mac_addr, OL_TXRX_PEER_STATE_AUTH,
+ false);
+}
+#endif
+
+/**
* hdd_roam_register_sta() - register station
* @adapter: pointer to adapter
* @roam_info: pointer to roam info
@@ -2153,30 +2163,20 @@
* Connections that do not need Upper layer auth, transition
* TLSHIM directly to 'Authenticated' state
*/
- qdf_status =
- hdd_change_peer_state(adapter, txrx_desc.sta_id,
- OL_TXRX_PEER_STATE_AUTH,
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
- roam_info->roamSynchInProgress
-#else
- false
-#endif
- );
+ qdf_status = hdd_conn_change_peer_state(
+ adapter, roam_info,
+ txrx_desc.peer_addr.bytes);
hdd_conn_set_authenticated(adapter, true);
hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, true);
} else {
hdd_debug("ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
sta_ctx->conn_info.sta_id[0]);
- qdf_status =
- hdd_change_peer_state(adapter, txrx_desc.sta_id,
- OL_TXRX_PEER_STATE_CONN,
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
- roam_info->roamSynchInProgress
-#else
- false
-#endif
- );
+
+ qdf_status = hdd_conn_change_peer_state(
+ adapter, roam_info,
+ txrx_desc.peer_addr.bytes);
+
hdd_conn_set_authenticated(adapter, false);
hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, false);
}
@@ -2448,38 +2448,6 @@
#ifdef QCA_IBSS_SUPPORT
/**
- * hdd_get_ibss_peer_sta_id() - get sta id for IBSS peer
- * @hddstactx: pointer to HDD sta context
- * @roaminfo: pointer to roaminfo structure
- *
- * This function returns sta_id for IBSS peer. If peer is broadcast
- * MAC address return self sta_id(0) else find the peer sta id of
- * the peer.
- *
- * Return: sta_id (HDD_WLAN_INVALID_STA_ID if peer not found).
- */
-static uint8_t hdd_get_ibss_peer_sta_id(struct hdd_station_ctx *hddstactx,
- struct csr_roam_info *roaminfo)
-{
- uint8_t sta_id = HDD_WLAN_INVALID_STA_ID;
- QDF_STATUS status;
-
- if (qdf_is_macaddr_broadcast(&roaminfo->peerMac)) {
- sta_id = 0;
- } else {
- status = hdd_get_peer_sta_id(hddstactx,
- &roaminfo->peerMac, &sta_id);
- if (status != QDF_STATUS_SUCCESS) {
- hdd_err("Unable to find station ID for "
- QDF_MAC_ADDR_STR,
- QDF_MAC_ADDR_ARRAY(roaminfo->peerMac.bytes));
- }
- }
-
- return sta_id;
-}
-
-/**
* hdd_roam_ibss_indication_handler() - update the status of the IBSS
* @adapter: pointer to adapter
* @roam_info: pointer to roam info
@@ -2694,8 +2662,8 @@
struct csr_roam_info *roaminfo)
{
QDF_STATUS status;
+ uint8_t *mac_addr;
uint32_t timeout, auto_bmps_timer_val;
- uint8_t sta_id = HDD_WLAN_INVALID_STA_ID;
struct hdd_station_ctx *hddstactx =
WLAN_HDD_GET_STATION_CTX_PTR(adapter);
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
@@ -2707,17 +2675,19 @@
(auto_bmps_timer_val * 1000);
if (QDF_IBSS_MODE == adapter->device_mode)
- sta_id = hdd_get_ibss_peer_sta_id(hddstactx, roaminfo);
+ mac_addr = roaminfo->peerMac.bytes;
else
- sta_id = hddstactx->conn_info.sta_id[0];
+ mac_addr = hddstactx->conn_info.bssid.bytes;
- hdd_debug("Changing Peer state to AUTHENTICATED for StaId = %d",
- sta_id);
+ hdd_debug("Changing Peer state to AUTHENTICATED for Sta = "
+ QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac_addr));
/* Connections that do not need Upper layer authentication,
* transition TL to 'Authenticated' state after the keys are set
*/
- status = hdd_change_peer_state(adapter, sta_id, OL_TXRX_PEER_STATE_AUTH,
+
+ status = hdd_change_peer_state(adapter, mac_addr,
+ OL_TXRX_PEER_STATE_AUTH,
hdd_is_roam_sync_in_progress(roaminfo));
hdd_conn_set_authenticated(adapter, true);
hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, true);
@@ -3443,7 +3413,7 @@
if (roam_info->fAuthRequired) {
qdf_status =
hdd_change_peer_state(adapter,
- sta_ctx->conn_info.sta_id[0],
+ roam_info->bssid.bytes,
OL_TXRX_PEER_STATE_CONN,
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
roam_info->roamSynchInProgress
@@ -3460,7 +3430,7 @@
sta_ctx->conn_info.sta_id[0]);
qdf_status =
hdd_change_peer_state(adapter,
- sta_ctx->conn_info.sta_id[0],
+ roam_info->bssid.bytes,
OL_TXRX_PEER_STATE_AUTH,
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
roam_info->roamSynchInProgress
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 46e382d..85638c2 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -142,6 +142,7 @@
#include "wlan_hdd_hw_capability.h"
#include "wlan_hdd_oemdata.h"
#include "os_if_fwol.h"
+#include "wlan_hdd_sta_info.h"
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -9865,9 +9866,9 @@
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_station_ctx *hdd_sta_ctx;
+ struct hdd_station_info *sta_info;
struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
- uint32_t sta_id;
struct sk_buff *reply_skb;
uint32_t rate_flags = 0;
uint8_t nss;
@@ -9925,26 +9926,24 @@
} else if (adapter->device_mode == QDF_P2P_GO_MODE ||
adapter->device_mode == QDF_SAP_MODE) {
- for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
- if (adapter->sta_info[sta_id].in_use &&
- !qdf_is_macaddr_broadcast(
- &adapter->sta_info[sta_id].sta_mac) &&
- !qdf_mem_cmp(
- &adapter->sta_info[sta_id].sta_mac.bytes,
- peer_mac, QDF_MAC_ADDR_SIZE))
- break;
- }
-
- if (WLAN_MAX_STA_COUNT == sta_id) {
- hdd_err("No active peer with mac="QDF_MAC_ADDR_STR,
- QDF_MAC_ADDR_ARRAY(peer_mac));
+ if (QDF_IS_ADDR_BROADCAST(peer_mac)) {
+ hdd_err("Ignore bcast/self sta");
return -EINVAL;
}
- nss = adapter->sta_info[sta_id].nss;
+ sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ peer_mac);
+
+ if (!sta_info) {
+ hdd_err("No active peer with mac = " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(peer_mac));
+ return -EINVAL;
+ }
+
+ nss = sta_info->nss;
freq = cds_chan_to_freq(
(WLAN_HDD_GET_AP_CTX_PTR(adapter))->operating_channel);
- rate_flags = adapter->sta_info[sta_id].rate_flags;
+ rate_flags = sta_info->rate_flags;
} else {
hdd_err("Not Associated! with mac "QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(peer_mac));
@@ -20961,6 +20960,110 @@
}
/**
+ * hdd_softap_deauth_current_sta() - Deauth current sta
+ * @sta_info: pointer to the current station info structure
+ * @adapter: pointer to adapter structure
+ * @hdd_ctx: pointer to hdd context
+ * @hapd_state: pointer to hostapd state structure
+ * @param: pointer to del sta params
+ *
+ * Return: QDF_STATUS on success, corresponding QDF failure status on failure
+ */
+static
+QDF_STATUS hdd_softap_deauth_current_sta(struct hdd_adapter *adapter,
+ struct hdd_station_info *sta_info,
+ struct hdd_hostapd_state *hapd_state,
+ struct csr_del_sta_params *param)
+{
+ qdf_event_t *disassoc_event = &hapd_state->qdf_sta_disassoc_event;
+ struct hdd_context *hdd_ctx;
+ QDF_STATUS qdf_status;
+
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ if (!hdd_ctx) {
+ hdd_err("hdd_ctx is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS)
+ return QDF_STATUS_E_INVAL;
+
+ qdf_event_reset(&hapd_state->qdf_sta_disassoc_event);
+
+ if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac))
+ sme_send_disassoc_req_frame(hdd_ctx->mac_handle,
+ adapter->vdev_id,
+ (uint8_t *)¶m->peerMacAddr,
+ param->reason_code, 0);
+
+ qdf_status = hdd_softap_sta_deauth(adapter, param);
+
+ if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ sta_info->is_deauth_in_progress = true;
+ qdf_status = qdf_wait_for_event_completion(
+ disassoc_event,
+ SME_PEER_DISCONNECT_TIMEOUT);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status))
+ hdd_warn("Deauth time expired");
+ } else {
+ sta_info->is_deauth_in_progress = false;
+ hdd_debug("STA removal failed for ::" QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
+ return QDF_STATUS_E_NOENT;
+ }
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * hdd_softap_deauth_all_sta() - Deauth all sta in the sta list
+ * @hdd_ctx: pointer to hdd context
+ * @adapter: pointer to adapter structure
+ * @hapd_state: pointer to hostapd state structure
+ * @param: pointer to del sta params
+ *
+ * Return: QDF_STATUS on success, corresponding QDF failure status on failure
+ */
+static
+QDF_STATUS hdd_softap_deauth_all_sta(struct hdd_adapter *adapter,
+ struct hdd_hostapd_state *hapd_state,
+ struct csr_del_sta_params *param)
+{
+ uint8_t index = 0;
+ QDF_STATUS status;
+ bool is_sap_bcast_deauth_enabled = false;
+ struct hdd_context *hdd_ctx;
+ struct hdd_station_info *sta_info;
+
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ if (!hdd_ctx) {
+ hdd_err("hdd_ctx is NULL");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ ucfg_mlme_get_sap_bcast_deauth_enabled(hdd_ctx->psoc,
+ &is_sap_bcast_deauth_enabled);
+
+ hdd_debug("sap_bcast_deauth_enabled %d", is_sap_bcast_deauth_enabled);
+
+ if (is_sap_bcast_deauth_enabled)
+ return QDF_STATUS_E_INVAL;
+
+ hdd_for_each_station(adapter->sta_info_list, sta_info, index) {
+ if (!sta_info->is_deauth_in_progress) {
+ hdd_debug("Delete STA with MAC:" QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
+ status =
+ hdd_softap_deauth_current_sta(adapter, sta_info,
+ hapd_state, param);
+ if (QDF_IS_STATUS_ERROR(status))
+ return status;
+ }
+ }
+
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
* __wlan_hdd_cfg80211_del_station() - delete station v2
* @wiphy: Pointer to wiphy
* @dev: Underlying net device
@@ -20975,11 +21078,10 @@
{
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hdd_ctx;
- QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
struct hdd_hostapd_state *hapd_state;
- uint8_t sta_id;
uint8_t *mac;
mac_handle_t mac_handle;
+ struct hdd_station_info *sta_info;
hdd_enter();
@@ -21004,123 +21106,43 @@
mac = (uint8_t *) param->peerMacAddr.bytes;
mac_handle = hdd_ctx->mac_handle;
- if ((QDF_SAP_MODE == adapter->device_mode) ||
- (QDF_P2P_GO_MODE == adapter->device_mode)) {
+ if (QDF_SAP_MODE != adapter->device_mode &&
+ QDF_P2P_GO_MODE != adapter->device_mode)
+ goto fn_end;
- hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
- if (!hapd_state) {
- hdd_err("Hostapd State is Null");
- return 0;
- }
+ hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
+ if (!hapd_state) {
+ hdd_err("Hostapd State is Null");
+ return 0;
+ }
- if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *) mac)) {
- uint16_t i;
+ if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *)mac)) {
+ if (!QDF_IS_STATUS_SUCCESS(hdd_softap_deauth_all_sta(adapter,
+ hapd_state,
+ param)))
+ goto fn_end;
+ } else {
+ sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ mac);
- bool is_sap_bcast_deauth_enabled = false;
-
- ucfg_mlme_is_sap_bcast_deauth_enabled(
- hdd_ctx->psoc,
- &is_sap_bcast_deauth_enabled);
- hdd_debug("is_sap_bcast_deauth_enabled %d",
- is_sap_bcast_deauth_enabled);
-
- if (is_sap_bcast_deauth_enabled)
- goto fn_end;
-
- for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
- if ((adapter->sta_info[i].in_use) &&
- (!adapter->sta_info[i].
- is_deauth_in_progress)) {
- qdf_mem_copy(
- mac,
- adapter->sta_info[i].
- sta_mac.bytes,
- QDF_MAC_ADDR_SIZE);
-
- hdd_debug("Delete STA with MAC::"
- QDF_MAC_ADDR_STR,
- QDF_MAC_ADDR_ARRAY(mac));
-
- if (hdd_ctx->dev_dfs_cac_status ==
- DFS_CAC_IN_PROGRESS)
- goto fn_end;
-
- qdf_event_reset(&hapd_state->qdf_sta_disassoc_event);
- qdf_status =
- hdd_softap_sta_deauth(adapter,
- param);
- if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
- adapter->sta_info[i].
- is_deauth_in_progress = true;
- qdf_status =
- qdf_wait_for_event_completion(
- &hapd_state->
- qdf_sta_disassoc_event,
- SME_PEER_DISCONNECT_TIMEOUT);
- if (!QDF_IS_STATUS_SUCCESS(
- qdf_status))
- hdd_warn("Deauth wait time expired");
- }
- }
- }
- } else {
- qdf_status =
- hdd_softap_get_sta_id(adapter,
- (struct qdf_mac_addr *) mac,
- &sta_id);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- hdd_debug("Skip DEL STA as this is not used::"
- QDF_MAC_ADDR_STR,
- QDF_MAC_ADDR_ARRAY(mac));
- return -ENOENT;
- }
-
- if (adapter->sta_info[sta_id].is_deauth_in_progress ==
- true) {
- hdd_debug("Skip DEL STA as deauth is in progress::"
- QDF_MAC_ADDR_STR,
- QDF_MAC_ADDR_ARRAY(mac));
- return -ENOENT;
- }
-
- adapter->sta_info[sta_id].is_deauth_in_progress = true;
-
- hdd_debug("ucast, Delete STA with MAC:" QDF_MAC_ADDR_STR,
+ if (!sta_info) {
+ hdd_debug("Skip DEL STA as this is not used::"
+ QDF_MAC_ADDR_STR,
QDF_MAC_ADDR_ARRAY(mac));
-
- /* Case: SAP in ACS selected DFS ch and client connected
- * Now Radar detected. Then if random channel is another
- * DFS ch then new CAC is initiated and no TX allowed.
- * So do not send any mgmt frames as it will timeout
- * during CAC.
- */
-
- if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS)
- goto fn_end;
-
- qdf_event_reset(&hapd_state->qdf_sta_disassoc_event);
- sme_send_disassoc_req_frame(mac_handle,
- adapter->vdev_id,
- (uint8_t *)¶m->peerMacAddr,
- param->reason_code, 0);
- qdf_status = hdd_softap_sta_deauth(adapter,
- param);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- adapter->sta_info[sta_id].is_deauth_in_progress =
- false;
- hdd_debug("STA removal failed for ::"
- QDF_MAC_ADDR_STR,
- QDF_MAC_ADDR_ARRAY(mac));
- return -ENOENT;
- }
- qdf_status = qdf_wait_for_event_completion(
- &hapd_state->
- qdf_sta_disassoc_event,
- SME_PEER_DISCONNECT_TIMEOUT);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status))
- hdd_warn("Deauth wait time expired");
-
+ return -ENOENT;
}
+
+ if (sta_info->is_deauth_in_progress) {
+ hdd_debug("Skip DEL STA as deauth is in progress::"
+ QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(mac));
+ return -ENOENT;
+ }
+
+ hdd_debug("ucast, Delete STA with MAC:" QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(mac));
+ hdd_softap_deauth_current_sta(adapter, sta_info, hapd_state,
+ param);
}
fn_end:
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index f8e9f93..b39d622 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -91,6 +91,7 @@
#include "wlan_fwol_ucfg_api.h"
#include "nan_ucfg_api.h"
#include <wlan_reg_services_api.h>
+#include "wlan_hdd_sta_info.h"
#define ACS_SCAN_EXPIRY_TIMEOUT_S 4
@@ -740,19 +741,15 @@
return errno;
}
-static void hdd_clear_sta(struct hdd_adapter *adapter, uint8_t sta_id)
+static void hdd_clear_sta(struct hdd_adapter *adapter,
+ struct hdd_station_info *sta_info)
{
struct hdd_ap_ctx *ap_ctx;
- struct hdd_station_info *sta_info;
struct csr_del_sta_params del_sta_params;
ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
- if (sta_id == ap_ctx->broadcast_sta_id)
- return;
-
- sta_info = &adapter->sta_info[sta_id];
- if (!sta_info->in_use)
+ if (qdf_is_macaddr_broadcast(&sta_info->sta_mac))
return;
wlansap_populate_del_sta_params(sta_info->sta_mac.bytes,
@@ -765,11 +762,14 @@
static void hdd_clear_all_sta(struct hdd_adapter *adapter)
{
- uint8_t sta_id;
+ uint8_t index = 0;
+ struct hdd_station_info *sta_info;
hdd_enter_dev(adapter->dev);
- for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++)
- hdd_clear_sta(adapter, sta_id);
+
+ hdd_for_each_station(adapter->sta_info_list, sta_info, index) {
+ hdd_clear_sta(adapter, sta_info);
+ }
}
static int hdd_stop_bss_link(struct hdd_adapter *adapter)
@@ -1452,7 +1452,8 @@
return;
}
- stainfo = &adapter->sta_info[event->staId];
+ stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ event->staMac.bytes);
if (!stainfo) {
hdd_err("invalid stainfo");
@@ -1748,6 +1749,7 @@
bool legacy_phymode;
tSap_StationDisassocCompleteEvent *disassoc_comp;
struct hdd_station_info *stainfo, *cache_stainfo;
+ uint8_t index = 0;
mac_handle_t mac_handle;
struct sap_config *sap_config;
@@ -2228,7 +2230,14 @@
if (QDF_IS_STATUS_SUCCESS(qdf_status))
hdd_fill_station_info(adapter, event);
- adapter->sta_info[sta_id].ecsa_capable = event->ecsa_capable;
+ stainfo = hdd_get_sta_info_by_mac(
+ &adapter->sta_info_list,
+ (uint8_t *)&wrqu.addr.sa_data);
+
+ if (stainfo)
+ stainfo->ecsa_capable = event->ecsa_capable;
+ else
+ hdd_err("Station not found");
if (ucfg_ipa_is_enabled()) {
status = ucfg_ipa_wlan_evt(hdd_ctx->pdev,
@@ -2339,48 +2348,40 @@
else
hdd_debug(" MAC initiated disassociation");
we_event = IWEVEXPIRED;
- qdf_status =
- hdd_softap_get_sta_id(adapter,
- &sap_event->sapevt.
- sapStationDisassocCompleteEvent.staMac,
- &sta_id);
- if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- hdd_err("Failed to find sta id status: %d", qdf_status);
- return QDF_STATUS_E_FAILURE;
- }
DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
adapter->vdev_id,
QDF_TRACE_DEFAULT_PDEV_ID,
QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
- stainfo = hdd_get_stainfo(adapter->sta_info,
- disassoc_comp->staMac);
- if (stainfo) {
- /* Send DHCP STOP indication to FW */
- stainfo->dhcp_phase = DHCP_PHASE_ACK;
- if (stainfo->dhcp_nego_status ==
- DHCP_NEGO_IN_PROGRESS)
- hdd_post_dhcp_ind(adapter, sta_id,
- WMA_DHCP_STOP_IND);
- stainfo->dhcp_nego_status = DHCP_NEGO_STOP;
+ stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ disassoc_comp->staMac.bytes);
+ if (!stainfo) {
+ hdd_err("Failed to find the right station");
+ return QDF_STATUS_E_INVAL;
}
- /* STA id will be removed as a part of Phase 2 cleanup */
- hdd_softap_deregister_sta(adapter, sta_id,
- disassoc_comp->staMac);
+
+ /* Send DHCP STOP indication to FW */
+ stainfo->dhcp_phase = DHCP_PHASE_ACK;
+ if (stainfo->dhcp_nego_status ==
+ DHCP_NEGO_IN_PROGRESS)
+ hdd_post_dhcp_ind(adapter,
+ disassoc_comp->staMac.bytes,
+ WMA_DHCP_STOP_IND);
+ stainfo->dhcp_nego_status = DHCP_NEGO_STOP;
+
+ hdd_softap_deregister_sta(adapter, stainfo);
ap_ctx->ap_active = false;
- spin_lock_bh(&adapter->sta_info_lock);
- for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
- if (adapter->sta_info[i].in_use
- && i !=
- (WLAN_HDD_GET_AP_CTX_PTR(adapter))->
- broadcast_sta_id) {
+
+ hdd_for_each_station(adapter->sta_info_list, stainfo,
+ index) {
+ if (!qdf_is_macaddr_broadcast(
+ &stainfo->sta_mac)) {
ap_ctx->ap_active = true;
break;
}
}
- spin_unlock_bh(&adapter->sta_info_lock);
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
wlan_hdd_auto_shutdown_enable(hdd_ctx, true);
@@ -3353,10 +3354,12 @@
hdd_register_hostapd_wext(adapter->dev);
/* Initialize the data path module */
- status = hdd_softap_init_tx_rx(adapter);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- hdd_err("hdd_softap_init_tx_rx failed");
- goto error_release_sap_session;
+ hdd_softap_init_tx_rx(adapter);
+
+ status = hdd_sta_info_init(&adapter->sta_info_list);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ hdd_err("sta info init failed");
+ goto error_release_softap_tx_rx;
}
status = hdd_wmm_adapter_init(adapter);
@@ -3394,12 +3397,13 @@
/* rcpi info initialization */
qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
-
hdd_exit();
return status;
error_release_wmm:
+ hdd_sta_info_deinit(&adapter->sta_info_list);
+error_release_softap_tx_rx:
hdd_softap_deinit_tx_rx(adapter);
error_release_sap_session:
hdd_unregister_wext(adapter->dev);
@@ -6590,8 +6594,9 @@
void hdd_sap_indicate_disconnect_for_sta(struct hdd_adapter *adapter)
{
struct sap_event sap_event;
- int sta_id;
+ uint8_t index = 0;
struct sap_context *sap_ctx;
+ struct hdd_station_info *sta_info;
hdd_enter();
@@ -6601,31 +6606,24 @@
return;
}
- for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
- if (adapter->sta_info[sta_id].in_use) {
- hdd_debug("sta_id: %d in_use: %d %pK",
- sta_id, adapter->sta_info[sta_id].in_use,
- adapter);
+ hdd_for_each_station(adapter->sta_info_list, sta_info, index) {
+ hdd_debug("sta_mac: " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
- if (qdf_is_macaddr_broadcast(
- &adapter->sta_info[sta_id].sta_mac))
- continue;
+ if (qdf_is_macaddr_broadcast(&sta_info->sta_mac))
+ continue;
- sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
- qdf_mem_copy(
- &sap_event.sapevt.
- sapStationDisassocCompleteEvent.staMac,
- &adapter->sta_info[sta_id].sta_mac,
- sizeof(struct qdf_mac_addr));
- sap_event.sapevt.sapStationDisassocCompleteEvent.
- reason =
+ sap_event.sapHddEventCode = eSAP_STA_DISASSOC_EVENT;
+
+ qdf_mem_copy(
+ &sap_event.sapevt.sapStationDisassocCompleteEvent.staMac,
+ &sta_info->sta_mac, sizeof(struct qdf_mac_addr));
+
+ sap_event.sapevt.sapStationDisassocCompleteEvent.reason =
eSAP_MAC_INITATED_DISASSOC;
- sap_event.sapevt.sapStationDisassocCompleteEvent.
- status_code =
+ sap_event.sapevt.sapStationDisassocCompleteEvent.status_code =
QDF_STATUS_E_RESOURCES;
- hdd_hostapd_sap_event_cb(&sap_event,
- sap_ctx->user_context);
- }
+ hdd_hostapd_sap_event_cb(&sap_event, sap_ctx->user_context);
}
hdd_exit();
@@ -6634,7 +6632,8 @@
bool hdd_is_peer_associated(struct hdd_adapter *adapter,
struct qdf_mac_addr *mac_addr)
{
- uint32_t cnt;
+ uint8_t index = 0;
+ bool is_associated = false;
struct hdd_station_info *sta_info;
if (!adapter || !mac_addr) {
@@ -6642,17 +6641,13 @@
return false;
}
- sta_info = adapter->sta_info;
- spin_lock_bh(&adapter->sta_info_lock);
- for (cnt = 0; cnt < WLAN_MAX_STA_COUNT; cnt++) {
- if ((sta_info[cnt].in_use) &&
- !qdf_mem_cmp(&(sta_info[cnt].sta_mac), mac_addr,
- QDF_MAC_ADDR_SIZE))
+ hdd_for_each_station(adapter->sta_info_list, sta_info, index) {
+ if (!qdf_mem_cmp(&sta_info->sta_mac, mac_addr,
+ QDF_MAC_ADDR_SIZE)) {
+ is_associated = true;
break;
+ }
}
- spin_unlock_bh(&adapter->sta_info_lock);
- if (cnt != WLAN_MAX_STA_COUNT)
- return true;
- return false;
+ return is_associated;
}
diff --git a/core/hdd/src/wlan_hdd_hostapd_wext.c b/core/hdd/src/wlan_hdd_hostapd_wext.c
index 42aab67..0f0ead6 100644
--- a/core/hdd/src/wlan_hdd_hostapd_wext.c
+++ b/core/hdd/src/wlan_hdd_hostapd_wext.c
@@ -43,6 +43,7 @@
#include <wlan_cfg80211_mc_cp_stats.h>
#include "wlan_mlme_ucfg_api.h"
#include "wlan_reg_ucfg_api.h"
+#include "wlan_hdd_sta_info.h"
#define WE_WLAN_VERSION 1
/* WEXT limitation: MAX allowed buf len for any *
@@ -144,7 +145,7 @@
struct cdp_pdev *pdev = NULL;
void *soc = NULL;
struct cdp_txrx_stats_req req = {0};
- uint8_t count = 0;
+ uint8_t index = 0;
struct hdd_station_info *sta_info;
hdd_enter_dev(dev);
@@ -171,23 +172,21 @@
req.mac_id = value[2];
hdd_info("QCSAP_PARAM_SET_TXRX_STATS stats_id: %d mac_id: %d",
req.stats, req.mac_id);
- sta_info = adapter->sta_info;
+
if (value[1] == CDP_TXRX_STATS_28) {
req.peer_addr = (char *)&adapter->mac_addr;
ret = cdp_txrx_stats_request(soc, vdev, &req);
- for (count = 0; count < WLAN_MAX_STA_COUNT; count++) {
- if (sta_info->in_use) {
- hdd_debug("sta: %d: bss_id: %pM",
- sta_info->sta_id,
- (void *)&sta_info->sta_mac);
- req.peer_addr =
- (char *)&sta_info->sta_mac;
- ret = cdp_txrx_stats_request(soc, vdev,
- &req);
- }
+ hdd_for_each_station(adapter->sta_info_list, sta_info,
+ index) {
+ hdd_debug("bss_id: " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(
+ sta_info->sta_mac.bytes));
- sta_info++;
+ req.peer_addr = (char *)
+ &sta_info->sta_mac;
+ ret = cdp_txrx_stats_request(
+ soc, vdev, &req);
}
} else {
ret = cdp_txrx_stats_request(soc, vdev, &req);
@@ -339,72 +338,6 @@
return QDF_STATUS_SUCCESS;
}
-/**
- * hdd_get_aid_rc() - Get AID and rate code passed from user
- * @aid: pointer to AID
- * @rc: pointer to rate code
- * @set_value: value passed from user
- *
- * If target is 11ax capable, set_value will have AID left shifted 16 bits
- * and 16 bits for rate code. If the target is not 11ax capable, rate code
- * will only be 8 bits.
- *
- * Return: None
- */
-static void hdd_get_aid_rc(uint8_t *aid, uint16_t *rc, int set_value)
-{
- uint8_t rc_bits;
-
- if (sme_is_feature_supported_by_fw(DOT11AX))
- rc_bits = 16;
- else
- rc_bits = 8;
-
- *aid = set_value >> rc_bits;
- *rc = set_value & ((1 << (rc_bits + 1)) - 1);
-}
-
-/**
- * hdd_set_peer_rate() - set peer rate
- * @adapter: adapter being modified
- * @set_value: rate code with AID
- *
- * Return: 0 on success, negative errno on failure
- */
-static int hdd_set_peer_rate(struct hdd_adapter *adapter, int set_value)
-{
- uint8_t aid, *peer_mac;
- uint16_t rc;
- QDF_STATUS status;
-
- if (adapter->device_mode != QDF_SAP_MODE) {
- hdd_err("Invalid devicde mode - %d", adapter->device_mode);
- return -EINVAL;
- }
-
- hdd_get_aid_rc(&aid, &rc, set_value);
-
- if ((adapter->sta_info[aid].in_use) &&
- (OL_TXRX_PEER_STATE_CONN == adapter->sta_info[aid].peer_state)) {
- peer_mac =
- (uint8_t *)&(adapter->sta_info[aid].sta_mac.bytes[0]);
- hdd_info("Peer AID: %d MAC_ADDR: "QDF_MAC_ADDR_STR,
- aid, QDF_MAC_ADDR_ARRAY(peer_mac));
- } else {
- hdd_err("No matching peer found for AID: %d", aid);
- return -EINVAL;
- }
-
- status = sme_set_peer_param(peer_mac, WMI_PEER_PARAM_FIXED_RATE,
- rc, adapter->vdev_id);
- if (status != QDF_STATUS_SUCCESS) {
- hdd_err("Failed to set peer fixed rate - status: %d", status);
- return -EIO;
- }
-
- return 0;
-}
-
int
static __iw_softap_setparam(struct net_device *dev,
struct iw_request_info *info,
@@ -1053,9 +986,6 @@
&adapter->session.ap.
sap_config);
break;
- case QCASAP_SET_PEER_RATE:
- ret = hdd_set_peer_rate(adapter, set_value);
- break;
case QCASAP_PARAM_DCM:
hdd_debug("Set WMI_VDEV_PARAM_HE_DCM: %d", set_value);
ret = wma_cli_set_command(adapter->vdev_id,
@@ -1749,10 +1679,10 @@
union iwreq_data *wrqu, char *extra)
{
struct hdd_adapter *adapter = (netdev_priv(dev));
- struct hdd_station_info *sta_info = adapter->sta_info;
+ struct hdd_station_info *sta_info;
struct hdd_context *hdd_ctx;
char *buf;
- int cnt = 0;
+ int index = 0;
int left;
int ret;
/* maclist_index must be u32 to match userspace */
@@ -1799,18 +1729,14 @@
maclist_index = sizeof(maclist_index);
left = wrqu->data.length - maclist_index;
- spin_lock_bh(&adapter->sta_info_lock);
- while ((cnt < WLAN_MAX_STA_COUNT) && (left >= QDF_MAC_ADDR_SIZE)) {
- if ((sta_info[cnt].in_use) &&
- (!qdf_is_macaddr_broadcast(&sta_info[cnt].sta_mac))) {
- memcpy(&buf[maclist_index], &(sta_info[cnt].sta_mac),
+ hdd_for_each_station(adapter->sta_info_list, sta_info, index) {
+ if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
+ memcpy(&buf[maclist_index], &sta_info->sta_mac,
QDF_MAC_ADDR_SIZE);
maclist_index += QDF_MAC_ADDR_SIZE;
left -= QDF_MAC_ADDR_SIZE;
}
- cnt++;
}
- spin_unlock_bh(&adapter->sta_info_lock);
*((u32 *) buf) = maclist_index;
wrqu->data.length = maclist_index;
@@ -2295,30 +2221,24 @@
uint8_t *buf,
int size)
{
- int i;
+ uint8_t index = 0;
int written;
- uint8_t bc_sta_id;
+ struct hdd_station_info *sta;
hdd_enter();
- bc_sta_id = WLAN_HDD_GET_AP_CTX_PTR(adapter)->broadcast_sta_id;
-
written = scnprintf(buf, size, "\nstaId staAddress\n");
- for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
- struct hdd_station_info *sta = &adapter->sta_info[i];
+ hdd_for_each_station(adapter->sta_info_list, sta, index) {
if (written >= size - 1)
break;
- if (!sta->in_use)
- continue;
-
- if (i == bc_sta_id)
+ if (QDF_IS_ADDR_BROADCAST(sta->sta_mac.bytes))
continue;
written += scnprintf(buf + written, size - written,
- "%5d "QDF_MAC_ADDR_STR" ecsa=%d\n",
- sta->sta_id,
+ QDF_MAC_ADDR_STR
+ " ecsa=%d\n",
sta->sta_mac.bytes[0],
sta->sta_mac.bytes[1],
sta->sta_mac.bytes[2],
@@ -2527,7 +2447,8 @@
struct qdf_mac_addr mac_address;
char macaddr_string[MAC_ADDRESS_STR_LEN + 1];
QDF_STATUS status = QDF_STATUS_E_FAILURE;
- int rc, ret, i;
+ int rc, ret;
+ uint8_t index = 0;
hdd_enter_dev(dev);
@@ -2567,14 +2488,12 @@
* link speed for first connected client will be returned.
*/
if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) {
- for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
- if (adapter->sta_info[i].in_use &&
- (!qdf_is_macaddr_broadcast
- (&adapter->sta_info[i].sta_mac))) {
- qdf_copy_macaddr(
- &mac_address,
- &adapter->sta_info[i].
- sta_mac);
+ struct hdd_station_info *sta_info;
+
+ hdd_for_each_station(adapter->sta_info_list, sta_info, index) {
+ if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
+ qdf_copy_macaddr(&mac_address,
+ &sta_info->sta_mac);
status = QDF_STATUS_SUCCESS;
break;
}
@@ -3248,12 +3167,6 @@
}
,
{
- QCASAP_SET_PEER_RATE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "set_peer_rate"
- }
- ,
- {
QCASAP_PARAM_DCM,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "enable_dcm"
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index fba90be..e01d0ab 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -173,6 +173,7 @@
#include "wlan_blm_ucfg_api.h"
#include "ol_txrx.h"
#include "nan_ucfg_api.h"
+#include "wlan_hdd_sta_info.h"
#ifdef MODULE
#define WLAN_MODULE_NAME module_name(THIS_MODULE)
@@ -4854,6 +4855,10 @@
hdd_apf_context_destroy(adapter);
qdf_spinlock_destroy(&adapter->vdev_lock);
+ if (adapter->device_mode == QDF_SAP_MODE ||
+ adapter->device_mode == QDF_P2P_GO_MODE)
+ hdd_sta_info_deinit(&adapter->sta_info_list);
+
wlan_hdd_debugfs_csr_deinit(adapter);
if (adapter->device_mode == QDF_STA_MODE)
hdd_sysfs_destroy_adapter_root_obj(adapter);
@@ -6182,9 +6187,10 @@
struct hdd_adapter *adapter;
struct hdd_station_ctx *sta_ctx;
struct qdf_mac_addr peer_macaddr;
- int sta_id;
bool value;
struct wlan_objmgr_vdev *vdev;
+ uint8_t index = 0;
+ struct hdd_station_info *sta_info;
hdd_enter();
@@ -6287,19 +6293,17 @@
} else if (adapter->device_mode == QDF_P2P_GO_MODE) {
clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
- for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
- sta_id++) {
- struct hdd_station_info sta =
- adapter->sta_info[sta_id];
- if (sta.in_use) {
- hdd_debug("[SSR] deregister STA with ID %d",
- sta_id);
- /* STA id will be removed */
- hdd_softap_deregister_sta(adapter,
- sta_id,
- sta.sta_mac);
- sta.in_use = 0;
- }
+
+ hdd_for_each_station(adapter->sta_info_list, sta_info,
+ index) {
+ hdd_debug(
+ "[SSR] deregister STA MAC:"
+ QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(
+ sta_info->sta_mac.bytes));
+ hdd_softap_deregister_sta(
+ adapter,
+ sta_info);
}
}
@@ -6316,6 +6320,10 @@
hdd_stop_tsf_sync(adapter);
hdd_softap_deinit_tx_rx(adapter);
+ if (adapter->device_mode == QDF_SAP_MODE ||
+ adapter->device_mode == QDF_P2P_GO_MODE)
+ hdd_sta_info_deinit(&adapter->sta_info_list);
+
hdd_deregister_hl_netdev_fc_timer(adapter);
hdd_deregister_tx_flow_control(adapter);
@@ -15433,10 +15441,11 @@
{
struct hdd_station_ctx *hdd_sta_ctx = NULL;
struct hdd_adapter *adapter = NULL;
- uint8_t sta_id = 0;
+ uint8_t index = 0;
uint8_t *sta_mac = NULL;
struct hdd_context *hdd_ctx;
mac_handle_t mac_handle;
+ struct hdd_station_info *sta_info = NULL;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@@ -15483,6 +15492,7 @@
}
return true;
}
+
if ((QDF_STA_MODE == adapter->device_mode) ||
(QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
(QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
@@ -15505,23 +15515,22 @@
}
} else if ((QDF_SAP_MODE == adapter->device_mode) ||
(QDF_P2P_GO_MODE == adapter->device_mode)) {
- for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
- sta_id++) {
- if (!((adapter->sta_info[sta_id].in_use)
- && (OL_TXRX_PEER_STATE_CONN ==
- adapter->sta_info[sta_id].peer_state)))
+ hdd_for_each_station(adapter->sta_info_list, sta_info,
+ index) {
+ if (sta_info->peer_state !=
+ OL_TXRX_PEER_STATE_CONN)
continue;
- sta_mac = (uint8_t *)
- &(adapter->sta_info[sta_id].
- sta_mac.bytes[0]);
+ sta_mac = sta_info->sta_mac.bytes;
hdd_debug("client " QDF_MAC_ADDR_STR
- " of SAP/GO is in middle of WPS/EAPOL exchange",
- QDF_MAC_ADDR_ARRAY(sta_mac));
+ " of SAP/GO is in middle of WPS/EAPOL exchange",
+ QDF_MAC_ADDR_ARRAY(sta_mac));
if (out_vdev_id && out_reason) {
*out_vdev_id = adapter->vdev_id;
- *out_reason = SAP_EAPOL_IN_PROGRESS;
+ *out_reason =
+ SAP_EAPOL_IN_PROGRESS;
}
+
return true;
}
if (hdd_ctx->connection_in_progress) {
diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c
index f4d018d..fa41309 100644
--- a/core/hdd/src/wlan_hdd_softap_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c
@@ -44,7 +44,7 @@
#include "wlan_ipa_ucfg_api.h"
#include "wlan_policy_mgr_ucfg.h"
#include <wma_types.h>
-#include <sap_internal.h>
+#include "wlan_hdd_sta_info.h"
/* Preprocessor definitions and constants */
#undef QCA_HDD_SAP_DUMP_SK_BUFF
@@ -246,13 +246,14 @@
*
* Return: error number
*/
-int hdd_post_dhcp_ind(struct hdd_adapter *adapter,
- uint8_t sta_id, uint16_t type)
+int hdd_post_dhcp_ind(struct hdd_adapter *adapter, uint8_t *mac_addr,
+ uint16_t type)
{
tAniDHCPInd pmsg;
QDF_STATUS status = QDF_STATUS_SUCCESS;
- hdd_debug("Post DHCP indication,sta_id=%d, type=%d", sta_id, type);
+ hdd_debug("Post DHCP indication,sta_mac=" QDF_MAC_ADDR_STR
+ " , type=%d", QDF_MAC_ADDR_ARRAY(mac_addr), type);
if (!adapter) {
hdd_err("NULL adapter");
@@ -266,7 +267,7 @@
adapter->mac_addr.bytes,
QDF_MAC_ADDR_SIZE);
qdf_mem_copy(pmsg.peerMacAddr.bytes,
- adapter->sta_info[sta_id].sta_mac.bytes,
+ mac_addr,
QDF_MAC_ADDR_SIZE);
status = wma_process_dhcp_ind(cds_get_context(QDF_MODULE_ID_WMA),
@@ -292,8 +293,7 @@
static void hdd_softap_notify_dhcp_ind(void *context, struct sk_buff *netbuf)
{
struct hdd_ap_ctx *hdd_ap_ctx;
- struct qdf_mac_addr *dest_mac_addr;
- uint8_t sta_id;
+ uint8_t *dest_mac_addr;
struct hdd_adapter *adapter = context;
if (hdd_validate_adapter(adapter))
@@ -305,59 +305,20 @@
return;
}
- dest_mac_addr = (struct qdf_mac_addr *)(netbuf->data +
- DHCP_CLIENT_MAC_ADDR_OFFSET);
+ dest_mac_addr = netbuf->data + DHCP_CLIENT_MAC_ADDR_OFFSET;
- if (QDF_STATUS_SUCCESS !=
- hdd_softap_get_sta_id(adapter,
- dest_mac_addr, &sta_id)) {
- QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
- QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: Failed to find right station", __func__);
- return;
- }
-
- hdd_post_dhcp_ind(adapter, sta_id, WMA_DHCP_STOP_IND);
+ hdd_post_dhcp_ind(adapter, dest_mac_addr, WMA_DHCP_STOP_IND);
}
-/**
- * hdd_softap_inspect_dhcp_packet() - Inspect DHCP packet
- * @adapter: pointer to hdd adapter
- * @skb: pointer to OS packet (sk_buff)
- * @dir: direction
- *
- * Inspect the Tx/Rx frame, and send DHCP START/STOP notification to the FW
- * through WMI message, during DHCP based IP address acquisition phase.
- *
- * - Send DHCP_START notification to FW when SAP gets DHCP Discovery
- * - Send DHCP_STOP notification to FW when SAP sends DHCP ACK/NAK
- *
- * DHCP subtypes are determined by a status octet in the DHCP Message type
- * option (option code 53 (0x35)).
- *
- * Each peer will be in one of 4 DHCP phases, starts from QDF_DHCP_PHASE_ACK,
- * and transitioned per DHCP message type as it arrives.
- *
- * - QDF_DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase
- * - QDF_DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase
- * - QDF_DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase
- * or ACK phase (Renewal process)
- * - QDF_DHCP_PHASE_ACK : upon receiving DHCP_ACK/NAK message in REQUEST phase
- * or DHCP_DELINE message in OFFER phase
- *
- * Return: error number
- */
int hdd_softap_inspect_dhcp_packet(struct hdd_adapter *adapter,
struct sk_buff *skb,
enum qdf_proto_dir dir)
{
enum qdf_proto_subtype subtype = QDF_PROTO_INVALID;
struct hdd_station_info *hdd_sta_info;
- uint8_t sta_id;
int errno = 0;
- struct qdf_mac_addr *src_mac;
- QDF_STATUS status;
-
+ struct qdf_mac_addr *src_mac, *macaddr =
+ (struct qdf_mac_addr *)(skb->data + QDF_NBUF_SRC_MAC_OFFSET);
if (((adapter->device_mode == QDF_SAP_MODE) ||
(adapter->device_mode == QDF_P2P_GO_MODE)) &&
@@ -367,14 +328,15 @@
src_mac = (struct qdf_mac_addr *)(skb->data +
DHCP_CLIENT_MAC_ADDR_OFFSET);
- status = hdd_softap_get_sta_id(adapter, src_mac, &sta_id);
- if (status != QDF_STATUS_SUCCESS) {
- hdd_err("invalid station id");
- return -EINVAL;
- }
subtype = qdf_nbuf_get_dhcp_subtype(skb);
- hdd_sta_info = &adapter->sta_info[sta_id];
+ hdd_sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ macaddr->bytes);
+
+ if (!hdd_sta_info) {
+ hdd_err("Station not found");
+ return -EINVAL;
+ }
hdd_debug("ENTER: type=%d, phase=%d, nego_status=%d",
subtype,
@@ -386,8 +348,10 @@
if (dir != QDF_RX)
break;
if (hdd_sta_info->dhcp_nego_status == DHCP_NEGO_STOP)
- errno = hdd_post_dhcp_ind(adapter, sta_id,
- WMA_DHCP_START_IND);
+ errno = hdd_post_dhcp_ind(
+ adapter,
+ hdd_sta_info->sta_mac.bytes,
+ WMA_DHCP_START_IND);
hdd_sta_info->dhcp_phase = DHCP_PHASE_DISCOVER;
hdd_sta_info->dhcp_nego_status = DHCP_NEGO_IN_PROGRESS;
break;
@@ -398,8 +362,10 @@
if (dir != QDF_RX)
break;
if (hdd_sta_info->dhcp_nego_status == DHCP_NEGO_STOP)
- errno = hdd_post_dhcp_ind(adapter, sta_id,
- WMA_DHCP_START_IND);
+ errno = hdd_post_dhcp_ind(
+ adapter,
+ hdd_sta_info->sta_mac.bytes,
+ WMA_DHCP_START_IND);
hdd_sta_info->dhcp_nego_status = DHCP_NEGO_IN_PROGRESS;
case QDF_PROTO_DHCP_DECLINE:
if (dir == QDF_RX)
@@ -453,9 +419,11 @@
struct hdd_adapter *adapter = (struct hdd_adapter *) netdev_priv(dev);
struct hdd_ap_ctx *ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
struct hdd_context *hdd_ctx = adapter->hdd_ctx;
- struct qdf_mac_addr *dest_mac_addr;
- uint8_t sta_id;
+ struct qdf_mac_addr *dest_mac_addr, *mac_addr;
+ static struct qdf_mac_addr bcast_mac_addr = QDF_MAC_ADDR_BCAST_INIT;
+
uint32_t num_seg;
+ struct hdd_station_info *sta_info;
++adapter->hdd_stats.tx_rx_stats.tx_called;
adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0;
@@ -505,53 +473,41 @@
dest_mac_addr = (struct qdf_mac_addr *)skb->data;
- if (QDF_NBUF_CB_GET_IS_BCAST(skb) ||
- QDF_NBUF_CB_GET_IS_MCAST(skb)) {
- /* The BC/MC station ID is assigned during BSS
- * starting phase. SAP will return the station ID
- * used for BC/MC traffic.
- */
- sta_id = ap_ctx->broadcast_sta_id;
- } else {
- if (QDF_STATUS_SUCCESS !=
- hdd_softap_get_sta_id(adapter,
- dest_mac_addr, &sta_id)) {
+ /* In case of mcast, fetch the bcast sta_info. Else use the pkt addr */
+ if (QDF_NBUF_CB_GET_IS_MCAST(skb))
+ mac_addr = &bcast_mac_addr;
+ else
+ mac_addr = dest_mac_addr;
+
+ sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ mac_addr->bytes);
+
+ if (!QDF_NBUF_CB_GET_IS_BCAST(skb) && !QDF_NBUF_CB_GET_IS_MCAST(skb)) {
+ if (!sta_info) {
QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
QDF_TRACE_LEVEL_INFO_HIGH,
"%s: Failed to find right station", __func__);
goto drop_pkt;
}
- if (sta_id >= WLAN_MAX_STA_COUNT) {
+ if (sta_info->is_deauth_in_progress) {
QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: Failed to find right station", __func__);
- goto drop_pkt;
- } else if (!adapter->sta_info[sta_id].in_use) {
- QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
- QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: STA %d is unregistered", __func__,
- sta_id);
- goto drop_pkt;
- } else if (adapter->sta_info[sta_id].
- is_deauth_in_progress) {
- QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
- QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: STA %d deauth in progress", __func__,
- sta_id);
+ "%s: STA " QDF_MAC_ADDR_STR
+ "deauth in progress", __func__,
+ QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
goto drop_pkt;
}
- if ((OL_TXRX_PEER_STATE_CONN !=
- adapter->sta_info[sta_id].peer_state)
- && (OL_TXRX_PEER_STATE_AUTH !=
- adapter->sta_info[sta_id].peer_state)) {
+ if (sta_info->peer_state != OL_TXRX_PEER_STATE_CONN &&
+ sta_info->peer_state != OL_TXRX_PEER_STATE_AUTH) {
QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
QDF_TRACE_LEVEL_INFO_HIGH,
"%s: Station not connected yet", __func__);
goto drop_pkt;
- } else if (OL_TXRX_PEER_STATE_CONN ==
- adapter->sta_info[sta_id].peer_state) {
+ }
+
+ if (sta_info->peer_state == OL_TXRX_PEER_STATE_CONN) {
if (ntohs(skb->protocol) != HDD_ETHERTYPE_802_1_X) {
QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA,
QDF_TRACE_LEVEL_INFO_HIGH,
@@ -600,18 +556,21 @@
qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__);
adapter->stats.tx_bytes += skb->len;
- adapter->sta_info[sta_id].tx_bytes += skb->len;
- if (qdf_nbuf_is_tso(skb)) {
- num_seg = qdf_nbuf_get_tso_num_seg(skb);
- adapter->stats.tx_packets += num_seg;
- adapter->sta_info[sta_id].tx_packets += num_seg;
- } else {
- ++adapter->stats.tx_packets;
- adapter->sta_info[sta_id].tx_packets++;
- hdd_ctx->no_tx_offload_pkt_cnt++;
+ if (sta_info) {
+ sta_info->tx_bytes += skb->len;
+
+ if (qdf_nbuf_is_tso(skb)) {
+ num_seg = qdf_nbuf_get_tso_num_seg(skb);
+ adapter->stats.tx_packets += num_seg;
+ sta_info->tx_packets += num_seg;
+ } else {
+ ++adapter->stats.tx_packets;
+ sta_info->tx_packets++;
+ hdd_ctx->no_tx_offload_pkt_cnt++;
+ }
+ sta_info->last_tx_rx_ts = qdf_system_ticks();
}
- adapter->sta_info[sta_id].last_tx_rx_ts = qdf_system_ticks();
QDF_NBUF_CB_TX_EXTRA_FRAG_FLAGS_NOTIFY_COMP(skb) = 0;
@@ -639,8 +598,9 @@
if (adapter->tx_fn(adapter->txrx_vdev,
(qdf_nbuf_t)skb) != NULL) {
QDF_TRACE(QDF_MODULE_ID_HDD_SAP_DATA, QDF_TRACE_LEVEL_INFO_HIGH,
- "%s: Failed to send packet to txrx for sta_id:%d",
- __func__, sta_id);
+ "%s: Failed to send packet to txrx for sta: "
+ QDF_MAC_ADDR_STR, __func__,
+ QDF_MAC_ADDR_ARRAY(dest_mac_addr->bytes));
++adapter->hdd_stats.tx_rx_stats.tx_dropped_ac[ac];
goto drop_pkt_and_release_skb;
}
@@ -756,22 +716,9 @@
osif_vdev_sync_op_stop(vdev_sync);
}
-QDF_STATUS hdd_softap_init_tx_rx(struct hdd_adapter *adapter)
+void hdd_softap_init_tx_rx(struct hdd_adapter *adapter)
{
- QDF_STATUS status = QDF_STATUS_SUCCESS;
-
- uint8_t STAId = 0;
-
qdf_mem_zero(&adapter->stats, sizeof(struct net_device_stats));
-
- spin_lock_init(&adapter->sta_info_lock);
-
- for (STAId = 0; STAId < WLAN_MAX_STA_COUNT; STAId++) {
- qdf_mem_zero(&adapter->sta_info[STAId],
- sizeof(struct hdd_station_info));
- }
-
- return status;
}
QDF_STATUS hdd_softap_deinit_tx_rx(struct hdd_adapter *adapter)
@@ -787,47 +734,34 @@
}
QDF_STATUS hdd_softap_init_tx_rx_sta(struct hdd_adapter *adapter,
- uint8_t sta_id,
struct qdf_mac_addr *sta_mac)
{
- spin_lock_bh(&adapter->sta_info_lock);
- if (adapter->sta_info[sta_id].in_use) {
- spin_unlock_bh(&adapter->sta_info_lock);
- hdd_err("Reinit of in use station %d", sta_id);
+ struct hdd_station_info *sta_info;
+ QDF_STATUS status;
+
+ sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ sta_mac->bytes);
+
+ if (sta_info) {
+ hdd_err("Reinit of in use station " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(sta_mac->bytes));
return QDF_STATUS_E_FAILURE;
}
- qdf_mem_zero(&adapter->sta_info[sta_id],
- sizeof(struct hdd_station_info));
+ sta_info = qdf_mem_malloc(sizeof(struct hdd_station_info));
+ if (!sta_info)
+ return QDF_STATUS_E_NOMEM;
- adapter->sta_info[sta_id].in_use = true;
- adapter->sta_info[sta_id].is_deauth_in_progress = false;
- qdf_copy_macaddr(&adapter->sta_info[sta_id].sta_mac, sta_mac);
+ sta_info->is_deauth_in_progress = false;
+ qdf_mem_copy(&sta_info->sta_mac, sta_mac, sizeof(struct qdf_mac_addr));
- spin_unlock_bh(&adapter->sta_info_lock);
- return QDF_STATUS_SUCCESS;
-}
-
-QDF_STATUS hdd_softap_deinit_tx_rx_sta(struct hdd_adapter *adapter,
- uint8_t sta_id)
-{
- QDF_STATUS status = QDF_STATUS_SUCCESS;
- struct hdd_hostapd_state *hostapd_state;
-
- hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
-
- spin_lock_bh(&adapter->sta_info_lock);
-
- if (false == adapter->sta_info[sta_id].in_use) {
- spin_unlock_bh(&adapter->sta_info_lock);
- hdd_err("Deinit station not inited %d", sta_id);
- return QDF_STATUS_E_FAILURE;
+ status = hdd_sta_info_attach(&adapter->sta_info_list, sta_info);
+ if (QDF_IS_STATUS_ERROR(status)) {
+ hdd_err("Failed to attach station: " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(sta_mac->bytes));
+ qdf_mem_free(sta_info);
}
- adapter->sta_info[sta_id].in_use = false;
- adapter->sta_info[sta_id].is_deauth_in_progress = false;
-
- spin_unlock_bh(&adapter->sta_info_lock);
return status;
}
@@ -889,7 +823,7 @@
struct sk_buff *next = NULL;
struct hdd_context *hdd_ctx = NULL;
struct qdf_mac_addr *src_mac;
- uint8_t sta_id;
+ struct hdd_station_info *sta_info;
/* Sanity check on inputs */
if (unlikely((!adapter_context) || (!rx_buf))) {
@@ -945,16 +879,14 @@
/* Send DHCP Indication to FW */
src_mac = (struct qdf_mac_addr *)(skb->data +
QDF_NBUF_SRC_MAC_OFFSET);
- if (QDF_STATUS_SUCCESS ==
- hdd_softap_get_sta_id(adapter, src_mac, &sta_id)) {
- if (sta_id < WLAN_MAX_STA_COUNT) {
- adapter->sta_info[sta_id].rx_packets++;
- adapter->sta_info[sta_id].rx_bytes += skb->len;
- adapter->sta_info[sta_id].last_tx_rx_ts =
- qdf_system_ticks();
- hdd_softap_inspect_dhcp_packet(adapter, skb,
- QDF_RX);
- }
+ sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ (uint8_t *)src_mac);
+
+ if (sta_info) {
+ sta_info->rx_packets++;
+ sta_info->rx_bytes += skb->len;
+ sta_info->last_tx_rx_ts = qdf_system_ticks();
+ hdd_softap_inspect_dhcp_packet(adapter, skb, QDF_RX);
}
hdd_event_eapol_log(skb, QDF_RX);
@@ -1002,11 +934,11 @@
}
QDF_STATUS hdd_softap_deregister_sta(struct hdd_adapter *adapter,
- uint8_t sta_id,
- struct qdf_mac_addr mac_addr)
+ struct hdd_station_info *sta_info)
{
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
struct hdd_context *hdd_ctx;
+ struct qdf_mac_addr *mac_addr;
if (!adapter) {
hdd_err("NULL adapter");
@@ -1018,40 +950,55 @@
return QDF_STATUS_E_INVAL;
}
- hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-
- if (sta_id >= WLAN_MAX_STA_COUNT) {
- hdd_err("Error: Invalid sta_id: %u", sta_id);
+ if (!sta_info) {
+ hdd_err("Invalid station");
return QDF_STATUS_E_INVAL;
}
+ hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+ if (!hdd_ctx) {
+ hdd_err("HDD context is null");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ /*
+ * If the address is a broadcast address then the CDP layers expects
+ * the self mac address of the adapter.
+ */
+ if (QDF_IS_ADDR_BROADCAST(sta_info->sta_mac.bytes))
+ mac_addr = &adapter->mac_addr;
+ else
+ mac_addr = &sta_info->sta_mac;
+
/* Clear station in TL and then update HDD data
* structures. This helps to block RX frames from other
* station to this station.
*/
- qdf_status = cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
+
+ hdd_debug("Deregistering sta: " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
+
+ qdf_status = cdp_clear_peer(
+ cds_get_context(QDF_MODULE_ID_SOC),
(struct cdp_pdev *)cds_get_context(QDF_MODULE_ID_TXRX),
- mac_addr);
+ *mac_addr);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
- hdd_err("cdp_clear_peer failed for staID %d, Status=%d [0x%08X]",
- sta_id, qdf_status, qdf_status);
+ hdd_err("cdp_clear_peer failed for sta: " QDF_MAC_ADDR_STR
+ ", Status=%d [0x%08X]",
+ QDF_MAC_ADDR_ARRAY(mac_addr->bytes), qdf_status,
+ qdf_status);
}
- if (adapter->sta_info[sta_id].in_use) {
- if (ucfg_ipa_is_enabled()) {
- if (ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev,
- adapter->device_mode,
- adapter->vdev_id,
- WLAN_IPA_CLIENT_DISCONNECT,
- adapter->sta_info[sta_id].sta_mac.
- bytes) != QDF_STATUS_SUCCESS)
- hdd_err("WLAN_CLIENT_DISCONNECT event failed");
- }
- spin_lock_bh(&adapter->sta_info_lock);
- qdf_mem_zero(&adapter->sta_info[sta_id],
- sizeof(struct hdd_station_info));
- spin_unlock_bh(&adapter->sta_info_lock);
+ if (ucfg_ipa_is_enabled()) {
+ if (ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev,
+ adapter->device_mode,
+ adapter->vdev_id,
+ WLAN_IPA_CLIENT_DISCONNECT,
+ mac_addr->bytes) != QDF_STATUS_SUCCESS)
+ hdd_err("WLAN_CLIENT_DISCONNECT event failed");
}
+ hdd_sta_info_detach(&adapter->sta_info_list, sta_info);
ucfg_mlme_update_oce_flags(hdd_ctx->pdev);
@@ -1073,42 +1020,43 @@
void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
struct cdp_vdev *txrx_vdev = NULL;
struct hdd_ap_ctx *ap_ctx;
-
- hdd_info("STA:%u, Auth:%u, Priv:%u, WMM:%u",
- sta_id, auth_required, privacy_required, wmm_enabled);
+ struct hdd_station_info *sta_info;
ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
- if (!ap_ctx)
- hdd_err("Invalid AP context");
-
- if (sta_id >= WLAN_MAX_STA_COUNT) {
- hdd_err("Error: Invalid sta_id: %u", sta_id);
- return qdf_status;
- }
/*
* Clean up old entry if it is not cleaned up properly
*/
- if (adapter->sta_info[sta_id].in_use) {
- hdd_info("clean up old entry for STA %d", sta_id);
- hdd_softap_deregister_sta(adapter, sta_id,
- adapter->sta_info[sta_id].sta_mac);
+
+ sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ sta_mac->bytes);
+ if (sta_info) {
+ hdd_info("clean up old entry for STA MAC " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(sta_mac->bytes));
+ hdd_softap_deregister_sta(adapter, sta_info);
}
/* Get the Station ID from the one saved during the association. */
txrx_desc.sta_id = sta_id;
-
/*
* If the address is a broadcast address, then provide the self mac addr
* to the data path. Else provide the mac address of the connected peer.
*/
if (qdf_is_macaddr_broadcast(sta_mac) && ap_ctx)
- qdf_copy_macaddr(&txrx_desc.peer_addr,
- &ap_ctx->sap_context->bssid);
+ qdf_mem_copy(&txrx_desc.peer_addr, &adapter->mac_addr,
+ QDF_MAC_ADDR_SIZE);
else
- qdf_copy_macaddr(&txrx_desc.peer_addr, sta_mac);
+ qdf_mem_copy(&txrx_desc.peer_addr, sta_mac,
+ QDF_MAC_ADDR_SIZE);
- qdf_status = hdd_softap_init_tx_rx_sta(adapter, sta_id, sta_mac);
+ qdf_status = hdd_softap_init_tx_rx_sta(adapter, sta_mac);
+ sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ sta_mac->bytes);
+
+ if (!sta_info) {
+ hdd_err("STA not found");
+ return QDF_STATUS_E_INVAL;
+ }
txrx_desc.is_qos_enabled = wmm_enabled;
@@ -1156,32 +1104,38 @@
* put TL directly into 'authenticated' state
*/
- adapter->sta_info[sta_id].sta_id = sta_id;
- adapter->sta_info[sta_id].is_qos_enabled = wmm_enabled;
+ sta_info->is_qos_enabled = wmm_enabled;
if (!auth_required) {
- hdd_info("open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time",
- adapter->sta_info[sta_id].sta_id);
+ hdd_info("open/shared auth STA MAC= " QDF_MAC_ADDR_STR
+ ". Changing TL state to AUTHENTICATED at Join time",
+ QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
/* Connections that do not need Upper layer auth,
* transition TL directly to 'Authenticated' state.
*/
- qdf_status = hdd_change_peer_state(adapter, txrx_desc.sta_id,
- OL_TXRX_PEER_STATE_AUTH, false);
+ qdf_status = hdd_change_peer_state(adapter,
+ txrx_desc.peer_addr.bytes,
+ OL_TXRX_PEER_STATE_AUTH,
+ false);
- adapter->sta_info[sta_id].peer_state = OL_TXRX_PEER_STATE_AUTH;
+ sta_info->peer_state = OL_TXRX_PEER_STATE_AUTH;
if (!qdf_is_macaddr_broadcast(sta_mac))
qdf_status = wlan_hdd_send_sta_authorized_event(
adapter, hdd_ctx,
sta_mac);
} else {
- hdd_info("ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
- adapter->sta_info[sta_id].sta_id);
+ hdd_info("ULA auth STA MAC = " QDF_MAC_ADDR_STR
+ ". Changing TL state to CONNECTED at Join time",
+ QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
- qdf_status = hdd_change_peer_state(adapter, txrx_desc.sta_id,
- OL_TXRX_PEER_STATE_CONN, false);
- adapter->sta_info[sta_id].peer_state = OL_TXRX_PEER_STATE_CONN;
+ qdf_status = hdd_change_peer_state(adapter,
+ txrx_desc.peer_addr.bytes,
+ OL_TXRX_PEER_STATE_CONN,
+ false);
+
+ sta_info->peer_state = OL_TXRX_PEER_STATE_CONN;
}
hdd_debug("Enabling queues");
@@ -1221,28 +1175,15 @@
return qdf_status;
}
-/**
- * hdd_softap_deregister_bc_sta() - Deregister the SoftAP broadcast STA
- * @adapter: pointer to adapter context
- *
- * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
- */
-static QDF_STATUS hdd_softap_deregister_bc_sta(struct hdd_adapter *adapter)
-{
- struct hdd_ap_ctx *ap_ctx;
-
- ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
-
- return hdd_softap_deregister_sta(adapter, ap_ctx->broadcast_sta_id,
- adapter->mac_addr);
-}
-
QDF_STATUS hdd_softap_stop_bss(struct hdd_adapter *adapter)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
- uint8_t sta_id = 0, indoor_chnl_marking = 0;
+ uint8_t indoor_chnl_marking = 0;
struct hdd_context *hdd_ctx;
struct hdd_ap_ctx *ap_ctx;
+ uint16_t index;
+ struct hdd_station_info *sta_info;
+ struct hdd_sta_info_entry *tmp;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
@@ -1255,24 +1196,17 @@
* driver unload in progress check otherwise it can lead to peer
* object leak
*/
- status = hdd_softap_deregister_bc_sta(adapter);
- if (!QDF_IS_STATUS_SUCCESS(status))
- hdd_err("Failed to deregister BC sta Id %d",
- ap_ctx->broadcast_sta_id);
+ hdd_for_each_station_safe(adapter->sta_info_list, sta_info,
+ index, tmp) {
+ status = hdd_softap_deregister_sta(adapter,
+ sta_info);
- for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
- /* This excludes BC sta as it is already deregistered */
- if (adapter->sta_info[sta_id].in_use) {
- status = hdd_softap_deregister_sta(
- adapter, sta_id,
- adapter->sta_info[sta_id].sta_mac);
- if (!QDF_IS_STATUS_SUCCESS(status)) {
- hdd_err("Failed to deregister sta Id %d",
- sta_id);
- }
- }
+ if (QDF_IS_STATUS_ERROR(status) && sta_info)
+ hdd_err("Deregistering STA " QDF_MAC_ADDR_STR " failed",
+ QDF_MAC_ADDR_ARRAY(sta_info->sta_mac.bytes));
}
+
if (adapter->device_mode == QDF_SAP_MODE &&
!hdd_ctx->config->disable_channel)
wlan_hdd_restore_channels(hdd_ctx, true);
@@ -1301,31 +1235,34 @@
struct qdf_mac_addr *sta_mac,
enum ol_txrx_peer_state state)
{
- uint8_t sta_id = WLAN_MAX_STA_COUNT;
QDF_STATUS qdf_status;
+ struct hdd_station_info *sta_info;
+ struct qdf_mac_addr mac_addr;
hdd_enter_dev(adapter->dev);
- qdf_status = hdd_softap_get_sta_id(adapter, sta_mac, &sta_id);
- if (QDF_STATUS_SUCCESS != qdf_status) {
- hdd_err("Failed to find right station");
- return qdf_status;
+ sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ sta_mac->bytes);
+
+ if (!sta_info) {
+ hdd_err("Failed to find right station MAC: " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(sta_mac->bytes));
+ return QDF_STATUS_E_INVAL;
}
- if (false ==
- qdf_is_macaddr_equal(&adapter->sta_info[sta_id].sta_mac,
- sta_mac)) {
- hdd_err("Station %u MAC address not matching", sta_id);
- return QDF_STATUS_E_FAILURE;
- }
+ if (qdf_is_macaddr_broadcast(&sta_info->sta_mac))
+ qdf_mem_copy(&mac_addr, &adapter->mac_addr, QDF_MAC_ADDR_SIZE);
+ else
+ qdf_mem_copy(&mac_addr, sta_mac, QDF_MAC_ADDR_SIZE);
qdf_status =
- hdd_change_peer_state(adapter, sta_id, state, false);
- hdd_info("Station %u changed to state %d", sta_id, state);
+ hdd_change_peer_state(adapter, mac_addr.bytes,
+ state, false);
+ hdd_info("Station " QDF_MAC_ADDR_STR " changed to state %d",
+ QDF_MAC_ADDR_ARRAY(mac_addr.bytes), state);
if (QDF_STATUS_SUCCESS == qdf_status) {
- adapter->sta_info[sta_id].peer_state =
- OL_TXRX_PEER_STATE_AUTH;
+ sta_info->peer_state = OL_TXRX_PEER_STATE_AUTH;
p2p_peer_authorized(adapter->vdev, sta_mac->bytes);
}
@@ -1333,20 +1270,3 @@
return qdf_status;
}
-QDF_STATUS hdd_softap_get_sta_id(struct hdd_adapter *adapter,
- struct qdf_mac_addr *sta_mac,
- uint8_t *sta_id)
-{
- uint8_t i;
-
- for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
- if (!qdf_mem_cmp
- (&adapter->sta_info[i].sta_mac, sta_mac,
- QDF_MAC_ADDR_SIZE) && adapter->sta_info[i].in_use) {
- *sta_id = i;
- return QDF_STATUS_SUCCESS;
- }
- }
-
- return QDF_STATUS_E_FAILURE;
-}
diff --git a/core/hdd/src/wlan_hdd_sta_info.c b/core/hdd/src/wlan_hdd_sta_info.c
new file mode 100644
index 0000000..961b05f
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_sta_info.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_sta_info.c
+ *
+ * Store and manage station info structure.
+ *
+ */
+
+#include "wlan_hdd_sta_info.h"
+#include <wlan_hdd_includes.h>
+
+/* Generate a numeric constant to form the key to be provided for hashing */
+#define WLAN_HDD_STA_INFO_HASH(addr) \
+ (((const uint8_t *)addr)[QDF_MAC_ADDR_SIZE - 1])
+
+QDF_STATUS hdd_sta_info_init(struct hdd_sta_info_obj *sta_info_container)
+{
+ if (!sta_info_container) {
+ hdd_err("Parameter null");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ qdf_spinlock_create(&sta_info_container->sta_obj_lock);
+ qdf_ht_init(sta_info_container->sta_obj);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+void hdd_sta_info_deinit(struct hdd_sta_info_obj *sta_info_container)
+{
+ if (!sta_info_container) {
+ hdd_err("Parameter null");
+ return;
+ }
+
+ qdf_ht_deinit(sta_info_container->sta_obj);
+ qdf_spinlock_destroy(&sta_info_container->sta_obj_lock);
+}
+
+QDF_STATUS hdd_sta_info_attach(struct hdd_sta_info_obj *sta_info_container,
+ struct hdd_station_info *sta_info)
+{
+ if (!sta_info_container || !sta_info) {
+ hdd_err("Parameter(s) null");
+ return QDF_STATUS_E_INVAL;
+ }
+
+ qdf_spin_lock_bh(&sta_info_container->sta_obj_lock);
+
+ qdf_ht_add(sta_info_container->sta_obj, &sta_info->sta_node,
+ WLAN_HDD_STA_INFO_HASH(sta_info->sta_mac.bytes));
+
+ qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+void hdd_sta_info_detach(struct hdd_sta_info_obj *sta_info_container,
+ struct hdd_station_info *sta_info)
+{
+ if (!sta_info_container || !sta_info) {
+ hdd_err("Parameter(s) null");
+ return;
+ }
+
+ qdf_spin_lock_bh(&sta_info_container->sta_obj_lock);
+
+ qdf_ht_remove(&sta_info->sta_node);
+
+ qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
+
+ qdf_mem_free(sta_info);
+ sta_info = NULL;
+}
+
+struct hdd_station_info *hdd_get_sta_info_by_mac(
+ struct hdd_sta_info_obj *sta_info_container,
+ const uint8_t *mac_addr)
+{
+ struct hdd_station_info *sta_info = NULL;
+
+ if (!mac_addr || !sta_info_container) {
+ hdd_err("Parameter(s) null");
+ return NULL;
+ }
+
+ qdf_spin_lock_bh(&sta_info_container->sta_obj_lock);
+
+ qdf_ht_for_each_in_bucket(sta_info_container->sta_obj, sta_info,
+ sta_node, WLAN_HDD_STA_INFO_HASH(mac_addr)) {
+ if (qdf_is_macaddr_equal(&sta_info->sta_mac,
+ (struct qdf_mac_addr *)mac_addr)) {
+ qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
+ return sta_info;
+ }
+ }
+
+ qdf_spin_unlock_bh(&sta_info_container->sta_obj_lock);
+
+ return NULL;
+}
diff --git a/core/hdd/src/wlan_hdd_sta_info.h b/core/hdd/src/wlan_hdd_sta_info.h
new file mode 100644
index 0000000..9e98adc
--- /dev/null
+++ b/core/hdd/src/wlan_hdd_sta_info.h
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2019 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * DOC: wlan_hdd_sta_info.h
+ *
+ * Store and manage station info structure.
+ *
+ */
+#if !defined(__WLAN_HDD_STA_INFO_H)
+#define __WLAN_HDD_STA_INFO_H
+
+#include "qdf_lock.h"
+#include "qdf_types.h"
+#include "qdf_hashtable.h"
+#include "sap_api.h"
+#include "cdp_txrx_cmn_struct.h"
+#include "sir_mac_prot_def.h"
+#include <linux/ieee80211.h>
+
+/* A bucket size of 2^4 = 16 */
+#define WLAN_HDD_STA_INFO_SIZE 4
+
+/* Opaque handle for abstraction */
+#define hdd_sta_info_entry qdf_ht_entry
+
+/**
+ * struct dhcp_phase - Per Peer DHCP Phases
+ * @DHCP_PHASE_ACK: upon receiving DHCP_ACK/NAK message in REQUEST phase or
+ * DHCP_DELINE message in OFFER phase
+ * @DHCP_PHASE_DISCOVER: upon receiving DHCP_DISCOVER message in ACK phase
+ * @DHCP_PHASE_OFFER: upon receiving DHCP_OFFER message in DISCOVER phase
+ * @DHCP_PHASE_REQUEST: upon receiving DHCP_REQUEST message in OFFER phase or
+ * ACK phase (Renewal process)
+ */
+enum dhcp_phase {
+ DHCP_PHASE_ACK,
+ DHCP_PHASE_DISCOVER,
+ DHCP_PHASE_OFFER,
+ DHCP_PHASE_REQUEST
+};
+
+/**
+ * struct dhcp_nego_status - Per Peer DHCP Negotiation Status
+ * @DHCP_NEGO_STOP: when the peer is in ACK phase or client disassociated
+ * @DHCP_NEGO_IN_PROGRESS: when the peer is in DISCOVER or REQUEST
+ * (Renewal process) phase
+ */
+enum dhcp_nego_status {
+ DHCP_NEGO_STOP,
+ DHCP_NEGO_IN_PROGRESS
+};
+
+/**
+ * struct hdd_station_info - Per station structure kept in HDD for
+ * multiple station support for SoftAP
+ * @in_use: Is the station entry in use?
+ * @sta_id: Station ID reported back from HAL (through SAP).
+ * Broadcast uses station ID zero by default.
+ * @sta_type: Type of station i.e. p2p client or infrastructure station
+ * @sta_mac: MAC address of the station
+ * @peer_state: Current Station state so HDD knows how to deal with packet
+ * queue. Most recent states used to change TLSHIM STA state.
+ * @is_qos_enabled: Track QoS status of station
+ * @is_deauth_in_progress: The station entry for which Deauth is in progress
+ * @nss: Number of spatial streams supported
+ * @rate_flags: Rate Flags for this connection
+ * @ecsa_capable: Extended CSA capabilities
+ * @max_phy_rate: Calcuated maximum phy rate based on mode, nss, mcs etc.
+ * @tx_packets: Packets send to current station
+ * @tx_bytes: Bytes send to current station
+ * @rx_packets: Packets received from current station
+ * @rx_bytes: Bytes received from current station
+ * @last_tx_rx_ts: Last tx/rx timestamp with current station
+ * @assoc_ts: Current station association timestamp
+ * @tx_rate: Tx rate with current station reported from F/W
+ * @rx_rate: Rx rate with current station reported from F/W
+ * @ampdu: Ampdu enable or not of the station
+ * @sgi_enable: Short GI enable or not of the station
+ * @tx_stbc: Tx Space-time block coding enable/disable
+ * @rx_stbc: Rx Space-time block coding enable/disable
+ * @ch_width: Channel Width of the connection
+ * @mode: Mode of the connection
+ * @max_supp_idx: Max supported rate index of the station
+ * @max_ext_idx: Max extended supported rate index of the station
+ * @max_mcs_idx: Max supported mcs index of the station
+ * @rx_mcs_map: VHT Rx mcs map
+ * @tx_mcs_map: VHT Tx mcs map
+ * @freq : Frequency of the current station
+ * @dot11_mode: 802.11 Mode of the connection
+ * @ht_present: HT caps present or not in the current station
+ * @vht_present: VHT caps present or not in the current station
+ * @ht_caps: HT capabilities of current station
+ * @vht_caps: VHT capabilities of current station
+ * @reason_code: Disconnection reason code for current station
+ * @rssi: RSSI of the current station reported from F/W
+ * @capability: Capability information of current station
+ * @support_mode: Max supported mode of a station currently
+ * connected to sap
+ * @rx_retry_cnt: Number of rx retries received from current station
+ * Currently this feature is not supported from FW
+ * @rx_mc_bc_cnt: Multicast broadcast packet count received from
+ * current station
+ * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt
+ * feature or not, if first bit is 1 it indicates that FW supports this
+ * feature, if it is 0 it indicates FW doesn't support this feature
+ * @sta_info: The sta_info node for the station info list maintained in adapter
+ */
+struct hdd_station_info {
+ bool in_use;
+ uint8_t sta_id;
+ eStationType sta_type;
+ struct qdf_mac_addr sta_mac;
+ enum ol_txrx_peer_state peer_state;
+ bool is_qos_enabled;
+ bool is_deauth_in_progress;
+ uint8_t nss;
+ uint32_t rate_flags;
+ uint8_t ecsa_capable;
+ uint32_t max_phy_rate;
+ uint32_t tx_packets;
+ uint64_t tx_bytes;
+ uint32_t rx_packets;
+ uint64_t rx_bytes;
+ qdf_time_t last_tx_rx_ts;
+ qdf_time_t assoc_ts;
+ qdf_time_t disassoc_ts;
+ uint32_t tx_rate;
+ uint32_t rx_rate;
+ bool ampdu;
+ bool sgi_enable;
+ bool tx_stbc;
+ bool rx_stbc;
+ tSirMacHTChannelWidth ch_width;
+ uint8_t mode;
+ uint8_t max_supp_idx;
+ uint8_t max_ext_idx;
+ uint8_t max_mcs_idx;
+ uint8_t rx_mcs_map;
+ uint8_t tx_mcs_map;
+ uint32_t freq;
+ uint8_t dot11_mode;
+ bool ht_present;
+ bool vht_present;
+ struct ieee80211_ht_cap ht_caps;
+ struct ieee80211_vht_cap vht_caps;
+ uint32_t reason_code;
+ int8_t rssi;
+ enum dhcp_phase dhcp_phase;
+ enum dhcp_nego_status dhcp_nego_status;
+ uint16_t capability;
+ uint8_t support_mode;
+ uint32_t rx_retry_cnt;
+ uint32_t rx_mc_bc_cnt;
+ struct qdf_ht_entry sta_node;
+};
+
+/**
+ * struct hdd_sta_info_obj - Station info container structure
+ * @sta_obj: The sta info object that stores the sta_info
+ * @sta_obj_lock: Lock to protect the sta_obj read/write access
+ */
+struct hdd_sta_info_obj {
+ qdf_ht_declare(sta_obj, WLAN_HDD_STA_INFO_SIZE);
+ qdf_spinlock_t sta_obj_lock;
+};
+
+/**
+ * hdd_for_each_station - Iterate over each station stored in the sta info
+ * container
+ * @sta_info_container: The station info container obj that stores and maintains
+ * the sta_info obj.
+ * @sta_info: The station info structure that acts as the iterator object.
+ * @index: The current index in which the current station is present.
+ *
+ * The sta_info will contain the structure that is fetched for that particular
+ * iteration. The index of the current iterator object in the container
+ * represents the bucket at which the given station info is stored.
+ */
+#define hdd_for_each_station(sta_info_container, sta_info, index) \
+ qdf_ht_for_each(sta_info_container.sta_obj, index, sta_info, sta_node)
+
+/**
+ * hdd_for_each_station_safe - Iterate over each station stored in the sta info
+ * container being safe for removal of the sta info
+ * @sta_info_container: The station info container obj that stores and maintains
+ * the sta_info obj.
+ * @sta_info: The station info structure that acts as the iterator object.
+ * @index: The current index in which the current station is present.
+ * @tmp: A &struct for temporary storage
+ *
+ * The sta_info will contain the structure that is fetched for that particular
+ * iteration. The index of the current iterator object in the container
+ * represents the bucket at which the given station info is stored.
+ */
+#define hdd_for_each_station_safe(sta_info_container, sta_info, index, tmp) \
+ qdf_ht_for_each_safe(sta_info_container.sta_obj, index, tmp, \
+ sta_info, sta_node)
+
+/**
+ * wlan_sta_info_init() - Initialise the wlan hdd station info container obj
+ * @sta_info_container: The station info container obj that stores and maintains
+ * the sta_info obj.
+ *
+ * Return: QDF_STATUS_SUCCESS on success, failure code otherwise
+ */
+QDF_STATUS hdd_sta_info_init(struct hdd_sta_info_obj *sta_info_container);
+
+/**
+ * wlan_sta_info_deinit() - Deinit the wlan hdd station info container obj
+ * @sta_info_container: The station info container obj that stores and maintains
+ * the sta_info obj.
+ *
+ * Return: None
+ */
+void hdd_sta_info_deinit(struct hdd_sta_info_obj *sta_info_container);
+
+/**
+ * hdd_sta_info_detach() - Detach the station info structure from the list
+ * @sta_info_container: The station info container obj that stores and maintains
+ * the sta_info obj.
+ * @sta_info: The station info structure that has to be detached from the
+ * container object.
+ *
+ * Return: None
+ */
+void hdd_sta_info_detach(struct hdd_sta_info_obj *sta_info_container,
+ struct hdd_station_info *sta_info);
+
+/**
+ * hdd_sta_info_attach() - Attach the station info structure into the list
+ * @sta_info_container: The station info container obj that stores and maintains
+ * the sta_info obj.
+ * @sta_info: The station info structure that is to be attached to the
+ * container object.
+ *
+ * Return: QDF STATUS SUCCESS on successful attach, error code otherwise
+ */
+QDF_STATUS hdd_sta_info_attach(struct hdd_sta_info_obj *sta_info_container,
+ struct hdd_station_info *sta_info);
+
+/**
+ * hdd_get_sta_info_by_mac() - Find the sta_info structure by mac addr
+ * @sta_info_container: The station info container obj that stores and maintains
+ * the sta_info obj.
+ * @mac_addr: The mac addr by which the sta_info has to be fetched.
+ *
+ * Return: Pointer to the hdd_station_info structure which contains the mac
+ * address passed
+ */
+struct hdd_station_info *hdd_get_sta_info_by_mac(
+ struct hdd_sta_info_obj *sta_info_container,
+ const uint8_t *mac_addr);
+
+#endif /* __WLAN_HDD_STA_INFO_H */
diff --git a/core/hdd/src/wlan_hdd_station_info.c b/core/hdd/src/wlan_hdd_station_info.c
index 601fcd1..48da5ca 100644
--- a/core/hdd/src/wlan_hdd_station_info.c
+++ b/core/hdd/src/wlan_hdd_station_info.c
@@ -34,6 +34,7 @@
#include <wlan_hdd_hostapd.h>
#include <wlan_hdd_station_info.h>
#include "wlan_mlme_ucfg_api.h"
+#include "wlan_hdd_sta_info.h"
/*
* define short names for the global vendor params
@@ -1225,10 +1226,11 @@
struct hdd_adapter *adapter,
struct qdf_mac_addr mac_addr)
{
- struct hdd_station_info *stainfo = hdd_get_stainfo(adapter->sta_info,
- mac_addr);
int status = 0;
bool is_associated = false;
+ struct hdd_station_info *stainfo =
+ hdd_get_sta_info_by_mac(&adapter->sta_info_list,
+ mac_addr.bytes);
if (!stainfo) {
status = hdd_get_cached_station_remote(hdd_ctx, adapter,
diff --git a/core/hdd/src/wlan_hdd_stats.c b/core/hdd/src/wlan_hdd_stats.c
index cf4faa8..66d0c9c 100644
--- a/core/hdd/src/wlan_hdd_stats.c
+++ b/core/hdd/src/wlan_hdd_stats.c
@@ -40,6 +40,7 @@
#include "wlan_cp_stats_mc_ucfg_api.h"
#include "wlan_mlme_ucfg_api.h"
#include "wlan_mlme_ucfg_api.h"
+#include "wlan_hdd_sta_info.h"
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
#define HDD_INFO_SIGNAL STATION_INFO_SIGNAL
@@ -3908,7 +3909,6 @@
struct sir_peer_info_ext peer_info;
struct hdd_fw_txrx_stats txrx_stats;
int status;
- int i;
status = wlan_hdd_validate_context(hddctx);
if (status != 0)
@@ -3916,15 +3916,7 @@
hdd_debug("get peer %pM info", mac);
- for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
- if (!qdf_mem_cmp(adapter->sta_info[i].sta_mac.bytes,
- mac,
- QDF_MAC_ADDR_SIZE)) {
- stainfo = &adapter->sta_info[i];
- break;
- }
- }
-
+ stainfo = hdd_get_sta_info_by_mac(&adapter->sta_info_list, mac);
if (!stainfo) {
hdd_err("peer %pM not found", mac);
return -EINVAL;