Browse Source

qcacmn: Initial version of UMAC object manager

Define object manager framework. The object manager framework implements
the management of UMAC objects(PSOC/PDEV/VDEV/PEER). All components of UMAC
have to register their APIs with object manager to be invoked on object
creation/deletion.

It also provides public APIs to retrieve objects.

CRS-Fixed: 1096009
Change-Id: If1465aed8b5e05e23ee0e1d9c9818dbf92fbe55a
Srinivas Pitla 8 years ago
parent
commit
fa5290fe30

+ 6 - 0
qdf/inc/qdf_status.h

@@ -79,6 +79,9 @@
  * @QDF_STATUS_CMD_NOT_QUEUED: command not queued
  * @QDF_STATUS_FW_MSG_TIMEDOUT: target message timeout
  * @QDF_STATUS_E_USB_ERROR: USB transaction error
+ * @QDF_STATUS_MAXCOMP_FAIL: Component id is more than MAX UMAC components
+ * @QDF_STATUS_COMP_DISABLED: UMAC Component is disabled
+ * @QDF_STATUS_COMP_ASYNC: UMAC component runs in asynchronous communication
  * @QDF_STATUS_MAX: not a realy value just a place holder for max
  */
 typedef enum {
@@ -125,6 +128,9 @@ typedef enum {
 	QDF_STATUS_CMD_NOT_QUEUED,
 	QDF_STATUS_FW_MSG_TIMEDOUT,
 	QDF_STATUS_E_USB_ERROR,
+	QDF_STATUS_MAXCOMP_FAIL,
+	QDF_STATUS_COMP_DISABLED,
+	QDF_STATUS_COMP_ASYNC,
 	QDF_STATUS_MAX
 } QDF_STATUS;
 

+ 6 - 0
qdf/inc/qdf_types.h

@@ -296,6 +296,9 @@ typedef enum {
  * @QDF_EPPING_MODE: EPPING device mode
  * @QDF_QVIT_MODE: QVIT device mode
  * @QDF_NDI_MODE: NAN datapath mode
+ * @QDF_WDS_MODE: WDS mode
+ * @QDF_BTAMP_MODE: BTAMP mode
+ * @QDF_AHDEMO_MODE: AHDEMO mode
  * @QDF_MAX_NO_OF_MODE: Max place holder
  *
  * These are generic IDs that identify the various roles
@@ -314,6 +317,9 @@ enum tQDF_ADAPTER_MODE {
 	QDF_EPPING_MODE,
 	QDF_QVIT_MODE,
 	QDF_NDI_MODE,
+	QDF_WDS_MODE,
+	QDF_BTAMP_MODE,
+	QDF_AHDEMO_MODE,
 	QDF_MAX_NO_OF_MODE
 };
 

+ 294 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h

@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2016 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: This file provides the common defintions for object manager
+  */
+
+#ifndef _WLAN_OBJMGR_CMN_H_
+#define _WLAN_OBJMGR_CMN_H_
+
+#include "qdf_lock.h"
+#include "qdf_list.h"
+#include "qdf_status.h"
+
+/* No. of PSOCs can be supported */
+#define WLAN_OBJMGR_MAX_DEVICES 2
+/* Max no of UMAC components */
+#define WLAN_UMAC_MAX_COMPONENTS 25
+/* Max no. of radios, a pSoc/Device can support */
+#define WLAN_UMAC_MAX_PDEVS 3
+/* Max no. of VDEV per PSOC */
+#define WLAN_UMAC_PSOC_MAX_VDEVS 51
+/* Max no. of VDEVs, a PDEV can support */
+#define WLAN_UMAC_PDEV_MAX_VDEVS 17
+/* Max no. of Peers, a device can support */
+#define WLAN_UMAC_PSOC_MAX_PEERS 1024
+
+
+/* Max length of a SSID */
+#define WLAN_SSID_MAX_LEN 32
+
+/* Max no. of Stations can be associated to VDEV*/
+#define WLAN_UMAC_MAX_AP_PEERS WLAN_UMAC_PSOC_MAX_PEERS
+/* Max no. of peers for STA vap */
+#define WLAN_UMAC_MAX_STA_PEERS 2
+
+/* 802.11 cap info */
+#define WLAN_CAPINFO_ESS               0x0001
+#define WLAN_CAPINFO_IBSS              0x0002
+#define WLAN_CAPINFO_CF_POLLABLE       0x0004
+#define WLAN_CAPINFO_CF_POLLREQ        0x0008
+#define WLAN_CAPINFO_PRIVACY           0x0010
+#define WLAN_CAPINFO_SHORT_PREAMBLE    0x0020
+#define WLAN_CAPINFO_PBCC              0x0040
+#define WLAN_CAPINFO_CHNL_AGILITY      0x0080
+#define WLAN_CAPINFO_SPECTRUM_MGMT     0x0100
+#define WLAN_CAPINFO_QOS               0x0200
+#define WLAN_CAPINFO_SHORT_SLOTTIME    0x0400
+#define WLAN_CAPINFO_APSD              0x0800
+#define WLAN_CAPINFO_RADIOMEAS         0x1000
+#define WLAN_CAPINFO_DSSSOFDM          0x2000
+
+/**
+ * enum wlan_umac_comp_id - UMAC component id
+ * @WLAN_UMAC_COMP_MLME:        MLME
+ * @WLAN_UMAC_COMP_SCANMGR:     SCAN MGR
+ * @WLAN_UMAC_COMP_SCANCACHE:   SCAN CACHE
+ * @WLAN_UMAC_COMP_MGMT_TXRX:   MGMT Tx/Rx
+ *
+ * This id is static.
+ * On Adding new component, new id has to be assigned
+ */
+enum wlan_umac_comp_id {
+	WLAN_UMAC_COMP_MLME       = 0,
+	WLAN_UMAC_COMP_SCANMGR    = 1,
+	WLAN_UMAC_COMP_SCANCACHE  = 2,
+	WLAN_UMAC_COMP_MGMT_TXRX  = 3,
+};
+
+/**
+ * enum WLAN_OBJ_STATE - State of Object
+ * @WLAN_OBJ_STATE_CREATED:             All component objects are created
+ * @WLAN_OBJ_STATE_DELETED:             All component objects are deleted
+ * @WLAN_OBJ_STATE_PARTIALLY_CREATED:   Few/All component objects creation is
+ *                                      in progress
+ * @WLAN_OBJ_STATE_PARTIALLY_DELETED:   Few/All component objects yet to be
+ *                                      deleted
+ * @WLAN_OBJ_STATE_COMP_DEL_PROGRESS:   If a component is disabled run time,
+ *                                      and this state is used to represent the
+ *                                      deletion in progress after that
+ *                                      component object is deleted, object
+ *                                      state would be moved to CREATED state
+ * @WLAN_OBJ_STATE_CREATION_FAILED:     any component object is failed to be
+ *                                      created
+ * @WLAN_OBJ_STATE_DELETION_FAILED:     any component object is failed to be
+ *                                      deleted
+ */
+typedef enum {
+	WLAN_OBJ_STATE_CREATED            = 0,
+	WLAN_OBJ_STATE_DELETED            = 1,
+	WLAN_OBJ_STATE_PARTIALLY_CREATED  = 2,
+	WLAN_OBJ_STATE_PARTIALLY_DELETED  = 3,
+	WLAN_OBJ_STATE_COMP_DEL_PROGRESS  = 4,
+	WLAN_OBJ_STATE_CREATION_FAILED    = 5,
+	WLAN_OBJ_STATE_DELETION_FAILED    = 6,
+} WLAN_OBJ_STATE;
+
+/* Object type is assigned with value */
+enum wlan_objmgr_obj_type {
+	WLAN_PSOC_OP  = 0,
+	WLAN_PDEV_OP  = 1,
+	WLAN_VDEV_OP  = 2,
+	WLAN_PEER_OP  = 3,
+};
+
+/**
+ *  enum WLAN_DEV_TYPE  - for DA or OL architecture types
+ *  @WLAN_DEV_DA:       Direct attach
+ *  @WLAN_DEV_OL:       Partial offload
+ *  @WLAN_DEV_INVALID:  Invalid dev type
+ */
+typedef enum {
+	WLAN_DEV_DA       = 0,
+	WLAN_DEV_OL       = 1,
+	WLAN_DEV_INVALID  = 3,
+} WLAN_DEV_TYPE;
+
+/**
+ *  enum wlan_phymode - phy mode
+ *  @WLAN_PHYMODE_AUTO:           autoselect
+ *  @WLAN_PHYMODE_11A:            5GHz, OFDM
+ *  @WLAN_PHYMODE_11B:            2GHz, CCK
+ *  @WLAN_PHYMODE_11G:            2GHz, OFDM
+ *  @WLAN_PHYMODE_11NA_HT20:      5Ghz, HT20
+ *  @WLAN_PHYMODE_11NG_HT20:      2Ghz, HT20
+ *  @WLAN_PHYMODE_11NA_HT40PLUS:  5Ghz, HT40 (ext ch +1)
+ *  @WLAN_PHYMODE_11NA_HT40MINUS: 5Ghz, HT40 (ext ch -1)
+ *  @WLAN_PHYMODE_11NG_HT40PLUS:  2Ghz, HT40 (ext ch +1)
+ *  @WLAN_PHYMODE_11NG_HT40MINUS: 2Ghz, HT40 (ext ch -1)
+ *  @WLAN_PHYMODE_11NG_HT40:      2Ghz, Auto HT40
+ *  @WLAN_PHYMODE_11NA_HT40:      5Ghz, Auto HT40
+ *  @WLAN_PHYMODE_11AC_VHT20:     5Ghz, VHT20
+ *  @WLAN_PHYMODE_11AC_VHT40PLUS: 5Ghz, VHT40 (Ext ch +1)
+ *  @WLAN_PHYMODE_11AC_VHT40MINUS:5Ghz  VHT40 (Ext ch -1)
+ *  @WLAN_PHYMODE_11AC_VHT40:     5Ghz, VHT40
+ *  @WLAN_PHYMODE_11AC_VHT80:     5Ghz, VHT80
+ *  @WLAN_PHYMODE_11AC_VHT160:    5Ghz, VHT160
+ *  @WLAN_PHYMODE_11AC_VHT80_80:  5Ghz, VHT80_80
+ */
+enum wlan_phymode {
+	WLAN_PHYMODE_AUTO             = 0,
+	WLAN_PHYMODE_11A              = 1,
+	WLAN_PHYMODE_11B              = 2,
+	WLAN_PHYMODE_11G              = 3,
+	WLAN_PHYMODE_11NA_HT20        = 4,
+	WLAN_PHYMODE_11NG_HT20        = 5,
+	WLAN_PHYMODE_11NA_HT40PLUS    = 6,
+	WLAN_PHYMODE_11NA_HT40MINUS   = 7,
+	WLAN_PHYMODE_11NG_HT40PLUS    = 8,
+	WLAN_PHYMODE_11NG_HT40MINUS   = 9,
+	WLAN_PHYMODE_11NG_HT40        = 10,
+	WLAN_PHYMODE_11NA_HT40        = 11,
+	WLAN_PHYMODE_11AC_VHT20       = 12,
+	WLAN_PHYMODE_11AC_VHT40PLUS   = 13,
+	WLAN_PHYMODE_11AC_VHT40MINUS  = 14,
+	WLAN_PHYMODE_11AC_VHT40       = 15,
+	WLAN_PHYMODE_11AC_VHT80       = 16,
+	WLAN_PHYMODE_11AC_VHT160      = 17,
+	WLAN_PHYMODE_11AC_VHT80_80    = 18,
+};
+
+#define WLAN_PHYMODE_MAX      (WLAN_PHYMODE_11AC_VHT80_80 + 1)
+
+/**
+ * enum wlan_peer_type  - peer type
+ * @WLAN_PEER_SELF:     for AP mode, SELF PEER or AP PEER are same
+ * @WLAN_PEER_AP:       BSS peer for STA mode, Self peer for AP mode
+ * @WLAN_PEER_STA:      Self Peer for STA mode, STA peer for AP mode
+ * @WLAN_PEER_TDLS:     TDLS Peer
+ * @WLAN_PEER_NAWDS:    NAWDS Peer
+ * @WLAN_PEER_STA_TEMP: STA Peer Temp (its host only node)
+ */
+enum wlan_peer_type {
+	WLAN_PEER_SELF     = 1,
+	WLAN_PEER_AP       = 2,
+	WLAN_PEER_STA      = 3,
+	WLAN_PEER_TDLS     = 4,
+	WLAN_PEER_NAWDS    = 5,
+	WLAN_PEER_STA_TEMP = 6,
+};
+
+/* MAC address length */
+#define WLAN_MACADDR_LEN 6
+/* Util API to copy the MAC address */
+#define WLAN_ADDR_COPY(dst, src)    qdf_mem_copy(dst, src, WLAN_MACADDR_LEN)
+/* Util API to compare the MAC address */
+#define WLAN_ADDR_EQ(a1, a2)   qdf_mem_cmp(a1, a2, WLAN_MACADDR_LEN)
+
+/* size of Hash */
+#define WLAN_PEER_HASHSIZE 64
+/* simple hash is enough for variation of macaddr */
+#define WLAN_PEER_HASH(addr)   \
+(((const uint8_t *)(addr))[WLAN_MACADDR_LEN - 1] % WLAN_PEER_HASHSIZE)
+
+/* Allowed time to wait for Object creation  */
+#define WLAN_VDEV_CREATE_TIMEOUT_CNT 300
+ /* 25 msec */
+#define WLAN_VDEV_CREATE_TIMEOUT ((CONVERT_SEC_TO_SYSTEM_TIME(1)/40) + 1)
+
+#define WLAN_PDEV_CREATE_TIMEOUT_CNT 300
+ /* 25 msec */
+#define WLAN_PDEV_CREATE_TIMEOUT ((CONVERT_SEC_TO_SYSTEM_TIME(1)/40) + 1)
+
+#define WLAN_PSOC_CREATE_TIMEOUT_CNT 300
+/* 25 msec */
+#define WLAN_PSOC_CREATE_TIMEOUT ((CONVERT_SEC_TO_SYSTEM_TIME(1)/40) + 1)
+
+/**
+ * struct wlan_peer_list {
+ * @peer_hash[]:    peer sub lists
+ * @peer_list_lock: List lock, this has to be acquired on
+ *		    accessing/updating the list
+ *
+ *  Peer list, it maintains sublists based on the MAC address as hash
+ *  Note: For DA WDS similar peer list has to be maintained
+ *  This peer list will not have WDS nodes
+ */
+struct wlan_peer_list {
+	qdf_list_t peer_hash[WLAN_PEER_HASHSIZE];
+	qdf_spinlock_t peer_list_lock;
+};
+
+struct wlan_objmgr_psoc;
+struct wlan_objmgr_pdev;
+struct wlan_objmgr_vdev;
+struct wlan_objmgr_peer;
+
+/* Create handler would return the following status
+	QDF_STATUS_SUCCESS--
+		For synchronous handler:- this is returned on successful
+	component object creation
+
+	QDF_STATUS_COMP_DISABLED--
+		For synchronous handler:- this is returned on if component
+	doesn't want to allocate
+
+	QDF_STATUS_COMP_ASYNC--
+		For asynchronous handler:- this is returned on if component
+	needs a context break
+
+	QDF_STATUS_E_NOMEM--
+		For synchronous handler:- this is returned on if component
+	can't allocate
+	QDF_STATUS_E_FAILURE--
+		For synchronous handler:- If it is failed,
+		For asynchronous handler:- If it is failed to post message
+	(means, not required)/feature is not supported
+*/
+typedef QDF_STATUS (*wlan_objmgr_psoc_create_handler)(
+				struct wlan_objmgr_psoc *psoc, void *arg);
+typedef QDF_STATUS (*wlan_objmgr_psoc_delete_handler)(
+				struct wlan_objmgr_psoc *psoc, void *arg);
+typedef void (*wlan_objmgr_psoc_status_handler)(struct wlan_objmgr_psoc *psoc,
+					 void *arg, QDF_STATUS status);
+
+typedef QDF_STATUS (*wlan_objmgr_pdev_create_handler)(
+				struct wlan_objmgr_pdev *pdev, void *arg);
+typedef QDF_STATUS (*wlan_objmgr_pdev_delete_handler)(
+				struct wlan_objmgr_pdev *pdev, void *arg);
+typedef void (*wlan_objmgr_pdev_status_handler)(
+				struct wlan_objmgr_pdev *pdev, void *arg,
+						QDF_STATUS status);
+
+typedef QDF_STATUS (*wlan_objmgr_vdev_create_handler)(
+				struct wlan_objmgr_vdev *vdev, void *arg);
+typedef QDF_STATUS (*wlan_objmgr_vdev_delete_handler)(
+				struct wlan_objmgr_vdev *vdev, void *arg);
+typedef void (*wlan_objmgr_vdev_status_handler)(
+				struct wlan_objmgr_vdev *vdev, void *arg,
+						QDF_STATUS status);
+
+typedef QDF_STATUS (*wlan_objmgr_peer_create_handler)(
+				struct wlan_objmgr_peer *peer, void *arg);
+typedef QDF_STATUS (*wlan_objmgr_peer_delete_handler)(
+				struct wlan_objmgr_peer *peer, void *arg);
+typedef void (*wlan_objmgr_peer_status_handler)(
+				struct wlan_objmgr_peer *peer, void *arg,
+						QDF_STATUS status);
+
+#endif /* _WLAN_OBJMGR_CMN_H_*/

+ 483 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_global_obj.h

@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2016 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: Public APIs to perform operations on Global objects
+  */
+#ifndef _WLAN_OBJMGR_GLOBAL_OBJ_H_
+#define _WLAN_OBJMGR_GLOBAL_OBJ_H_
+
+/**
+ * wlan_objmgr_global_obj_create() - Creates global object
+ *
+ * Creates global object, intializes with default values
+ *
+ * Return: SUCCESS  on successful creation,
+ *         FAILURE  on Mem alloc failure or allocated already
+ *
+ */
+QDF_STATUS wlan_objmgr_global_obj_create(void);
+
+/**
+ * wlan_objmgr_global_obj_delete() - Deletes global object
+ *
+ * Deletes global object
+ *
+ * Return: SUCCESS  on successful deletion,
+ *         FAILURE  on object is not found
+ *
+ */
+QDF_STATUS wlan_objmgr_global_obj_delete(void);
+
+/**
+ * wlan_objmgr_global_obj_can_deleted() - Checks whether global object
+ *					  can be deleted
+ *
+ * Checks the psoc table of global object, if psoc table is empty
+ * returns the SUCCESS
+ *
+ * Return: SUCCESS  on can be deleted,
+ *         FAILURE  on can't be deleted
+ *
+ */
+QDF_STATUS wlan_objmgr_global_obj_can_deleted(void);
+
+/**
+ * wlan_objmgr_register_psoc_create_handler() - register psoc create handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PSOC creation
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on PSOC creation
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_psoc_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_create_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_psoc_create_handler() - unregister psoc create handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PSOC creation
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_psoc_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_create_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_psoc_delete_handler() - register delete handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PSOC deletion
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on PSOC deletion
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_psoc_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_delete_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_psoc_delete_handler() - unregister delete handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PSOC deletion
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_psoc_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_delete_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_psoc_status_handler() - register status handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PSOC status
+ *         change
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on PSOC object status change
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_psoc_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_status_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_psoc_status_handler() - unregister status handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PSOC status
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_psoc_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_status_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_pdev_create_handler() - register pdev create handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PDEV creation
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on PDEV creation
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_pdev_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_create_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_pdev_create_handler() - unregister pdev create handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PDEV creation
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_pdev_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_create_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_pdev_delete_handler() - register pdev delete handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PDEV deletion
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on PDEV deletion
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_pdev_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_delete_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_pdev_delete_handler() - unregister pdev delete handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PDEV deletion
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_pdev_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_delete_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_pdev_status_handler() - register pdev status handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PDEV status
+ *         change
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on PDEV object status change
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_pdev_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_status_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_pdev_status_handler() - unregister pdev status handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PDEV status
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_pdev_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_status_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_vdev_create_handler() - register vdev create handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on VDEV creation
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on VDEV creation
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_vdev_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_create_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_vdev_create_handler() - unregister vdev create handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on VDEV creation
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_vdev_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_create_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_vdev_delete_handler() - register vdev delete handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on VDEV deletion
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on VDEV deletion
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_vdev_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_delete_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_vdev_delete_handler() - unregister vdev delete handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on VDEV deletion
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_vdev_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_delete_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_vdev_status_handler() - register vdev status handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on VDEV status
+ *         change
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on VDEV object status change
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_vdev_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_status_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_vdev_status_handler() - unregister vdev status handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on VDEV status
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_vdev_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_status_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_peer_create_handler() - register peer create handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PEER creation
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on PEER creation
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_peer_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_create_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_peer_create_handler() - unregister peer create handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PEER creation
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_peer_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_create_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_peer_delete_handler() - register peer delete handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PEER deletion
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on PEER deletion
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_peer_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_delete_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_peer_delete_handler() - unregister peer delete handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PEER deletion
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_peer_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_delete_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_register_peer_status_handler() - register peer status handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PEER status
+ *         change
+ *
+ * API, allows other UMAC components to register handler
+ * The registered handler would be invoked on PEER object status change
+ *
+ * Return: SUCCESS,
+ *         Failure (if registration fails, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_register_peer_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_status_handler handler,
+		void *args);
+
+/**
+ * wlan_objmgr_unregister_peer_status_handler() - unregister peer status handler
+ * @id: component id
+ * @handler: function pointer of the component
+ * @args: args, if component wants certain args to be passed on PEER status
+ *
+ * API, allows other UMAC components to unregister handler
+ *
+ * Return: SUCCESS,
+ *         Failure (if handler is not present, each failure has different error
+ *         code)
+ */
+QDF_STATUS wlan_objmgr_unregister_peer_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_status_handler handler,
+		void *args);
+
+#endif /* _WLAN_OBJMGR_GLOBAL_OBJ_H_*/

+ 527 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_pdev_obj.h

@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2016 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: Define the pdev data structure of UMAC
+  * Public APIs to perform operations on Global objects
+  */
+#ifndef _WLAN_OBJMGR_PDEV_OBJ_H_
+#define _WLAN_OBJMGR_PDEV_OBJ_H_
+#include <wlan_objmgr_cmn.h>
+
+/* STATUS: scanning */
+#define WLAN_PDEV_F_SCAN                    0x00000001
+/* STATUS: use short slot time*/
+#define WLAN_PDEV_F_SHSLOT                  0x00000002
+  /* STATUS: channel switch event pending after DFS RADAR */
+#define WLAN_PDEV_F_DFS_CHANSWITCH_PENDING  0x00000004
+  /* TX Power: fixed rate */
+#define WLAN_PDEV_F_TXPOW_FIXED             0x00000008
+  /* STATUS: use short preamble */
+#define WLAN_PDEV_F_SHPREAMBLE              0x00000010
+  /* CONF: do alignment pad */
+#define WLAN_PDEV_F_DATAPAD                 0x00000020
+  /* STATUS: protection enabled */
+#define WLAN_PDEV_F_USEPROT                 0x00000040
+  /* STATUS: use barker preamble*/
+#define WLAN_PDEV_F_USEBARKER               0x00000080
+  /* CONF: DISABLE 2040 coexistance */
+#define WLAN_PDEV_F_COEXT_DISABLE           0x00000100
+  /* STATE: scan pending */
+#define WLAN_PDEV_F_SCAN_PENDING            0x00000200
+  /* CONF: send regclassids in country ie */
+#define WLAN_PDEV_F_REGCLASS                0x00000400
+  /* CONF: block the use of DFS channels */
+#define WLAN_PDEV_F_BLKDFSCHAN              0x00000800
+  /* STATUS: 11D in used */
+#define WLAN_PDEV_F_DOT11D                  0x00001000
+  /* STATUS: 11D channel-switch detected */
+#define WLAN_PDEV_F_RADAR                   0x00002000
+  /* CONF: A-MPDU supported */
+#define WLAN_PDEV_F_AMPDU                   0x00004000
+  /* CONF: A-MSDU supported */
+#define WLAN_PDEV_F_AMSDU                   0x00008000
+  /* CONF: HT traffic protected */
+#define WLAN_PDEV_F_HTPROT                  0x00010000
+  /* CONF: Reset once */
+#define WLAN_PDEV_F_RESET                   0x00020000
+  /* CONF: ignore 11d beacon */
+#define WLAN_PDEV_F_IGNORE_11D_BEACON       0x00040000
+  /* HT CAP IE present */
+#define WLAN_PDEV_F_HTVIE                   0x00080000
+ /* radio in middle of CSA */
+#define WLAN_PDEV_F_CSA_WAIT                0x00100000
+ /* wnm support flag */
+#define WLAN_PDEV_F_WNM                     0x00200000
+#define WLAN_PDEV_F_2G_CSA                  0x00400000
+  /* enhanced independent repeater  */
+#define WLAN_PDEV_F_ENH_REP_IND             0x00800000
+ /* Disable Tx AMSDU for station vap */
+#define WLAN_PDEV_F_STA_AMPDU_DIS           0x01000000
+/* do not send probe request in passive channel */
+#define WLAN_PDEV_F_STRICT_PSCAN_EN         0x02000000
+  /* dupie (ANA,pre ANA ) */
+/*#define WLAN_PDEV_F_DUPIE                 0x00200000*/
+
+/* PDEV op flags */
+   /* Enable htrate for wep and tkip */
+#define WLAN_PDEV_OP_WEP_TKIP_HTRATE    0x00000001
+  /* non HT AP found flag */
+#define WLAN_PDEV_OP_NON_HT_AP          0x00000002
+  /* block the use of DFS channels flag */
+#define WLAN_PDEV_OP_BLK_DFS_CHAN       0x00000004
+  /* 11.h flag */
+#define WLAN_PDEV_OP_DOTH               0x00000008
+  /* Off-channel support enabled */
+#define WLAN_PDEV_OP_OFFCHAN            0x00000010
+#define WLAN_PDEV_OP_HT20ADHOC          0x00000020
+#define WLAN_PDEV_OP_HT40ADHOC          0x00000040
+#define WLAN_PDEV_OP_HTADHOC_AGGR       0x00000080
+   /* disallow CC change when assoc completes */
+#define WLAN_PDEV_OP_DISALLOW_AUTO_CC   0x00000100
+   /* Is P2P Enabled? */
+#define WLAN_PDEV_OP_P2P                0x00000200
+   /* disallowed  */
+#define WLAN_PDEV_OP_IGNORE_DYNHALT     0x00000400
+   /* overwrite probe response IE with beacon IE */
+#define WLAN_PDEV_OP_OVERRIDE_PROBERESP 0x00000800
+#define WLAN_PDEV_OP_DROPSTA_QUERY      0x00001000
+#define WLAN_PDEV_OP_BLK_REPORT_FLOOD   0x00002000
+   /* Offchan scan */
+#define WLAN_PDEV_OP_OFFCHAN_SCAN       0x00004000
+   /*Consider OBSS non-erp to change to long slot*/
+#define WLAN_PDEV_OP_OBSS_LONGSLOT      0x00008000
+   /* enable/disable min rssi cli block */
+#define WLAN_PDEV_OP_MIN_RSSI_ENABLE    0x00010000
+
+/**
+ * struct wlan_objmgr_pdev_nif  - pdev object nif structure
+ * @pdev_fw_caps:       radio specific FW capabilities
+ * @pdev_feature_caps:  radio specific feature capabilities
+ * @pdev_ospriv:        OS specific pointer
+ * @notified_ap_vdev:   ap vdev
+ */
+struct wlan_objmgr_pdev_nif {
+	uint32_t pdev_fw_caps;
+	uint32_t pdev_feature_caps;
+	void *pdev_ospriv;
+	uint8_t notified_ap_vdev;
+};
+
+/**
+ * struct wlan_objmgr_pdev_mlme - pdev object mlme structure
+ * @pdev_op_flags:    PDEV operation flags, can be used to know the
+ *                    operation status (deletion progress, etc)
+ */
+struct wlan_objmgr_pdev_mlme {
+	uint32_t pdev_op_flags;
+};
+
+/**
+ * struct wlan_objmgr_pdev_objmgr - pdev object object manager structure
+ * @wlan_pdev_id:    PDEV id
+ * @wlan_vdev_list:  List maintains the VDEVs created on this PDEV
+ * @wlan_vdev_count: VDEVs count
+ * @max_vdev_count:  Max no. of VDEVs supported by this PDEV
+ * @wlan_psoc:       back pointer to PSOC, its attached to
+ */
+struct wlan_objmgr_pdev_objmgr {
+	uint8_t wlan_pdev_id;
+	qdf_list_t wlan_vdev_list;
+	uint8_t wlan_vdev_count;
+	uint8_t max_vdev_count;
+	struct wlan_objmgr_psoc *wlan_psoc;
+};
+
+/**
+ * struct wlan_objmgr_pdev - PDEV common object
+ * @current_chan_list: Active/current Channel list of the radio
+ * @pdev_nif:          pdev nif structure
+ * @pdev_objmgr:       pdev object manager structure
+ * @pdev_mlme:         pdev MLME structure
+ * @pdev_comp_obj[]:   component objects array
+ * @obj_status[]:      object status of each component object
+ * @obj_state:         object state
+ * @pdev_lock:         lock to protect object
+*/
+struct wlan_objmgr_pdev {
+	struct wlan_chan_list *current_chan_list;
+	struct wlan_objmgr_pdev_nif  pdev_nif;
+	struct wlan_objmgr_pdev_objmgr pdev_objmgr;
+	struct wlan_objmgr_pdev_mlme   pdev_mlme;
+	void *pdev_comp_obj[WLAN_UMAC_MAX_COMPONENTS];
+	QDF_STATUS obj_status[WLAN_UMAC_MAX_COMPONENTS];
+	WLAN_OBJ_STATE obj_state;
+	qdf_spinlock_t pdev_lock;
+};
+
+
+/**
+ ** APIs to Create/Delete Global object APIs
+ */
+/**
+ * wlan_objmgr_pdev_obj_create() - pdev create
+ * @psoc: PSOC object
+ * @scn: os private object
+ *
+ * Creates PDEV object, intializes with default values
+ * Invokes the registered notifiers to create component object
+ *
+ * Return: Handle to struct wlan_objmgr_psoc on successful creation,
+ *         NULL on Failure (on Mem alloc failure and Component objects
+ *         Failure)
+ */
+struct wlan_objmgr_pdev *wlan_objmgr_pdev_obj_create(
+			struct wlan_objmgr_psoc *psoc, void *scn);
+
+/**
+ * wlan_objmgr_pdev_obj_delete() - pdev delete
+ * @psoc: PDEV object
+ *
+ * Deletes PDEV object,
+ * Invokes the registered notifiers to delete component objects
+ *
+ * Return: SUCCESS/FAILURE
+ */
+QDF_STATUS wlan_objmgr_pdev_obj_delete(struct wlan_objmgr_pdev *pdev);
+
+/**
+ ** APIs to attach/detach component objects
+ */
+/**
+ * wlan_objmgr_pdev_component_obj_attach() - pdev comp object attach
+ * @psoc: PDEV object
+ * @id: Component id
+ * @comp_objptr: component's private object pointer
+ * @status: Component's private object creation status
+ *
+ * API to be used for attaching component object with PDEV common object
+ *
+ * Return: SUCCESS on successful storing of component's object in common object
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_pdev_component_obj_attach(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr,
+		QDF_STATUS status);
+
+/**
+ * wlan_objmgr_pdev_component_obj_detach() - pdev comp object detach
+ * @psoc: PDEV object
+ * @id: Component id
+ * @comp_objptr: component's private object pointer
+ *
+ * API to be used for detaching component object with PDEV common object
+ *
+ * Return: SUCCESS on successful removal of component's object from common
+ *         object
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_pdev_component_obj_detach(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr);
+
+/**
+ ** APIs to operations on pdev objects
+ */
+
+/**
+ * wlan_objmgr_pdev_iterate_obj_list() - operate on all objects of pdev
+ * @pdev: PDEV object
+ * @obj_type: VDEV_OP/PEER_OP
+ * @handler: the handler will be called for each object of requested type
+ *           the handler should be implemented to perform required operation
+ * @arg: agruments passed by caller
+ * @lock_free_op: This gives provision to run this API with out lock protected
+ *                It would be useful, for operations like Obj Delete, where
+ *                lock should not be taken by caller.
+ *
+ * API to be used for performing the operations on all VDEV/PEER objects
+ * of pdev
+ *
+ * Return: SUCCESS/FAILURE
+ */
+
+typedef void (*wlan_objmgr_pdev_op_handler)(struct wlan_objmgr_pdev *pdev,
+					void *object,
+					void *arg);
+
+QDF_STATUS wlan_objmgr_pdev_iterate_obj_list(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_objmgr_obj_type obj_type,
+		wlan_objmgr_pdev_op_handler handler,
+		void *arg, uint8_t lock_free_op);
+
+/**
+ * wlan_objmgr_trigger_pdev_comp_object_creation() - create comp object of pdev
+ * @pdev: PDEV object
+ * @id: Component id
+ *
+ * API to create component object in run time, this would be used for features
+ * which gets enabled in run time
+ *
+ * Return: SUCCESS on successful creation
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_trigger_pdev_comp_object_creation(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_umac_comp_id id);
+
+/**
+ * wlan_objmgr_trigger_pdev_comp_object_deletion() - delete comp object of pdev
+ * @pdev: PDEV object
+ * @id: Component id
+ *
+ * API to delete component object in run time, this would be used for features
+ * which gets disabled in run time
+ *
+ * Return: SUCCESS on successful deletion
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_trigger_pdev_comp_object_deletion(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_umac_comp_id id);
+
+/**
+ * wlan_objmgr_find_vdev_by_id_from_pdev() - find vdev using id from pdev
+ * @pdev: PDEV object
+ * @vdev_id: vdev id
+ *
+ * API to find vdev object pointer by vdev id from pdev's vdev list
+ *
+ * Return: vdev pointer
+ *         NULL on FAILURE
+ */
+struct wlan_objmgr_vdev *wlan_objmgr_find_vdev_by_id_from_pdev(
+			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id);
+
+/**
+ * wlan_objmgr_find_vdev_by_macaddr_from_pdev() - find vdev using macaddr
+ * @pdev: PDEV object
+ * @macaddr: MAC address
+ *
+ * API to find vdev object pointer by vdev mac addr from pdev's vdev list
+ *
+ * Return: vdev pointer
+ *         NULL on FAILURE
+ */
+struct wlan_objmgr_vdev *wlan_objmgr_find_vdev_by_macaddr_from_pdev(
+		struct wlan_objmgr_pdev *pdev, uint8_t *macaddr);
+
+/**
+ * wlan_pdev_obj_lock() - Acquire PDEV spinlock
+ * @pdev: PDEV object
+ *
+ * API to acquire PDEV lock
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_obj_lock(struct wlan_objmgr_pdev *pdev)
+{
+	qdf_spin_lock_bh(&pdev->pdev_lock);
+}
+
+/**
+ * wlan_pdev_obj_unlock() - Release PDEV spinlock
+ * @pdev: PDEV object
+ *
+ * API to Release PDEV lock
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_obj_unlock(struct wlan_objmgr_pdev *pdev)
+{
+	qdf_spin_unlock_bh(&pdev->pdev_lock);
+}
+
+/**
+ * wlan_pdev_get_psoc() - get psoc
+ * @pdev: PDEV object
+ *
+ * API to get the psoc object from PDEV
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return:
+ * @psoc: PSOC object
+ */
+static inline struct wlan_objmgr_psoc *wlan_pdev_get_psoc(
+			struct wlan_objmgr_pdev *pdev)
+{
+	return pdev->pdev_objmgr.wlan_psoc;
+}
+
+/**
+ * wlan_pdev_set_psoc() - set psoc
+ * @pdev: PDEV object
+ * @psoc: PSOC object
+ *
+ * API to set the psoc object from PDEV
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_set_psoc(struct wlan_objmgr_pdev *pdev,
+				struct wlan_objmgr_psoc *psoc)
+{
+	pdev->pdev_objmgr.wlan_psoc = psoc;
+}
+
+/**
+ * wlan_pdev_nif_fw_cap_set() - set fw caps
+ * @pdev: PDEV object
+ * @cap: capability flag to be set
+ *
+ * API to set fw caps in pdev
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_nif_fw_cap_set(struct wlan_objmgr_pdev *pdev,
+				uint32_t cap)
+{
+	pdev->pdev_nif.pdev_fw_caps |= cap;
+}
+
+/**
+ * wlan_pdev_nif_fw_cap_clear() - clear fw cap
+ * @pdev: PDEV object
+ * @cap: capability flag to be cleared
+ *
+ * API to clear fw caps in pdev
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_nif_fw_cap_clear(struct wlan_objmgr_pdev *pdev,
+				uint32_t cap)
+{
+	pdev->pdev_nif.pdev_fw_caps &= ~cap;
+}
+
+/**
+ * wlan_pdev_nif_fw_cap_get() - get fw caps
+ * @pdev: PDEV object
+ * @cap: capability flag to be checked
+ *
+ * API to know, whether particular fw caps flag is set in pdev
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return: 1 (for set) or 0 (for not set)
+ */
+static inline uint8_t wlan_pdev_nif_fw_cap_get(struct wlan_objmgr_pdev *pdev,
+				uint32_t cap)
+{
+	return (pdev->pdev_nif.pdev_fw_caps & cap) ? 1 : 0;
+}
+
+/**
+ * wlan_pdev_nif_feat_cap_set() - set feature caps
+ * @pdev: PDEV object
+ * @cap: capability flag to be set
+ *
+ * API to set feat caps in pdev
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_nif_feat_cap_set(struct wlan_objmgr_pdev *pdev,
+				uint32_t cap)
+{
+	pdev->pdev_nif.pdev_feature_caps |= cap;
+}
+
+/**
+ * wlan_pdev_nif_feat_cap_clear() - clear feature caps
+ * @pdev: PDEV object
+ * @cap: capability flag to be cleared
+ *
+ * API to clear feat caps in pdev
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_nif_feat_cap_clear(struct wlan_objmgr_pdev *pdev,
+				uint32_t cap)
+{
+	pdev->pdev_nif.pdev_feature_caps &= ~cap;
+}
+
+/**
+ * wlan_pdev_nif_feat_cap_get() - get feature caps
+ * @pdev: PDEV object
+ * @cap: capability flag to be checked
+ *
+ * API to know, whether particular feat caps flag is set in pdev
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return: 1 (for set) or 0 (for not set)
+ */
+static inline uint8_t wlan_pdev_nif_feat_cap_get(struct wlan_objmgr_pdev *pdev,
+				uint32_t cap)
+{
+	return (pdev->pdev_nif.pdev_feature_caps & cap) ? 1 : 0;
+}
+
+/**
+ * wlan_pdev_get_hw_macaddr() - get hw macaddr
+ * @pdev: PDEV object
+ *
+ * API to get HW MAC address form PDEV
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return: @macaddr -MAC address
+ */
+static inline uint8_t *wlan_pdev_get_hw_macaddr(struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+	return wlan_psoc_get_hw_macaddr(psoc);
+}
+
+/**
+ * wlan_pdev_set_hw_macaddr() - set hw macaddr
+ * @pdev: PDEV object
+ * @macaddr: MAC address
+ *
+ * API to set HW MAC address form PDEV
+ *
+ * Caller need to acquire lock with wlan_pdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_pdev_set_hw_macaddr(struct wlan_objmgr_pdev *pdev,
+			uint8_t *macaddr)
+{
+	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
+
+	if (psoc != NULL)
+		wlan_psoc_set_hw_macaddr(psoc, macaddr);
+}
+
+
+#endif /* _WLAN_OBJMGR_PDEV_H_*/

+ 648 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_peer_obj.h

@@ -0,0 +1,648 @@
+/*
+ * Copyright (c) 2016 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: Define the peer data structure of UMAC
+  *	Public APIs to perform operations on Global objects
+  */
+#ifndef _WLAN_OBJMGR_PEER_OBJ_H_
+#define _WLAN_OBJMGR_PEER_OBJ_H_
+#include <qdf_types.h>
+#include <qdf_atomic.h>
+
+/* peer flags */
+/* authorized for data */
+#define WLAN_PEER_F_AUTH                            0x00000001
+/* QoS enabled */
+#define WLAN_PEER_F_QOS                             0x00000002
+/* ERP enabled */
+#define WLAN_PEER_F_ERP                             0x00000004
+/* HT enabled */
+#define WLAN_PEER_F_HT                              0x00000008
+/* NB: tWLANhave the same value as IEEE80211_FC1_PWR_MGT */
+/* power save mode enabled */
+#define WLAN_PEER_F_PWR_MGT                         0x00000010
+/* keytsc for node has already been updated */
+#define WLAN_PEER_F_TSC_SET                         0x00000020
+/* U-APSD power save enabled */
+#define WLAN_PEER_F_UAPSD                           0x00000040
+/* U-APSD triggerable state */
+#define WLAN_PEER_F_UAPSD_TRIG                      0x00000080
+/* U-APSD SP in progress */
+#define WLAN_PEER_F_UAPSD_SP                        0x00000100
+/* Atheros Owl or follow-on device */
+#define WLAN_PEER_F_ATH                             0x00000200
+/* Owl WDS workaround needed*/
+#define WLAN_PEER_F_OWL_WDSWAR                      0x00000400
+/* WDS link */
+#define WLAN_PEER_F_WDS                             0x00000800
+/* No AMPDU support */
+#define WLAN_PEER_F_NOAMPDU                         0x00001000
+/* Atheros proprietary wep/tkip aggregation support */
+#define WLAN_PEER_F_WEPTKIPAGGR                     0x00002000
+#define WLAN_PEER_F_WEPTKIP                         0x00004000
+/* temp node (not in the node table) */
+#define WLAN_PEER_F_TEMP                            0x00008000
+/* 2.4ng VHT interop AMSDU disabled */
+#define WLAN_PEER_F_11NG_VHT_INTEROP_AMSDU_DISABLE  0x00010000
+/* HT40 Intolerant  */
+#define WLAN_PEER_F_40_INTOLERANT                   0x00020000
+/* node is  paused*/
+#define WLAN_PEER_F_PAUSED                          0x00040000
+#define WLAN_PEER_F_EXTRADELIMWAR                   0x00080000
+/* HT20 requesting node */
+#define WLAN_PEER_F_REQ_HT20                        0x00100000
+/* all the tid queues in ath layer are paused*/
+#define WLAN_PEER_F_ATH_PAUSED                      0x00200000
+/*Require credit update*/
+#define WLAN_PEER_F_UAPSD_CREDIT_UPDATE             0x00400000
+/*Require send deauth when h/w queue no data*/
+#define WLAN_PEER_F_KICK_OUT_DEAUTH                 0x00800000
+/* RRM enabled node */
+#define WLAN_PEER_F_RRM                             0x01000000
+/* Wakeup node */
+#define WLAN_PEER_F_WAKEUP                          0x02000000
+/* VHT enabled node */
+#define WLAN_PEER_F_VHT                             0x04000000
+/* deauth/Disassoc wait for node cleanup till frame goes on
+   air and tx feedback received */
+#define WLAN_PEER_F_DELAYED_CLEANUP                 0x08000000
+/* Extended stats enabled node */
+#define WLAN_PEER_F_EXT_STATS                       0x10000000
+/* Prevent _ieee80211_node_leave() from reentry */
+#define WLAN_PEER_F_LEAVE_ONGOING                   0x20000000
+/* band steering is enabled for this node */
+#define WLAN_PEER_F_BSTEERING_CAPABLE               0x40000000
+/* node is a local mesh peer */
+#define WLAN_PEER_F_LOCAL_MESH_PEER                 0x80000000
+
+/**
+ * enum wlan_peer_state  - peer state
+ * @WLAN_INIT_STATE:       Default state
+ * @WLAN_JOIN_STATE:       Station mode, STA is waiting for Join
+ * @WLAN_AUTH_STATE:       AUTH in progress
+ * @WLAN_ASSOC_STATE:      ASSOC in progress
+ * @WLAN_WAITKEY_STATE:    4-way KEY handshake is in progress
+ * @WLAN_CONNECTED_STATE:  Connected state
+ * @WLAN_PREAUTH_STATE:    Station mode: Preauth
+ * @WLAN_DISCONNECT_STATE: Disconnect is in progress
+ */
+enum wlan_peer_state {
+	WLAN_INIT_STATE       = 1,
+	WLAN_JOIN_STATE       = 2,
+	WLAN_AUTH_STATE       = 3,
+	WLAN_ASSOC_STATE      = 4,
+	WLAN_WAITKEY_STATE    = 5,
+	WLAN_CONNECTED_STATE  = 6,
+	WLAN_PREAUTH_STATE    = 7,
+	WLAN_DISCONNECT_STATE = 8,
+};
+
+/**
+ * struct wlan_objmgr_peer_mlme - mlme common data of peer
+ * @peer_capinfo:    protocol cap info
+ * @peer_flags:      PEER OP flags
+ * @peer_type:       Type of PEER, (STA/AP/etc.)
+ * @phymode:         phy mode of station
+ * @rssi:            Last received RSSI value
+ * @max_rate:        Max Rate supported
+ * @state:           State of the peer
+ */
+struct wlan_objmgr_peer_mlme {
+	uint32_t peer_capinfo;
+	uint32_t peer_flags;
+	enum wlan_peer_type peer_type;
+	enum wlan_phymode phymode;
+	int8_t rssi;
+	uint32_t max_rate;
+	enum wlan_peer_state state;
+};
+
+/**
+ * struct wlan_objmgr_peer_objmgr - object manager data of peer
+ * @vdev:      VDEV pointer to which it is associated
+ * @ref_cnt:  Ref count
+ */
+struct wlan_objmgr_peer_objmgr {
+	struct wlan_objmgr_vdev *vdev;
+	qdf_atomic_t ref_cnt;
+};
+
+/**
+ * struct wlan_peer_activity -- peer inactivity info
+ *
+ */
+struct wlan_peer_activity {  /*TODO */
+
+};
+
+/**
+ * struct wlan_objmgr_peer -  PEER common object
+ * @psoc_peer:        peer list node for psoc's qdf list
+ * @vdev_peer:        peer list node for vdev's qdf list
+ * @macaddr[]:        Peer MAC address
+ * @peer_mlme:	      Peer MLME common structure
+ * @peer_activity:    peer activity
+ * @peer_objmgr:      Peer Object manager common structure
+ * @peer_comp_obj[]:  Component object pointers
+ * @obj_status[]:     status of each component object
+ * @obj_state:        Status of Peer object
+ * @peer_lock:        Lock for access/update peer contents
+ */
+struct wlan_objmgr_peer {
+	qdf_list_node_t psoc_peer;
+	qdf_list_node_t vdev_peer;
+	uint8_t macaddr[WLAN_MACADDR_LEN];
+	struct wlan_objmgr_peer_mlme peer_mlme;
+	struct wlan_peer_activity peer_activity;
+	struct wlan_objmgr_peer_objmgr peer_objmgr;
+	void *peer_comp_obj[WLAN_UMAC_MAX_COMPONENTS];
+	QDF_STATUS obj_status[WLAN_UMAC_MAX_COMPONENTS];
+	WLAN_OBJ_STATE obj_state;
+	qdf_spinlock_t peer_lock;
+};
+
+/**
+ ** APIs to Create/Delete Global object APIs
+ */
+/**
+ * wlan_objmgr_peer_obj_create() - peer object create
+ * @vdev: VDEV object on which this peer gets created
+ * @peer_type: peer type (AP/STA)
+ * @macaddr: MAC address
+ *
+ * Creates Peer object, intializes with default values
+ * Attaches to psoc and vdev objects
+ * Invokes the registered notifiers to create component object
+ *
+ * Return: Handle to struct wlan_objmgr_peer on successful creation,
+ *         NULL on Failure (on Mem alloc failure and Component objects
+ *         Failure)
+ */
+struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create(
+			struct wlan_objmgr_vdev *vdev,
+			enum wlan_peer_type type,
+			uint8_t macaddr[]);
+
+/**
+ * wlan_objmgr_peer_obj_delete() - peer object delete
+ * @peer: PEER object
+ *
+ * Deletes PEER object, removes it from PSOC's, VDEV's peer list
+ * Invokes the registered notifiers to delete component objects
+ *
+ * Return: SUCCESS/FAILURE
+ */
+QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer);
+
+/**
+ ** APIs to attach/detach component objects
+ */
+/**
+ * wlan_objmgr_peer_component_obj_attach() - attach comp object to peer
+ * @peer: PEER object
+ * @id: Component id
+ * @comp_objptr: component's private object pointer
+ * @status: Component's private object creation status
+ *
+ * API to be used for attaching component object with PEER common object
+ *
+ * Return: SUCCESS on successful storing of component's object in common object
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_peer_component_obj_attach(
+		struct wlan_objmgr_peer *peer,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr,
+		QDF_STATUS status);
+
+/**
+ * wlan_objmgr_peer_component_obj_detach() - detach comp object from peer
+ * @peer: PEER object
+ * @id: Component id
+ * @comp_objptr: component's private object pointer
+ *
+ * API to be used for detaching component object with PEER common object
+ *
+ * Return: SUCCESS on successful removal of component's object from common
+ *         object
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_peer_component_obj_detach(
+		struct wlan_objmgr_peer *peer,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr);
+
+/**
+ ** APIs to operations on peer objects
+ */
+
+/**
+ * wlan_objmgr_trigger_peer_comp_object_creation() - create peer comp object
+ * @peer: PEER object
+ * @id: Component id
+ *
+ * API to create component object in run time, this would be used for features
+ * which gets enabled in run time
+ *
+ * Return: SUCCESS on successful creation
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_trigger_peer_comp_object_creation(
+		struct wlan_objmgr_peer *peer,
+		enum wlan_umac_comp_id id);
+
+/**
+ * wlan_objmgr_trigger_peer_comp_object_deletion() - delete peer comp object
+ * @peer: PEER object
+ * @id: Component id
+ *
+ * API to delete component object in run time, this would be used for features
+ * which gets disabled in run time
+ *
+ * Return: SUCCESS on successful deletion
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_trigger_peer_comp_object_deletion(
+		struct wlan_objmgr_peer *peer,
+		enum wlan_umac_comp_id id);
+
+/**
+ * wlan_peer_obj_lock() - Acquire PEER spinlock
+ * @psoc: PEER object
+ *
+ * API to acquire PEER spin lock
+ *
+ * Return: void
+ */
+static inline void wlan_peer_obj_lock(struct wlan_objmgr_peer *peer)
+{
+	qdf_spin_lock_bh(&peer->peer_lock);
+}
+
+/**
+ * wlan_peer_obj_unlock() - Release PEER spinlock
+ * @peer: PEER object
+ *
+ * API to Release PEER spin lock
+ *
+ * Return: void
+ */
+static inline void wlan_peer_obj_unlock(struct wlan_objmgr_peer *peer)
+{
+	qdf_spin_unlock_bh(&peer->peer_lock);
+}
+/**
+ * wlan_objmgr_peer_ref_peer() - increment ref count
+ * @peer: PEER object
+ *
+ * API to increment ref count of peer
+ *
+ * Return: void
+ */
+static inline void wlan_objmgr_peer_ref_peer(struct wlan_objmgr_peer *peer)
+{
+	if (peer == NULL) {
+		qdf_print("%s: peer obj is NULL\n", __func__);
+		return;
+	}
+	/* Increment ref count */
+	qdf_atomic_inc(&peer->peer_objmgr.ref_cnt);
+	return;
+}
+
+/**
+ * wlan_objmgr_peer_unref_peer() - decrement ref count
+ * @peer: PEER object
+ *
+ * API to decrement ref count of peer, if ref count is 1, it initiates the
+ * peer deletion
+ *
+ * Return: void
+ */
+static inline void wlan_objmgr_peer_unref_peer(struct wlan_objmgr_peer *peer)
+{
+	if (peer == NULL) {
+		qdf_print("%s: peer obj is NULL\n", __func__);
+		return;
+	}
+	/* Decrement ref count, free peer, if count becomes 0 */
+	if (qdf_atomic_dec_and_test(&peer->peer_objmgr.ref_cnt))
+		wlan_objmgr_peer_obj_delete(peer);
+	return;
+}
+
+/**
+ * wlan_psoc_peer_list_peek_head() - get head of psoc peer list
+ * @peer_list: qdf_list_t
+ *
+ * API to get the head peer of given peer (of psoc's peer list)
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return:
+ * @peer: head peer
+ */
+static inline struct wlan_objmgr_peer *wlan_psoc_peer_list_peek_head(
+					qdf_list_t *peer_list)
+{
+	struct wlan_objmgr_peer *peer;
+	qdf_list_node_t *psoc_node = NULL;
+
+	if (qdf_list_peek_front(peer_list, &psoc_node) != QDF_STATUS_SUCCESS)
+		return NULL;
+
+	peer = qdf_container_of(psoc_node, struct wlan_objmgr_peer, psoc_peer);
+	return peer;
+}
+
+/**
+ * wlan_vdev_peer_list_peek_head() - get head of vdev peer list
+ * @peer_list: qdf_list_t
+ *
+ * API to get the head peer of given peer (of vdev's peer list)
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return:
+ * @peer: head peer
+ */
+static inline struct wlan_objmgr_peer *wlan_vdev_peer_list_peek_head(
+					qdf_list_t *peer_list)
+{
+	struct wlan_objmgr_peer *peer;
+	qdf_list_node_t *vdev_node = NULL;
+
+	if (qdf_list_peek_front(peer_list, &vdev_node) != QDF_STATUS_SUCCESS)
+		return NULL;
+
+	peer = qdf_container_of(vdev_node, struct wlan_objmgr_peer, vdev_peer);
+	return peer;
+}
+
+/**
+ * wlan_peer_get_next_peer_of_vdev() - get next peer of vdev list
+ * @peer: PEER object
+ *
+ * API to get the next peer of given peer (of vdev's peer list)
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return:
+ * @next_peer: PEER object
+ */
+static inline struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_vdev(
+			qdf_list_t *peer_list, struct wlan_objmgr_peer *peer)
+{
+	struct wlan_objmgr_peer *peer_next;
+	qdf_list_node_t *node;
+	qdf_list_node_t *next_node = NULL;
+
+	if (peer == NULL)
+		return NULL;
+
+	node = &peer->vdev_peer;
+	if (qdf_list_peek_next(peer_list, node, &next_node) !=
+						QDF_STATUS_SUCCESS)
+		return NULL;
+
+	peer_next = qdf_container_of(next_node, struct wlan_objmgr_peer,
+					vdev_peer);
+	return peer_next;
+}
+
+/**
+ * wlan_peer_set_next_peer_of_vdev() - add peer to vdev peer list
+ * @peer: PEER object
+ * @new_peer: PEER object
+ *
+ * API to set as the next peer to given peer (of vdev's peer list)
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_peer_set_next_peer_of_vdev(qdf_list_t *peer_list,
+				struct wlan_objmgr_peer *new_peer)
+{
+	/* set next peer with new peer */
+	qdf_list_insert_back(peer_list, &new_peer->vdev_peer);
+	return;
+}
+
+/**
+ * wlan_peer_get_next_peer_of_psoc() - get next peer to psoc peer list
+ * @peer: PEER object
+ *
+ * API to get the next peer of given peer (of psoc's peer list)
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return:
+ * @next_peer: PEER object
+ */
+static inline struct wlan_objmgr_peer *wlan_peer_get_next_peer_of_psoc(
+			qdf_list_t *peer_list, struct wlan_objmgr_peer *peer)
+{
+	struct wlan_objmgr_peer *peer_next;
+	qdf_list_node_t *node = NULL;
+	qdf_list_node_t *next_node = NULL;
+
+	if (peer == NULL)
+		return NULL;
+
+	node = &peer->psoc_peer;
+	if (qdf_list_peek_next(peer_list, node, &next_node) !=
+						QDF_STATUS_SUCCESS)
+		return NULL;
+
+	peer_next = qdf_container_of(next_node, struct wlan_objmgr_peer,
+					psoc_peer);
+	return peer_next;
+}
+
+/**
+ * wlan_peer_set_next_peer_of_psoc() - add peer to psoc peer list
+ * @peer: PEER object
+ * @new_peer: PEER object
+ *
+ * API to set as the next peer to given peer (of psoc's peer list)
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_peer_set_next_peer_of_psoc(qdf_list_t *peer_list,
+					struct wlan_objmgr_peer *new_peer)
+{
+	/* set next peer with new peer */
+	qdf_list_insert_back(peer_list, &new_peer->psoc_peer);
+	return;
+}
+
+/**
+ * wlan_peer_set_peer_type() - set peer type
+ * @peer: PEER object
+ * @peer_type: type of PEER
+ *
+ * API to set peer type
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_peer_set_peer_type(struct wlan_objmgr_peer *peer,
+			enum wlan_peer_type type)
+{
+	peer->peer_mlme.peer_type = type;
+}
+
+/**
+ * wlan_peer_get_peer_type() - get peer type
+ * @peer: PEER object
+ *
+ * API to get peer type
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return:
+ * @peer_type: type of PEER
+ */
+static inline enum wlan_peer_type wlan_peer_get_peer_type(
+				struct wlan_objmgr_peer *peer)
+{
+	return peer->peer_mlme.peer_type;
+}
+
+/**
+ * wlan_peer_set_macaddr() - set mac addr
+ * @peer: PEER object
+ * @macaddr: MAC address
+ *
+ * API to set peer mac address
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_peer_set_macaddr(struct wlan_objmgr_peer *peer,
+			uint8_t *macaddr)
+{
+	WLAN_ADDR_COPY(peer->macaddr, macaddr);
+}
+
+/**
+ * wlan_peer_get_macaddr() - get mac addr
+ * @peer: PEER object
+ *
+ * API to get peer mac address
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return:
+ * @macaddr: MAC address
+ */
+static inline uint8_t *wlan_peer_get_macaddr(struct wlan_objmgr_peer *peer)
+{
+	return peer->macaddr;
+}
+
+/**
+ * wlan_peer_get_vdev() - get vdev
+ * @peer: PEER object
+ *
+ * API to get peer's vdev
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return:
+ * @vdev: VDEV object
+ */
+static inline struct wlan_objmgr_vdev *wlan_peer_get_vdev(
+			struct wlan_objmgr_peer *peer)
+{
+	return peer->peer_objmgr.vdev;
+}
+
+/**
+ * wlan_peer_set_vdev() - set vdev
+ * @peer: PEER object
+ * @vdev: VDEV object
+ *
+ * API to set peer's vdev
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_peer_set_vdev(struct wlan_objmgr_peer *peer,
+		struct wlan_objmgr_vdev *vdev)
+{
+	peer->peer_objmgr.vdev = vdev;
+}
+
+/**
+ * wlan_peer_mlme_flag_set() - mlme flag set
+ * @peer: PEER object
+ * @flag: flag to be set
+ *
+ * API to set flag in peer
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_peer_mlme_flag_set(struct wlan_objmgr_peer *peer,
+				uint32_t flag)
+{
+	peer->peer_mlme.peer_flags |= flag;
+}
+
+/**
+ * wlan_peer_mlme_flag_clear() - mlme flag clear
+ * @peer: PEER object
+ * @flag: flag to be cleared
+ *
+ * API to clear flag in peer
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_peer_mlme_flag_clear(struct wlan_objmgr_peer *peer,
+				uint32_t flag)
+{
+	peer->peer_mlme.peer_flags &= ~flag;
+}
+
+/**
+ * wlan_peer_mlme_flag_get() - mlme flag get
+ * @peer: PEER object
+ * @flag: flag to be checked
+ *
+ * API to know, whether particular flag is set in peer
+ *
+ * Caller need to acquire lock with wlan_peer_obj_lock()
+ *
+ * Return: 1 (for set) or 0 (for not set)
+ */
+static inline uint8_t wlan_peer_mlme_flag_get(struct wlan_objmgr_peer *peer,
+				uint32_t flag)
+{
+	return (peer->peer_mlme.peer_flags & flag) ? 1 : 0;
+}
+#endif /* _WLAN_OBJMGR_PEER_OBJ_H_*/

+ 742 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h

@@ -0,0 +1,742 @@
+/*
+ * Copyright (c) 2016 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: Define the pSoc data structure of UMAC
+  *      Public APIs to perform operations on Global objects
+  */
+#ifndef _WLAN_OBJMGR_PSOC_OBJ_H_
+#define _WLAN_OBJMGR_PSOC_OBJ_H_
+
+#include "wlan_objmgr_cmn.h"
+
+#define REG_DMN_CH144        0x0001
+#define REG_DMN_ENTREPRISE   0x0002
+
+
+/* fw_caps */
+	/* CAPABILITY: WEP available */
+#define WLAN_SOC_C_WEP                  0x00000001
+	/* CAPABILITY: TKIP available */
+#define WLAN_SOC_C_TKIP                 0x00000002
+	/* CAPABILITY: AES OCB avail */
+#define WLAN_SOC_C_AES                  0x00000004
+	/* CAPABILITY: AES CCM avail */
+#define WLAN_SOC_C_AES_CCM              0x00000008
+	/* CAPABILITY: 11n HT available */
+#define WLAN_SOC_C_HT                   0x00000010
+	/* CAPABILITY: CKIP available */
+#define WLAN_SOC_C_CKIP                 0x00000020
+	/* CAPABILITY: ATH FF avail */
+#define WLAN_SOC_C_FF                   0x00000040
+	/* CAPABILITY: ATH Turbo avail*/
+#define WLAN_SOC_C_TURBOP               0x00000080
+	/* CAPABILITY: IBSS available */
+#define WLAN_SOC_C_IBSS                 0x00000100
+	/* CAPABILITY: Power mgmt */
+#define WLAN_SOC_C_PMGT                 0x00000200
+	/* CAPABILITY: HOSTAP avail */
+#define WLAN_SOC_C_HOSTAP               0x00000400
+	/* CAPABILITY: Old Adhoc Demo */
+#define WLAN_SOC_C_AHDEMO               0x00000800
+	/* CAPABILITY: tx power mgmt */
+#define WLAN_SOC_C_TXPMGT               0x00001000
+	/* CAPABILITY: short slottime */
+#define WLAN_SOC_C_SHSLOT               0x00002000
+	/* CAPABILITY: short preamble */
+#define WLAN_SOC_C_SHPREAMBLE           0x00004000
+	/* CAPABILITY: monitor mode */
+#define WLAN_SOC_C_MONITOR              0x00008000
+	/* CAPABILITY: TKIP MIC avail */
+#define WLAN_SOC_C_TKIPMIC              0x00010000
+	/* CAPABILITY: ATH WAPI avail */
+#define WLAN_SOC_C_WAPI                 0x00020000
+	/* CONF: WDS auto Detect/DELBA */
+#define WLAN_SOC_C_WDS_AUTODETECT       0x00040000
+	/* CAPABILITY: WPA1 avail */
+#define WLAN_SOC_C_WPA1                 0x00080000
+	/* CAPABILITY: WPA2 avail */
+#define WLAN_SOC_C_WPA2                 0x00100000
+	/* CAPABILITY: WPA1+WPA2 avail*/
+#define WLAN_SOC_C_WPA                  0x00180000
+	/* CAPABILITY: frame bursting */
+#define WLAN_SOC_C_BURST                0x00200000
+	/* CAPABILITY: WME avail */
+#define WLAN_SOC_C_WME                  0x00400000
+	/* CAPABILITY: 4-addr support */
+#define WLAN_SOC_C_WDS                  0x00800000
+	/* CAPABILITY: TKIP MIC for QoS frame */
+#define WLAN_SOC_C_WME_TKIPMIC          0x01000000
+	/* CAPABILITY: bg scanning */
+#define WLAN_SOC_C_BGSCAN               0x02000000
+	/* CAPABILITY: UAPSD */
+#define WLAN_SOC_C_UAPSD                0x04000000
+	/* CAPABILITY: enabled 11.h */
+#define WLAN_SOC_C_DOTH                 0x08000000
+
+/* XXX protection/barker? */
+	/* CAPABILITY: crypto alg's */
+#define WLAN_SOC_C_CRYPTO         0x0000002f
+
+/* fw_caps_ext */
+	/* CAPABILITY: fast channel change */
+#define WLAN_SOC_CEXT_FASTCC           0x00000001
+	/* CAPABILITY: P2P */
+#define WLAN_SOC_CEXT_P2P              0x00000002
+	/* CAPABILITY: Multi-Channel Operations */
+#define WLAN_SOC_CEXT_MULTICHAN        0x00000004
+	/* CAPABILITY: the device supports perf and power offload */
+#define WLAN_SOC_CEXT_PERF_PWR_OFLD    0x00000008
+	/* CAPABILITY: the device supports 11ac */
+#define WLAN_SOC_CEXT_11AC             0x00000010
+	/* CAPABILITY: the device support acs channel hopping */
+#define WLAN_SOC_CEXT_ACS_CHAN_HOP     0x00000020
+	/* CAPABILITY: the device support STA DFS */
+#define WLAN_SOC_CEXT_STADFS           0x00000040
+
+/* feature_flags */
+	/* CONF: ATH FF enabled */
+#define WLAN_SOC_F_FF                   0x00000001
+	/* CONF: ATH Turbo enabled*/
+#define WLAN_SOC_F_TURBOP               0x00000002
+	/* STATUS: promiscuous mode */
+#define WLAN_SOC_F_PROMISC              0x00000004
+	/* STATUS: all multicast mode */
+#define WLAN_SOC_F_ALLMULTI             0x00000008
+/* NB: this is intentionally setup to be IEEE80211_CAPINFO_PRIVACY */
+	/* STATUS: start IBSS */
+#define WLAN_SOC_F_SIBSS                0x00000010
+/* NB: this is intentionally setup to be IEEE80211_CAPINFO_SHORT_SLOTTIME */
+	/* CONF: Power mgmt enable */
+#define WLAN_SOC_F_PMGTON               0x00000020
+	/* CONF: IBSS creation enable */
+#define WLAN_SOC_F_IBSSON               0x00000040
+	/* force chanswitch */
+#define WLAN_SOC_F_CHANSWITCH           0x00000080
+
+/* ic_flags_ext and/or iv_flags_ext */
+	/* CONF: enable country IE */
+#define WLAN_SOC_F_COUNTRYIE           0x00000100
+	/* STATE: enable full bgscan completion */
+#define WLAN_SOC_F_BGSCAN              0x00000200
+	/* CONF: enable U-APSD */
+#define WLAN_SOC_F_UAPSD               0x00000400
+	/* STATUS: sleeping */
+#define WLAN_SOC_F_SLEEP               0x00000800
+	/* Enable marking of dfs interfernce */
+#define WLAN_SOC_F_MARKDFS             0x00001000
+	/* enable or disable s/w ccmp encrypt decrypt support */
+#define WLAN_SOC_F_CCMPSW_ENCDEC       0x00002000
+	/* STATE: hibernating */
+#define WLAN_SOC_F_HIBERNATION         0x00004000
+	/* CONF: desired country has been set */
+#define WLAN_SOC_F_DESCOUNTRY          0x00008000
+	/* CONF: enable power capability or contraint IE */
+#define WLAN_SOC_F_PWRCNSTRIE          0x00010000
+	/* STATUS: 11D in used */
+#define WLAN_SOC_F_DOT11D              0x00020000
+
+/**
+ * struct wlan_objmgr_psoc_regulatory -  Regulatory sub structure of PSOC
+ * @country_code:  Country code
+ * @reg_dmn:       Regulatory Domain
+ * @reg_flags:     Regulatory flags
+ */
+struct wlan_objmgr_psoc_regulatory {
+	uint16_t country_code;
+	uint16_t reg_dmn;
+	uint16_t reg_flags;
+};
+
+/**
+ * struct wlan_objmgr_psoc_nif - HDD/OSIF specific sub structure of PSOC
+ * @phy_version:     phy version, read in device probe
+ * @phy_type:        OL/DA type
+ * @soc_fw_caps:     FW capabilities
+ * @soc_fw_ext_caps: FW ext capabilities
+ * @soc_feature_caps:Feature capabilities
+ * @soc_hw_macaddr[]:HW MAC address
+ */
+struct wlan_objmgr_psoc_nif {
+	uint32_t phy_version;
+	WLAN_DEV_TYPE phy_type;
+	uint32_t soc_fw_caps;
+	uint32_t soc_fw_ext_caps;
+	uint32_t soc_feature_caps;
+	uint8_t soc_hw_macaddr[WLAN_MACADDR_LEN];
+};
+
+/**
+ * struct wlan_objmgr_psoc_objmgr - psoc object manager sub structure
+ * @wlan_pdev_count:      PDEV count
+ * @wlan_pdev_list[]:     PDEV list
+ * @wlan_pdev_id_map:     PDEV id map, to allocate free ids
+ * @wlan_vdev_count:      VDEV count
+ * @max_vdev_count:       Max no. of VDEVs supported by this PSOC
+ * @wlan_vdev_list[]:     VDEV list
+ * @wlan_vdev_id_map[]:   VDEV id map, to allocate free ids
+ * @wlan_peer_count:      PEER count
+ * @peer_list:            Peer list
+ */
+struct wlan_objmgr_psoc_objmgr {
+	uint8_t wlan_pdev_count;
+	struct wlan_objmgr_pdev *wlan_pdev_list[WLAN_UMAC_MAX_PDEVS];
+	uint8_t wlan_pdev_id_map;
+	uint8_t wlan_vdev_count;
+	uint8_t max_vdev_count;
+	struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_PSOC_MAX_VDEVS];
+	uint32_t wlan_vdev_id_map[2];
+	uint16_t wlan_peer_count;
+	struct wlan_peer_list peer_list;
+};
+
+/**
+ * struct wlan_soc_southbound_cb - structure for south bound callbacks
+ *
+ */
+struct wlan_soc_southbound_cb {
+};
+
+/**
+ * struct wlan_concurrency_info - structure for concurrency info
+ *
+ */
+struct wlan_concurrency_info {
+};
+
+/**
+ * struct wlan_soc_timer - structure for soc timer
+ *
+ */
+struct wlan_soc_timer {
+};
+
+/**
+ * struct wlan_objmgr_psoc - PSOC common object
+ * @soc_reg:               regulatory sub structure
+ * @soc_nif:               nif sub strucutre
+ * @soc_objmgr:            object manager sub structure
+ * @soc_cb:                south bound callbacks
+ * @soc_timer:             soc timer for inactivity
+ * @soc_concurrency:       concurrency info
+ * @wlan_active_vdevs[]:   List of active VDEVs
+ * @soc_comp_obj[]:        component object pointers
+ * @obj_status[]:          component object status
+ * @obj_state:             object state
+ * @psoc_lock:             psoc lock
+ */
+struct wlan_objmgr_psoc {
+	struct wlan_objmgr_psoc_regulatory soc_reg;
+	struct wlan_objmgr_psoc_nif  soc_nif;
+	struct wlan_objmgr_psoc_objmgr soc_objmgr;
+	struct wlan_soc_southbound_cb soc_cb;
+	struct wlan_soc_timer soc_timer;
+	struct wlan_concurrency_info soc_concurrency; /*TODO */
+	uint8_t wlan_active_vdevs[WLAN_UMAC_PSOC_MAX_VDEVS];
+	void *soc_comp_obj[WLAN_UMAC_MAX_COMPONENTS];
+	QDF_STATUS obj_status[WLAN_UMAC_MAX_COMPONENTS];
+	WLAN_OBJ_STATE obj_state;
+	qdf_spinlock_t psoc_lock;
+};
+
+/**
+ ** APIs to Create/Delete Global object APIs
+ */
+/**
+ * wlan_objmgr_psoc_obj_create() - psoc object create
+ * @phy_version: device id (from probe)
+ * @dev_type: Offload/DA
+ *
+ * Creates PSOC object, intializes with default values
+ * Invokes the registered notifiers to create component object
+ *
+ * Return: Handle to struct wlan_objmgr_psoc on successful creation,
+ *         NULL on Failure (on Mem alloc failure and Component objects
+ *         Failure)
+ */
+struct wlan_objmgr_psoc *wlan_objmgr_psoc_obj_create(uint32_t phy_version,
+				WLAN_DEV_TYPE dev_type);
+
+/**
+ * wlan_objmgr_psoc_obj_delete() - psoc object delete
+ * @psoc: PSOC object
+ *
+ * Deletes PSOC object,
+ * Invokes the registered notifiers to delete component objects
+ *
+ * Return: SUCCESS/FAILURE
+ */
+QDF_STATUS wlan_objmgr_psoc_obj_delete(struct wlan_objmgr_psoc *psoc);
+
+/**
+ ** APIs to attach/detach component objects
+ */
+
+/**
+ * wlan_objmgr_psoc_component_obj_attach() - psoc comp object attach
+ * @psoc: PSOC object
+ * @id: Component id
+ * @comp_objptr: component's private object pointer
+ * @status: Component's private object creation status
+ *
+ * API to be used for attaching component object with PSOC common object
+ *
+ * Return: SUCCESS on successful storing of component's object in common object
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_psoc_component_obj_attach(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr,
+		QDF_STATUS status);
+
+/**
+ * wlan_objmgr_psoc_component_obj_detach() - psoc comp object detach
+ * @psoc: PSOC object
+ * @id: Component id
+ * @comp_objptr: component's private object pointer
+ *
+ * API to be used for detaching component object with PSOC common object
+ *
+ * Return: SUCCESS on successful removal of component's object from common
+ *         object
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_psoc_component_obj_detach(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr);
+
+/**
+ ** APIs to operations on psoc objects
+ */
+/**
+ * wlan_objmgr_iterate_obj_list() - iterate through all psoc objects
+ * @psoc: PSOC object
+ * @obj_type: PDEV_OP/VDEV_OP/PEER_OP
+ * @handler: the handler will be called for each object of requested type
+ *            the handler should be implemented to perform required operation
+ * @arg:     agruments passed by caller
+ * @lock_free_op: This gives provision to run this API with out lock protected
+ *                 It would be useful, for operations like Obj Delete, where
+ *                 lock should not be taken by caller.
+ *
+ * API to be used for performing the operations on all PDEV/VDEV/PEER objects
+ * of psoc
+ *
+ * Return: SUCCESS/FAILURE
+ */
+typedef void (*wlan_objmgr_op_handler)(struct wlan_objmgr_psoc *psoc,
+					void *object,
+					void *arg);
+/* handler should not take obj lock */
+QDF_STATUS wlan_objmgr_iterate_obj_list(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_objmgr_obj_type obj_type,
+		wlan_objmgr_op_handler handler,
+		void *arg, uint8_t lock_free_op);
+
+/**
+ * wlan_objmgr_free_all_objects_per_psoc() - free all psoc objects
+ * @psoc: PSOC object
+ *
+ * API to be used free all the objects(pdev/vdev/peer) of psoc
+ *
+ * Return: SUCCESS/FAILURE
+ */
+QDF_STATUS wlan_objmgr_free_all_objects_per_psoc(
+		struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_objmgr_trigger_psoc_comp_object_creation() - create psoc comp object
+ * @psoc: PSOC object
+ * @id: Component id
+ *
+ * API to create component object in run time, this would be used for features
+ * which gets enabled in run time
+ *
+ * Return: SUCCESS on successful creation
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_trigger_psoc_comp_object_creation(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_umac_comp_id id);
+
+/**
+ * wlan_objmgr_trigger_psoc_comp_object_deletion() - delete psoc comp object
+ * @psoc: PSOC object
+ * @id: Component id
+ *
+ * API to delete component object in run time, this would be used for features
+ * which gets disabled in run time
+ *
+ * Return: SUCCESS on successful deletion
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_trigger_psoc_comp_object_deletion(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_umac_comp_id id);
+
+/**
+ * wlan_objmgr_find_peer() - find peer from psoc's peer list
+ * @psoc: PSOC object
+ * @macaddr: MAC address
+ *
+ * API to find peer object pointer by MAC addr
+ *
+ * Return: peer pointer
+ *         NULL on FAILURE
+ */
+struct wlan_objmgr_peer *wlan_objmgr_find_peer(
+			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr);
+
+/**
+ * wlan_objmgr_find_pdev_by_id() - retrieve pdev by id
+ * @psoc: PSOC object
+ * @id: pdev id
+ *
+ * API to find pdev object pointer by pdev id
+ *
+ * Return: pdev pointer
+ *         NULL on FAILURE
+ */
+struct wlan_objmgr_pdev *wlan_objmgr_find_pdev_by_id(
+		struct wlan_objmgr_psoc *psoc, uint8_t id);
+
+/**
+ * wlan_objmgr_find_pdev_by_macaddr() - retrieve pdev by macaddr
+ * @psoc: PSOC object
+ * @macaddr: MAC address
+ *
+ * API to find pdev object pointer by pdev macaddr
+ *
+ * Return: pdev pointer
+ *         NULL on FAILURE
+ */
+struct wlan_objmgr_pdev *wlan_objmgr_find_pdev_by_macaddr(
+		struct wlan_objmgr_psoc *psoc, uint8_t *macaddr);
+
+/**
+ * wlan_objmgr_find_vdev_by_id_from_psoc() - retrieve vdev by id
+ * @psoc: PSOC object
+ * @id: vdev id
+ *
+ * API to find vdev object pointer by vdev id from psoc
+ *
+ * Return: vdev pointer
+ *         NULL on FAILURE
+ */
+struct wlan_objmgr_vdev *wlan_objmgr_find_vdev_by_id_from_psoc(
+			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id);
+
+/**
+ * wlan_objmgr_find_vdev_by_macaddr_from_psoc() - retrieve vdev by macaddr
+ * @psoc: PSOC object
+ * @macaddr: macaddr
+ *
+ * API to find vdev object pointer by vdev macaddr from psoc
+ *
+ * Return: vdev pointer
+ *         NULL on FAILURE
+ */
+struct wlan_objmgr_vdev *wlan_objmgr_find_vdev_by_macaddr_from_psoc(
+		struct wlan_objmgr_psoc *psoc, uint8_t *macaddr);
+
+/**
+ * wlan_psoc_obj_lock() - Acquire PSOC spinlock
+ * @psoc: PSOC object
+ *
+ * API to acquire PSOC lock
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_obj_lock(struct wlan_objmgr_psoc *psoc)
+{
+	qdf_spin_lock_bh(&psoc->psoc_lock);
+}
+
+/**
+ * wlan_psoc_obj_unlock() - Release PSOC spinlock
+ * @psoc: PSOC object
+ *
+ * API to Release PSOC lock
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_obj_unlock(struct wlan_objmgr_psoc *psoc)
+{
+	qdf_spin_unlock_bh(&psoc->psoc_lock);
+}
+
+/**
+ * wlan_psoc_set_nif_phy_version() - set nif phy version
+ * @psoc: PSOC object
+ * @phy_ver: phy version
+ *
+ * API to set nif phy version in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_set_nif_phy_version(struct wlan_objmgr_psoc *psoc,
+			uint32_t phy_ver)
+{
+	psoc->soc_nif.phy_version = phy_ver;
+}
+
+/**
+ * wlan_psoc_get_nif_phy_version() - get nif phy version
+ * @psoc: PSOC object
+ *
+ * API to set nif phy version in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: @phy_ver: phy version
+ */
+static inline uint32_t wlan_psoc_get_nif_phy_version(
+			struct wlan_objmgr_psoc *psoc)
+{
+	if (psoc == NULL)
+		return (uint32_t)-1;
+	return psoc->soc_nif.phy_version;
+}
+
+/**
+ * wlan_psoc_set_dev_type() - set dev type
+ * @psoc: PSOC object
+ * @phy_type: phy type (OL/DA)
+ *
+ * API to set dev type in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_set_dev_type(struct wlan_objmgr_psoc *psoc,
+				WLAN_DEV_TYPE phy_type)
+{
+	psoc->soc_nif.phy_type = phy_type;
+}
+
+/**
+ * wlan_objmgr_psoc_get_dev_type - get dev type
+ * @psoc: PSOC object
+ *
+ * API to get dev type in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: phy type (OL/DA)
+ */
+static inline WLAN_DEV_TYPE wlan_objmgr_psoc_get_dev_type(
+				struct wlan_objmgr_psoc *psoc)
+{
+	if (psoc == NULL)
+		return (uint32_t)-1;
+	return psoc->soc_nif.phy_type;
+}
+
+/**
+ * wlan_psoc_nif_fw_cap_set() - set fw caps
+ * @psoc: PSOC object
+ * @cap: capability flag to be set
+ *
+ * API to set fw caps in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_nif_fw_cap_set(struct wlan_objmgr_psoc *psoc,
+					uint32_t cap)
+{
+	psoc->soc_nif.soc_fw_caps |= cap;
+}
+
+/**
+ * wlan_psoc_nif_fw_cap_clear() - clear fw caps
+ * @psoc: PSOC object
+ * @cap: capability flag to be cleared
+ *
+ * API to clear fw caps in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_nif_fw_cap_clear(struct wlan_objmgr_psoc *psoc,
+				uint32_t cap)
+{
+	psoc->soc_nif.soc_fw_caps &= ~cap;
+}
+
+/**
+ * wlan_psoc_nif_fw_cap_get() - get fw caps
+ * @psoc: PSOC object
+ * @cap: capability flag to be checked
+ *
+ * API to know, whether particular fw caps flag is set in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: 1 (for set) or 0 (for not set)
+ */
+static inline uint8_t wlan_psoc_nif_fw_cap_get(struct wlan_objmgr_psoc *psoc,
+				uint32_t cap)
+{
+	return (psoc->soc_nif.soc_fw_caps & cap) ? 1 : 0;
+}
+
+/**
+ * wlan_psoc_nif_fw_ext_cap_set() - set fw ext caps
+ * @psoc: PSOC object
+ * @ext_cap: capability flag to be set
+ *
+ * API to set fw ext caps in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_nif_fw_ext_cap_set(struct wlan_objmgr_psoc *psoc,
+				uint32_t ext_cap)
+{
+	psoc->soc_nif.soc_fw_ext_caps |= ext_cap;
+}
+
+/**
+ * wlan_psoc_nif_fw_ext_cap_clear() - clear fw ext caps
+ * @psoc: PSOC object
+ * @ext_cap: capability flag to be cleared
+ *
+ * API to clear fw ext caps in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_nif_fw_ext_cap_clear(struct wlan_objmgr_psoc *psoc,
+				uint32_t ext_cap)
+{
+	psoc->soc_nif.soc_fw_ext_caps &= ~ext_cap;
+}
+
+/**
+ * wlan_psoc_nif_fw_ext_cap_get() - get fw caps
+ * @psoc: PSOC object
+ * @ext_cap: capability flag to be checked
+ *
+ * API to know, whether particular fw caps flag is set in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: 1 (for set) or 0 (for not set)
+ */
+static inline uint8_t wlan_psoc_nif_fw_ext_cap_get(
+		struct wlan_objmgr_psoc *psoc, uint32_t ext_cap)
+{
+	return (psoc->soc_nif.soc_fw_ext_caps & ext_cap) ? 1 : 0;
+}
+
+/**
+ * wlan_psoc_nif_feat_cap_set() - set feature caps
+ * @psoc: PSOC object
+ * @cap: feature flag to be set
+ *
+ * API to set feature caps in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_nif_feat_cap_set(struct wlan_objmgr_psoc *psoc,
+				uint32_t feat_cap)
+{
+	psoc->soc_nif.soc_feature_caps |= feat_cap;
+}
+
+/**
+ * wlan_psoc_nif_feat_cap_clear() - clear feature caps
+ * @psoc: PSOC object
+ * @cap: feature flag to be cleared
+ *
+ * API to clear feature caps in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_nif_feat_cap_clear(struct wlan_objmgr_psoc *psoc,
+				uint32_t feat_cap)
+{
+	psoc->soc_nif.soc_feature_caps &= ~feat_cap;
+}
+
+/**
+ * wlan_psoc_nif_feat_cap_get() - get feature caps
+ * @psoc: PSOC object
+ * @cap: feature flag to be checked
+ *
+ * API to know, whether particular feature cap flag is set in psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: 1 (for set) or 0 (for not set)
+ */
+static inline uint8_t wlan_psoc_nif_feat_cap_get(struct wlan_objmgr_psoc *psoc,
+				uint32_t feat_cap)
+{
+	return (psoc->soc_nif.soc_feature_caps & feat_cap) ? 1 : 0;
+}
+
+/**
+ * wlan_psoc_set_hw_macaddr() - set hw mac addr
+ * @psoc: PSOC object
+ * @macaddr: hw macaddr
+ *
+ * API to set hw macaddr of psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_psoc_set_hw_macaddr(struct wlan_objmgr_psoc *psoc,
+					uint8_t *macaddr)
+{
+	if (psoc != NULL)
+		WLAN_ADDR_COPY(psoc->soc_nif.soc_hw_macaddr, macaddr);
+}
+
+/**
+ * wlan_psoc_get_hw_macaddr() - get hw macaddr
+ * @psoc: PSOC object
+ *
+ * API to set hw macaddr of psoc
+ *
+ * Caller need to acquire lock with wlan_psoc_obj_lock()
+ *
+ * Return: hw macaddr
+ */
+static inline uint8_t *wlan_psoc_get_hw_macaddr(struct wlan_objmgr_psoc *psoc)
+{
+	if (psoc == NULL)
+		return NULL;
+	return psoc->soc_nif.soc_hw_macaddr;
+}
+#endif /* _WLAN_OBJMGR_PSOC_OBJ_H_*/

+ 1289 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h

@@ -0,0 +1,1289 @@
+/*
+ * Copyright (c) 2016 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: Define the vdev data structure of UMAC
+  */
+#ifndef _WLAN_OBJMGR_VDEV_OBJ_H_
+#define _WLAN_OBJMGR_VDEV_OBJ_H_
+	/* CONF: privacy enabled */
+#define WLAN_VDEV_F_PRIVACY              0x00000001
+	/* CONF: 11g w/o 11b sta's */
+#define WLAN_VDEV_F_PUREG                0x00000002
+	/* CONF: des_bssid is set */
+#define WLAN_VDEV_F_DESBSSID             0x00000004
+	/* CONF: bg scan enabled */
+#define WLAN_VDEV_F_BGSCAN               0x00000008
+	/* CONF: sw tx retry enabled */
+#define WLAN_VDEV_F_SWRETRY              0x00000010
+	/* STATUS: update beacon tim */
+#define WLAN_VDEV_F_TIMUPDATE            0x00000020
+	/* CONF: WPA enabled */
+#define WLAN_VDEV_F_WPA1                 0x00000040
+	/* CONF: WPA2 enabled */
+#define WLAN_VDEV_F_WPA2                 0x00000080
+	/* CONF: WPA/WPA2 enabled */
+#define WLAN_VDEV_F_WPA                  0x000000c0
+	/* CONF: drop unencrypted */
+#define WLAN_VDEV_F_DROPUNENC            0x00000100
+	/* CONF: TKIP countermeasures */
+#define WLAN_VDEV_F_COUNTERM             0x00000200
+	/* CONF: hide SSID in beacon */  /*TODO PDEV/PSOC */
+#define WLAN_VDEV_F_HIDESSID             0x00000400
+	/* CONF: disable internal bridge */ /*TODO PDEV/PSOC */
+#define WLAN_VDEV_F_NOBRIDGE             0x00000800
+	/* STATUS: update beacon wme */
+#define WLAN_VDEV_F_WMEUPDATE            0x00001000
+	/* CONF: 4 addr allowed */
+#define WLAN_VDEV_F_WDS                  0x00002000
+	/* CONF: enable U-APSD */
+#define WLAN_VDEV_F_UAPSD                0x00004000
+	/* STATUS: sleeping */
+#define WLAN_VDEV_F_SLEEP                0x00008000
+	/* drop uapsd EOSP frames for test */
+#define WLAN_VDEV_F_EOSPDROP             0x00010000
+	/* drop uapsd EOSP frames for test */
+#define WLAN_VDEV_F_AMPDU                0x00020000
+	/* STATE: beacon APP IE updated */
+#define WLAN_VDEV_F_APPIE_UPDATE         0x00040000
+	/* CONF: WDS auto Detect/DELBA */
+#define WLAN_VDEV_F_WDS_AUTODETECT       0x00080000
+	/* 11b only without 11g stations */
+#define WLAN_VDEV_F_PUREB                0x00100000
+	/* disable HT rates */
+#define WLAN_VDEV_F_HTRATES              0x00200000
+	/* Extender AP */
+#define WLAN_VDEV_F_AP                   0x00400000
+	/* CONF: deliver rx frames with 802.11 header */
+#define WLAN_VDEV_F_DELIVER_80211        0x00800000
+	/* CONF: os sends down tx frames with 802.11 header */
+#define WLAN_VDEV_F_SEND_80211           0x01000000
+	/* CONF: statically configured WDS */
+#define WLAN_VDEV_F_WDS_STATIC           0x02000000
+	/* CONF: pure 11n mode */
+#define WLAN_VDEV_F_PURE11N              0x04000000
+	/* CONF: pure 11ac mode */
+#define WLAN_VDEV_F_PURE11AC             0x08000000
+	/* Basic Rates Update */
+#define WLAN_VDEV_F_BR_UPDATE            0x10000000
+	/* CONF: restrict bw ont top of per 11ac/n */
+#define WLAN_VDEV_F_STRICT_BW            0x20000000
+	/* Wi-Fi SON mode (with APS) */
+#define WLAN_VDEV_F_SON                  0x40000000
+	/* Wi-Fi SON mode (with APS) */
+#define WLAN_VDEV_F_MBO                  0x80000000
+
+/* Feature extension flags */
+		/* CONF: MSFT safe mode         */
+#define WLAN_VDEV_FEXT_SAFEMODE             0x00000001
+		/* if the vap can sleep*/
+#define WLAN_VDEV_FEXT_CANSLEEP             0x00000002
+		/* use sw bmiss timer */
+#define WLAN_VDEV_FEXT_SWBMISS              0x00000004
+		/* enable beacon copy */
+#define WLAN_VDEV_FEXT_COPY_BEACON          0x00000008
+#define WLAN_VDEV_FEXT_WAPI                 0x00000010
+		/* 802.11h enabled */
+#define WLAN_VDEV_FEXT_DOTH                 0x00000020
+	/* if the vap has wds independance set */
+#define WLAN_VDEV_FEXT_VAPIND               0x00000040
+	/* QBSS load IE enabled */
+#define WLAN_VDEV_FEXT_BSSLOAD              0x00000080
+	/* Short Guard Interval Enable:1 Disable:0 */
+#define WLAN_VDEV_FEXT_SGI                  0x00000100
+	/* Short Guard Interval Enable:1 Disable:0 for VHT fixed rates */
+#define WLAN_VDEV_FEXT_DATASGI              0x00000200
+	/* LDPC Enable Rx:1 TX: 2 ; Disable:0 */
+#define WLAN_VDEV_FEXT_LDPC_TX              0x00000400
+#define WLAN_VDEV_FEXT_LDPC_RX              0x00000800
+#define WLAN_VDEV_FEXT_LDPC                 0x00000c00
+	/* wme enabled */
+#define WLAN_VDEV_FEXT_WME                  0x00001000
+	/* WNM Capabilities */
+#define WLAN_VDEV_FEXT_WNM                  0x00002000
+	/* RRM Capabilities */
+#define WLAN_VDEV_FEXT_RRM                  0x00004000
+	/* WNM Proxy ARP Capabilities */
+#define WLAN_VDEV_FEXT_PROXYARP             0x00008000
+	/* 256 QAM support in 2.4GHz mode Enable:1 Disable:0 */
+#define WLAN_VDEV_FEXT_256QAM               0x00010000
+	/* 2.4NG 256 QAM Interop mode Enable:1 Disable:0 */
+#define WLAN_VDEV_FEXT_256QAM_INTEROP       0x00020000
+	/* static mimo ps enabled */
+#define WLAN_VDEV_FEXT_STATIC_MIMOPS        0x00040000
+	/* dynamic mimo ps enabled */
+#define WLAN_VDEV_FEXT_DYN_MIMOPS           0x00080000
+	/* Country IE enabled */
+#define WLAN_VDEV_FEXT_CNTRY_IE             0x00100000
+	/*does not want to trigger multi channel operation
+	instead follow master vaps channel (for AP/GO Vaps) */
+#define WLAN_VDEV_FEXT_NO_MULCHAN           0x00200000
+	/*non-beaconing AP VAP*/
+#define WLAN_VDEV_FEXT_NON_BEACON           0x00400000
+
+/* VDEV OP flags  */
+  /* if the vap deleted by user */
+#define WLAN_VDEV_OP_DELETE_PROGRESS        0x00000001
+ /* set to enable sta-fws fweature */
+#define WLAN_VDEV_OP_STAFWD                 0x00000002
+   /* Off-channel support enabled */
+#define WLAN_VDEV_OP_OFFCHAN                0x00000004
+  /* if the vap has erp update set */
+#define WLAN_VDEV_OP_ERPUPDATE              0x00000008
+  /* this vap needs scheduler for off channel operation */
+#define WLAN_VDEV_OP_NEEDS_SCHED            0x00000010
+  /*STA in forced sleep set PS bit for all outgoing frames */
+#define WLAN_VDEV_OP_FORCED_SLEEP           0x00000020
+  /* update bssload IE in beacon */
+#define WLAN_VDEV_OP_BSSLOAD_UPDATE         0x00000040
+  /* Hotspot 2.0 DGAF Disable bit */
+#define WLAN_VDEV_OP_DGAF_DISABLE           0x00000080
+  /* STA SmartNet enabled */
+#define WLAN_VDEV_OP_SMARTNET_EN            0x00000100
+  /* SoftAP to reject resuming in DFS channels */
+#define WLAN_VDEV_OP_REJ_DFS_CHAN           0x00000200
+  /* Trigger mlme response */
+#define WLAN_VDEV_OP_TRIGGER_MLME_RESP      0x00000400
+  /* test flag for MFP */
+#define WLAN_VDEV_OP_MFP_TEST               0x00000800
+  /* flag to indicate using default ratemask */
+#define WLAN_VDEV_OP_DEF_RATEMASK           0x00001000
+/*For wakeup AP VAP when wds-sta connect to the AP only use when
+	export (UMAC_REPEATER_DELAYED_BRINGUP || DBDC_REPEATER_SUPPORT)=1*/
+#define WLAN_VDEV_OP_KEYFLAG                0x00002000
+  /* if performe the iwlist scanning */
+#define WLAN_VDEV_OP_LIST_SCANNING          0x00004000
+   /*Set when VAP down*/
+#define WLAN_VDEV_OP_IS_DOWN                0x00008000
+  /* if vap may require acs when another vap is brought down */
+#define WLAN_VDEV_OP_NEEDS_UP_ACS           0x00010000
+  /* Block data traffic tx for this vap */
+#define WLAN_VDEV_OP_BLOCK_TX_TRAFFIC       0x00020000
+  /* for mbo functionality */
+#define WLAN_VDEV_OP_MBO                    0x00040000
+
+ /* CAPABILITY: IBSS available */
+#define WLAN_VDEV_C_IBSS                    0x00000001
+/* CAPABILITY: HOSTAP avail */
+#define WLAN_VDEV_C_HOSTAP               0x00000002
+   /* CAPABILITY: Old Adhoc Demo */
+#define WLAN_VDEV_C_AHDEMO               0x00000004
+  /* CAPABILITY: sw tx retry */
+#define WLAN_VDEV_C_SWRETRY              0x00000008
+  /* CAPABILITY: monitor mode */
+#define WLAN_VDEV_C_MONITOR              0x00000010
+  /* CAPABILITY: TKIP MIC avail */
+#define WLAN_VDEV_C_TKIPMIC              0x00000020
+  /* CAPABILITY: 4-addr support */
+#define WLAN_VDEV_C_WDS                  0x00000040
+  /* CAPABILITY: TKIP MIC for QoS frame */
+#define WLAN_VDEV_C_WME_TKIPMIC          0x00000080
+  /* CAPABILITY: bg scanning */
+#define WLAN_VDEV_C_BGSCAN               0x00000100
+
+/**
+ * enum wlan_vdev_state - VDEV state
+ * @WLAN_VDEV_S_INIT:    Default state, IDLE state
+ * @WLAN_VDEV_S_SCAN:    SCAN state
+ * @WLAN_VDEV_S_JOIN:    Join state
+ * @WLAN_VDEV_S_DFS_WAIT:CAC period
+ * @WLAN_VDEV_S_RUN:     RUN state
+ * @WLAN_VDEV_S_STOP:    STOP state
+ * @WLAN_VDEV_S_RESET:   RESET state, STOP+INIT+JOIN
+ * @WLAN_VDEV_S_MAX:     MAX state
+ */
+enum wlan_vdev_state {
+	WLAN_VDEV_S_INIT     = 0,
+	WLAN_VDEV_S_SCAN     = 1,
+	WLAN_VDEV_S_JOIN     = 2,
+	WLAN_VDEV_S_DFS_WAIT = 3,
+	WLAN_VDEV_S_RUN      = 4,
+	WLAN_VDEV_S_STOP     = 5,
+	WLAN_VDEV_S_RESET    = 6,
+	WLAN_VDEV_S_MAX,
+};
+
+/**
+ * struct wlan_vdev_create_params - Create params, HDD/OSIF passes this
+ *				    structure While creating VDEV
+ * @opmode:      Opmode of VDEV
+ * @macaddr[]:   MAC address
+ * @flags:       create flags
+ * @osifp:       OS structure
+ * @mataddr[]:   MAT address
+ */
+struct wlan_vdev_create_params {
+	enum tQDF_ADAPTER_MODE opmode;
+	uint8_t macaddr[WLAN_MACADDR_LEN];
+	uint32_t flags;
+	void *osifp;
+	uint8_t mataddr[WLAN_MACADDR_LEN];
+};
+
+/**
+ * struct wlan_channel - channel structure
+ */
+struct wlan_channel {
+
+};
+
+/**
+ * struct wlan_objmgr_vdev_mlme - VDEV MLME specific sub structure
+ * @vdev_opmode:        Opmode of VDEV
+ * @ssid[]:             SSID
+ * @ssid_len:           SSID length
+ * @bss_chan:           BSS channel
+ * @des_chan:           Desired channel, for STA Desired may not be used
+ * @nss:                Num. Spatial streams
+ * @chainmask:          Chainmask
+ * @macaddr[]:          VDEV self MAC address
+ * @vdev_caps:          VDEV capabilities
+ * @vdev_feat_caps:     VDEV feature caps
+ * @vdev_feat_ext_caps: VDEV Extended feature caps
+ * @max_rate:           MAX rate
+ * @tx_mgmt_rate:       TX Mgmt. Rate
+ * @tx_power:           Tx power
+ * @mlme_state:         VDEV state
+ * @vdev_op_flags:      Operation flags
+ * @mataddr[]:          MAT address
+ */
+struct wlan_objmgr_vdev_mlme {
+	enum tQDF_ADAPTER_MODE vdev_opmode;
+	char ssid[WLAN_SSID_MAX_LEN+1];
+	uint8_t ssid_len;
+	struct wlan_channel  *bss_chan;   /* Define wlan_channel */
+	struct wlan_channel  *des_chan;  /*TODO ??? */
+	uint8_t nss;
+	uint8_t chainmask;
+	uint8_t  macaddr[WLAN_MACADDR_LEN];
+	uint32_t vdev_caps;
+	uint32_t vdev_feat_caps;
+	uint32_t vdev_feat_ext_caps;
+	uint32_t max_rate;
+	uint32_t tx_mgmt_rate;
+	uint8_t  tx_power;
+	enum wlan_vdev_state mlme_state;
+	uint32_t vdev_op_flags;
+	uint8_t  mataddr[WLAN_MACADDR_LEN];
+};
+
+/**
+ *  struct wlan_objmgr_vdev_nif - VDEV HDD specific sub structure
+ *  @osdev:  OS specific pointer
+ */
+struct wlan_objmgr_vdev_nif {
+	void *osdev;
+};
+
+/**
+ *  struct wlan_objmgr_vdev_objmgr - vdev object manager sub structure
+ *  @vdev_id:          VDEV id
+ *  @self_peer:        Self PEER
+ *  @bss_peer:         BSS PEER
+ *  @wlan_peer_list:   PEER list
+ *  @wlan_pdev:        PDEV pointer
+ *  @wlan_peer_count:  Peer count
+ *  @max_peer_count:   Max Peer count
+ *  @c_flags:          creation specific flags
+ */
+struct wlan_objmgr_vdev_objmgr {
+	uint8_t vdev_id;
+	struct wlan_objmgr_peer *self_peer;
+	struct wlan_objmgr_peer *bss_peer;
+	qdf_list_t wlan_peer_list;
+	struct wlan_objmgr_pdev *wlan_pdev;
+	uint16_t wlan_peer_count;
+	uint16_t max_peer_count;
+	uint32_t c_flags;
+};
+
+/**
+ * struct wlan_objmgr_vdev - VDEV common object
+ * @vdev_node:      qdf list of pdev's vdev list
+ * @vdev_mlme:      VDEV MLME substructure
+ * @vdev_objmgr:    VDEV Object Mgr substructure
+ * @vdev_nif:       VDEV HDD substructure
+ * @vdev_comp_obj[]:Component objects list
+ * @obj_status[]:   Component object status
+ * @obj_state:      VDEV object state
+ * @vdev_lock:      VDEV lock
+ */
+struct wlan_objmgr_vdev {
+	qdf_list_node_t vdev_node;
+	struct wlan_objmgr_vdev_mlme vdev_mlme;
+	struct wlan_objmgr_vdev_objmgr vdev_objmgr;
+	struct wlan_objmgr_vdev_nif vdev_nif;
+	void *vdev_comp_obj[WLAN_UMAC_MAX_COMPONENTS];
+	QDF_STATUS obj_status[WLAN_UMAC_MAX_COMPONENTS];
+	WLAN_OBJ_STATE obj_state;
+	qdf_spinlock_t vdev_lock;
+};
+
+/**
+ ** APIs to Create/Delete Global object APIs
+ */
+/**
+ * wlan_objmgr_vdev_obj_create() - vdev object create
+ * @pdev: PDEV object on which this vdev gets created
+ * @params: VDEV create params from HDD
+ *
+ * Creates vdev object, intializes with default values
+ * Attaches to psoc and pdev objects
+ * Invokes the registered notifiers to create component object
+ *
+ * Return: Handle to struct wlan_objmgr_vdev on successful creation,
+ *         NULL on Failure (on Mem alloc failure and Component objects
+ *         Failure)
+ */
+struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create(
+			struct wlan_objmgr_pdev *pdev,
+			struct wlan_vdev_create_params *params);
+
+/**
+ * wlan_objmgr_vdev_obj_delete() - vdev object delete
+ * @vdev: vdev object
+ *
+ * Deletes VDEV object, removes it from PSOC's, PDEV's VDEV list
+ * Invokes the registered notifiers to delete component objects
+ *
+ * Return: SUCCESS/FAILURE
+ */
+QDF_STATUS wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev *vdev);
+
+/**
+ ** APIs to attach/detach component objects
+ */
+/**
+ * wlan_objmgr_vdev_component_obj_attach() - vdev comp object attach
+ * @vdev: VDEV object
+ * @id: Component id
+ * @comp_objptr: component's private object pointer
+ * @status: Component's private object creation status
+ *
+ * API to be used for attaching component object with VDEV common object
+ *
+ * Return: SUCCESS on successful storing of component's object in common object
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_vdev_component_obj_attach(
+		struct wlan_objmgr_vdev *vdev,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr,
+		QDF_STATUS status);
+
+/**
+ * wlan_objmgr_vdev_component_obj_detach() - vdev comp object detach
+ * @vdev: VDEV object
+ * @id: Component id
+ * @comp_objptr: component's private object pointer
+ *
+ * API to be used for detaching component object with VDEV common object
+ *
+ * Return: SUCCESS on successful removal of component's object from common
+ *         object
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_vdev_component_obj_detach(
+		struct wlan_objmgr_vdev *vdev,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr);
+/*
+ ** APIs to operations on vdev objects
+*/
+
+/**
+ * wlan_objmgr_iterate_peerobj_list() - iterate vdev's peer list
+ * @vdev: vdev object
+ * @handler: the handler will be called for each object of requested type
+ *            the handler should be implemented to perform required operation
+ * @arg:     agruments passed by caller
+ *
+ * API to be used for performing the operations on all PEER objects
+ * of vdev
+ *
+ * Return: SUCCESS/FAILURE
+ */
+typedef void (*wlan_objmgr_vdev_op_handler)(struct wlan_objmgr_vdev *vdev,
+					void *object,
+					void *arg);
+
+QDF_STATUS wlan_objmgr_iterate_peerobj_list(
+		struct wlan_objmgr_vdev *vdev,
+		wlan_objmgr_vdev_op_handler handler,
+		void *arg);
+
+/**
+ * wlan_objmgr_trigger_vdev_comp_object_creation() - vdev comp object creation
+ * @vdev: VDEV object
+ * @id: Component id
+ *
+ * API to create component object in run time, this would be used for features
+ * which gets enabled in run time
+ *
+ * Return: SUCCESS on successful creation
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_trigger_vdev_comp_object_creation(
+		struct wlan_objmgr_vdev *vdev,
+		enum wlan_umac_comp_id id);
+
+/**
+ * wlan_objmgr_trigger_vdev_comp_object_deletion() - vdev comp object deletion
+ * @vdev: VDEV object
+ * @id: Component id
+ *
+ * API to delete component object in run time, this would be used for features
+ * which gets disabled in run time
+ *
+ * Return: SUCCESS on successful deletion
+ *         On FAILURE (appropriate failure codes are returned)
+ */
+QDF_STATUS wlan_objmgr_trigger_vdev_comp_object_deletion(
+		struct wlan_objmgr_vdev *vdev,
+		enum wlan_umac_comp_id id);
+
+/* Util APIs */
+
+/**
+ * wlan_vdev_get_pdev() - get pdev
+ * @vdev: VDEV object
+ *
+ * API to get pdev object pointer from vdev
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: pdev object pointer
+ */
+static inline struct wlan_objmgr_pdev *wlan_vdev_get_pdev(
+				struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_objmgr.wlan_pdev;
+}
+
+/**
+ * wlan_pdev_vdev_list_peek_head() - get first vdev from pdev list
+ * @peer_list: qdf_list_t
+ *
+ * API to get the head vdev of given peer (of pdev's vdev list)
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @peer: head peer
+ */
+static inline struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_head(
+					qdf_list_t *vdev_list)
+{
+	struct wlan_objmgr_vdev *vdev;
+	qdf_list_node_t *vdev_node = NULL;
+
+	if (qdf_list_peek_front(vdev_list, &vdev_node) != QDF_STATUS_SUCCESS)
+		return NULL;
+
+	vdev = qdf_container_of(vdev_node, struct wlan_objmgr_vdev, vdev_node);
+	return vdev;
+}
+
+/**
+ * wlan_vdev_get_next_vdev_of_pdev() - get next vdev
+ * @vdev: VDEV object
+ *
+ * API to get next vdev object pointer of vdev
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @vdev_next: VDEV object
+ */
+static inline struct wlan_objmgr_vdev *wlan_vdev_get_next_vdev_of_pdev(
+					qdf_list_t *vdev_list,
+					struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_vdev *vdev_next;
+	qdf_list_node_t *node = &vdev->vdev_node;
+	qdf_list_node_t *next_node = NULL;
+
+	if (node == NULL)
+		return NULL;
+
+	if (qdf_list_peek_next(vdev_list, node, &next_node) !=
+						QDF_STATUS_SUCCESS)
+		return NULL;
+
+	vdev_next = qdf_container_of(next_node, struct wlan_objmgr_vdev,
+				vdev_node);
+	return vdev_next;
+}
+
+/**
+ * wlan_vdev_set_pdev() - set pdev
+ * @vdev: VDEV object
+ * @pdev: PDEV object
+ *
+ * API to get pdev object pointer from vdev
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_set_pdev(struct wlan_objmgr_vdev *vdev,
+					struct wlan_objmgr_pdev *pdev)
+{
+	vdev->vdev_objmgr.wlan_pdev = pdev;
+}
+
+/**
+ * wlan_vdev_get_psoc() - get psoc
+ * @vdev: VDEV object
+ *
+ * API to get pdev object pointer from vdev
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: psoc object pointer
+ */
+static inline struct wlan_objmgr_psoc *wlan_vdev_get_psoc(
+				struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_pdev *pdev;
+
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (pdev == NULL)
+		return NULL;
+
+	return wlan_pdev_get_psoc(pdev);
+}
+
+/**
+ * wlan_vdev_mlme_set_opmode() - set vdev opmode
+ * @vdev: VDEV object
+ * @mode: VDEV op mode
+ *
+ * API to set opmode in vdev object
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_opmode(struct wlan_objmgr_vdev *vdev,
+				enum tQDF_ADAPTER_MODE mode)
+{
+	vdev->vdev_mlme.vdev_opmode = mode;
+}
+
+/**
+ * wlan_vdev_mlme_get_opmode() - get vdev opmode
+ * @vdev: VDEV object
+ *
+ * API to set opmode of vdev object
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @mode: VDEV op mode
+ */
+static inline enum tQDF_ADAPTER_MODE wlan_vdev_mlme_get_opmode(
+					struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.vdev_opmode;
+}
+
+/**
+ * wlan_vdev_mlme_set_macaddr() - set vdev macaddr
+ * @vdev: VDEV object
+ * @macaddr: MAC address
+ *
+ * API to set macaddr in vdev object
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_macaddr(struct wlan_objmgr_vdev *vdev,
+					 uint8_t *macaddr)
+{
+	WLAN_ADDR_COPY(vdev->vdev_mlme.macaddr, macaddr);
+}
+
+/**
+ * wlan_vdev_mlme_get_macaddr() - get vdev macaddr
+ * @vdev: VDEV object
+ *
+ * API to get MAC address from vdev object
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @macaddr: MAC address
+ */
+static inline uint8_t *wlan_vdev_mlme_get_macaddr(struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.macaddr;
+}
+
+/**
+ * wlan_vdev_mlme_set_mataddr() - set vdev mataddr
+ * @vdev: VDEV object
+ * @mataddr: MAT address
+ *
+ * API to set mataddr in vdev object
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_mataddr(struct wlan_objmgr_vdev *vdev,
+					uint8_t *mataddr)
+{
+	WLAN_ADDR_COPY(vdev->vdev_mlme.mataddr, mataddr);
+}
+
+/**
+ * wlan_vdev_mlme_get_mataddr() - get mataddr
+ * @vdev: VDEV object
+ *
+ * API to get MAT address from vdev object
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @mataddr: MAT address
+ */
+static inline uint8_t *wlan_vdev_mlme_get_mataddr(struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.mataddr;
+}
+
+/**
+ * wlan_vdev_get_id() - get vdev id
+ * @vdev: VDEV object
+ *
+ * API to get vdev id
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @id: vdev id
+ */
+static inline uint8_t wlan_vdev_get_id(struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_objmgr.vdev_id;
+}
+
+/**
+ * wlan_vdev_get_hw_macaddr() - get hw macaddr
+ * @vdev: VDEV object
+ *
+ * API to retrieve the HW MAC address from PDEV
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @macaddr: HW MAC address
+ */
+static inline uint8_t *wlan_vdev_get_hw_macaddr(struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
+
+	if (pdev != NULL) {
+		return wlan_pdev_get_hw_macaddr(pdev);
+	} else {
+		qdf_print("%s:pdev is NULL\n", __func__);
+		return NULL;
+	}
+}
+
+/**
+ * wlan_vdev_mlme_set_ssid() - set ssid
+ * @vdev: VDEV object
+ * @ssid: SSID (input)
+ * @ssid_len: Length of SSID
+ *
+ * API to set the SSID of VDEV
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: SUCCESS, if update is done
+ *          FAILURE, if ssid length is > max ssid len
+ */
+static inline QDF_STATUS wlan_vdev_mlme_set_ssid(
+				struct wlan_objmgr_vdev *vdev,
+				const uint8_t *ssid, uint8_t ssid_len)
+{
+	if (ssid_len < WLAN_SSID_MAX_LEN) {
+		qdf_mem_copy(vdev->vdev_mlme.ssid, ssid, ssid_len);
+		vdev->vdev_mlme.ssid_len = ssid_len;
+	} else {
+		vdev->vdev_mlme.ssid_len = 0;
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_vdev_mlme_get_ssid() - get ssid
+ * @vdev: VDEV object
+ * @ssid: SSID
+ * @ssid_len: Length of SSID
+ *
+ * API to get the SSID of VDEV, it updates the SSID and its length
+ * in @ssid, @ssid_len respectively
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: SUCCESS, if update is done
+ *          FAILURE, if ssid length is > max ssid len
+ */
+static inline QDF_STATUS wlan_vdev_mlme_get_ssid(
+				struct wlan_objmgr_vdev *vdev,
+				 uint8_t *ssid, uint8_t *ssid_len)
+{
+	if (vdev->vdev_mlme.ssid_len > 0) {
+		*ssid_len = vdev->vdev_mlme.ssid_len;
+		qdf_mem_copy(ssid, vdev->vdev_mlme.ssid, *ssid_len);
+	} else {
+		*ssid_len = 0;
+		return QDF_STATUS_E_FAILURE;
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * wlan_vdev_obj_lock() - Acquire VDEV spinlock
+ * @vdev: VDEV object
+ *
+ * API to acquire VDEV lock
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_obj_lock(struct wlan_objmgr_vdev *vdev)
+{
+	qdf_spin_lock_bh(&vdev->vdev_lock);
+}
+
+/**
+ * wlan_vdev_obj_unlock() - Release VDEV spinlock
+ * @vdev: VDEV object
+ *
+ * API to Release VDEV lock
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_obj_unlock(struct wlan_objmgr_vdev *vdev)
+{
+	qdf_spin_unlock_bh(&vdev->vdev_lock);
+}
+
+/**
+ * wlan_vdev_mlme_set_bss_chan() - set bss chan
+ * @vdev: VDEV object
+ * @bss_chan: Channel
+ *
+ * API to set the BSS channel
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_bss_chan(struct wlan_objmgr_vdev *vdev,
+			struct wlan_channel *bss_chan)
+{
+	vdev->vdev_mlme.bss_chan = bss_chan;
+}
+
+/**
+ * wlan_vdev_mlme_get_bss_chan() - get bss chan
+ * @vdev: VDEV object
+ *
+ * API to get the BSS channel
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @bss_chan: Channel
+ */
+static inline struct wlan_channel *wlan_vdev_mlme_get_bss_chan(
+				struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.bss_chan;
+}
+
+/**
+ * wlan_vdev_mlme_set_des_chan() - set desired chan
+ * @vdev: VDEV object
+ * @des_chan: Channel configured by user
+ *
+ * API to set the desired channel
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_des_chan(struct wlan_objmgr_vdev *vdev,
+			struct wlan_channel *des_chan)
+{
+	vdev->vdev_mlme.des_chan = des_chan;
+}
+
+/**
+ * wlan_vdev_mlme_get_des_chan() - get desired chan
+ * @vdev: VDEV object
+ *
+ * API to get the desired channel
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @des_chan: Channel configured by user
+ */
+static inline struct wlan_channel *wlan_vdev_mlme_get_des_chan(
+				struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.des_chan;
+}
+
+/**
+ * wlan_vdev_mlme_set_nss() - set NSS
+ * @vdev: VDEV object
+ * @nss: nss configured by user
+ *
+ * API to set the Number of Spatial streams
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_nss(struct wlan_objmgr_vdev *vdev,
+			uint8_t nss)
+{
+	vdev->vdev_mlme.nss = nss;
+}
+
+/**
+ * wlan_vdev_mlme_get_nss() - get NSS
+ * @vdev: VDEV object
+ *
+ * API to get the Number of Spatial Streams
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @nss: nss value
+ */
+static inline uint8_t wlan_vdev_mlme_get_nss(
+				struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.nss;
+}
+
+/**
+ * wlan_vdev_mlme_set_chainmask() - set chainmask
+ * @vdev: VDEV object
+ * @chainmask : chainmask either configured by user or max supported
+ *
+ * API to set the chainmask
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_chainmask(struct wlan_objmgr_vdev *vdev,
+			uint8_t chainmask)
+{
+	vdev->vdev_mlme.chainmask = chainmask;
+}
+
+/**
+ * wlan_vdev_mlme_get_chainmask() - get chainmask
+ * @vdev: VDEV object
+ *
+ * API to get the chainmask
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @chainmask : chainmask either configured by user or max supported
+ */
+static inline uint8_t wlan_vdev_mlme_get_chainmask(
+				struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.chainmask;
+}
+
+/**
+ * wlan_vdev_mlme_set_txpower() - set tx power
+ * @vdev: VDEV object
+ * @txpow: tx power either configured by used or max allowed
+ *
+ * API to set the tx power
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_txpower(struct wlan_objmgr_vdev *vdev,
+			uint8_t txpow)
+{
+	vdev->vdev_mlme.tx_power = txpow;
+}
+
+/**
+ * wlan_vdev_mlme_get_txpower() - get tx power
+ * @vdev: VDEV object
+ *
+ * API to get the tx power
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @txpow: tx power either configured by used or max allowed
+ */
+static inline uint8_t wlan_vdev_mlme_get_txpower(
+				struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.tx_power;
+}
+
+/**
+ * wlan_vdev_mlme_set_maxrate() - set max rate
+ * @vdev: VDEV object
+ * @maxrate: configured by used or based on configured mode
+ *
+ * API to set the max rate the vdev supports
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_maxrate(struct wlan_objmgr_vdev *vdev,
+			uint32_t maxrate)
+{
+	vdev->vdev_mlme.max_rate = maxrate;
+}
+
+/**
+ * wlan_vdev_mlme_get_maxrate() - get max rate
+ * @vdev: VDEV object
+ *
+ * API to get the max rate the vdev supports
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @maxrate: configured by used or based on configured mode
+ */
+static inline uint32_t wlan_vdev_mlme_get_maxrate(
+				struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.max_rate;
+}
+
+/**
+ * wlan_vdev_mlme_set_txmgmtrate() - set txmgmtrate
+ * @vdev: VDEV object
+ * @txmgmtrate: Tx Mgmt rate
+ *
+ * API to set Mgmt Tx rate
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_txmgmtrate(struct wlan_objmgr_vdev *vdev,
+			uint32_t txmgmtrate)
+{
+	vdev->vdev_mlme.tx_mgmt_rate = txmgmtrate;
+}
+
+/**
+ * wlan_vdev_mlme_get_txmgmtrate() - get txmgmtrate
+ * @vdev: VDEV object
+ *
+ * API to get Mgmt Tx rate
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @txmgmtrate: Tx Mgmt rate
+ */
+static inline uint32_t wlan_vdev_mlme_get_txmgmtrate(
+				struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.tx_mgmt_rate;
+}
+
+/**
+ * wlan_vdev_mlme_feat_cap_set() - set feature caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be set
+ *
+ * API to set MLME feature capabilities
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_feat_cap_set(struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	vdev->vdev_mlme.vdev_feat_caps |= cap;
+}
+
+/**
+ * wlan_vdev_mlme_feat_cap_clear() - clear feature caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be cleared
+ *
+ * API to clear MLME feature capabilities
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_feat_cap_clear(struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	vdev->vdev_mlme.vdev_feat_caps &= ~cap;
+}
+
+/**
+ * wlan_vdev_mlme_feat_cap_get() - get feature caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be checked
+ *
+ * API to know MLME feature capability is set or not
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: 1 -- if capabilities set
+ *         0 -- if capabilities clear
+ */
+static inline uint8_t wlan_vdev_mlme_feat_cap_get(struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	return (vdev->vdev_mlme.vdev_feat_caps & cap) ? 1 : 0;
+}
+
+/**
+ * wlan_vdev_mlme_feat_ext_cap_set() - set ext feature caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be set
+ *
+ * API to set the MLME extensive feature capabilities
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_feat_ext_cap_set(
+				struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	vdev->vdev_mlme.vdev_feat_ext_caps |= cap;
+}
+
+/**
+ * wlan_vdev_mlme_feat_ext_cap_clear() - clear ext feature caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be cleared
+ *
+ * API to clear the MLME extensive feature capabilities
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_feat_ext_cap_clear(
+				struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	vdev->vdev_mlme.vdev_feat_ext_caps &= ~cap;
+}
+
+/**
+ * wlan_vdev_mlme_feat_ext_cap_get() - get feature ext caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be checked
+ *
+ * API to know MLME ext feature capability is set or not
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: 1 -- if capabilities set
+ *         0 -- if capabilities clear
+ */
+static inline uint8_t wlan_vdev_mlme_feat_ext_cap_get(
+				struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	return (vdev->vdev_mlme.vdev_feat_ext_caps & cap) ? 1 : 0;
+}
+
+/**
+ * wlan_vdev_mlme_cap_set() - mlme caps set
+ * @vdev: VDEV object
+ * @cap: capabilities to be set
+ *
+ * API to set the MLME capabilities
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_cap_set(struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	vdev->vdev_mlme.vdev_caps |= cap;
+}
+
+/**
+ * wlan_vdev_mlme_cap_clear() -  mlme caps clear
+ * @vdev: VDEV object
+ * @cap: capabilities to be cleared
+ *
+ * API to clear the MLME capabilities
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_cap_clear(struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	vdev->vdev_mlme.vdev_caps &= ~cap;
+}
+
+/**
+ * wlan_vdev_mlme_cap_get() - get mlme caps
+ * @vdev: VDEV object
+ * @cap: capabilities to be checked
+ *
+ * API to know MLME capability is set or not
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: 1 -- if capabilities set
+ *         0 -- if capabilities clear
+ */
+static inline uint8_t wlan_vdev_mlme_cap_get(struct wlan_objmgr_vdev *vdev,
+				uint32_t cap)
+{
+	return (vdev->vdev_mlme.vdev_caps & cap) ? 1 : 0;
+}
+
+/**
+ * wlan_vdev_mlme_get_state() - get mlme state
+ * @vdev: VDEV object
+ *
+ * API to get MLME state
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: state of MLME
+ */
+static inline enum wlan_vdev_state wlan_vdev_mlme_get_state(
+				struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_mlme.mlme_state;
+}
+
+/**
+ * wlan_vdev_mlme_set_state() - set mlme state
+ * @vdev: VDEV object
+ * @state: MLME state
+ *
+ * API to set MLME state
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_mlme_set_state(struct wlan_objmgr_vdev *vdev,
+					enum wlan_vdev_state state)
+{
+	if (state < WLAN_VDEV_S_MAX)
+		vdev->vdev_mlme.mlme_state = state;
+}
+
+/**
+ * wlan_vdev_set_selfpeer() - set self peer
+ * @vdev: VDEV object
+ * @peer: peer pointer
+ *
+ * API to set the self peer of VDEV
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_set_selfpeer(struct wlan_objmgr_vdev *vdev,
+						struct wlan_objmgr_peer *peer)
+{
+	vdev->vdev_objmgr.self_peer = peer;
+}
+
+/**
+ * wlan_vdev_get_selfpeer() - get self peer
+ * @vdev: VDEV object
+ *
+ * API to get the self peer of VDEV
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @peer: peer pointer
+ */
+static inline struct wlan_objmgr_peer *wlan_vdev_get_selfpeer(
+					struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_objmgr.self_peer;
+}
+
+/**
+ * wlan_vdev_set_bsspeer() - set bss peer
+ * @vdev: VDEV object
+ * @peer: BSS peer pointer
+ *
+ * API to set the BSS peer of VDEV
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return: void
+ */
+static inline void wlan_vdev_set_bsspeer(struct wlan_objmgr_vdev *vdev,
+						 struct wlan_objmgr_peer *peer)
+{
+	vdev->vdev_objmgr.bss_peer = peer;
+}
+
+/**
+ * wlan_vdev_get_bsspeer() - get bss peer
+ * @vdev: VDEV object
+ *
+ * API to get the BSS peer of VDEV
+ *
+ * Caller need to acquire lock with wlan_vdev_obj_lock()
+ *
+ * Return:
+ * @peer: BSS peer pointer
+ */
+static inline struct wlan_objmgr_peer *wlan_vdev_get_bsspeer(
+					struct wlan_objmgr_vdev *vdev)
+{
+	return vdev->vdev_objmgr.bss_peer;
+}
+#endif /* _WLAN_OBJMGR_VDEV_OBJ_H_*/

+ 774 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj.c

@@ -0,0 +1,774 @@
+/*
+ * Copyright (c) 2016 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: Public APIs to perform operations on Global objects
+  */
+
+#include <wlan_objmgr_global_obj_i.h>
+#include <wlan_objmgr_global_obj.h>
+#include "qdf_mem.h"
+
+/* Global object, it is declared globally */
+struct wlan_objmgr_global *g_umac_glb_obj;
+/* Component Name table */
+const char *wlan_umac_component_name[] = {
+	"MLME",
+	"SCAN_MGR",
+	"SCAN_CACHE",
+	"MGMT_TXRX",
+	"",
+};
+/*
+** APIs to Create/Delete Global object APIs
+*/
+QDF_STATUS wlan_objmgr_global_obj_create(void)
+{
+	struct wlan_objmgr_global *umac_global_obj;
+
+	/* If it is already created, ignore */
+	if (g_umac_glb_obj != NULL) {
+		qdf_print("%s: Global object is already created\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Allocation of memory for Global object */
+	umac_global_obj = (struct wlan_objmgr_global *)qdf_mem_malloc(
+				sizeof(*umac_global_obj));
+	if (umac_global_obj == NULL) {
+		qdf_print("%s: Global object alloc failed due to malloc\n",
+			  __func__);
+		return QDF_STATUS_E_NOMEM;
+	}
+	/* Store Global object pointer in Global variable */
+	g_umac_glb_obj = umac_global_obj;
+	/* Initialize spinlock */
+	qdf_spinlock_create(&g_umac_glb_obj->global_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(wlan_objmgr_global_obj_create);
+
+QDF_STATUS wlan_objmgr_global_obj_delete(void)
+{
+	/* If it is already deleted */
+	if (g_umac_glb_obj == NULL) {
+		qdf_print("%s: Global object is not allocated\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* TODO: Do we need to check, if any object
+	*  is not freed before this is called ??
+	*  ideally, init/deinit module should take care of freeing */
+	/* Initialize spinlock */
+	qdf_spinlock_destroy(&g_umac_glb_obj->global_lock);
+	/* Free Global object memory */
+	qdf_mem_free(g_umac_glb_obj);
+	/* Reset Global variable to NULL */
+	g_umac_glb_obj = NULL;
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(wlan_objmgr_global_obj_delete);
+
+/**
+ ** APIs to register/unregister handlers
+ */
+QDF_STATUS wlan_objmgr_register_psoc_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_create_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->psoc_create_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->psoc_create_handler[id] = handler;
+	g_umac_glb_obj->psoc_create_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_psoc_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_create_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->psoc_create_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->psoc_create_handler[id] = NULL;
+	g_umac_glb_obj->psoc_create_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_register_psoc_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_delete_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->psoc_delete_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->psoc_delete_handler[id] = handler;
+	g_umac_glb_obj->psoc_delete_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_psoc_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_delete_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->psoc_delete_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->psoc_delete_handler[id] = NULL;
+	g_umac_glb_obj->psoc_delete_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_register_psoc_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_status_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->psoc_status_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->psoc_status_handler[id] = handler;
+	g_umac_glb_obj->psoc_status_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_psoc_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_psoc_status_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->psoc_status_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->psoc_status_handler[id] = NULL;
+	g_umac_glb_obj->psoc_status_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS wlan_objmgr_register_pdev_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_create_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->pdev_create_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->pdev_create_handler[id] = handler;
+	g_umac_glb_obj->pdev_create_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_pdev_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_create_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->pdev_create_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->pdev_create_handler[id] = NULL;
+	g_umac_glb_obj->pdev_create_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_register_pdev_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_delete_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->pdev_delete_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->pdev_delete_handler[id] = handler;
+	g_umac_glb_obj->pdev_delete_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_pdev_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_delete_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->pdev_delete_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for component %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->pdev_delete_handler[id] = NULL;
+	g_umac_glb_obj->pdev_delete_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_register_pdev_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_status_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->pdev_status_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->pdev_status_handler[id] = handler;
+	g_umac_glb_obj->pdev_status_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_pdev_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_pdev_status_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->pdev_status_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for component %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->pdev_status_handler[id] = NULL;
+	g_umac_glb_obj->pdev_status_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS wlan_objmgr_register_vdev_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_create_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->vdev_create_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->vdev_create_handler[id] = handler;
+	g_umac_glb_obj->vdev_create_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_vdev_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_create_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->vdev_create_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->vdev_create_handler[id] = NULL;
+	g_umac_glb_obj->vdev_create_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_register_vdev_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_delete_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->vdev_delete_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->vdev_delete_handler[id] = handler;
+	g_umac_glb_obj->vdev_delete_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_vdev_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_delete_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->vdev_delete_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->vdev_delete_handler[id] = NULL;
+	g_umac_glb_obj->vdev_delete_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_register_vdev_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_status_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->vdev_status_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->vdev_status_handler[id] = handler;
+	g_umac_glb_obj->vdev_status_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_vdev_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_vdev_status_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->vdev_status_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for component %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->vdev_status_handler[id] = NULL;
+	g_umac_glb_obj->vdev_status_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS wlan_objmgr_register_peer_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_create_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->peer_create_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->peer_create_handler[id] = handler;
+	g_umac_glb_obj->peer_create_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS wlan_objmgr_unregister_peer_create_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_create_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->peer_create_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->peer_create_handler[id] = NULL;
+	g_umac_glb_obj->peer_create_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_register_peer_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_delete_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->peer_delete_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->peer_delete_handler[id] = handler;
+	g_umac_glb_obj->peer_delete_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_peer_delete_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_delete_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->peer_delete_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->peer_delete_handler[id] = NULL;
+	g_umac_glb_obj->peer_delete_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_register_peer_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_status_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is a valid entry, return failure */
+	if (g_umac_glb_obj->peer_status_handler[id] != NULL) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is already registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Store handler and args in Global object table */
+	g_umac_glb_obj->peer_status_handler[id] = handler;
+	g_umac_glb_obj->peer_status_handler_arg[id] = arg;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_unregister_peer_status_handler(
+		enum wlan_umac_comp_id id,
+		wlan_objmgr_peer_status_handler handler,
+		void *arg)
+{
+	/* If id is not within valid range, return */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component %d is out of range\n", __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* If there is an invalid entry, return failure */
+	if (g_umac_glb_obj->peer_status_handler[id] != handler) {
+		qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+		qdf_print("%s:callback for comp %d is not registered\n",
+			  __func__, id);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset handlers, and args to NULL */
+	g_umac_glb_obj->peer_status_handler[id] = NULL;
+	g_umac_glb_obj->peer_status_handler_arg[id] = NULL;
+
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS wlan_objmgr_psoc_object_attach(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t index = 0;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* Find free slot in PSOC table, store the PSOC */
+	while (index < WLAN_OBJMGR_MAX_DEVICES) {
+		if (g_umac_glb_obj->psoc[index] == NULL) {
+			/* Found free slot, store psoc */
+			g_umac_glb_obj->psoc[index] = psoc;
+			status = QDF_STATUS_SUCCESS;
+			break;
+		}
+		index++;
+	}
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return status;
+}
+
+QDF_STATUS wlan_objmgr_psoc_object_detach(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t index = 0;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	while (index < WLAN_OBJMGR_MAX_DEVICES) {
+		if (g_umac_glb_obj->psoc[index] == psoc) {
+			/* found psoc, store NULL */
+			g_umac_glb_obj->psoc[index] = NULL;
+			status = QDF_STATUS_SUCCESS;
+			break;
+		}
+		index++;
+	}
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return status;
+}
+
+QDF_STATUS wlan_objmgr_global_obj_can_deleted(void)
+{
+	uint8_t index = 0;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	qdf_spin_lock_bh(&g_umac_glb_obj->global_lock);
+	/* Check whether all PSOCs are freed */
+	while (index < WLAN_OBJMGR_MAX_DEVICES) {
+		if (g_umac_glb_obj->psoc[index] != NULL) {
+			status = QDF_STATUS_E_FAILURE;
+			break;
+		}
+		index++;
+	}
+	qdf_spin_unlock_bh(&g_umac_glb_obj->global_lock);
+	return status;
+}
+EXPORT_SYMBOL(wlan_objmgr_global_obj_can_deleted);

+ 100 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_global_obj_i.h

@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016 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: Define the global data structure of UMAC
+  */
+#ifndef _WLAN_OBJMGR_GLOBAL_OBJ_I_H_
+#define _WLAN_OBJMGR_GLOBAL_OBJ_I_H_
+
+#include "wlan_objmgr_cmn.h"
+/**
+ *  struct wlan_objmgr_global - Global object definition
+ *  @psoc[]:                    Array of PSOCs to maintain PSOC's list,
+ *                              its optional
+ *  @psoc_create_handler[]:     PSOC create handler array
+ *  @psoc_create_handler_arg[]: PSOC create handler args array
+ *  @psoc_delete_handler[]:     PSOC delete handler array
+ *  @psoc_delete_handler_arg[]: PSOC delete handler args array
+ *  @psoc_status_handler[]:     PSOC status handler array
+ *  @psoc_status_handler_arg[]: PSOC status handler args array
+ *  @pdev_create_handler[]:     PDEV create handler array
+ *  @pdev_create_handler_arg[]: PDEV create handler args array
+ *  @pdev_delete_handler[]:     PDEV delete handler array
+ *  @pdev_delete_handler_arg[]: PDEV delete handler args array
+ *  @pdev_status_handler[]:     PDEV status handler array
+ *  @pdev_status_handler_arg[]: PDEV status handler args array
+ *  @vdev_create_handler[]:     VDEV create handler array
+ *  @vdev_create_handler_arg[]: VDEV create handler args array
+ *  @vdev_delete_handler[]:     VDEV delete handler array
+ *  @vdev_delete_handler_arg[]: VDEV delete handler args array
+ *  @vdev_status_handler[]:     VDEV status handler array
+ *  @vdev_status_handler_arg[]: VDEV status handler args array
+ *  @peer_create_handler[]:     PEER create handler array
+ *  @peer_create_handler_arg[]: PEER create handler args array
+ *  @peer_delete_handler[]:     PEER delete handler array
+ *  @peer_delete_handler_arg[]: PEER delete handler args array
+ *  @peer_status_handler[]:     PEER status handler array
+ *  @peer_status_handler_arg[]: PEER status handler args array
+ *  @global_lock:               Global lock
+ */
+struct wlan_objmgr_global {
+	struct wlan_objmgr_psoc *psoc[WLAN_OBJMGR_MAX_DEVICES];
+	wlan_objmgr_psoc_create_handler
+		psoc_create_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *psoc_create_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_psoc_delete_handler
+		psoc_delete_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *psoc_delete_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_psoc_status_handler
+		psoc_status_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *psoc_status_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_pdev_create_handler
+		pdev_create_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *pdev_create_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_pdev_delete_handler
+		pdev_delete_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *pdev_delete_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_pdev_status_handler
+		pdev_status_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *pdev_status_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_vdev_create_handler
+		vdev_create_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *vdev_create_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_vdev_delete_handler
+		vdev_delete_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *vdev_delete_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_vdev_status_handler
+		vdev_status_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *vdev_status_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_peer_create_handler
+		peer_create_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *peer_create_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_peer_delete_handler
+		peer_delete_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *peer_delete_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	wlan_objmgr_peer_status_handler
+		peer_status_handler[WLAN_UMAC_MAX_COMPONENTS];
+	void *peer_status_handler_arg[WLAN_UMAC_MAX_COMPONENTS];
+	qdf_spinlock_t	global_lock;
+};
+
+#define MAX_SLEEP_ITERATION 5
+
+extern struct wlan_objmgr_global *g_umac_glb_obj;
+
+#endif /* _WLAN_OBJMGR_GLOBAL_OBJ_I_H_ */

+ 628 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c

@@ -0,0 +1,628 @@
+/*
+ * Copyright (c) 2016 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: Public APIs to perform operations on Global objects
+  */
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_objmgr_global_obj_i.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_peer_obj.h>
+#include <wlan_objmgr_psoc_obj_i.h>
+#include <wlan_objmgr_pdev_obj_i.h>
+#include <qdf_mem.h>
+
+
+/**
+ ** APIs to Create/Delete Global object APIs
+ */
+static QDF_STATUS wlan_objmgr_pdev_object_status(
+		struct wlan_objmgr_pdev *pdev)
+{
+	uint8_t id;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	wlan_pdev_obj_lock(pdev);
+	/* Iterate through all components to derive the object status */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		/* If component disabled, Ignore */
+		if (pdev->obj_status[id] == QDF_STATUS_COMP_DISABLED) {
+			continue;
+		/* If component operates in Async, status is Partially created,
+			break */
+		} else if (pdev->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
+			if (pdev->pdev_comp_obj[id] == NULL) {
+				status = QDF_STATUS_COMP_ASYNC;
+				break;
+			}
+		/* If component failed to allocate its object, treat it as
+			failure, complete object need to be cleaned up */
+		} else if ((pdev->obj_status[id] == QDF_STATUS_E_NOMEM) ||
+			(pdev->obj_status[id] == QDF_STATUS_E_FAILURE)) {
+			status = QDF_STATUS_E_FAILURE;
+			break;
+		}
+	}
+	wlan_pdev_obj_unlock(pdev);
+	return status;
+}
+
+struct wlan_objmgr_pdev *wlan_objmgr_pdev_obj_create(
+			struct wlan_objmgr_psoc *psoc, void *osdev_priv)
+{
+	struct wlan_objmgr_pdev *pdev;
+	uint8_t id;
+	wlan_objmgr_pdev_create_handler handler;
+	wlan_objmgr_pdev_status_handler s_handler;
+	void *arg;
+	QDF_STATUS obj_status;
+
+	if (psoc == NULL) {
+		qdf_print("%s:psoc is NULL\n", __func__);
+		return NULL;
+	}
+	/* Allocate PDEV object's memory */
+	pdev = qdf_mem_malloc(sizeof(*pdev));
+	if (pdev == NULL) {
+		qdf_print("%s:pdev alloc failed\n", __func__);
+		return NULL;
+	}
+	/* Attach PDEV with PSOC */
+	if (wlan_objmgr_psoc_pdev_attach(psoc, pdev)
+				!= QDF_STATUS_SUCCESS) {
+		qdf_print("%s:pdev psoc attach failed\n", __func__);
+		qdf_mem_free(pdev);
+		return NULL;
+	}
+	/* Save PSOC object pointer in PDEV */
+	wlan_pdev_set_psoc(pdev, psoc);
+	/* Initialize PDEV spinlock */
+	qdf_spinlock_create(&pdev->pdev_lock);
+	/* Initialize PDEV's VDEV list, assign default values */
+	qdf_list_create(&pdev->pdev_objmgr.wlan_vdev_list,
+			WLAN_UMAC_PDEV_MAX_VDEVS);
+	pdev->pdev_objmgr.wlan_vdev_count = 0;
+	pdev->pdev_objmgr.max_vdev_count = WLAN_UMAC_PDEV_MAX_VDEVS;
+	/* Save HDD/OSIF pointer */
+	pdev->pdev_nif.pdev_ospriv = osdev_priv;
+
+	/* Invoke registered create handlers */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		handler = g_umac_glb_obj->pdev_create_handler[id];
+		arg = g_umac_glb_obj->pdev_create_handler_arg[id];
+		if (handler != NULL)
+			pdev->obj_status[id] = handler(pdev, arg);
+		else
+			pdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
+	}
+	/* Derive object status */
+	obj_status = wlan_objmgr_pdev_object_status(pdev);
+
+	if (obj_status == QDF_STATUS_SUCCESS) {
+		/* Object status is SUCCESS, Object is created */
+		pdev->obj_state = WLAN_OBJ_STATE_CREATED;
+		/* Invoke component registered status handlers */
+		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+			s_handler = g_umac_glb_obj->pdev_status_handler[id];
+			arg = g_umac_glb_obj->pdev_status_handler_arg[id];
+			if (s_handler != NULL) {
+				s_handler(pdev, arg,
+					  QDF_STATUS_SUCCESS);
+			}
+		}
+	/* Few components operates in Asynchrous communction, Object state
+	partially created */
+	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
+		pdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
+	/* Component object failed to be created, clean up the object */
+	} else if (obj_status == QDF_STATUS_E_FAILURE) {
+		/* Clean up the psoc */
+		qdf_print("%s: PDEV component objects allocation failed\n",
+			  __func__);
+		wlan_objmgr_pdev_obj_delete(pdev);
+		return NULL;
+	}
+	return pdev;
+}
+EXPORT_SYMBOL(wlan_objmgr_pdev_obj_create);
+
+QDF_STATUS wlan_objmgr_pdev_obj_delete(struct wlan_objmgr_pdev *pdev)
+{
+	uint8_t id;
+	wlan_objmgr_pdev_delete_handler handler;
+	QDF_STATUS obj_status;
+	void *arg;
+
+	if (pdev == NULL) {
+		qdf_print("%s:pdev is NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Invoke registered delete handlers */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		handler = g_umac_glb_obj->pdev_delete_handler[id];
+		arg = g_umac_glb_obj->pdev_delete_handler_arg[id];
+		if (handler != NULL)
+			pdev->obj_status[id] = handler(pdev, arg);
+		else
+			pdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
+	}
+	/* Derive object status */
+	obj_status = wlan_objmgr_pdev_object_status(pdev);
+
+	if (obj_status == QDF_STATUS_E_FAILURE) {
+		qdf_print("%s: PDEV component objects delete failed\n",
+			  __func__);
+		/* Ideally should not happen */
+		/* This leads to memleak ??? how to handle */
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Deletion is in progress */
+	if (obj_status == QDF_STATUS_COMP_ASYNC) {
+		pdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
+		return QDF_STATUS_COMP_ASYNC;
+	} else {
+		/* Detach PDEV from PSOC PDEV's list */
+		if (wlan_objmgr_psoc_pdev_detach(pdev->pdev_objmgr.wlan_psoc,
+						 pdev) ==
+						 QDF_STATUS_E_FAILURE) {
+			qdf_print("%s: PSOC PDEV detach failed\n",
+				  __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+		/* de-init lock */
+		qdf_spinlock_destroy(&pdev->pdev_lock);
+		/* Free the memory */
+		qdf_mem_free(pdev);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(wlan_objmgr_pdev_obj_delete);
+
+/**
+ ** APIs to attach/detach component objects
+ */
+QDF_STATUS wlan_objmgr_pdev_component_obj_attach(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr,
+		QDF_STATUS status)
+{
+	uint8_t i;
+	wlan_objmgr_pdev_status_handler s_hlr;
+	void *a;
+	QDF_STATUS obj_status;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS) {
+		qdf_print("%s: component-id %d is not supported\n",
+			  __func__, id);
+		return QDF_STATUS_MAXCOMP_FAIL;
+	}
+	wlan_pdev_obj_lock(pdev);
+	/* If there is a valid entry, return failure */
+	if (pdev->pdev_comp_obj[id] != NULL) {
+		qdf_print("%s: component-%d already have valid pointer\n",
+			  __func__, id);
+		wlan_pdev_obj_unlock(pdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Save component's pointer and status */
+	pdev->pdev_comp_obj[id] = comp_objptr;
+	pdev->obj_status[id] = status;
+	wlan_pdev_obj_unlock(pdev);
+
+	if (pdev->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
+		return QDF_STATUS_SUCCESS;
+	/* If PDEV object status is partially created means, this API is
+	invoked with differnt context, this block should be executed for async
+	components only */
+	/* Derive status */
+	obj_status = wlan_objmgr_pdev_object_status(pdev);
+	/* STATUS_SUCCESS means, object is CREATED */
+	if (obj_status == QDF_STATUS_SUCCESS)
+		pdev->obj_state = WLAN_OBJ_STATE_CREATED;
+	/* update state as CREATION failed, caller has to delete the
+	PDEV object */
+	else if (obj_status == QDF_STATUS_E_FAILURE)
+		pdev->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
+	/* Notify components about the CREATION success/failure */
+	if ((obj_status == QDF_STATUS_SUCCESS) ||
+	    (obj_status == QDF_STATUS_E_FAILURE)) {
+		/* nofity object status */
+		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
+			s_hlr = g_umac_glb_obj->pdev_status_handler[i];
+			a = g_umac_glb_obj->pdev_status_handler_arg[i];
+			if (s_hlr != NULL)
+				s_hlr(pdev, a, obj_status);
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_pdev_component_obj_detach(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr)
+{
+	QDF_STATUS obj_status;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_pdev_obj_lock(pdev);
+	/* If there is a invalid entry, return failure */
+	if (pdev->pdev_comp_obj[id] != comp_objptr) {
+		pdev->obj_status[id] = QDF_STATUS_E_FAILURE;
+		wlan_pdev_obj_unlock(pdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset pointers to NULL, update the status*/
+	pdev->pdev_comp_obj[id] = NULL;
+	pdev->obj_status[id] = QDF_STATUS_SUCCESS;
+	wlan_pdev_obj_unlock(pdev);
+
+	/* If PDEV object status is partially deleted means, this API is
+	invoked with differnt context, this block should be executed for async
+	components only */
+	if ((pdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
+	    (pdev->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
+		/* Derive object status */
+		obj_status = wlan_objmgr_pdev_object_status(pdev);
+		if (obj_status == QDF_STATUS_SUCCESS) {
+			/*Update the status as Deleted, if full object
+				deletion is in progress */
+			if (pdev->obj_state ==
+				WLAN_OBJ_STATE_PARTIALLY_DELETED)
+				pdev->obj_state = WLAN_OBJ_STATE_DELETED;
+			/* Move to creation state, since this component
+			deletion alone requested */
+			if (pdev->obj_state ==
+				WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
+				pdev->obj_state = WLAN_OBJ_STATE_CREATED;
+		/* Object status is failure */
+		} else if (obj_status == QDF_STATUS_E_FAILURE) {
+			/*Update the status as Deletion failed, if full object
+				deletion is in progress */
+			if (pdev->obj_state ==
+					WLAN_OBJ_STATE_PARTIALLY_DELETED)
+				pdev->obj_state =
+					WLAN_OBJ_STATE_DELETION_FAILED;
+			/* Move to creation state, since this component
+			deletion alone requested (do not block other
+			components)*/
+			if (pdev->obj_state ==
+					WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
+				pdev->obj_state = WLAN_OBJ_STATE_CREATED;
+		}
+
+		/* Delete pdev object */
+		if ((obj_status == QDF_STATUS_SUCCESS) &&
+		    (pdev->obj_state == WLAN_OBJ_STATE_DELETED)) {
+			/* Detach pdev object from psoc */
+			if (wlan_objmgr_psoc_pdev_detach(
+				pdev->pdev_objmgr.wlan_psoc, pdev) ==
+						QDF_STATUS_E_FAILURE)
+				return QDF_STATUS_E_FAILURE;
+			/* Destroy spinlock */
+			qdf_spinlock_destroy(&pdev->pdev_lock);
+			/* Free PDEV memory */
+			qdf_mem_free(pdev);
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ ** APIs to operations on pdev objects
+ */
+static void wlan_objmgr_pdev_vdev_iterate_peers(struct wlan_objmgr_pdev *pdev,
+				struct wlan_objmgr_vdev *vdev,
+				wlan_objmgr_pdev_op_handler handler,
+				void *arg, uint8_t lock_free_op)
+{
+	qdf_list_t *peer_list = NULL;
+	struct wlan_objmgr_peer *peer = NULL;
+	struct wlan_objmgr_peer *peer_next = NULL;
+
+	/* Iterating through vdev's peer list, so lock is
+		needed */
+	if (!lock_free_op)
+		wlan_vdev_obj_lock(vdev);
+	/* Get peer list of the vdev */
+	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
+	if (peer_list != NULL) {
+		peer = wlan_vdev_peer_list_peek_head(peer_list);
+		while (peer != NULL) {
+			/* Increment ref count, to hold the
+				peer pointer */
+			wlan_objmgr_peer_ref_peer(peer);
+			/* Get next peer pointer */
+			peer_next = wlan_peer_get_next_peer_of_vdev(peer_list,
+								    peer);
+			/* Invoke the handler */
+			handler(pdev, (void *)peer, arg);
+			/* Decrement ref count, this can lead
+				to peer deletion also */
+			wlan_objmgr_peer_unref_peer(peer);
+			peer = peer_next;
+		}
+	}
+	if (!lock_free_op)
+		wlan_vdev_obj_unlock(vdev);
+}
+
+QDF_STATUS wlan_objmgr_pdev_iterate_obj_list(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_objmgr_obj_type obj_type,
+		wlan_objmgr_pdev_op_handler handler,
+		void *arg, uint8_t lock_free_op)
+{
+	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
+	qdf_list_t *vdev_list = NULL;
+	struct wlan_objmgr_vdev *vdev = NULL;
+	struct wlan_objmgr_vdev *vdev_next = NULL;
+
+	/* If caller requests for lock free opeation, do not acquire
+		handler will handle the synchronization*/
+	if (!lock_free_op)
+		wlan_pdev_obj_lock(pdev);
+	/* VDEV list */
+	vdev_list = &objmgr->wlan_vdev_list;
+	switch (obj_type) {
+	case WLAN_VDEV_OP:
+		/* Iterate through all VDEV object, and invoke handler for each
+			VDEV object */
+		vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
+		while (vdev != NULL) {
+				/* TODO increment ref count */
+			/* Get next vdev (handler can be invoked for
+				vdev deletion also */
+			vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list,
+						vdev);
+			handler(pdev, (void *)vdev, arg);
+			vdev = vdev_next;
+				/* TODO decrement ref count */
+		}
+		break;
+	case WLAN_PEER_OP:
+		vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
+		while (vdev != NULL) {
+			/* TODO increment ref count */
+			wlan_objmgr_pdev_vdev_iterate_peers(pdev, vdev, handler,
+							    arg, lock_free_op);
+			/* Get Next VDEV */
+			vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list,
+						vdev);
+			/* TODO decrement ref count */
+		}
+		break;
+	default:
+		break;
+	}
+	if (!lock_free_op)
+		wlan_pdev_obj_unlock(pdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(wlan_objmgr_pdev_iterate_obj_list);
+
+QDF_STATUS wlan_objmgr_trigger_pdev_comp_object_creation(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_umac_comp_id id)
+{
+	wlan_objmgr_pdev_create_handler handler;
+	void *arg;
+	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
+
+	/* Component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_pdev_obj_lock(pdev);
+	/* If component object is already created, delete old
+		component object, then invoke creation */
+	if (pdev->pdev_comp_obj[id] != NULL) {
+		wlan_pdev_obj_unlock(pdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wlan_pdev_obj_unlock(pdev);
+
+	/* Invoke registered create handlers */
+	handler = g_umac_glb_obj->pdev_create_handler[id];
+	arg = g_umac_glb_obj->pdev_create_handler_arg[id];
+	if (handler != NULL)
+		pdev->obj_status[id] = handler(pdev, arg);
+	else
+		return QDF_STATUS_E_FAILURE;
+	/* If object status is created, then only handle this object status */
+	if (pdev->obj_state == WLAN_OBJ_STATE_CREATED) {
+		/* Derive object status */
+		obj_status = wlan_objmgr_pdev_object_status(pdev);
+		/* Move PDEV object state to Partially created state */
+		if (obj_status == QDF_STATUS_COMP_ASYNC) {
+			/*TODO atomic */
+			pdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
+		}
+	}
+	return obj_status;
+}
+
+QDF_STATUS wlan_objmgr_trigger_pdev_comp_object_deletion(
+		struct wlan_objmgr_pdev *pdev,
+		enum wlan_umac_comp_id id)
+{
+	wlan_objmgr_pdev_delete_handler handler;
+	void *arg;
+	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_pdev_obj_lock(pdev);
+	/* Component object was never created, invalid operation */
+	if (pdev->pdev_comp_obj[id] == NULL) {
+		wlan_pdev_obj_unlock(pdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wlan_pdev_obj_unlock(pdev);
+
+	/* Invoke registered create handlers */
+	handler = g_umac_glb_obj->pdev_delete_handler[id];
+	arg = g_umac_glb_obj->pdev_delete_handler_arg[id];
+	if (handler != NULL)
+		pdev->obj_status[id] = handler(pdev, arg);
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	/* If object status is created, then only handle this object status */
+	if (pdev->obj_state == WLAN_OBJ_STATE_CREATED) {
+		obj_status = wlan_objmgr_pdev_object_status(pdev);
+		/* move object state to DEL progress */
+		if (obj_status == QDF_STATUS_COMP_ASYNC)
+			pdev->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
+	}
+	return obj_status;
+}
+
+static void wlan_obj_pdev_vdevlist_add_tail(qdf_list_t *obj_list,
+				struct wlan_objmgr_vdev *obj)
+{
+	qdf_list_insert_back(obj_list, &obj->vdev_node);
+}
+
+static QDF_STATUS wlan_obj_pdev_vdevlist_remove_vdev(
+				qdf_list_t *obj_list,
+				struct wlan_objmgr_vdev *vdev)
+{
+	qdf_list_node_t *vdev_node = NULL;
+
+	if (vdev == NULL)
+		return QDF_STATUS_E_FAILURE;
+	/* get vdev list node element */
+	vdev_node = &vdev->vdev_node;
+	/* list is empty, return failure */
+	if (qdf_list_remove_node(obj_list, vdev_node) != QDF_STATUS_SUCCESS)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_pdev_vdev_attach(struct wlan_objmgr_pdev *pdev,
+					struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
+
+	wlan_pdev_obj_lock(pdev);
+	/* If Max vdev count exceeds, return failure */
+	if (objmgr->wlan_vdev_count > objmgr->max_vdev_count) {
+		wlan_pdev_obj_unlock(pdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Add vdev to pdev's vdev list */
+	wlan_obj_pdev_vdevlist_add_tail(&objmgr->wlan_vdev_list, vdev);
+	/* Increment vdev count of pdev */
+	objmgr->wlan_vdev_count++;
+	wlan_pdev_obj_unlock(pdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_pdev_vdev_detach(struct wlan_objmgr_pdev *pdev,
+				struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
+
+	wlan_pdev_obj_lock(pdev);
+	/* if vdev count is 0, return failure */
+	if (objmgr->wlan_vdev_count == 0) {
+		wlan_pdev_obj_unlock(pdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* remove vdev from pdev's vdev list */
+	wlan_obj_pdev_vdevlist_remove_vdev(&objmgr->wlan_vdev_list, vdev);
+	/* decrement vdev count */
+	objmgr->wlan_vdev_count--;
+
+	wlan_pdev_obj_unlock(pdev);
+	return QDF_STATUS_SUCCESS;
+}
+
+struct wlan_objmgr_vdev *wlan_objmgr_find_vdev_by_id_from_pdev(
+			struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_vdev *vdev_next;
+	struct wlan_objmgr_pdev_objmgr *objmgr;
+	qdf_list_t *vdev_list;
+
+	wlan_pdev_obj_lock(pdev);
+
+	objmgr = &pdev->pdev_objmgr;
+	vdev_list = &objmgr->wlan_vdev_list;
+	/* Get first vdev */
+	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
+	/* Iterate through pdev's vdev list, till vdev id matches with
+	entry of vdev list */
+	while (vdev != NULL) {
+		if (wlan_vdev_get_id(vdev) == vdev_id) {
+			wlan_pdev_obj_unlock(pdev);
+			return vdev;
+		}
+		/* get next vdev */
+		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
+		vdev = vdev_next;
+	}
+	wlan_pdev_obj_unlock(pdev);
+	return NULL;
+}
+EXPORT_SYMBOL(wlan_objmgr_find_vdev_by_id_from_pdev);
+
+struct wlan_objmgr_vdev *wlan_objmgr_find_vdev_by_macaddr_from_pdev(
+		struct wlan_objmgr_pdev *pdev, uint8_t *macaddr)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_vdev *vdev_next;
+	struct wlan_objmgr_pdev_objmgr *objmgr;
+	qdf_list_t *vdev_list;
+
+	wlan_pdev_obj_lock(pdev);
+	objmgr = &pdev->pdev_objmgr;
+	vdev_list = &objmgr->wlan_vdev_list;
+	/* Get first vdev */
+	vdev = wlan_pdev_vdev_list_peek_head(vdev_list);
+	/* Iterate through pdev's vdev list, till vdev macaddr matches with
+	entry of vdev list */
+	while (vdev != NULL) {
+		if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr)
+					== QDF_STATUS_SUCCESS) {
+			wlan_pdev_obj_unlock(pdev);
+			return vdev;
+		}
+		/* get next vdev */
+		vdev_next = wlan_vdev_get_next_vdev_of_pdev(vdev_list, vdev);
+		vdev = vdev_next;
+	}
+	wlan_pdev_obj_unlock(pdev);
+	return NULL;
+}

+ 50 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj_i.h

@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 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: Public APIs to perform operations on PDEV object
+  */
+#ifndef _WLAN_OBJMGR_PDEV_OBJ_I_H_
+#define _WLAN_OBJMGR_PDEV_OBJ_I_H_
+
+/**
+ * wlan_objmgr_pdev_vdev_attach() - attach vdev to pdev
+ * @pdev: PDEV object
+ * @vdev: VDEV object
+ *
+ * API to be used for adding the VDEV object in PDEV's VDEV object list
+ *
+ * Return: SUCCESS on successful storing of VDEV object
+ *         FAILURE
+ */
+QDF_STATUS wlan_objmgr_pdev_vdev_attach(struct wlan_objmgr_pdev *pdev,
+					struct wlan_objmgr_vdev *vdev);
+
+/**
+ * wlan_objmgr_pdev_vdev_detach() - detach vdev from pdev
+ * @pdev: PDEV object
+ * @vdev: VDEV object
+ *
+ * API to be used for removing the VDEV object from PDEV's VDEV object list
+ *
+ * Return: SUCCESS on successful removal of VDEV object
+ *         FAILURE
+ */
+QDF_STATUS wlan_objmgr_pdev_vdev_detach(struct wlan_objmgr_pdev *pdev,
+				struct wlan_objmgr_vdev *vdev);
+
+#endif /* _WLAN_OBJMGR_PDEV_OBJ_I_H_*/

+ 463 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c

@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2016 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: Public APIs to perform operations on Peer object
+ */
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_objmgr_global_obj_i.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_peer_obj.h>
+#include <wlan_objmgr_psoc_obj_i.h>
+#include <wlan_objmgr_pdev_obj_i.h>
+#include <wlan_objmgr_vdev_obj_i.h>
+#include <qdf_mem.h>
+
+
+/**
+ ** APIs to Create/Delete Peer object APIs
+ */
+static QDF_STATUS wlan_objmgr_peer_object_status(
+		struct wlan_objmgr_peer *peer)
+{
+	uint8_t id;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	wlan_peer_obj_lock(peer);
+	/* Iterate through all components to derive the object status */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		/* If component disabled, Ignore */
+		if (peer->obj_status[id] == QDF_STATUS_COMP_DISABLED)
+			continue;
+		/* If component operates in Async, status is Partially created,
+			break */
+		else if (peer->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
+			if (peer->peer_comp_obj[id] == NULL) {
+				status = QDF_STATUS_COMP_ASYNC;
+				break;
+			}
+		/* If component failed to allocate its object, treat it as
+			failure, complete object need to be cleaned up */
+		} else if ((peer->obj_status[id] == QDF_STATUS_E_NOMEM) ||
+			(peer->obj_status[id] == QDF_STATUS_E_FAILURE)) {
+			status = QDF_STATUS_E_FAILURE;
+			break;
+		}
+	}
+	wlan_peer_obj_unlock(peer);
+	return status;
+}
+
+struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create(
+			struct wlan_objmgr_vdev *vdev,
+			enum wlan_peer_type type,
+			uint8_t *macaddr)
+{
+	struct wlan_objmgr_peer *peer;
+	struct wlan_objmgr_psoc *psoc;
+	wlan_objmgr_peer_create_handler handler;
+	wlan_objmgr_peer_status_handler stat_handler;
+	void *arg;
+	QDF_STATUS obj_status;
+	uint8_t id;
+
+	if (vdev == NULL) {
+		qdf_print("%s: VDEV is NULL\n", __func__);
+		return NULL;
+	}
+	/* Get psoc, if psoc is NULL, return */
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (psoc == NULL) {
+		qdf_print("%s: PSOC is NULL\n", __func__);
+		return NULL;
+	}
+	/* Allocate memory for peer object */
+	peer = qdf_mem_malloc(sizeof(*peer));
+	if (peer == NULL) {
+		qdf_print("%s: Peer allocation failure\n", __func__);
+		return NULL;
+	}
+	/* set vdev to peer */
+	wlan_peer_set_vdev(peer, vdev);
+	/* set peer type */
+	wlan_peer_set_peer_type(peer, type);
+	/* set mac address of peer */
+	wlan_peer_set_macaddr(peer, macaddr);
+	/* Attach peer to psoc, psoc maintains the node table for the device */
+	if (wlan_objmgr_psoc_peer_attach(psoc, peer) !=
+					QDF_STATUS_SUCCESS) {
+		qdf_print("%s: Peer PSOC attach failure\n", __func__);
+		qdf_mem_free(peer);
+		return NULL;
+	}
+	/* Attach peer to vdev peer table */
+	if (wlan_objmgr_vdev_peer_attach(vdev, peer) !=
+					QDF_STATUS_SUCCESS) {
+		qdf_print("%s: Peer VDEV attach failure\n", __func__);
+		/* if attach fails, detach from psoc table before free */
+		wlan_objmgr_psoc_peer_detach(psoc, peer);
+		qdf_mem_free(peer);
+		return NULL;
+	}
+	/* init spinlock */
+	qdf_spinlock_create(&peer->peer_lock);
+	/* Increment ref count for BSS peer, so that BSS peer deletes last*/
+	if ((type == WLAN_PEER_STA) || (type == WLAN_PEER_STA_TEMP))
+		wlan_objmgr_peer_ref_peer(wlan_vdev_get_bsspeer(vdev));
+	/* TODO init other parameters */
+	/* Invoke registered create handlers */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		handler = g_umac_glb_obj->peer_create_handler[id];
+		arg = g_umac_glb_obj->peer_create_handler_arg[id];
+		if (handler != NULL)
+			peer->obj_status[id] = handler(peer, arg);
+		else
+			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
+	}
+	/* derive the object status */
+	obj_status = wlan_objmgr_peer_object_status(peer);
+	/* If SUCCESS, Object is created */
+	if (obj_status == QDF_STATUS_SUCCESS) {
+		peer->obj_state = WLAN_OBJ_STATE_CREATED;
+		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+			stat_handler = g_umac_glb_obj->peer_status_handler[id];
+			arg = g_umac_glb_obj->peer_status_handler_arg[id];
+			if (stat_handler != NULL)
+				stat_handler(peer, arg,
+					     QDF_STATUS_SUCCESS);
+		}
+	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
+		/* If any component operates in different context, update it
+		as partially created */
+		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
+	} else if (obj_status == QDF_STATUS_E_FAILURE) {
+		/* Clean up the peer */
+		qdf_print("%s: Peer component object alloc failure\n",
+			  __func__);
+		wlan_objmgr_peer_obj_delete(peer);
+		return NULL;
+	}
+	return peer;
+}
+
+QDF_STATUS wlan_objmgr_peer_obj_delete(struct wlan_objmgr_peer *peer)
+{
+	uint8_t id;
+	wlan_objmgr_peer_delete_handler handler;
+	QDF_STATUS obj_status;
+	void *arg;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (peer == NULL) {
+		qdf_print("%s: PEER is NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* get VDEV from peer, if it is NULL, return */
+	vdev = wlan_peer_get_vdev(peer);
+	if (vdev == NULL) {
+		qdf_print("%s: VDEV is NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* get PSOC from VDEV, if it is NULL, return */
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (psoc == NULL) {
+		qdf_print("%s: PSOC is NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Decrement ref count for BSS peer, so that BSS peer deletes last*/
+	if ((wlan_peer_get_peer_type(peer) == WLAN_PEER_STA) ||
+	    (wlan_peer_get_peer_type(peer) == WLAN_PEER_STA_TEMP))
+		wlan_objmgr_peer_unref_peer(wlan_vdev_get_bsspeer(vdev));
+
+	/* Invoke registered delete handlers */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		handler = g_umac_glb_obj->peer_delete_handler[id];
+		arg = g_umac_glb_obj->peer_delete_handler_arg[id];
+		if (handler != NULL)
+			peer->obj_status[id] = handler(peer, arg);
+		else
+			peer->obj_status[id] = QDF_STATUS_COMP_DISABLED;
+	}
+	/* Derive the object status */
+	obj_status = wlan_objmgr_peer_object_status(peer);
+	if (obj_status == QDF_STATUS_E_FAILURE) {
+		/* If it status is failure, memory will not be freed */
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* few components deletion is in progress */
+	if (obj_status == QDF_STATUS_COMP_ASYNC) {
+		peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
+		return QDF_STATUS_COMP_ASYNC;
+	} else {
+		/* Detach peer from VDEV's peer list */
+		if (wlan_objmgr_vdev_peer_detach(vdev, peer)
+				== QDF_STATUS_E_FAILURE) {
+			qdf_print("%s: Peer VDEV detach failure\n", __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+		/* Detach peer from PSOC's peer list */
+		if (wlan_objmgr_psoc_peer_detach(psoc, peer)
+					== QDF_STATUS_E_FAILURE) {
+			qdf_print("%s: Peer PSOC detach failure\n", __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+		/* destroy spinlock */
+		qdf_spinlock_destroy(&peer->peer_lock);
+		/* Free memory */
+		qdf_mem_free(peer);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ ** APIs to attach/detach component objects
+ */
+QDF_STATUS wlan_objmgr_peer_component_obj_attach(
+		struct wlan_objmgr_peer *peer,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr,
+		QDF_STATUS status)
+{
+	wlan_objmgr_peer_status_handler s_hler;
+	void *arg;
+	uint8_t i;
+	QDF_STATUS obj_status;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_peer_obj_lock(peer);
+	/* If there is a valid entry, return failure,
+	valid object needs to be freed first */
+	if (peer->peer_comp_obj[id] != NULL) {
+		wlan_peer_obj_unlock(peer);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Assign component object pointer(can be NULL also), status */
+	peer->peer_comp_obj[id] = comp_objptr;
+	peer->obj_status[id] = status;
+	wlan_peer_obj_unlock(peer);
+
+	if (peer->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
+		return QDF_STATUS_SUCCESS;
+
+	/* If PEER object status is partially created means, this API is
+	invoked with differnt context. this block should be executed for async
+	components only */
+	/* Derive status */
+	obj_status = wlan_objmgr_peer_object_status(peer);
+	/* STATUS_SUCCESS means, object is CREATED */
+	if (obj_status == QDF_STATUS_SUCCESS)
+		peer->obj_state = WLAN_OBJ_STATE_CREATED;
+	/* update state as CREATION failed, caller has to delete the
+	PEER object */
+	else if (obj_status == QDF_STATUS_E_FAILURE)
+		peer->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
+	/* Notify components about the CREATION success/failure */
+	if ((obj_status == QDF_STATUS_SUCCESS) ||
+	    (obj_status == QDF_STATUS_E_FAILURE)) {
+		/* nofity object status */
+		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
+			s_hler = g_umac_glb_obj->peer_status_handler[i];
+			arg = g_umac_glb_obj->peer_status_handler_arg[i];
+			if (s_hler != NULL)
+				s_hler(peer, arg, obj_status);
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_peer_component_obj_detach(
+		struct wlan_objmgr_peer *peer,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr)
+{
+	QDF_STATUS obj_status;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_vdev *vdev;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	/* get VDEV from peer, if it is NULL, return */
+	vdev = wlan_peer_get_vdev(peer);
+	if (vdev == NULL) {
+		qdf_print("%s: VDEV is NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* get PSOC from VDEV, if it is NULL, return */
+	psoc = wlan_vdev_get_psoc(vdev);
+	if (psoc == NULL) {
+		qdf_print("%s: PSOC is NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wlan_peer_obj_lock(peer);
+	/* If there is a invalid entry, return failure */
+	if (peer->peer_comp_obj[id] != comp_objptr) {
+		peer->obj_status[id] = QDF_STATUS_E_FAILURE;
+		wlan_peer_obj_unlock(peer);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset the pointer to NULL */
+	peer->peer_comp_obj[id] = NULL;
+	peer->obj_status[id] = QDF_STATUS_SUCCESS;
+	wlan_peer_obj_unlock(peer);
+
+	/* If PEER object status is partially deleted means, this API is
+	invoked with differnt context, this block should be executed for async
+	components only */
+	if ((peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
+	    (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
+		/* Derive object status */
+		obj_status = wlan_objmgr_peer_object_status(peer);
+		if (obj_status == QDF_STATUS_SUCCESS) {
+			/*Update the status as Deleted, if full object
+				deletion is in progress */
+			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
+				peer->obj_state = WLAN_OBJ_STATE_DELETED;
+			/* Move to creation state, since this component
+			deletion alone requested */
+			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
+				peer->obj_state = WLAN_OBJ_STATE_CREATED;
+		/* Object status is failure */
+		} else if (obj_status == QDF_STATUS_E_FAILURE) {
+			/*Update the status as Deletion failed, if full object
+				deletion is in progress */
+			if (peer->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
+				peer->obj_state =
+					WLAN_OBJ_STATE_DELETION_FAILED;
+			/* Move to creation state, since this component
+			deletion alone requested (do not block other
+			components) */
+			if (peer->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
+				peer->obj_state = WLAN_OBJ_STATE_CREATED;
+		}
+
+			/* Delete peer object */
+		if ((obj_status == QDF_STATUS_SUCCESS)  &&
+		    (peer->obj_state == WLAN_OBJ_STATE_DELETED)) {
+			/* delete peer from vdev's peer list */
+			if (wlan_objmgr_vdev_peer_detach(vdev, peer) ==
+						QDF_STATUS_E_FAILURE)
+				return QDF_STATUS_E_FAILURE;
+
+			/* delete peer from psoc's peer list */
+			if (wlan_objmgr_psoc_peer_detach(psoc, peer) ==
+						QDF_STATUS_E_FAILURE)
+				return QDF_STATUS_E_FAILURE;
+			/* Destroy spinlock */
+			qdf_spinlock_destroy(&peer->peer_lock);
+			/* free memory */
+			qdf_mem_free(peer);
+			return QDF_STATUS_SUCCESS;
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+
+QDF_STATUS wlan_objmgr_trigger_peer_comp_object_creation(
+		struct wlan_objmgr_peer *peer,
+		enum wlan_umac_comp_id id)
+{
+	wlan_objmgr_peer_create_handler handler;
+	void *arg;
+	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
+
+	/* Component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_peer_obj_lock(peer);
+	/* If component object is already created, delete old
+		component object, then invoke creation */
+	if (peer->peer_comp_obj[id] != NULL) {
+		wlan_peer_obj_unlock(peer);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wlan_peer_obj_unlock(peer);
+
+	/* Invoke registered create handlers */
+	handler = g_umac_glb_obj->peer_create_handler[id];
+	arg = g_umac_glb_obj->peer_create_handler_arg[id];
+	if (handler != NULL)
+		peer->obj_status[id] = handler(peer, arg);
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	/* If object status is created, then only handle this object status */
+	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
+		/* Derive object status */
+		obj_status = wlan_objmgr_peer_object_status(peer);
+		/* Move PDEV object state to Partially created state */
+		if (obj_status == QDF_STATUS_COMP_ASYNC) {
+			/*TODO atomic */
+			peer->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
+		}
+	}
+
+	return obj_status;
+}
+
+
+QDF_STATUS wlan_objmgr_trigger_peer_comp_object_deletion(
+		struct wlan_objmgr_peer *peer,
+		enum wlan_umac_comp_id id)
+{
+	wlan_objmgr_peer_delete_handler handler;
+	void *arg;
+	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_peer_obj_lock(peer);
+	/* Component object was never created, invalid operation */
+	if (peer->peer_comp_obj[id] == NULL) {
+		wlan_peer_obj_unlock(peer);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wlan_peer_obj_unlock(peer);
+
+	/* Invoke registered delete handlers */
+	handler = g_umac_glb_obj->peer_delete_handler[id];
+	arg = g_umac_glb_obj->peer_delete_handler_arg[id];
+	if (handler != NULL)
+		peer->obj_status[id] = handler(peer, arg);
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	/* If object status is created, then only handle this object status */
+	if (peer->obj_state == WLAN_OBJ_STATE_CREATED) {
+		obj_status = wlan_objmgr_peer_object_status(peer);
+			/* move object state to DEL progress */
+		if (obj_status == QDF_STATUS_COMP_ASYNC)
+			peer->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
+	}
+	return obj_status;
+}

+ 880 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c

@@ -0,0 +1,880 @@
+/*
+ * Copyright (c) 2016 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: Public APIs to perform operations on Global objects
+  */
+
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_objmgr_global_obj_i.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_peer_obj.h>
+#include <wlan_objmgr_psoc_obj_i.h>
+#include <wlan_objmgr_pdev_obj_i.h>
+#include <qdf_mem.h>
+
+/**
+ ** APIs to Create/Delete Global object APIs
+ */
+static QDF_STATUS wlan_objmgr_psoc_object_status(
+			struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t id;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	wlan_psoc_obj_lock(psoc);
+	/* Iterate through all components to derive the object status */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		/* If component disabled, Ignore */
+		if (psoc->obj_status[id] == QDF_STATUS_COMP_DISABLED)
+			continue;
+		/* If component operates in Async, status is Partially created,
+			break */
+		else if (psoc->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
+			if (psoc->soc_comp_obj[id] == NULL) {
+				status = QDF_STATUS_COMP_ASYNC;
+				break;
+			}
+		/*
+		 * If component failed to allocate its object, treat it as
+		 * failure, complete object need to be cleaned up
+		 */
+		} else if ((psoc->obj_status[id] == QDF_STATUS_E_NOMEM) ||
+			(psoc->obj_status[id] == QDF_STATUS_E_FAILURE)) {
+			status = QDF_STATUS_E_FAILURE;
+			break;
+		}
+	}
+	wlan_psoc_obj_unlock(psoc);
+	return status;
+}
+
+static void wlan_objmgr_psoc_peer_list_init(struct wlan_peer_list *peer_list)
+{
+	uint8_t i;
+
+	qdf_spinlock_create(&peer_list->peer_list_lock);
+	for (i = 0; i < WLAN_PEER_HASHSIZE; i++)
+		qdf_list_create(&peer_list->peer_hash[i],
+				WLAN_UMAC_PSOC_MAX_PEERS);
+}
+
+static void wlan_objmgr_psoc_peer_list_deinit(struct wlan_peer_list *peer_list)
+{
+	uint8_t i;
+
+	/* deinit the lock */
+	qdf_spinlock_destroy(&peer_list->peer_list_lock);
+	for (i = 0; i < WLAN_PEER_HASHSIZE; i++)
+		qdf_list_destroy(&peer_list->peer_hash[i]);
+}
+/*
+ * wlan_objmgr_psco_create_handler would return following status values
+ */
+struct wlan_objmgr_psoc *wlan_objmgr_psoc_obj_create(uint32_t phy_version,
+						WLAN_DEV_TYPE dev_type)
+{
+	uint8_t id;
+	struct wlan_objmgr_psoc *psoc = NULL;
+	wlan_objmgr_psoc_create_handler handler;
+	wlan_objmgr_psoc_status_handler stat_handler;
+	struct wlan_objmgr_psoc_objmgr *objmgr;
+	QDF_STATUS obj_status;
+	void *arg;
+
+	/* Allocate PSOC object's memory */
+	psoc = qdf_mem_malloc(sizeof(*psoc));
+	if (psoc == NULL) {
+		qdf_print("%s: PSOC allocation failed\n", __func__);
+		return NULL;
+	}
+	/* Init spinlock */
+	qdf_spinlock_create(&psoc->psoc_lock);
+	/* Initialize with default values */
+	objmgr = &psoc->soc_objmgr;
+	objmgr->wlan_pdev_count = 0;
+	objmgr->wlan_vdev_count = 0;
+	objmgr->max_vdev_count = WLAN_UMAC_PSOC_MAX_VDEVS;
+	objmgr->wlan_peer_count = 0;
+	/* set phy version, dev_type in psoc */
+	wlan_psoc_set_nif_phy_version(psoc, phy_version);
+	wlan_psoc_set_dev_type(psoc, dev_type);
+	/* Initialize peer list */
+	wlan_objmgr_psoc_peer_list_init(&objmgr->peer_list);
+	/* Invoke registered create handlers */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		handler = g_umac_glb_obj->psoc_create_handler[id];
+		arg = g_umac_glb_obj->psoc_create_handler_arg[id];
+		if (handler != NULL)
+			psoc->obj_status[id] = handler(psoc, arg);
+		else
+			psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED;
+	}
+	/* Derive object status */
+	obj_status = wlan_objmgr_psoc_object_status(psoc);
+
+	if (obj_status == QDF_STATUS_SUCCESS) {
+		/* Object status is SUCCESS, Object is created */
+		psoc->obj_state = WLAN_OBJ_STATE_CREATED;
+		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+			stat_handler = g_umac_glb_obj->psoc_status_handler[id];
+			arg = g_umac_glb_obj->psoc_status_handler_arg[id];
+			if (stat_handler != NULL)
+				stat_handler(psoc, arg,
+					     QDF_STATUS_SUCCESS);
+		}
+	/*
+	 * Few components operates in Asynchrous communction, Object state
+	 * partially created
+	 */
+	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
+		psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
+	/* Component object failed to be created, clean up the object */
+	} else if (obj_status == QDF_STATUS_E_FAILURE) {
+		qdf_print("%s: PSOC component objects allocation failed\n",
+			  __func__);
+		/* Clean up the psoc */
+		wlan_objmgr_psoc_obj_delete(psoc);
+		return NULL;
+	}
+
+	if (wlan_objmgr_psoc_object_attach(psoc) !=
+				QDF_STATUS_SUCCESS) {
+		qdf_print("%s: PSOC object attach failed\n", __func__);
+		wlan_objmgr_psoc_obj_delete(psoc);
+		return NULL;
+	}
+	return psoc;
+}
+EXPORT_SYMBOL(wlan_objmgr_psoc_obj_create);
+
+QDF_STATUS wlan_objmgr_psoc_obj_delete(struct wlan_objmgr_psoc *psoc)
+{
+	uint8_t id;
+	wlan_objmgr_psoc_delete_handler handler;
+	QDF_STATUS obj_status;
+	void *arg;
+
+	/* if PSOC is NULL, return */
+	if (psoc == NULL) {
+		qdf_print("%s:psoc is NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Invoke registered create handlers */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		handler = g_umac_glb_obj->psoc_delete_handler[id];
+		arg = g_umac_glb_obj->psoc_delete_handler_arg[id];
+		if (handler != NULL)
+			psoc->obj_status[id] = handler(psoc, arg);
+		else
+			psoc->obj_status[id] = QDF_STATUS_COMP_DISABLED;
+	}
+	/* Derive object status */
+	obj_status = wlan_objmgr_psoc_object_status(psoc);
+
+	if (obj_status == QDF_STATUS_E_FAILURE) {
+		qdf_print("%s: PSOC component object free failed\n", __func__);
+		/* Ideally should not happen */
+		/*This leads to memleak ??? how to handle */
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Deletion is in progress */
+	if (obj_status == QDF_STATUS_COMP_ASYNC) {
+		psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
+		return QDF_STATUS_COMP_ASYNC;
+	} else {
+		/* Detach PSOC from global object's psoc list  */
+		if (wlan_objmgr_psoc_object_detach(psoc) ==
+					QDF_STATUS_E_FAILURE) {
+			qdf_print("%s: PSOC object detach failed\n", __func__);
+			return QDF_STATUS_E_FAILURE;
+		}
+		wlan_objmgr_psoc_peer_list_deinit(&psoc->soc_objmgr.peer_list);
+		/* Destroy spinlock */
+		qdf_spinlock_destroy(&psoc->psoc_lock);
+		/* Free the memory */
+		qdf_mem_free(psoc);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(wlan_objmgr_psoc_obj_delete);
+
+/**
+ ** APIs to attach/detach component objects
+ */
+QDF_STATUS wlan_objmgr_psoc_component_obj_attach(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr,
+		QDF_STATUS status)
+{
+	wlan_objmgr_psoc_status_handler stat_handler;
+	void *arg = NULL;
+	QDF_STATUS obj_status;
+	uint8_t i;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_psoc_obj_lock(psoc);
+	/* If there is a valid entry, return failure */
+	if (psoc->soc_comp_obj[id] != NULL) {
+		wlan_psoc_obj_unlock(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Save component's pointer and status */
+	psoc->soc_comp_obj[id] = comp_objptr;
+	psoc->obj_status[id] = status;
+	wlan_psoc_obj_unlock(psoc);
+
+	if (psoc->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
+		return QDF_STATUS_SUCCESS;
+	/* If PSOC object status is partially created means, this API is
+	 * invoked with differnt context, this block should be executed for
+	 * async components only
+	 */
+	/* Derive status */
+	obj_status = wlan_objmgr_psoc_object_status(psoc);
+	/* STATUS_SUCCESS means, object is CREATED */
+	if (obj_status == QDF_STATUS_SUCCESS)
+		psoc->obj_state = WLAN_OBJ_STATE_CREATED;
+	/* update state as CREATION failed, caller has to delete the
+	 * PSOC object
+	 */
+	else if (obj_status == QDF_STATUS_E_FAILURE)
+		psoc->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
+
+	/* Notify components about the CREATION success/failure */
+	if ((obj_status == QDF_STATUS_SUCCESS) ||
+	    (obj_status == QDF_STATUS_E_FAILURE)) {
+		/* nofity object status */
+		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
+			stat_handler = g_umac_glb_obj->psoc_status_handler[i];
+			arg = g_umac_glb_obj->psoc_status_handler_arg[i];
+			if (stat_handler != NULL)
+				stat_handler(psoc, arg, obj_status);
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_psoc_component_obj_detach(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr)
+{
+	QDF_STATUS obj_status;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_psoc_obj_lock(psoc);
+	/* If there is a valid entry, return failure */
+	if (psoc->soc_comp_obj[id] != comp_objptr) {
+		psoc->obj_status[id] = QDF_STATUS_E_FAILURE;
+		wlan_psoc_obj_unlock(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset pointers to NULL, update the status*/
+	psoc->soc_comp_obj[id] = NULL;
+	psoc->obj_status[id] = QDF_STATUS_SUCCESS;
+	wlan_psoc_obj_unlock(psoc);
+
+	/* If PSOC object status is partially created means, this API is
+	 * invoked with differnt context, this block should be executed for
+	 * async components only
+	 */
+	if ((psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
+	    (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
+		/* Derive object status */
+		obj_status = wlan_objmgr_psoc_object_status(psoc);
+		if (obj_status == QDF_STATUS_SUCCESS) {
+			/* Update the status as Deleted, if full object
+			 * deletion is in progress
+			 */
+			if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
+				psoc->obj_state = WLAN_OBJ_STATE_DELETED;
+
+			/* Move to creation state, since this component
+			 * deletion alone requested
+			 */
+			if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
+				psoc->obj_state = WLAN_OBJ_STATE_CREATED;
+		/* Object status is failure */
+		} else if (obj_status == QDF_STATUS_E_FAILURE) {
+			/* Update the status as Deletion failed, if full object
+			 * deletion is in progress
+			 */
+			if (psoc->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
+				psoc->obj_state =
+					WLAN_OBJ_STATE_DELETION_FAILED;
+
+			/* Move to creation state, since this component
+			 * deletion alone requested (do not block other
+			 * components)
+			 */
+			if (psoc->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
+				psoc->obj_state = WLAN_OBJ_STATE_CREATED;
+		}
+
+		/* Delete psoc object */
+		if ((obj_status == QDF_STATUS_SUCCESS)  &&
+		    (psoc->obj_state == WLAN_OBJ_STATE_DELETED)) {
+			/* Detach PSOC from global object's psoc list */
+			if (wlan_objmgr_psoc_object_detach(psoc) ==
+						QDF_STATUS_E_FAILURE)
+				return QDF_STATUS_E_FAILURE;
+
+			wlan_objmgr_psoc_peer_list_deinit(
+				&psoc->soc_objmgr.peer_list);
+			/* Destroy spinlock */
+			qdf_spinlock_destroy(&psoc->psoc_lock);
+			/* Free memory */
+			qdf_mem_free(psoc);
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ ** APIs to operations on psoc objects
+ */
+
+QDF_STATUS wlan_objmgr_iterate_obj_list(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_objmgr_obj_type obj_type,
+		wlan_objmgr_op_handler handler,
+		void *arg, uint8_t lock_free_op)
+{
+	uint16_t obj_id;
+	uint8_t i;
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	struct wlan_peer_list *peer_list;
+	qdf_list_t *obj_list;
+	struct wlan_objmgr_peer *peer;
+	struct wlan_objmgr_peer *peer_next;
+
+	/* If caller requests for lock free opeation, do not acquire,
+	 * handler will handle the synchronization
+	 */
+	if (!lock_free_op)
+		wlan_psoc_obj_lock(psoc);
+
+	switch (obj_type) {
+	case WLAN_PDEV_OP:
+		/* Iterate through PDEV list, invoke handler for each pdev */
+		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
+			if (objmgr->wlan_pdev_list[obj_id] != NULL) {
+				/* TODO increment ref count */
+				handler(psoc,
+					(void *)objmgr->wlan_pdev_list[obj_id],
+					arg);
+				/* TODO decrement ref count */
+			}
+		}
+		break;
+	case WLAN_VDEV_OP:
+		/* Iterate through VDEV list, invoke handler for each vdev */
+		for (obj_id = 0; obj_id < WLAN_UMAC_PSOC_MAX_VDEVS; obj_id++) {
+			if (objmgr->wlan_vdev_list[obj_id] != NULL) {
+				/* TODO increment ref count */
+				handler(psoc,
+					(void *)objmgr->wlan_vdev_list[obj_id],
+					arg);
+				/* TODO decrement ref count */
+			}
+		}
+		break;
+	case WLAN_PEER_OP:
+		/* Iterate through PEER list, invoke handler for each peer */
+		peer_list = &objmgr->peer_list;
+		if (!lock_free_op)
+			qdf_spin_lock_bh(&peer_list->peer_list_lock);
+		/* Since peer list has sublist, iterate through sublists */
+		for (i = 0; i < WLAN_PEER_HASHSIZE; i++) {
+			obj_list = &peer_list->peer_hash[i];
+			peer = wlan_psoc_peer_list_peek_head(obj_list);
+			while (peer) {
+				/* Increment ref count, to hold the
+					peer pointer */
+				wlan_objmgr_peer_ref_peer(peer);
+				handler(psoc, (void *)peer, arg);
+				/* Get next peer */
+				peer_next = wlan_peer_get_next_peer_of_psoc(
+								obj_list, peer);
+				/* Decrement ref count, this can lead
+					to peer deletion also */
+				wlan_objmgr_peer_unref_peer(peer);
+				peer = peer_next;
+			}
+		}
+		if (!lock_free_op)
+			qdf_spin_unlock_bh(&peer_list->peer_list_lock);
+		break;
+	default:
+		break;
+	}
+	if (!lock_free_op)
+		wlan_psoc_obj_unlock(psoc);
+	return QDF_STATUS_SUCCESS;
+}
+
+void wlan_objmgr_psoc_peer_delete(struct wlan_objmgr_psoc *psoc, void *obj,
+						 void *args)
+{
+	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)obj;
+
+	wlan_objmgr_peer_obj_delete(peer);
+}
+
+void wlan_objmgr_psoc_vdev_delete(struct wlan_objmgr_psoc *psoc, void *obj,
+							void *args)
+{
+	struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)obj;
+
+	wlan_objmgr_vdev_obj_delete(vdev);
+}
+
+void wlan_objmgr_psoc_pdev_delete(struct wlan_objmgr_psoc *psoc, void *obj,
+							void *args)
+{
+	struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)obj;
+
+	wlan_objmgr_pdev_obj_delete(pdev);
+}
+
+QDF_STATUS wlan_objmgr_free_all_objects_per_psoc(
+		struct wlan_objmgr_psoc *psoc)
+{
+	/* Free all peers */
+	wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
+				     wlan_objmgr_psoc_peer_delete, NULL, 1);
+	/* Free all vdevs */
+	wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
+				     wlan_objmgr_psoc_vdev_delete, NULL, 1);
+	/* Free all PDEVs */
+	wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
+				     wlan_objmgr_psoc_pdev_delete, NULL, 1);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_trigger_psoc_comp_object_creation(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_umac_comp_id id)
+{
+	wlan_objmgr_psoc_create_handler handler;
+	void *arg;
+	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
+
+	/* Component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_psoc_obj_lock(psoc);
+	/* If component object is already created, delete old
+	 * component object, then invoke creation
+	 */
+	if (psoc->soc_comp_obj[id] != NULL) {
+		wlan_psoc_obj_unlock(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wlan_psoc_obj_unlock(psoc);
+	/* Invoke registered create handlers */
+	handler = g_umac_glb_obj->psoc_create_handler[id];
+	arg = g_umac_glb_obj->psoc_create_handler_arg[id];
+	if (handler != NULL)
+		psoc->obj_status[id] = handler(psoc, arg);
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	/* If object status is created, then only handle this object status */
+	if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) {
+		/* Derive object status */
+		obj_status = wlan_objmgr_psoc_object_status(psoc);
+		/* Move PSOC object state to Partially created state */
+		if (obj_status == QDF_STATUS_COMP_ASYNC) {
+			/*TODO atomic */
+			psoc->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
+		}
+	}
+	return obj_status;
+}
+
+QDF_STATUS wlan_objmgr_trigger_psoc_comp_object_deletion(
+		struct wlan_objmgr_psoc *psoc,
+		enum wlan_umac_comp_id id)
+{
+	wlan_objmgr_psoc_delete_handler handler;
+	void *arg;
+	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_psoc_obj_lock(psoc);
+	/* Component object was never created, invalid operation */
+	if (psoc->soc_comp_obj[id] == NULL) {
+		wlan_psoc_obj_unlock(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wlan_psoc_obj_unlock(psoc);
+	/* Invoke registered create handlers */
+	handler = g_umac_glb_obj->psoc_delete_handler[id];
+	arg = g_umac_glb_obj->psoc_delete_handler_arg[id];
+	if (handler != NULL)
+		psoc->obj_status[id] = handler(psoc, arg);
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	/* If object status is created, then only handle this object status */
+	if (psoc->obj_state == WLAN_OBJ_STATE_CREATED) {
+		obj_status = wlan_objmgr_psoc_object_status(psoc);
+			/* move object state to DEL progress */
+		if (obj_status == QDF_STATUS_COMP_ASYNC)
+			psoc->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
+	}
+	return obj_status;
+}
+
+/* Util APIs */
+
+QDF_STATUS wlan_objmgr_psoc_pdev_attach(struct wlan_objmgr_psoc *psoc,
+					struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	uint8_t id = 0;
+	QDF_STATUS status;
+
+	wlan_psoc_obj_lock(psoc);
+	/*
+	 * Derive pdev id from pdev map
+	 * First free pdev id is assigned
+	 */
+	while ((id < WLAN_UMAC_MAX_PDEVS) &&
+			(objmgr->wlan_pdev_id_map & (1<<id)))
+		id++;
+
+	if (id == WLAN_UMAC_MAX_PDEVS) {
+		status = QDF_STATUS_E_FAILURE;
+	} else {
+		/* Update the map for reserving the id */
+		objmgr->wlan_pdev_id_map |= (1<<id);
+		/* store pdev in pdev list */
+		objmgr->wlan_pdev_list[id] = pdev;
+		/* Increment pdev count */
+		objmgr->wlan_pdev_count++;
+		/* save pdev id */
+		pdev->pdev_objmgr.wlan_pdev_id = id;
+		status = QDF_STATUS_SUCCESS;
+	}
+	wlan_psoc_obj_unlock(psoc);
+	return status;
+}
+
+QDF_STATUS wlan_objmgr_psoc_pdev_detach(struct wlan_objmgr_psoc *psoc,
+						struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	uint8_t id;
+
+	id = pdev->pdev_objmgr.wlan_pdev_id;
+	/* If id is invalid, return */
+	if (id >= WLAN_UMAC_MAX_PDEVS)
+		return QDF_STATUS_E_FAILURE;
+
+	wlan_psoc_obj_lock(psoc);
+	/* Free pdev id slot */
+	objmgr->wlan_pdev_id_map &= ~(1<<id);
+	objmgr->wlan_pdev_list[id] = NULL;
+	objmgr->wlan_pdev_count--;
+	pdev->pdev_objmgr.wlan_pdev_id = 0xff;
+	wlan_psoc_obj_unlock(psoc);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+struct wlan_objmgr_pdev *wlan_objmgr_find_pdev_by_id(
+		struct wlan_objmgr_psoc *psoc, uint8_t id)
+{
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	struct wlan_objmgr_pdev *pdev = NULL;
+
+	wlan_psoc_obj_lock(psoc);
+	/* get pdev from pdev list */
+	pdev = objmgr->wlan_pdev_list[id];
+	wlan_psoc_obj_unlock(psoc);
+	return pdev;
+}
+
+QDF_STATUS wlan_objmgr_psoc_vdev_attach(struct wlan_objmgr_psoc *psoc,
+					struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	uint8_t id = 0;
+	uint8_t map_index = 0;
+	uint8_t map_entry_size = 32;
+	uint8_t adjust_ix = 0;
+	QDF_STATUS status;
+
+	wlan_psoc_obj_lock(psoc);
+	/* Find first free vdev id */
+	while ((id < objmgr->max_vdev_count) &&
+		(objmgr->wlan_vdev_id_map[map_index] & (1<<(id - adjust_ix)))) {
+		id++;
+		/*
+		 * The map is two DWORDS(32 bits), so, map_index
+		 * adjust_ix derived based on the id value
+		 */
+		if (id == ((map_index+1)*map_entry_size)) {
+			adjust_ix = map_index*map_entry_size;
+			map_index++;
+		}
+	}
+	/* If no free slot, return failure */
+	if (id == objmgr->max_vdev_count) {
+		status = QDF_STATUS_E_FAILURE;
+	} else {
+		/* set free vdev id index */
+		objmgr->wlan_vdev_id_map[map_index] |= (1<<(id-adjust_ix));
+		/* store vdev pointer in vdev list */
+		objmgr->wlan_vdev_list[id] = vdev;
+		/* increment vdev counter */
+		objmgr->wlan_vdev_count++;
+		/* save vdev id */
+		vdev->vdev_objmgr.vdev_id = id;
+		status = QDF_STATUS_SUCCESS;
+	}
+	wlan_psoc_obj_unlock(psoc);
+	return status;
+}
+
+QDF_STATUS wlan_objmgr_psoc_vdev_detach(struct wlan_objmgr_psoc *psoc,
+					struct wlan_objmgr_vdev *vdev)
+{
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	uint8_t id = 0;
+	uint8_t map_index = 0;
+	uint8_t map_entry_size = 32;
+	uint8_t adjust_ix = 0;
+
+	id = vdev->vdev_objmgr.vdev_id;
+	/* Invalid vdev id */
+	if (id >= WLAN_UMAC_PSOC_MAX_VDEVS)
+		return QDF_STATUS_E_FAILURE;
+	/*
+	 * Derive map_index and adjust_ix to find actual DWORD
+	 * the id map is present
+	 */
+	while ((id - adjust_ix) >= map_entry_size) {
+		map_index++;
+		adjust_ix = map_index * map_entry_size;
+	}
+	wlan_psoc_obj_lock(psoc);
+	/* unset bit, to free the slot */
+	objmgr->wlan_vdev_id_map[map_index] &= ~(1<<(id-adjust_ix));
+	/* reset VDEV pointer to NULL in VDEV list array */
+	objmgr->wlan_vdev_list[id] = NULL;
+	/* decrement vdev count */
+	objmgr->wlan_vdev_count--;
+	vdev->vdev_objmgr.vdev_id = 0xff;
+	wlan_psoc_obj_unlock(psoc);
+	return QDF_STATUS_SUCCESS;
+}
+
+
+struct wlan_objmgr_vdev *wlan_objmgr_find_vdev_by_id_from_psoc(
+			struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	/* if PSOC is NULL, return */
+	if (psoc == NULL)
+		return NULL;
+	/* vdev id is invalid */
+	if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS)
+		return NULL;
+
+	wlan_psoc_obj_lock(psoc);
+	/* retrieve vdev pointer from vdev list */
+	vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
+	wlan_psoc_obj_unlock(psoc);
+	return vdev;
+}
+
+struct wlan_objmgr_vdev *wlan_objmgr_find_vdev_by_macaddr_from_psoc(
+		struct wlan_objmgr_psoc *psoc, uint8_t *macaddr)
+{
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t id;
+
+	/* if PSOC is NULL, return */
+	if (psoc == NULL)
+		return NULL;
+
+	wlan_psoc_obj_lock(psoc);
+	/* Iterate through PSOC's vdev list */
+	for (id = 0; id < WLAN_UMAC_PSOC_MAX_VDEVS; id++) {
+		vdev = psoc->soc_objmgr.wlan_vdev_list[id];
+		if (vdev == NULL)
+			continue;
+		/* MAC address matches, break */
+		if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), macaddr)
+			== QDF_STATUS_SUCCESS) {
+			wlan_psoc_obj_unlock(psoc);
+			return vdev;
+		}
+	}
+	wlan_psoc_obj_unlock(psoc);
+	return NULL;
+}
+
+static void wlan_obj_psoc_peerlist_add_tail(qdf_list_t *obj_list,
+				struct wlan_objmgr_peer *obj)
+{
+	qdf_list_insert_back(obj_list, &obj->psoc_peer);
+}
+
+static QDF_STATUS wlan_obj_psoc_peerlist_remove_peer(
+				qdf_list_t *obj_list,
+				struct wlan_objmgr_peer *peer)
+{
+	qdf_list_node_t *psoc_node = NULL;
+
+	if (peer == NULL)
+		return QDF_STATUS_E_FAILURE;
+	/* get vdev list node element */
+	psoc_node = &peer->psoc_peer;
+	/* list is empty, return failure */
+	if (qdf_list_remove_node(obj_list, psoc_node) != QDF_STATUS_SUCCESS)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+struct wlan_objmgr_peer *wlan_obj_psoc_peerlist_get_peer(
+				qdf_list_t *obj_list,
+				uint8_t *macaddr)
+{
+	struct wlan_objmgr_peer *peer;
+	struct wlan_objmgr_peer *peer_temp;
+
+	/* Iterate through hash list to get the peer */
+	peer = wlan_psoc_peer_list_peek_head(obj_list);
+	while (peer != NULL) {
+		/* For peer, macaddr is key */
+		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer), macaddr)
+			== QDF_STATUS_SUCCESS) {
+			/* Increment ref count for access */
+			wlan_objmgr_peer_ref_peer(peer);
+			return peer;
+		}
+		/* Move to next peer */
+		peer_temp = peer;
+		peer = wlan_peer_get_next_peer_of_psoc(obj_list, peer_temp);
+	}
+	/* Not found, return NULL */
+	return NULL;
+}
+
+QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc,
+					 struct wlan_objmgr_peer *peer)
+{
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	uint8_t hash_index;
+
+	wlan_psoc_obj_lock(psoc);
+	/* Max peer limit is reached, return failure */
+	if (objmgr->wlan_peer_count > WLAN_UMAC_PSOC_MAX_PEERS) {
+		wlan_psoc_obj_unlock(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Derive hash index from mac address */
+	hash_index = WLAN_PEER_HASH(peer->macaddr);
+	/* add peer to hash peer list */
+	wlan_obj_psoc_peerlist_add_tail(
+			&objmgr->peer_list.peer_hash[hash_index],
+							peer);
+	/* Increment peer count */
+	objmgr->wlan_peer_count++;
+
+	wlan_psoc_obj_unlock(psoc);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc,
+						struct wlan_objmgr_peer *peer)
+{
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	uint8_t hash_index;
+
+	wlan_psoc_obj_lock(psoc);
+	/* if list is empty, return */
+	if (objmgr->wlan_peer_count == 0) {
+		wlan_psoc_obj_unlock(psoc);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Get hash index, to locate the actual peer list */
+	hash_index = WLAN_PEER_HASH(peer->macaddr);
+	/* removes the peer from peer_list */
+	if (wlan_obj_psoc_peerlist_remove_peer(
+				&objmgr->peer_list.peer_hash[hash_index],
+						peer) ==
+				QDF_STATUS_E_FAILURE) {
+		wlan_psoc_obj_unlock(psoc);
+		qdf_print("%s: Failed to detach peer\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Decrement peer count */
+	objmgr->wlan_peer_count--;
+
+	wlan_psoc_obj_unlock(psoc);
+	return QDF_STATUS_SUCCESS;
+}
+
+struct wlan_objmgr_peer *wlan_objmgr_find_peer(
+			struct wlan_objmgr_psoc *psoc, uint8_t *macaddr)
+{
+	struct wlan_objmgr_psoc_objmgr *objmgr = &psoc->soc_objmgr;
+	uint8_t hash_index;
+	struct wlan_objmgr_peer *peer = NULL;
+	struct wlan_peer_list *peer_list;
+
+	wlan_psoc_obj_lock(psoc);
+	/* List is empty, return NULL */
+	if (objmgr->wlan_peer_count == 0) {
+		wlan_psoc_obj_unlock(psoc);
+		return NULL;
+	}
+	/* reduce the search window, with hash key */
+	hash_index = WLAN_PEER_HASH(macaddr);
+	peer_list = &objmgr->peer_list;
+	qdf_spin_lock_bh(&peer_list->peer_list_lock);
+	/* Iterate through peer list, get peer */
+	peer = wlan_obj_psoc_peerlist_get_peer(
+		&peer_list->peer_hash[hash_index], macaddr);
+	qdf_spin_unlock_bh(&peer_list->peer_list_lock);
+	wlan_psoc_obj_unlock(psoc);
+	return peer;
+}

+ 126 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj_i.h

@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2016 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: Public APIs to perform operations on Global objects
+  */
+#ifndef _WLAN_OBJMGR_PSOC_OBJ_I_H_
+#define _WLAN_OBJMGR_PSOC_OBJ_I_H_
+
+/**
+ * wlan_objmgr_psoc_pdev_attach() - store pdev in psoc's pdev list
+ * @psoc - PSOC object
+ * @pdev - PDEV object
+ *
+ * Attaches PDEV to PSOC, allocates PDEV id
+ *
+ * Return: SUCCESS
+ *         Failure (Max PDEVs are exceeded)
+ */
+QDF_STATUS wlan_objmgr_psoc_pdev_attach(struct wlan_objmgr_psoc *psoc,
+					 struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_objmgr_psoc_pdev_detach() - remove pdev from psoc's pdev list
+ * @psoc - PSOC object
+ * @pdev - PDEV object
+ *
+ * detaches PDEV to PSOC, frees PDEV id
+ *
+ * Return: SUCCESS
+ *         Failure (No PDEVs are present)
+ */
+QDF_STATUS wlan_objmgr_psoc_pdev_detach(struct wlan_objmgr_psoc *psoc,
+						struct wlan_objmgr_pdev *pdev);
+
+/**
+ * wlan_objmgr_psoc_vdev_attach() - store vdev in psoc's vdev list
+ * @psoc - PSOC object
+ * @vdev - VDEV object
+ *
+ * Attaches VDEV to PSOC, allocates VDEV id
+ *
+ * Return: SUCCESS
+ *         Failure (Max VDEVs are exceeded)
+ */
+QDF_STATUS wlan_objmgr_psoc_vdev_attach(struct wlan_objmgr_psoc *psoc,
+					struct wlan_objmgr_vdev *vdev);
+
+/**
+ * wlan_objmgr_psoc_vdev_detach() - remove vdev from psoc's vdev list
+ * @psoc - PSOC object
+ * @vdev - VDEV object
+ *
+ * detaches VDEV to PSOC, frees VDEV id
+ *
+ * Return: SUCCESS
+ *         Failure (No VDEVs are present)
+ */
+QDF_STATUS wlan_objmgr_psoc_vdev_detach(struct wlan_objmgr_psoc *psoc,
+					struct wlan_objmgr_vdev *vdev);
+
+/**
+ * wlan_objmgr_psoc_peer_attach() - store peer in psoc's peer table
+ * @psoc - PSOC object
+ * @peer - PEER object
+ *
+ * Attaches PEER to PSOC, derives the HASH, add peer to its peer list
+ *
+ * Return: SUCCESS
+ *         Failure (Max PEERs are exceeded)
+ */
+QDF_STATUS wlan_objmgr_psoc_peer_attach(struct wlan_objmgr_psoc *psoc,
+					 struct wlan_objmgr_peer *peer);
+
+/**
+ * wlan_objmgr_psoc_peer_detach() - remove peer from psoc's peer table
+ * @psoc - PSOC object
+ * @peer - PEER object
+ *
+ * detaches PEER to PSOC, removes the peer from the peer list
+ *
+ * Return: SUCCESS
+ *         Failure (PEER is not present)
+ */
+QDF_STATUS wlan_objmgr_psoc_peer_detach(struct wlan_objmgr_psoc *psoc,
+						struct wlan_objmgr_peer *peer);
+
+/**
+ * wlan_objmgr_psoc_object_attach() - attach psoc to global object
+ * @psoc - PSOC object
+ *
+ * attaches PSOC to global psoc list
+ *
+ * Return: SUCCESS
+ *         Failure (Max supported PSOCs exceeded)
+ */
+QDF_STATUS wlan_objmgr_psoc_object_attach(
+			struct wlan_objmgr_psoc *psoc);
+
+/**
+ * wlan_objmgr_psoc_object_detach() - detach psoc from global object
+ * @psoc - PSOC object
+ *
+ * detaches PSOC from global psoc list
+ *
+ * Return: SUCCESS
+ *         Failure (if list is empty and PSOC is not present)
+ */
+QDF_STATUS wlan_objmgr_psoc_object_detach(
+			struct wlan_objmgr_psoc *psoc);
+
+#endif /* _WLAN_OBJMGR_PSOC_OBJ_I_H_ */

+ 593 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c

@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2016 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: Public APIs to perform operations on Global objects
+  */
+#include <wlan_objmgr_cmn.h>
+#include <wlan_objmgr_global_obj.h>
+#include <wlan_objmgr_global_obj_i.h>
+#include <wlan_objmgr_psoc_obj.h>
+#include <wlan_objmgr_pdev_obj.h>
+#include <wlan_objmgr_vdev_obj.h>
+#include <wlan_objmgr_peer_obj.h>
+#include <wlan_objmgr_psoc_obj_i.h>
+#include <wlan_objmgr_pdev_obj_i.h>
+#include <qdf_mem.h>
+
+/**
+ ** APIs to Create/Delete Global object APIs
+ */
+
+static QDF_STATUS wlan_objmgr_vdev_object_status(
+		struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t id;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	wlan_vdev_obj_lock(vdev);
+
+	/* Iterate through all components to derive the object status */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		/* If component disabled, Ignore */
+		if (vdev->obj_status[id] == QDF_STATUS_COMP_DISABLED) {
+			continue;
+		/*
+		 * If component operates in Async, status is Partially created,
+		 * break
+		 */
+		} else if (vdev->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
+			if (vdev->vdev_comp_obj[id] == NULL) {
+				status = QDF_STATUS_COMP_ASYNC;
+				break;
+			}
+		/*
+		 * If component failed to allocate its object, treat it as
+		 * failure, complete object need to be cleaned up
+		 */
+		} else if ((vdev->obj_status[id] == QDF_STATUS_E_NOMEM) ||
+			(vdev->obj_status[id] == QDF_STATUS_E_FAILURE)) {
+			status = QDF_STATUS_E_FAILURE;
+			break;
+		}
+	}
+	wlan_vdev_obj_unlock(vdev);
+	return status;
+}
+
+struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create(
+			struct wlan_objmgr_pdev *pdev,
+			struct wlan_vdev_create_params *params)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_psoc *psoc;
+	uint8_t id;
+	wlan_objmgr_vdev_create_handler handler;
+	wlan_objmgr_vdev_status_handler stat_handler;
+	void *arg;
+	QDF_STATUS obj_status;
+
+	if (pdev == NULL) {
+		qdf_print("%s: pdev is NULL\n", __func__);
+		return NULL;
+	}
+	psoc = wlan_pdev_get_psoc(pdev);
+	/* PSOC is NULL */
+	if (psoc == NULL) {
+		qdf_print("%s: psoc is NULL\n", __func__);
+		return NULL;
+	}
+	/* Allocate vdev object memory */
+	vdev = qdf_mem_malloc(sizeof(*vdev));
+	if (vdev == NULL) {
+		qdf_print("%s: Memory allocation failure\n", __func__);
+		return NULL;
+	}
+	/* Attach VDEV to PSOC VDEV's list */
+	if (wlan_objmgr_psoc_vdev_attach(psoc, vdev) !=
+				QDF_STATUS_SUCCESS) {
+		qdf_mem_free(vdev);
+		qdf_print("%s: psoc vdev attach failed\n", __func__);
+		return NULL;
+	}
+	/* Store pdev in vdev */
+	wlan_vdev_set_pdev(vdev, pdev);
+	/* Attach vdev to PDEV */
+	if (wlan_objmgr_pdev_vdev_attach(pdev, vdev) !=
+				QDF_STATUS_SUCCESS) {
+		qdf_print("%s: pdev vdev attach failed\n", __func__);
+		wlan_objmgr_psoc_vdev_detach(psoc, vdev);
+		qdf_mem_free(vdev);
+		return NULL;
+	}
+	/* Initialize spinlock */
+	qdf_spinlock_create(&vdev->vdev_lock);
+	/* set opmode */
+	wlan_vdev_mlme_set_opmode(vdev, params->opmode);
+	/* set MAC address */
+	wlan_vdev_mlme_set_macaddr(vdev, params->macaddr);
+	/* set MAT address */
+	wlan_vdev_mlme_set_mataddr(vdev, params->mataddr);
+	/* Set create flags */
+	vdev->vdev_objmgr.c_flags = params->flags;
+	/* store os-specific pointer */
+	vdev->vdev_nif.osdev = params->osifp;
+	/* peer count to 0 */
+	vdev->vdev_objmgr.wlan_peer_count = 0;
+	/* Initialize max peer count based on opmode type */
+	if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
+		vdev->vdev_objmgr.max_peer_count = WLAN_UMAC_MAX_STA_PEERS;
+	else
+		vdev->vdev_objmgr.max_peer_count = WLAN_UMAC_MAX_AP_PEERS;
+
+	/* Initialize peer list */
+	qdf_list_create(&vdev->vdev_objmgr.wlan_peer_list,
+			vdev->vdev_objmgr.max_peer_count);
+	/* TODO init other parameters */
+
+	/* Invoke registered create handlers */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		handler = g_umac_glb_obj->vdev_create_handler[id];
+		arg = g_umac_glb_obj->vdev_create_handler_arg[id];
+		if (handler != NULL)
+			vdev->obj_status[id] = handler(vdev, arg);
+		else
+			vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
+	}
+
+	/* Derive object status */
+	obj_status = wlan_objmgr_vdev_object_status(vdev);
+
+	if (obj_status == QDF_STATUS_SUCCESS) {
+		/* Object status is SUCCESS, Object is created */
+		vdev->obj_state = WLAN_OBJ_STATE_CREATED;
+		/* Invoke component registered status handlers */
+		for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+			stat_handler = g_umac_glb_obj->vdev_status_handler[id];
+			arg = g_umac_glb_obj->vdev_status_handler_arg[id];
+			if (stat_handler != NULL) {
+				stat_handler(vdev, arg,
+					     QDF_STATUS_SUCCESS);
+			}
+		}
+	/*
+	 * Few components operates in Asynchrous communction, Object state
+	 * partially created
+	 */
+	} else if (obj_status == QDF_STATUS_COMP_ASYNC) {
+		vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
+	/* Component object failed to be created, clean up the object */
+	} else if (obj_status == QDF_STATUS_E_FAILURE) {
+		/* Clean up the psoc */
+		wlan_objmgr_vdev_obj_delete(vdev);
+		qdf_print("%s:VDEV component objects creation failed\n",
+			  __func__);
+		return NULL;
+	}
+	return vdev;
+}
+
+QDF_STATUS wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev *vdev)
+{
+	uint8_t id;
+	wlan_objmgr_vdev_delete_handler handler;
+	QDF_STATUS obj_status;
+	void *arg;
+	struct wlan_objmgr_pdev *pdev;
+
+	if (vdev == NULL) {
+		qdf_print("%s:vdev is NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* if PDEV is NULL, return */
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (pdev == NULL) {
+		qdf_print("%s:pdev is NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Invoke registered create handlers */
+	for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
+		handler = g_umac_glb_obj->vdev_delete_handler[id];
+		arg = g_umac_glb_obj->vdev_delete_handler_arg[id];
+		if (handler != NULL)
+			vdev->obj_status[id] = handler(vdev, arg);
+		else
+			vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
+	}
+	/* Derive object status */
+	obj_status = wlan_objmgr_vdev_object_status(vdev);
+
+	if (obj_status == QDF_STATUS_E_FAILURE) {
+		qdf_print("%s: VDEV object deletion failed\n", __func__);
+		/* Ideally should not happen */
+		/* This leads to memleak ??? how to handle */
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/* Deletion is in progress */
+	if (obj_status == QDF_STATUS_COMP_ASYNC) {
+		vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
+		return QDF_STATUS_COMP_ASYNC;
+	} else {
+		/* Detach VDEV from PDEV VDEV's list */
+		if (wlan_objmgr_pdev_vdev_detach(pdev, vdev) ==
+						QDF_STATUS_E_FAILURE)
+			return QDF_STATUS_E_FAILURE;
+
+		/* Detach VDEV from PSOC VDEV's list */
+		if (wlan_objmgr_psoc_vdev_detach(
+				pdev->pdev_objmgr.wlan_psoc, vdev) ==
+						QDF_STATUS_E_FAILURE)
+			return QDF_STATUS_E_FAILURE;
+
+		/* de-init lock */
+		qdf_spinlock_destroy(&vdev->vdev_lock);
+		/* Free the memory */
+		qdf_mem_free(vdev);
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ ** APIs to attach/detach component objects
+ */
+QDF_STATUS wlan_objmgr_vdev_component_obj_attach(
+		struct wlan_objmgr_vdev *vdev,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr,
+		QDF_STATUS status)
+{
+	wlan_objmgr_vdev_status_handler stat_handler;
+	void *arg;
+	uint8_t i;
+	QDF_STATUS obj_status;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_vdev_obj_lock(vdev);
+	/* If there is a valid entry, return failure */
+	if (vdev->vdev_comp_obj[id] != NULL) {
+		wlan_vdev_obj_unlock(vdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Save component's pointer and status */
+	vdev->vdev_comp_obj[id] = comp_objptr;
+	vdev->obj_status[id] = status;
+	wlan_vdev_obj_unlock(vdev);
+
+	if (vdev->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
+		return QDF_STATUS_SUCCESS;
+	/*
+	 * If VDEV object status is partially created means, this API is
+	 * invoked with differnt context, this block should be executed for
+	 * async components only
+	 */
+	/* Derive status */
+	obj_status = wlan_objmgr_vdev_object_status(vdev);
+	/* STATUS_SUCCESS means, object is CREATED */
+	if (obj_status == QDF_STATUS_SUCCESS)
+		vdev->obj_state = WLAN_OBJ_STATE_CREATED;
+	/*
+	 * update state as CREATION failed, caller has to delete the
+	 * VDEV object
+	 */
+	else if (obj_status == QDF_STATUS_E_FAILURE)
+		vdev->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
+	/* Notify components about the CREATION success/failure */
+	if ((obj_status == QDF_STATUS_SUCCESS) ||
+	    (obj_status == QDF_STATUS_E_FAILURE)) {
+		for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
+			stat_handler = g_umac_glb_obj->vdev_status_handler[i];
+			arg = g_umac_glb_obj->vdev_status_handler_arg[i];
+			if (stat_handler != NULL)
+				stat_handler(vdev, arg, obj_status);
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+EXPORT_SYMBOL(wlan_objmgr_vdev_component_obj_attach);
+
+QDF_STATUS wlan_objmgr_vdev_component_obj_detach(
+		struct wlan_objmgr_vdev *vdev,
+		enum wlan_umac_comp_id id,
+		void *comp_objptr)
+{
+	QDF_STATUS obj_status;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+	wlan_vdev_obj_lock(vdev);
+	/* If there is a valid entry, return failure */
+	if (vdev->vdev_comp_obj[id] != comp_objptr) {
+		vdev->obj_status[id] = QDF_STATUS_E_FAILURE;
+		wlan_vdev_obj_unlock(vdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Reset pointers to NULL, update the status*/
+	vdev->vdev_comp_obj[id] = NULL;
+	vdev->obj_status[id] = QDF_STATUS_SUCCESS;
+	wlan_vdev_obj_unlock(vdev);
+
+	/**
+	 *If VDEV object status is partially deleted means, this API is
+	 * invoked with differnt context, this block should be executed for
+	 * async components only
+	 */
+	if ((vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
+	    (vdev->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
+		/* Derive object status */
+		obj_status = wlan_objmgr_vdev_object_status(vdev);
+		if (obj_status == QDF_STATUS_SUCCESS) {
+			/*
+			 * Update the status as Deleted, if full object
+			 * deletion is in progress
+			 */
+			if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
+				vdev->obj_state = WLAN_OBJ_STATE_DELETED;
+			/*
+			 * Move to creation state, since this component
+			 * deletion alone requested
+			 */
+			else if (vdev->obj_state ==
+					WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
+				vdev->obj_state = WLAN_OBJ_STATE_CREATED;
+		/* Object status is failure */
+		} else if (obj_status == QDF_STATUS_E_FAILURE) {
+			/*
+			 * Update the status as Deletion failed, if full object
+			 * deletion is in progress
+			 */
+			if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
+				vdev->obj_state =
+					WLAN_OBJ_STATE_DELETION_FAILED;
+			/* Move to creation state, since this component
+			deletion alone requested (do not block other
+			components) */
+			else if (vdev->obj_state ==
+					WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
+				vdev->obj_state = WLAN_OBJ_STATE_CREATED;
+		}
+		/* Delete vdev object */
+		if ((obj_status == QDF_STATUS_SUCCESS)  &&
+		    (vdev->obj_state == WLAN_OBJ_STATE_DELETED)) {
+			/* Detach vdev object from psoc */
+			if (wlan_objmgr_pdev_vdev_detach(
+					wlan_vdev_get_pdev(vdev), vdev)
+						== QDF_STATUS_E_FAILURE)
+				return QDF_STATUS_E_FAILURE;
+			/* Detach vdev object from psoc */
+			if (wlan_objmgr_psoc_vdev_detach(
+				wlan_vdev_get_psoc(vdev), vdev) ==
+						QDF_STATUS_E_FAILURE)
+				return QDF_STATUS_E_FAILURE;
+
+			/* Destroy spinlock */
+			qdf_spinlock_destroy(&vdev->vdev_lock);
+			/* Free VDEV memory */
+			qdf_mem_free(vdev);
+		}
+	}
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ ** APIs to operations on vdev objects
+ */
+QDF_STATUS wlan_objmgr_iterate_peerobj_list(
+		struct wlan_objmgr_vdev *vdev,
+		wlan_objmgr_vdev_op_handler handler,
+		void *arg)
+{
+	qdf_list_t *peer_list = NULL;
+	struct wlan_objmgr_peer *peer = NULL;
+	struct wlan_objmgr_peer *prev_peer = NULL;
+
+	if (vdev == NULL) {
+		qdf_print("%s: VDEV NULL\n", __func__);
+		return QDF_STATUS_E_FAILURE;
+	}
+		/* TODO increment ref count */
+	wlan_vdev_obj_lock(vdev);
+	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
+	if (peer_list != NULL) {
+		/* Iterate through VDEV's peer list */
+		peer = wlan_vdev_peer_list_peek_head(peer_list);
+		while (peer != NULL) {
+			wlan_objmgr_peer_ref_peer(peer);
+			/* Invoke handler for operation */
+			handler(vdev, (void *)peer, arg);
+			prev_peer = peer;
+			peer = wlan_peer_get_next_peer_of_vdev(peer_list,
+							       prev_peer);
+			wlan_objmgr_peer_unref_peer(prev_peer);
+		}
+	}
+	wlan_vdev_obj_unlock(vdev);
+		/* TODO decrement ref count */
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_trigger_vdev_comp_object_creation(
+		struct wlan_objmgr_vdev *vdev,
+		enum wlan_umac_comp_id id)
+{
+	wlan_objmgr_vdev_create_handler handler;
+	void *arg;
+	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
+
+	/* Component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_vdev_obj_lock(vdev);
+	/*
+	 * If component object is already created, delete old
+	 * component object, then invoke creation
+	 */
+	if (vdev->vdev_comp_obj[id] != NULL) {
+		wlan_vdev_obj_unlock(vdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wlan_vdev_obj_unlock(vdev);
+
+	/* Invoke registered create handlers */
+	handler = g_umac_glb_obj->vdev_create_handler[id];
+	arg = g_umac_glb_obj->vdev_create_handler_arg[id];
+	if (handler != NULL)
+		vdev->obj_status[id] = handler(vdev, arg);
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	/* If object status is created, then only handle this object status */
+	if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) {
+		/* Derive object status */
+		obj_status = wlan_objmgr_vdev_object_status(vdev);
+		/* Move PDEV object state to Partially created state */
+		if (obj_status == QDF_STATUS_COMP_ASYNC) {
+			/*TODO atomic */
+			vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
+		}
+	}
+	return obj_status;
+}
+
+QDF_STATUS wlan_objmgr_trigger_vdev_comp_object_deletion(
+		struct wlan_objmgr_vdev *vdev,
+		enum wlan_umac_comp_id id)
+{
+	wlan_objmgr_vdev_delete_handler handler;
+	void *arg;
+	QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
+
+	/* component id is invalid */
+	if (id >= WLAN_UMAC_MAX_COMPONENTS)
+		return QDF_STATUS_MAXCOMP_FAIL;
+
+	wlan_vdev_obj_lock(vdev);
+	/* Component object was never created, invalid operation */
+	if (vdev->vdev_comp_obj[id] == NULL) {
+		wlan_vdev_obj_unlock(vdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	wlan_vdev_obj_unlock(vdev);
+
+	/* Invoke registered create handlers */
+	handler = g_umac_glb_obj->vdev_delete_handler[id];
+	arg = g_umac_glb_obj->vdev_delete_handler_arg[id];
+	if (handler != NULL)
+		vdev->obj_status[id] = handler(vdev, arg);
+	else
+		return QDF_STATUS_E_FAILURE;
+
+	/* If object status is created, then only handle this object status */
+	if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) {
+		obj_status = wlan_objmgr_vdev_object_status(vdev);
+		/* move object state to DEL progress */
+		if (obj_status == QDF_STATUS_COMP_ASYNC)
+			vdev->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
+	}
+	return obj_status;
+}
+
+
+
+static void wlan_obj_vdev_peerlist_add_tail(qdf_list_t *obj_list,
+	struct wlan_objmgr_peer *obj)
+{
+	qdf_list_insert_back(obj_list, &obj->vdev_peer);
+}
+
+static QDF_STATUS wlan_obj_vdev_peerlist_remove_peer(qdf_list_t *obj_list,
+					struct wlan_objmgr_peer *peer)
+{
+	qdf_list_node_t *vdev_node = NULL;
+
+	if (peer == NULL)
+		return QDF_STATUS_E_FAILURE;
+	/* get vdev list node element */
+	vdev_node = &peer->vdev_peer;
+	/* list is empty, return failure */
+	if (qdf_list_remove_node(obj_list, vdev_node) != QDF_STATUS_SUCCESS)
+		return QDF_STATUS_E_FAILURE;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev,
+						struct wlan_objmgr_peer *peer)
+{
+	struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
+
+	wlan_vdev_obj_lock(vdev);
+	/* If Max peer count exceeds, return failure */
+	if (objmgr->wlan_peer_count > objmgr->max_peer_count) {
+		wlan_vdev_obj_unlock(vdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* Add peer to vdev's peer list */
+	wlan_obj_vdev_peerlist_add_tail(&objmgr->wlan_peer_list, peer);
+	objmgr->wlan_peer_count++;
+
+	if (wlan_peer_get_peer_type(peer) == WLAN_PEER_AP) {
+		if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer),
+				 wlan_vdev_mlme_get_macaddr(vdev)) ==
+					QDF_STATUS_SUCCESS) {
+			/*
+			 * if peer mac address and vdev mac address match, set
+			 * this peer as self peer
+			 */
+			wlan_vdev_set_selfpeer(vdev, peer);
+			/* For AP mode, self peer and BSS peer are same */
+			if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE)
+				wlan_vdev_set_bsspeer(vdev, peer);
+		}
+		/* set BSS peer for sta */
+		if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
+			wlan_vdev_set_bsspeer(vdev, peer);
+	}
+	wlan_vdev_obj_unlock(vdev);
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev *vdev,
+					struct wlan_objmgr_peer *peer)
+{
+	struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
+
+	wlan_vdev_obj_lock(vdev);
+	/* if peer count is 0, return failure */
+	if (objmgr->wlan_peer_count == 0) {
+		wlan_vdev_obj_unlock(vdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* remove peer from vdev's peer list */
+	if (wlan_obj_vdev_peerlist_remove_peer(&objmgr->wlan_peer_list, peer)
+				== QDF_STATUS_E_FAILURE) {
+		wlan_vdev_obj_unlock(vdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+	/* decrement peer count */
+	objmgr->wlan_peer_count--;
+	wlan_vdev_obj_unlock(vdev);
+	return QDF_STATUS_SUCCESS;
+}
+

+ 50 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj_i.h

@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 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: Public APIs to perform operations on VDEV objects
+ */
+#ifndef _WLAN_OBJMGR_VDEV_OBJ_I_H_
+#define _WLAN_OBJMGR_VDEV_OBJ_I_H_
+
+/**
+ * wlan_objmgr_vdev_peer_attach() - attach peer to vdev peer list
+ * @vdev: VDEV object
+ * @peer: PEER object
+ *
+ * Attaches PEER to VDEV, stores it in VDEV's peer list
+ *
+ * Return: SUCCESS
+ *         Failure (Max PEERs are exceeded)
+ */
+QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev,
+			struct wlan_objmgr_peer *peer);
+
+/**
+ * wlan_objmgr_vdev_peer_detach() - detach peer from vdev peer list
+ * @vdev: VDEV object
+ * @peer: PEER object
+ *
+ * detaches PEER from VDEV's peer list
+ *
+ * Return: SUCCESS
+ *         Failure (No PEERs are present)
+ */
+QDF_STATUS wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev *vdev,
+			struct wlan_objmgr_peer *peer);
+
+#endif /* _WLAN_OBJMGR_VDEV_OBJ_I_H_*/