summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrashanth Bhatta <bhattap@qca.qualcomm.com>2014-01-30 11:32:40 -0800
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-02-07 17:38:25 -0800
commit6470743622fefeab82e630b99d083087dd4cfedd (patch)
treee2ca75702bbed4d218707c3ee143d5cffd561659
parent0f41098d4e100728d0bae03392f4cbb227e71473 (diff)
qcacld: ipa: Add interface specific changes
IPA implementation was added for pipe based implementation but lately design got changed due to various throughput optimization to achieve high throughput. But the optimization did not account interface based implementation and hence concurrency cases like STA-AP mode wasn't working. Now the implementation is interface based and concurrency of STA-AP, AP-AP and STA-AP-AP can be supported with none or minimum changes to IPA. Also fixed issues related to IPA header installation. Change-Id: I1c77fd2f46218aed6dfb898e3cdc28d1f7987a19 CRs-fixed: 606551
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c50
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.h5
-rw-r--r--CORE/HDD/inc/wlan_hdd_ipa.h12
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h3
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c10
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c8
-rw-r--r--CORE/HDD/src/wlan_hdd_ipa.c1215
-rw-r--r--CORE/VOSS/src/vos_trace.c7
8 files changed, 685 insertions, 625 deletions
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
index ef00f2d6fe26..b3df3a7f9f5c 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
@@ -1575,3 +1575,53 @@ VOS_STATUS tl_shim_get_vdevid(struct ol_txrx_peer_t *peer, u_int8_t *vdev_id)
*vdev_id = peer->vdev->vdev_id;
return VOS_STATUS_SUCCESS;
}
+
+/*
+ * Function to get vdev(tl_context) given the MAC address.
+ */
+void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr)
+{
+ struct ol_txrx_peer_t *peer = NULL;
+ ol_txrx_pdev_handle pdev = NULL;
+ uint8_t peer_id;
+
+ if (vos_context == NULL || mac_addr == NULL) {
+ TLSHIM_LOGE("Invalid argument %p, %p", vos_context, mac_addr);
+ return NULL;
+ }
+
+ pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_context);
+ peer = ol_txrx_find_peer_by_addr(pdev, mac_addr, &peer_id);
+
+ if (!peer) {
+ TLSHIM_LOGE("PEER [%pM] not found", mac_addr);
+ return NULL;
+ }
+
+ return peer->vdev;
+}
+
+/*
+ * Function to get vdev(tl_context) given the TL station ID.
+ */
+void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id)
+{
+ struct ol_txrx_peer_t *peer = NULL;
+ ol_txrx_pdev_handle pdev = NULL;
+
+ if (sta_id >= WLAN_MAX_STA_COUNT) {
+ TLSHIM_LOGE("Invalid sta id passed");
+ return NULL;
+ }
+
+ pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_context);
+
+ peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
+
+ if (!peer) {
+ TLSHIM_LOGE("PEER [%d] not found", sta_id);
+ return NULL;
+ }
+
+ return peer->vdev;
+}
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/CORE/CLD_TXRX/TLSHIM/tl_shim.h
index a5d8fa836a3c..31084662b82b 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.h
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.h
@@ -28,6 +28,9 @@
#ifndef TXRX_TL_SHIM_H
#define TXRX_TL_SHIM_H
+#include <ol_txrx_osif_api.h>
+#include <adf_os_lock.h>
+
#ifdef FEATURE_WLAN_CCX
typedef struct deferred_iapp_work {
pVosContextType pVosGCtx;
@@ -86,5 +89,7 @@ VOS_STATUS tl_shim_get_vdevid(struct ol_txrx_peer_t *peer, u_int8_t *vdev_id);
* BETTER_AP_FOUND event is received from roam engine.
*/
int tlshim_mgmt_roam_event_ind(void *context, u_int32_t vdev_id);
+void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr);
+void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id);
#endif
diff --git a/CORE/HDD/inc/wlan_hdd_ipa.h b/CORE/HDD/inc/wlan_hdd_ipa.h
index d0c532f945e0..aaac547e70ce 100644
--- a/CORE/HDD/inc/wlan_hdd_ipa.h
+++ b/CORE/HDD/inc/wlan_hdd_ipa.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -44,12 +44,12 @@
#ifdef IPA_OFFLOAD
#include <mach/ipa.h>
-VOS_STATUS hdd_ipa_init(hdd_context_t *pHddCtx);
-VOS_STATUS hdd_ipa_cleanup(hdd_context_t *pHddCtx);
-int hdd_ipa_wlan_evt(void *pAdapter, uint8_t sta_id,
- enum ipa_wlan_event type, uint8_t *mac_addr);
+VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx);
+VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx);
+int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
+ enum ipa_wlan_event type, uint8_t *mac_addr);
VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rxBuf,
- v_U8_t staId);
+ v_U8_t sta_id);
bool hdd_ipa_is_enabled(hdd_context_t *pHddCtx);
#endif
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 7213c73da511..0f741496f550 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1026,6 +1026,9 @@ struct hdd_adapter_s
#ifdef QCA_WIFI_2_0
v_BOOL_t internalCancelRemainOnChReq;
#endif
+#ifdef IPA_OFFLOAD
+ void *ipa_context;
+#endif
};
#define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station)
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index f07a5df4674c..30dc08dd1d77 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -813,8 +813,8 @@ static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *
#ifdef IPA_OFFLOAD
if (hdd_ipa_is_enabled(pHddCtx))
- hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
- WLAN_STA_DISCONNECT, pAdapter->dev->dev_addr);
+ hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
+ WLAN_STA_DISCONNECT, pHddStaCtx->conn_info.bssId);
#endif
if(pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting)
@@ -1299,9 +1299,9 @@ static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCs
pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
#ifdef IPA_OFFLOAD
- if (hdd_ipa_is_enabled(pHddCtx))
- hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId, WLAN_STA_CONNECT,
- pAdapter->dev->dev_addr);
+ if (hdd_ipa_is_enabled(pHddCtx))
+ hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId, WLAN_STA_CONNECT,
+ pRoamInfo->bssid);
#endif
#ifdef FEATURE_WLAN_TDLS
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 5dafbabe316f..3518e8f62882 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -511,8 +511,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
}
#ifdef IPA_OFFLOAD
if (hdd_ipa_is_enabled(pHddCtx))
- hdd_ipa_wlan_evt(pHostapdAdapter, WLAN_RX_SAP_SELF_STA_ID,
- WLAN_AP_CONNECT, pHostapdAdapter->dev->dev_addr);
+ hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId,
+ WLAN_AP_CONNECT, pHostapdAdapter->dev->dev_addr);
#endif
if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
@@ -596,8 +596,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
#ifdef IPA_OFFLOAD
if (hdd_ipa_is_enabled(pHddCtx))
- hdd_ipa_wlan_evt(pHostapdAdapter, WLAN_RX_SAP_SELF_STA_ID,
- WLAN_AP_DISCONNECT, pHostapdAdapter->dev->dev_addr);
+ hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId,
+ WLAN_AP_DISCONNECT, pHostapdAdapter->dev->dev_addr);
#endif
goto stopbss;
case eSAP_STA_SET_KEY_EVENT:
diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c
index 5965f7892afc..88da1e7337b0 100644
--- a/CORE/HDD/src/wlan_hdd_ipa.c
+++ b/CORE/HDD/src/wlan_hdd_ipa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -24,7 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-
/*========================================================================
\file wlan_hdd_ipa.c
@@ -50,18 +49,14 @@ Include Files
#include <wlan_hdd_softap_tx_rx.h>
#include "vos_sched.h"
-#include "wlan_qct_tl.h"
-#include "ol_txrx_peer_find.h"
#include "tl_shim.h"
+#include "wlan_qct_tl.h"
#define HDD_IPA_DESC_BUFFER_RATIO 4
#define HDD_IPA_IPV4_NAME_EXT "_ipv4"
#define HDD_IPA_IPV6_NAME_EXT "_ipv6"
#define HDD_IPA_RX_INACTIVITY_MSEC_DELAY 2000
-#define HDD_IPA_WLAN_HDR_ONLY_LEN 4
-#define HDD_IPA_WLAN_HDR_STA_ID_OFFSET 3
-#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0
struct llc_snap_hdr {
uint8_t dsap;
@@ -70,49 +65,60 @@ struct llc_snap_hdr {
__be16 eth_type;
} __packed;
-struct ipa_tx_hdr {
+struct hdd_ipa_tx_hdr {
struct ethhdr eth;
struct llc_snap_hdr llc_snap;
} __packed;
/* For Tx pipes, use 802.3 Header format */
-struct ipa_tx_hdr ipa_set_tx_hdr = {
+static struct hdd_ipa_tx_hdr ipa_tx_hdr = {
{
- {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */
- {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */
- 0x00 /* length can be zero */
+ {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF},
+ {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF},
+ 0x00 /* length can be zero */
},
{
- /* LLC SNAP header 8 bytes */
- 0xaa, 0xaa,
- {0x03, 0x00, 0x00, 0x00},
- 0x0008 /* type value(2 bytes) ,filled by wlan */
- /* 0x0800 - IPV4, 0x86dd - IPV6 */
+ /* LLC SNAP header 8 bytes */
+ 0xaa, 0xaa,
+ {0x03, 0x00, 0x00, 0x00},
+ 0x0008 /* type value(2 bytes) ,filled by wlan */
+ /* 0x0800 - IPV4, 0x86dd - IPV6 */
}
};
-struct ipa_rx_hdr {
- uint8_t hdr[HDD_IPA_WLAN_HDR_ONLY_LEN];
+/*
+ +----------+----------+--------------+--------+
+ | Reserved | QCMAP ID | interface id | STA ID |
+ +----------+----------+--------------+--------+
+ */
+struct hdd_ipa_cld_hdr {
+ uint8_t reserved[2];
+ uint8_t iface_id;
+ uint8_t sta_id;
+} __packed;
+
+struct hdd_ipa_rx_hdr {
+ struct hdd_ipa_cld_hdr cld_hdr;
struct ethhdr eth;
} __packed;
-/* For Rx pipe, use Ethernet-II Header format */
-struct ipa_rx_hdr ipa_set_rx_hdr = {
- {0x00, 0x00, 0x00, 0x00}, /* 4 bytes header */
- {
- {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */
- {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */
- 0x0008 /* type value(2 bytes) ,filled by wlan */
- /* 0x0800 - IPV4, 0x86dd - IPV6 */
- }
-};
+#define HDD_IPA_WLAN_CLD_HDR_LEN sizeof(struct hdd_ipa_cld_hdr)
+#define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_tx_hdr)
+#define HDD_IPA_WLAN_RX_HDR_LEN sizeof(struct hdd_ipa_rx_hdr)
+#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0
+
+#define HDD_IPA_GET_IFACE_ID(_data) \
+ (((struct hdd_ipa_cld_hdr *) (_data))->iface_id)
-#define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_set_tx_hdr)
-#define HDD_IPA_WLAN_RX_HDR_LEN sizeof(ipa_set_rx_hdr)
-#define HDD_IPA_WLAN_HDR_PARTIAL 1
#define HDD_IPA_LOG(LVL, fmt, args...) VOS_TRACE(VOS_MODULE_ID_HDD, LVL, \
- "%s:%d "fmt"\n", __func__, __LINE__, ## args)
+ "%s:%d: "fmt, __func__, __LINE__, ## args)
+
+#define HDD_IPA_DBG_DUMP(_lvl, _prefix, _buf, _len) \
+ do {\
+ VOS_TRACE(VOS_MODULE_ID_HDD, _lvl, "%s:", _prefix); \
+ VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, _lvl, _buf, _len); \
+ } while(0)
enum hdd_ipa_rm_state {
HDD_IPA_RM_RELEASED,
@@ -121,101 +127,106 @@ enum hdd_ipa_rm_state {
HDD_IPA_RM_RELEASE_PENDING,
};
-enum hdd_ipa_pipe_index {
- HDD_IPA_TX_WLAN0_PIPE,
- HDD_IPA_TX_WLAN1_PIPE,
- HDD_IPA_TX_WLAN2_PIPE,
- HDD_IPA_RX_PIPE,
- HDD_IPA_MAX_PIPE
+#define HDD_IPA_MAX_IFACE 3
+#define HDD_IPA_MAX_SYSBAM_PIPE 4
+#define HDD_IPA_RX_PIPE HDD_IPA_MAX_IFACE
+
+static struct hdd_ipa_adapter_2_client {
+ enum ipa_client_type cons_client;
+ enum ipa_client_type prod_client;
+} hdd_ipa_adapter_2_client[HDD_IPA_MAX_IFACE] = {
+ {IPA_CLIENT_WLAN1_CONS, IPA_CLIENT_WLAN1_PROD},
+ {IPA_CLIENT_WLAN2_CONS, IPA_CLIENT_WLAN1_PROD},
+ {IPA_CLIENT_WLAN3_CONS, IPA_CLIENT_WLAN1_PROD},
};
-enum hdd_ipa_ip_ver {
- HDD_IPA_IPV4 = 1,
- HDD_IPA_IPV6 = 2
+struct hdd_ipa_sys_pipe {
+ uint32_t conn_hdl;
+ uint8_t conn_hdl_valid;
+ struct ipa_sys_connect_params ipa_sys_params;
};
-#define HDD_IPA_WLAN_MAX_STA_ID 255
+struct hdd_ipa_priv;
-uint8_t wlan_sta_id_2_hdd_pipe_id[HDD_IPA_WLAN_MAX_STA_ID] = {0xFF};
+struct hdd_ipa_iface_context {
+ struct hdd_ipa_priv *hdd_ipa;
+ hdd_adapter_t *adapter;
+ void *tl_context;
-uint8_t hdd_pipe_id_2_ipa_client_id[HDD_IPA_MAX_PIPE] = {
- IPA_CLIENT_WLAN1_CONS,
- IPA_CLIENT_WLAN2_CONS,
- IPA_CLIENT_WLAN3_CONS,
- IPA_CLIENT_WLAN1_PROD
-};
+ enum ipa_client_type cons_client;
+ enum ipa_client_type prod_client;
-uint8_t ipa_client_id_2_hdd_pipe_id[IPA_CLIENT_MAX] = {
- [IPA_CLIENT_WLAN1_CONS] = HDD_IPA_TX_WLAN0_PIPE,
- [IPA_CLIENT_WLAN2_CONS] = HDD_IPA_TX_WLAN1_PIPE,
- [IPA_CLIENT_WLAN3_CONS] = HDD_IPA_TX_WLAN2_PIPE,
- [IPA_CLIENT_WLAN1_PROD] = HDD_IPA_RX_PIPE
+ uint8_t iface_id; /* This iface ID */
+ uint8_t sta_id; /* This iface station ID */
};
-struct hdd_ipa_sys_pipe {
- uint32_t conn_hdl;
- uint8_t conn_hdl_valid;
- struct ipa_sys_connect_params ipa_sys_params;
+
+struct hdd_ipa_stats {
+ uint32_t event[IPA_WLAN_EVENT_MAX];
+ uint32_t send_msg;
+ uint32_t free_msg;
+
+ uint64_t prefilter;
+ uint64_t rm_grant;
+ uint64_t rm_release;
+#ifdef HDD_IPA_EXTRA_DP_COUNTERS
+ uint64_t rx_ipa_rm_qued;
+#endif
+ uint64_t rx_ipa_sent_desc_cnt;
+ uint64_t rx_ipa_write_done;
+ uint64_t rx_ipa_excep;
+
+ uint64_t rx_ipa_hw_maxed_out;
+
+ uint64_t freeq_empty;
+ uint64_t freeq_cnt;
+
+#ifdef HDD_IPA_EXTRA_DP_COUNTERS
+ uint64_t rxt_drop;
+ uint64_t rxt_recv;
+ uint64_t rx_ipa_hw_max_qued;
+ uint64_t rxt_d_drop;
+ uint64_t rxt_dh_drop;
+ uint64_t rxt_0;
+ uint64_t rxt_1;
+ uint64_t rxt_2;
+ uint64_t rxt_3;
+ uint64_t rxt_4;
+ uint64_t rxt_5;
+ uint64_t rxt_6;
+ uint64_t freeq_use;
+ uint64_t freeq_reclaim;
+ uint64_t rx_ipa_dh_sent;
+ uint64_t rx_ipa_dh_reclaim;
+ uint64_t rx_ipa_dh_not_used;
+#endif
+ uint64_t ipa_lb_cnt;
+ uint64_t tx_ipa_recv;
+ uint64_t tx_comp_cnt;
+ uint64_t tx_dp_err_cnt;
};
struct hdd_ipa_priv {
- struct hdd_ipa_sys_pipe sys_pipe[HDD_IPA_MAX_PIPE];
+ struct hdd_ipa_sys_pipe sys_pipe[HDD_IPA_MAX_SYSBAM_PIPE];
+ struct hdd_ipa_iface_context iface_context[HDD_IPA_MAX_IFACE];
atomic_t rm_state;
#ifndef HDD_IPA_USE_IPA_RM_TIMER
struct timer_list rm_timer;
uint8_t rm_timer_on;
#endif
+ enum ipa_client_type prod_client;
+
uint32_t pending_desc_cnt;
uint32_t hw_desc_cnt;
spinlock_t q_lock;
struct list_head free_desc_head;
struct list_head pend_desc_head;
- struct ol_txrx_vdev_t *pipe_to_vdev[HDD_IPA_MAX_PIPE];
-
hdd_context_t *hdd_ctx;
struct dentry *debugfs_dir;
- struct {
- uint64_t prefilter;
- uint64_t rm_grant;
- uint64_t rm_release;
-#ifdef HDD_IPA_EXTRA_DP_COUNTERS
- uint64_t rx_ipa_rm_qued;
-#endif
- uint64_t rx_ipa_sent_desc_cnt;
- uint64_t rx_ipa_write_done;
- uint64_t rx_ipa_excep;
-
- uint64_t rx_ipa_hw_maxed_out;
-
- uint64_t freeq_empty;
- uint64_t freeq_cnt;
+ struct hdd_ipa_stats stats;
-#ifdef HDD_IPA_EXTRA_DP_COUNTERS
- uint64_t rxt_drop;
- uint64_t rxt_recv;
- uint64_t rx_ipa_hw_max_qued;
- uint64_t rxt_d_drop;
- uint64_t rxt_dh_drop;
- uint64_t rxt_0;
- uint64_t rxt_1;
- uint64_t rxt_2;
- uint64_t rxt_3;
- uint64_t rxt_4;
- uint64_t rxt_5;
- uint64_t rxt_6;
- uint64_t freeq_use;
- uint64_t freeq_reclaim;
- uint64_t rx_ipa_dh_sent;
- uint64_t rx_ipa_dh_reclaim;
- uint64_t rx_ipa_dh_not_used;
-#endif
- uint64_t ipa_lb_cnt;
- uint64_t tx_ipa_recv;
- uint64_t tx_comp_cnt;
- uint64_t tx_dp_err_cnt;
- } stats;
};
enum hdd_ipa_evt {
@@ -239,12 +250,22 @@ bool hdd_ipa_is_enabled(hdd_context_t *hdd_ctx)
return hdd_ctx->cfg_ini->IpaEnable;
}
-static inline void *hdd_ipa_kzalloc(uint32_t size)
+static inline bool hdd_ipa_is_pre_filter_enabled(struct hdd_ipa_priv *hdd_ipa)
+{
+ hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
+ return hdd_ctx->cfg_ini->IpaPreFilterEnable;
+}
+
+static inline bool hdd_ipa_is_ipv6_enabled(struct hdd_ipa_priv *hdd_ipa)
{
- void *data = NULL;
+ hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
+ return hdd_ctx->cfg_ini->IpaIPv6Enable;
+}
- data = adf_os_mem_alloc(NULL, size);
- return data;
+static inline bool hdd_ipa_is_rm_enabled(struct hdd_ipa_priv *hdd_ipa)
+{
+ hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
+ return hdd_ctx->cfg_ini->IpaRMEnable;
}
static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void)
@@ -254,7 +275,8 @@ static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void)
spin_lock_bh(&ghdd_ipa->q_lock);
if (!list_empty(&ghdd_ipa->free_desc_head)) {
- desc = list_first_entry(&ghdd_ipa->free_desc_head, struct ipa_tx_data_desc, link);
+ desc = list_first_entry(&ghdd_ipa->free_desc_head,
+ struct ipa_tx_data_desc, link);
list_del(&desc->link);
hdd_ipa->stats.freeq_cnt--;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
@@ -267,22 +289,33 @@ static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void)
return desc;
}
-static inline bool hdd_ipa_can_pre_filter(struct hdd_ipa_priv *hdd_ipa)
+static bool hdd_ipa_can_send_to_ipa(struct hdd_ipa_priv *hdd_ipa, void *data)
{
- hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
- return hdd_ctx->cfg_ini->IpaPreFilterEnable;
-}
+ struct ethhdr *eth = (struct ethhdr *)data;
+ struct llc_snap_hdr *ls_hdr;
+ uint16_t eth_type;
-static inline bool hdd_ipa_is_ipv6_enabled(struct hdd_ipa_priv *hdd_ipa)
-{
- hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
- return hdd_ctx->cfg_ini->IpaIPv6Enable;
-}
+ if (!hdd_ipa_is_pre_filter_enabled(hdd_ipa))
+ return true;
-static inline bool hdd_ipa_is_rm_enabled(struct hdd_ipa_priv *hdd_ipa)
-{
- hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
- return hdd_ctx->cfg_ini->IpaRMEnable;
+ eth_type = be16_to_cpu(eth->h_proto);
+ if (eth_type < 0x600) {
+ /* Non Ethernet II framing format */
+ ls_hdr = (struct llc_snap_hdr *)((uint8_t *)data +
+ sizeof(struct ethhdr));
+
+ if (((ls_hdr->dsap == 0xAA) && (ls_hdr->ssap == 0xAA)) ||
+ ((ls_hdr->dsap == 0xAB) && (ls_hdr->ssap == 0xAB)))
+ eth_type = be16_to_cpu(ls_hdr->eth_type);
+ }
+
+ if (eth_type == ETH_P_IP)
+ return true;
+
+ if (hdd_ipa_is_ipv6_enabled(hdd_ipa) && eth_type == ETH_P_IPV6)
+ return true;
+
+ return false;
}
static int hdd_ipa_rm_request(struct hdd_ipa_priv *hdd_ipa)
@@ -362,7 +395,7 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa)
ret = ipa_rm_create_resource(&create_params);
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "create resource fail");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Create RM resource failed");
goto setup_rm_fail;
}
@@ -370,11 +403,13 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa)
ret = ipa_rm_inactivity_timer_init(IPA_RM_RESOURCE_WLAN_PROD,
HDD_IPA_RX_INACTIVITY_MSEC_DELAY);
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "timer fail");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Timer init failed");
goto setup_rm_fail;
}
#endif
+ atomic_set(&hdd_ipa->rm_state, HDD_IPA_RM_RELEASED);
+
setup_rm_fail:
return ret;
}
@@ -391,10 +426,10 @@ static void hdd_ipa_destory_rm_resource(struct hdd_ipa_priv *hdd_ipa)
#endif
ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WLAN_PROD);
if (ret)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "fail");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "RM resource delete failed");
}
-void hdd_ipa_rm_timer_handler(unsigned long ptr)
+static void hdd_ipa_rm_timer_handler(unsigned long ptr)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
atomic_set(&hdd_ipa->rm_state,
@@ -402,27 +437,26 @@ void hdd_ipa_rm_timer_handler(unsigned long ptr)
hdd_ipa_rm_release(hdd_ipa);
}
-void hdd_ipa_send_skb_to_network(adf_nbuf_t skb, hdd_adapter_t *adap_dev)
+static void hdd_ipa_send_skb_to_network(adf_nbuf_t skb, hdd_adapter_t *adapter)
{
- if (!adap_dev || (adap_dev &&
- adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid adapter: adap=0x%x",
- adap_dev);
+ if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid adapter: 0x%p",
+ adapter);
- adf_nbuf_free(skb);
- return;
- }
- skb->dev = adap_dev->dev;
- skb->protocol = eth_type_trans(skb, skb->dev);
- skb->ip_summed = CHECKSUM_NONE;
- ++adap_dev->hdd_stats.hddTxRxStats.rxPackets;
- ++adap_dev->stats.rx_packets;
- adap_dev->stats.rx_bytes += skb->len;
- if (netif_rx_ni(skb) == NET_RX_SUCCESS)
- ++adap_dev->hdd_stats.hddTxRxStats.rxDelivered;
- else
- ++adap_dev->hdd_stats.hddTxRxStats.rxRefused;
- adap_dev->dev->last_rx = jiffies;
+ adf_nbuf_free(skb);
+ return;
+ }
+ skb->dev = adapter->dev;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ skb->ip_summed = CHECKSUM_NONE;
+ ++adapter->hdd_stats.hddTxRxStats.rxPackets;
+ ++adapter->stats.rx_packets;
+ adapter->stats.rx_bytes += skb->len;
+ if (netif_rx_ni(skb) == NET_RX_SUCCESS)
+ ++adapter->hdd_stats.hddTxRxStats.rxDelivered;
+ else
+ ++adapter->hdd_stats.hddTxRxStats.rxRefused;
+ adapter->dev->last_rx = jiffies;
}
static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
@@ -478,21 +512,25 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
hdd_ipa->stats.rx_ipa_dh_sent++; /* for desc head */
#endif
spin_unlock_bh(&hdd_ipa->q_lock);
- if (ipa_tx_dp_mul(hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE],
+ if (ipa_tx_dp_mul(hdd_ipa->prod_client,
send_desc_head) != 0) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ipa_tx_dp_mul failed!!! (cur_send_cnt=%d)", cur_send_cnt);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "ipa_tx_dp_mul failed!!!"
+ " (cur_send_cnt=%d)",
+ cur_send_cnt);
hdd_ipa->stats.tx_dp_err_cnt++;
spin_lock_bh(&hdd_ipa->q_lock);
list_for_each_entry_safe(desc, tmp,
- &send_desc_head->link, link) {
+ &send_desc_head->link, link) {
list_del(&desc->link);
buf = desc->priv;
adf_nbuf_free(buf);
desc->priv = NULL;
desc->pyld_buffer = NULL;
desc->pyld_len = 0;
- list_add_tail(&desc->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&desc->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.freeq_reclaim++;
@@ -501,7 +539,8 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
}
/* return anchor node */
- list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&send_desc_head->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.rx_ipa_dh_reclaim++;
@@ -517,7 +556,8 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
hdd_ipa->stats.rx_ipa_hw_maxed_out++;
list_splice_tail_init(&send_desc_head->link,
&hdd_ipa->pend_desc_head);
- list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&send_desc_head->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.rx_ipa_dh_not_used++;
@@ -528,52 +568,25 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
}
-static int hdd_ipa_is_ip_pkt(void *data, uint8_t ip_ver)
-{
- struct ethhdr *eth = (struct ethhdr *)data;
- struct llc_snap_hdr *ls_hdr;
- uint16_t eth_type;
- int ret = 0;
-
- eth_type = be16_to_cpu(eth->h_proto);
- if (eth_type < 0x600) {
- /* Non Ethernet II framing format */
- ls_hdr = (struct llc_snap_hdr *)((uint8_t *)data +
- sizeof(struct ethhdr));
-
- if (((ls_hdr->dsap == 0xAA) && (ls_hdr->ssap == 0xAA)) ||
- ((ls_hdr->dsap == 0xAB) && (ls_hdr->ssap == 0xAB)))
- eth_type = be16_to_cpu(ls_hdr->eth_type);
- }
-
- if (((eth_type == ETH_P_IP) && (ip_ver == HDD_IPA_IPV4)) ||
- ((eth_type == ETH_P_IPV6) && (ip_ver == HDD_IPA_IPV6)))
- ret = 1;
-
- if (ret != 1)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "NOT IP Packet!!! (eth_type=0x%x, ip_ver=%d)", eth_type, ip_ver);
-
- return ret;
-}
-
-
static void hdd_ipa_process_evt(int evt, void *priv)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
struct hdd_ipa_rxt *rxt;
struct ipa_tx_data_desc *send_desc_head = NULL, *send_desc,
*done_desc_head, *done_desc, *tmp;
- hdd_adapter_t *adap_dev = NULL;
+ hdd_adapter_t *adapter = NULL;
+ struct hdd_ipa_iface_context *iface_context = NULL;
adf_nbuf_t buf, next_buf;
uint8_t cur_cnt = 0;
+ struct hdd_ipa_cld_hdr *cld_hdr;
switch (evt) {
case HDD_IPA_RXT_EVT:
rxt = priv;
- adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[rxt->sta_id];
- if (!adap_dev ||
- (adap_dev && adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+ adapter = hdd_ipa->hdd_ctx->sta_to_adapter[rxt->sta_id];
+ if (!adapter ||
+ (adapter && adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid sta_id");
buf = rxt->rx_buf_list;
while (buf) {
@@ -586,10 +599,14 @@ static void hdd_ipa_process_evt(int evt, void *priv)
}
return;
}
+
+ iface_context =
+ (struct hdd_ipa_iface_context *) adapter->ipa_context;
/* send_desc_head is a anchor node */
send_desc_head = hdd_ipa_get_desc_from_freeq();
if (!send_desc_head) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "send_desc_head=Null. FreeQ Empty");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "send_desc_head=Null. FreeQ Empty");
buf = rxt->rx_buf_list;
while (buf) {
next_buf = adf_nbuf_queue_next(buf);
@@ -612,34 +629,28 @@ static void hdd_ipa_process_evt(int evt, void *priv)
INIT_LIST_HEAD(&send_desc_head->link);
buf = rxt->rx_buf_list;
while (buf) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "RX data:\n \
- %02x %02x %02x %02x %02x %02x %02x %02x\n \
- %02x %02x %02x %02x %02x %02x %02x %02x\n \
- %02x %02x %02x %02x %02x %02x %02x %02x\n",
- buf->data[0], buf->data[1], buf->data[2], buf->data[3],
- buf->data[4], buf->data[5], buf->data[6], buf->data[7],
- buf->data[8], buf->data[9], buf->data[10], buf->data[11],
- buf->data[12], buf->data[13], buf->data[14], buf->data[15],
- buf->data[16], buf->data[17], buf->data[18], buf->data[19],
- buf->data[20], buf->data[21], buf->data[22], buf->data[23]);
+ HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "RX data",
+ buf->data, 24);
next_buf = adf_nbuf_queue_next(buf);
- /* we want to send Rx packets to IPA only when it is IPV4 or IPV6i(if IPV6
- is enabled). All other packets will be sent to network stack directly. */
- if (hdd_ipa_can_pre_filter(hdd_ipa) &&
- (!hdd_ipa_is_ip_pkt(buf->data, HDD_IPA_IPV4) &&
- (!hdd_ipa_is_ipv6_enabled(hdd_ipa) ||
- !hdd_ipa_is_ip_pkt(buf->data, HDD_IPA_IPV6)))) {
+ /*
+ * we want to send Rx packets to IPA only when it is
+ * IPV4 or IPV6i(if IPV6 is enabled). All other packets
+ * will be sent to network stack directly.
+ */
+ if (!hdd_ipa_can_send_to_ipa(hdd_ipa, buf->data)) {
hdd_ipa->stats.prefilter++;
- hdd_ipa_send_skb_to_network(buf, adap_dev);
+ hdd_ipa_send_skb_to_network(buf, adapter);
buf = next_buf;
continue;
}
- skb_push(buf, HDD_IPA_WLAN_HDR_ONLY_LEN);
- /* vos_mem_zero(((struct ipa_rx_hdr *)(buf->data))->hdr, HDD_IPA_WLAN_HDR_ONLY_LEN); */
- ((struct ipa_rx_hdr *)(buf->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET] = rxt->sta_id;
+ cld_hdr = (struct hdd_ipa_cld_hdr *) skb_push(buf,
+ HDD_IPA_WLAN_CLD_HDR_LEN);
+ cld_hdr->sta_id = rxt->sta_id;
+ cld_hdr->iface_id = iface_context->iface_id;
+
send_desc = hdd_ipa_get_desc_from_freeq();
if (send_desc) {
send_desc->priv = buf;
@@ -680,7 +691,8 @@ static void hdd_ipa_process_evt(int evt, void *priv)
if(cur_cnt == 0){
spin_lock_bh(&hdd_ipa->q_lock);
- list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&send_desc_head->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.rx_ipa_dh_not_used++;
@@ -699,7 +711,8 @@ static void hdd_ipa_process_evt(int evt, void *priv)
HDD_IPA_RM_GRANT_PENDING);
hdd_ipa_rm_request(hdd_ipa);
}
- /* hdd_ipa_rm_request can immediately grant so check again. */
+ /* hdd_ipa_rm_request can immediately grant so check
+ again. */
if (atomic_read(&hdd_ipa->rm_state)
== HDD_IPA_RM_GRANT_PENDING) {
spin_lock_bh(&hdd_ipa->q_lock);
@@ -740,7 +753,8 @@ rxt_end:
done_desc->priv = NULL;
done_desc->pyld_buffer = NULL;
done_desc->pyld_len = 0;
- list_add_tail(&done_desc->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&done_desc->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.freeq_reclaim++;
@@ -781,12 +795,6 @@ rxt_end:
}
}
-static void hdd_ipa_w2i_write_done_handler(
- struct ipa_tx_data_desc *done_desc_head)
-{
- hdd_ipa_process_evt(HDD_IPA_WRITE_DONE_EVT, done_desc_head);
-}
-
VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rx_buf_list,
v_U8_t sta_id)
{
@@ -804,50 +812,43 @@ VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rx_buf_list,
return VOS_STATUS_SUCCESS;
}
-
-
-void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
+static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt,
+ unsigned long data)
{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- uint8_t client;
+ struct hdd_ipa_priv *hdd_ipa = NULL;
+ hdd_adapter_t *adapter = NULL;
struct ipa_tx_data_desc *done_desc_head;
adf_nbuf_t skb;
- uint8_t sta_id;
- hdd_adapter_t *adap_dev=NULL;
+ uint8_t iface_id;
- client = *((uint8_t *)priv);
- if (client != hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
- "w2i cb wrong pipe: %d %x %x",
- client, priv,
- &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]);
- return;
- }
+ hdd_ipa = (struct hdd_ipa_priv *)priv;
switch (evt) {
case IPA_RECEIVE:
skb = (adf_nbuf_t) data;
- sta_id = ((struct ipa_rx_hdr *)(skb->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET];
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb,
- skb->data[0], skb->data[1], skb->data[2], skb->data[3],
- skb->data[4], skb->data[5], skb->data[6], skb->data[7]);
- skb_pull(skb, HDD_IPA_WLAN_HDR_ONLY_LEN);
-
- if (sta_id < ARRAY_SIZE(hdd_ipa->hdd_ctx->sta_to_adapter)) {
- adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id];
- } else {
+ iface_id = HDD_IPA_GET_IFACE_ID(skb->data);
+ if (iface_id >= HDD_IPA_MAX_IFACE) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
- "w2i cb: wrong sta_id: %d", sta_id);
+ "IPA_RECEIVE: Invalid iface_id: %u\n",
+ iface_id);
+ adf_nbuf_free(skb);
+ return;
}
+ adapter = hdd_ipa->iface_context[iface_id].adapter;
+
+ HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb", skb->data,
+ 8);
+
+ skb_pull(skb, HDD_IPA_WLAN_CLD_HDR_LEN);
+
hdd_ipa->stats.rx_ipa_excep++;
- hdd_ipa_send_skb_to_network(skb, adap_dev);
+ hdd_ipa_send_skb_to_network(skb, adapter);
break;
case IPA_WRITE_DONE:
done_desc_head = (struct ipa_tx_data_desc *)data;
- hdd_ipa_w2i_write_done_handler(done_desc_head);
+ hdd_ipa_process_evt(HDD_IPA_WRITE_DONE_EVT, done_desc_head);
break;
default:
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
@@ -856,93 +857,33 @@ void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
}
}
-void hdd_ipa_nbuf_cb(adf_nbuf_t skb)
+static void hdd_ipa_nbuf_cb(adf_nbuf_t skb)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
/* TX COMP counter at frame free location. */
hdd_ipa->stats.tx_comp_cnt++;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb));
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "%lx", NBUF_OWNER_PRIV_DATA(skb));
ipa_free_skb((struct ipa_rx_data *) NBUF_OWNER_PRIV_DATA(skb));
}
-#ifdef WLAN_TX_MUL
-void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
+static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt,
+ unsigned long data)
{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- struct ipa_rx_data_mul *ipa_tx_desc;
- adf_nbuf_t skb;
- uint8_t client, pipe_id;
-
- if (evt == IPA_RECEIVE) {
- client = *((uint8_t *)priv);
- struct list_head *head = (struct list_head *)data;
-
- pipe_id = ipa_client_id_2_hdd_pipe_id[client];
-
- if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (vdev=NULL)");
- /* TODO: need to free ipa_desc and skb here */
- return;
- }
-
- list_for_each_entry(ipa_tx_desc, head, link) {
- if (ipa_tx_desc->dd == NULL)
- break;
-
- /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer.*/
- hdd_ipa->stats.tx_ipa_recv++;
-
- skb = ipa_tx_desc->dd->skb;
-
- /* skb->dev = ipa_client_id_2_hdd_pipe_id[client]; */
- adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
- NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID;
- NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb;
- NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dd->dma_addr;
-
- NBUF_OWNER_PRIV_DATA(skb) = (unsigned long)ipa_tx_desc->dd;
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb,
- skb->data[0], skb->data[1], skb->data[2], skb->data[3],
- skb->data[4], skb->data[5], skb->data[6], skb->data[7]);
-
- skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id],
- ipa_tx_desc->dd->skb);
- if (skb) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail");
- ipa_free_skb(ipa_tx_desc->dd);
- continue;
- }
- }
- ipa_free_desc(data);
-
- } else {
- /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt);
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */
- skb = (adf_nbuf_t) data;
- dev_kfree_skb_any(skb);
- }
-}
-
-#else
-
-void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
-{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
+ struct hdd_ipa_priv *hdd_ipa = NULL;
struct ipa_rx_data *ipa_tx_desc;
+ struct hdd_ipa_iface_context *iface_context;
adf_nbuf_t skb;
- uint8_t client, pipe_id;
if (evt == IPA_RECEIVE) {
- /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer */
- hdd_ipa->stats.tx_ipa_recv++;
- client = *((uint8_t *)priv);
+ iface_context = (struct hdd_ipa_iface_context *) priv;
ipa_tx_desc = (struct ipa_rx_data *)data;
skb = ipa_tx_desc->skb;
+ hdd_ipa = iface_context->hdd_ipa;
+
adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID;
NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb;
@@ -950,36 +891,22 @@ void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
NBUF_OWNER_PRIV_DATA(skb) = data;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb));
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb,
- skb->data[0], skb->data[1], skb->data[2], skb->data[3],
- skb->data[4], skb->data[5], skb->data[6], skb->data[7]);
-
- pipe_id = ipa_client_id_2_hdd_pipe_id[client];
+ HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "i2w", skb->data, 8);
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "client=%d, pipe_to_vdev[%d]=0x%x", client, pipe_id, hdd_ipa->pipe_to_vdev[pipe_id]);
-
- if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (pipe_to_vdev[%d]=NULL)", pipe_id);
- ipa_free_skb(ipa_tx_desc);
- return;
- }
+ hdd_ipa->stats.tx_ipa_recv++;
- skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id],
- ipa_tx_desc->skb);
+ skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext,
+ iface_context->tl_context, ipa_tx_desc->skb);
if (skb) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail");
ipa_free_skb(ipa_tx_desc);
return;
}
} else {
- /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt);
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */
skb = (adf_nbuf_t) data;
dev_kfree_skb_any(skb);
}
}
-#endif
static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
{
@@ -987,12 +914,12 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
struct ipa_sys_connect_params *ipa;
/*setup TX pipes */
- for (i = 0; i < HDD_IPA_RX_PIPE; i++) {
+ for (i = 0; i < HDD_IPA_MAX_IFACE; i++) {
ipa = &hdd_ipa->sys_pipe[i].ipa_sys_params;
- ipa->client = hdd_pipe_id_2_ipa_client_id[i];
+ ipa->client = hdd_ipa_adapter_2_client[i].cons_client;
ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize;
- ipa->priv = &hdd_pipe_id_2_ipa_client_id[i];
+ ipa->priv = &hdd_ipa->iface_context[i];
ipa->notify = hdd_ipa_i2w_cb;
ipa->ipa_ep_cfg.hdr.hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
@@ -1000,17 +927,35 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
ret = ipa_setup_sys_pipe(ipa, &(hdd_ipa->sys_pipe[i].conn_hdl));
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Fail: %d", ret);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed for pipe %d"
+ " ret: %d", i, ret);
goto setup_sys_pipe_fail;
}
hdd_ipa->sys_pipe[i].conn_hdl_valid = 1;
}
+ /*
+ * Hard code it here, this can be extended if in case PROD pipe is also
+ * per interface. Right now there is no advantage of doing this.
+ */
+ hdd_ipa->prod_client = IPA_CLIENT_WLAN1_PROD;
+
ipa = &hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].ipa_sys_params;
- ipa->client = hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE];
- ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize + sizeof(struct sps_iovec); /* To make sure total # of desc is 1 less than the desc FIFO size */
- ipa->priv = &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE];
+ ipa->client = hdd_ipa->prod_client;
+
+ /* The maximum number of descriptors that can be provided to a BAM at
+ * once is one less than the total number of descriptors that the buffer
+ * can contain.
+ * If max_num_of_descriptors = (BAM_PIPE_DESCRIPTOR_FIFO_SIZE / sizeof
+ * (SPS_DESCRIPTOR)), then (max_num_of_descriptors - 1) descriptors can
+ * be provided at once.
+ * Because of above requirement, one extra descriptor will be added to
+ * make sure hardware always has one descriptor.
+ */
+ ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize
+ + sizeof(struct sps_iovec);
+ ipa->priv = hdd_ipa;
ipa->notify = hdd_ipa_w2i_cb;
ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
@@ -1020,59 +965,73 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
ret = ipa_setup_sys_pipe(ipa, &(hdd_ipa->sys_pipe[i].conn_hdl));
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Fail: %d", ret);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed for RX pipe: %d",
+ ret);
goto setup_sys_pipe_fail;
}
hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].conn_hdl_valid = 1;
+ return ret;
+
setup_sys_pipe_fail:
+
+ while (--i >= 0) {
+ ipa_teardown_sys_pipe(hdd_ipa->sys_pipe[i].conn_hdl);
+ vos_mem_zero(&hdd_ipa->sys_pipe[i],
+ sizeof(struct hdd_ipa_sys_pipe ));
+ }
+
return ret;
}
/* Disconnect all the Sys pipes */
-void hdd_ipa_teardown_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
+static void hdd_ipa_teardown_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
{
int ret = 0, i;
- for (i = 0; i < HDD_IPA_MAX_PIPE; i++) {
+ for (i = 0; i < HDD_IPA_MAX_SYSBAM_PIPE; i++) {
if (hdd_ipa->sys_pipe[i].conn_hdl_valid) {
ret = ipa_teardown_sys_pipe(
hdd_ipa->sys_pipe[i].conn_hdl);
if (ret)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "fail: %d",
- ret);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed: %d",
+ ret);
hdd_ipa->sys_pipe[i].conn_hdl_valid = 0;
}
}
}
-int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, const char *ifname)
+static int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa,
+ struct hdd_ipa_iface_context *iface_context)
{
struct ipa_tx_intf tx_intf;
struct ipa_rx_intf rx_intf;
struct ipa_ioc_tx_intf_prop *tx_prop = NULL;
struct ipa_ioc_rx_intf_prop *rx_prop = NULL;
+ char *ifname = iface_context->adapter->dev->name;
char ipv4_hdr_name[IPA_RESOURCE_NAME_MAX];
char ipv6_hdr_name[IPA_RESOURCE_NAME_MAX];
- int ip_max = HDD_IPA_IPV4;
+ int num_prop = 1;
int ret = 0;
if (hdd_ipa_is_ipv6_enabled(hdd_ipa))
- ip_max = HDD_IPA_IPV6;
+ num_prop++;
/* Allocate TX properties for TOS categories, 1 each for IPv4 & IPv6 */
- tx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_tx_intf_prop) * ip_max);
+ tx_prop = vos_mem_malloc(sizeof(struct ipa_ioc_tx_intf_prop) *
+ num_prop);
if (!tx_prop) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "tx_prop allocation failed");
goto register_interface_fail;
}
/* Allocate RX properties, 1 each for IPv4 & IPv6 */
- rx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_rx_intf_prop) * ip_max);
+ rx_prop = vos_mem_malloc(sizeof(struct ipa_ioc_rx_intf_prop) *
+ num_prop);
if (!rx_prop) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "rx_prop allocation failed");
goto register_interface_fail;
}
vos_mem_zero(&tx_intf, sizeof(tx_intf));
@@ -1084,23 +1043,42 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, con
ifname, HDD_IPA_IPV6_NAME_EXT);
rx_prop[IPA_IP_v4].ip = IPA_IP_v4;
- rx_prop[IPA_IP_v4].src_pipe = IPA_CLIENT_WLAN1_PROD;
+ rx_prop[IPA_IP_v4].src_pipe = iface_context->prod_client;
+
+ rx_prop[IPA_IP_v4].attrib.attrib_mask = IPA_FLT_META_DATA;
+
+ /*
+ * Interface ID is 3rd byte in the CLD header. Add the meta data and
+ * mask to identify the interface in IPA hardware
+ */
+ rx_prop[IPA_IP_v4].attrib.meta_data =
+ htonl(iface_context->iface_id << 16);
+ rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000);
+
rx_intf.num_props++;
if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
rx_prop[IPA_IP_v6].ip = IPA_IP_v6;
- rx_prop[IPA_IP_v6].src_pipe = IPA_CLIENT_WLAN1_PROD;
+ rx_prop[IPA_IP_v6].src_pipe = iface_context->prod_client;
+
+ rx_prop[IPA_IP_v4].attrib.attrib_mask = IPA_FLT_META_DATA;
+ rx_prop[IPA_IP_v4].attrib.meta_data =
+ htonl(iface_context->iface_id << 16);
+ rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000);
+
rx_intf.num_props++;
}
tx_prop[IPA_IP_v4].ip = IPA_IP_v4;
- tx_prop[IPA_IP_v4].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]];
- strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name, IPA_RESOURCE_NAME_MAX);
+ tx_prop[IPA_IP_v4].dst_pipe = iface_context->cons_client;
+ strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name,
+ IPA_RESOURCE_NAME_MAX);
tx_intf.num_props++;
+
if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
tx_prop[IPA_IP_v6].ip = IPA_IP_v6;
- tx_prop[IPA_IP_v6].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]];
+ tx_prop[IPA_IP_v6].dst_pipe = iface_context->cons_client;
strlcpy(tx_prop[IPA_IP_v6].hdr_name, ipv6_hdr_name,
- IPA_RESOURCE_NAME_MAX);
+ IPA_RESOURCE_NAME_MAX);
tx_intf.num_props++;
}
@@ -1111,201 +1089,248 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, con
ret = ipa_register_intf(ifname, &tx_intf, &rx_intf);
register_interface_fail:
- adf_os_mem_free(tx_prop);
- adf_os_mem_free(rx_prop);
+ vos_mem_free(tx_prop);
+ vos_mem_free(rx_prop);
return ret;
}
-static int hdd_ipa_add_header_info(enum ipa_wlan_event type, uint8_t sta_id, uint8_t *mac_addr)
+static void hdd_remove_ipa_header(char *name)
{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- char *ifname;
- struct ipa_ioc_add_hdr *ipahdr = NULL;
- int i, ret = -EINVAL;
- hdd_adapter_t *adap_dev;
- struct ol_txrx_pdev_t *pdev;
- struct ol_txrx_vdev_t *vdev;
-
- adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id];
- if (!adap_dev) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "adap_dev NULL");
- goto add_header_info_ctx_fail;
+ struct ipa_ioc_get_hdr hdrlookup;
+ int ret = 0, len;
+ struct ipa_ioc_del_hdr *ipa_hdr;
+
+ vos_mem_zero(&hdrlookup, sizeof(hdrlookup));
+ strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name));
+ ret = ipa_get_hdr(&hdrlookup);
+ if (ret) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Hdr deleted already %s, %d",
+ name, ret);
+ return;
}
- ifname = adap_dev->dev->name;
- for (i = 0; i < HDD_IPA_MAX_PIPE; i++)
- hdd_ipa->pipe_to_vdev[i] = NULL;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "hdl: 0x%x", hdrlookup.hdl);
+ len = sizeof(struct ipa_ioc_del_hdr) + sizeof(struct ipa_hdr_del)*1;
+ ipa_hdr = (struct ipa_ioc_del_hdr *) vos_mem_malloc(len);
+ if (ipa_hdr == NULL) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ipa_hdr allocation failed");
+ return;
+ }
+ ipa_hdr->num_hdls = 1;
+ ipa_hdr->commit = 0;
+ ipa_hdr->hdl[0].hdl = hdrlookup.hdl;
+ ipa_hdr->hdl[0].status = -1;
+ ret = ipa_del_hdr(ipa_hdr);
+ if (ret != 0)
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Delete header failed: %d",
+ ret);
- if (wlan_sta_id_2_hdd_pipe_id[sta_id] == 0xFF) {
- switch (type) {
- case WLAN_AP_CONNECT:
- wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN0_PIPE; /* TODO: need to expand to AP+AP */
- break;
- case WLAN_STA_CONNECT:
- /* Register pipe_to_vdev for STA mode */
- pdev = ((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev)->pvosContext))->pdev_txrx_ctx;
- /* find the "vdev" this STA interface belongs to */
- TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
- if (adf_os_mem_cmp(mac_addr, vdev->mac_addr.raw, IEEE80211_ADDR_LEN) == 0) {
- hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = vdev;
- break;
- }
- }
+ vos_mem_free(ipa_hdr);
+}
- wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN2_PIPE; /* STA Mode */
- break;
- default:
- break;
- }
- }
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, " wlan_sta_id_2_hdd_pipe_id[%d]: %d",
- sta_id, wlan_sta_id_2_hdd_pipe_id[sta_id]);
+static int hdd_ipa_add_header_info(struct hdd_ipa_priv *hdd_ipa,
+ struct hdd_ipa_iface_context *iface_context, uint8_t *mac_addr)
+{
+ hdd_adapter_t *adapter = iface_context->adapter;
+ char *ifname;
+ struct ipa_ioc_add_hdr *ipa_hdr = NULL;
+ int ret = -EINVAL;
+ struct hdd_ipa_tx_hdr *tx_hdr = NULL;
+ ifname = adapter->dev->name;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifindex: %d Add Partial hdr: %s, %p\n",
- sta_id, ifname, mac_addr);
- if (ifname == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifname NULL");
- goto add_header_info_ctx_fail;
- }
+
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Add Partial hdr: %s, %pM",
+ ifname, mac_addr);
/* dynamically allocate the memory to add the hdrs */
- ipahdr = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_add_hdr) +
- sizeof(struct ipa_hdr_add));
- if (!ipahdr) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s: ENOMEM", ifname);
- return -ENOMEM;
+ ipa_hdr = vos_mem_malloc(sizeof(struct ipa_ioc_add_hdr)
+ + sizeof(struct ipa_hdr_add));
+ if (!ipa_hdr) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: ipa_hdr allocation failed", ifname);
+ ret = -ENOMEM;
+ goto end;
}
- ipahdr->commit = 0;
- ipahdr->num_hdrs = 1;
+ ipa_hdr->commit = 0;
+ ipa_hdr->num_hdrs = 1;
+
+ tx_hdr = (struct hdd_ipa_tx_hdr *)ipa_hdr->hdr[0].hdr;
+
/* Set the Source MAC */
- memcpy(ipahdr->hdr[0].hdr, (uint8_t *)&ipa_set_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN);
- memcpy((uint8_t *)(((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->eth.h_source), mac_addr,
- ETH_ALEN);
+ memcpy(tx_hdr, &ipa_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN);
+ memcpy(tx_hdr->eth.h_source, mac_addr, ETH_ALEN);
- snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
- ifname, HDD_IPA_IPV4_NAME_EXT);
- ipahdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
- ipahdr->hdr[0].is_partial = HDD_IPA_WLAN_HDR_PARTIAL;
- ipahdr->hdr[0].hdr_hdl = 0;
+ snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+ ifname, HDD_IPA_IPV4_NAME_EXT);
+ ipa_hdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
+ ipa_hdr->hdr[0].is_partial = 1;
+ ipa_hdr->hdr[0].hdr_hdl = 0;
/* Set the type to IPV4 in the header*/
- ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IP);
+ tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IP);
- ret = ipa_add_hdr(ipahdr);
+ ret = ipa_add_hdr(ipa_hdr);
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s IPv4 fail: %d", ifname
- , ret);
- goto add_header_info_fail;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s IPv4 add hdr failed: %d",
+ ifname, ret);
+ goto end;
}
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv4 hdr_hdl: %x",
- ipahdr->hdr[0].name, ipahdr->hdr[0].hdr_hdl);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv4 hdr_hdl: 0x%x",
+ ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl);
+
if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
- snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
- ifname, HDD_IPA_IPV6_NAME_EXT);
+ snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+ ifname, HDD_IPA_IPV6_NAME_EXT);
+
/* Set the type to IPV6 in the header*/
- ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6);
+ tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6);
+
+ ret = ipa_add_hdr(ipa_hdr);
- ret = ipa_add_hdr(ipahdr);
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
- "%s: IPv6 hdr fail: %d", ifname, ret);
- goto add_header_info_fail;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: IPv6 add hdr failed: %d",
+ ifname, ret);
+ goto clean_ipv4_hdr;
}
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv6 hdr_hdl: %x",
- ipahdr->hdr[0].name, ipahdr->hdr[0].hdr_hdl);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv6 hdr_hdl: 0x%x",
+ ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl);
}
- /* Configure the TX and RX pipes filter rules */
- ret = hdd_ipa_register_interface(hdd_ipa, sta_id, ifname);
-add_header_info_fail:
- adf_os_mem_free(ipahdr);
-add_header_info_ctx_fail:
- return ret;
-}
-
-void hdd_remove_ipa_header(char *name)
-{
- struct ipa_ioc_get_hdr hdrlookup;
- int ret = 0, len;
- struct ipa_ioc_del_hdr *ipahdr;
-
- vos_mem_zero(&hdrlookup, sizeof(hdrlookup));
- strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name));
- ret = ipa_get_hdr(&hdrlookup);
- if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Hdr deleted already %s, %d",
- name, ret);
- return;
- }
+ vos_mem_free(ipa_hdr);
+ return ret;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "hdl: %x", hdrlookup.hdl);
- len = sizeof(struct ipa_ioc_del_hdr) + sizeof(struct ipa_hdr_del)*1;
- ipahdr = (struct ipa_ioc_del_hdr *) hdd_ipa_kzalloc(len);
- if (ipahdr == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM");
- return;
- }
- ipahdr->num_hdls = 1;
- ipahdr->commit = 0;
- ipahdr->hdl[0].hdl = hdrlookup.hdl;
- ipahdr->hdl[0].status = -1;
- ret = ipa_del_hdr(ipahdr);
- if (ret != 0)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Fail: %d", ret);
+clean_ipv4_hdr:
+ snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+ ifname, HDD_IPA_IPV4_NAME_EXT);
+ hdd_remove_ipa_header(ipa_hdr->hdr[0].name);
+end:
+ if(ipa_hdr)
+ vos_mem_free(ipa_hdr);
- adf_os_mem_free(ipahdr);
+ return ret;
}
-void hdd_ipa_clean_hdr(hdd_adapter_t *adap_dev, uint8_t sta_id)
+static void hdd_ipa_clean_hdr(hdd_adapter_t *adapter)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
int ret;
char name_ipa[IPA_RESOURCE_NAME_MAX];
- wlan_sta_id_2_hdd_pipe_id[sta_id] = 0xFF;
-
/* Remove the headers */
snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
- adap_dev->dev->name, HDD_IPA_IPV4_NAME_EXT);
+ adapter->dev->name, HDD_IPA_IPV4_NAME_EXT);
hdd_remove_ipa_header(name_ipa);
if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
- adap_dev->dev->name, HDD_IPA_IPV6_NAME_EXT);
+ adapter->dev->name, HDD_IPA_IPV6_NAME_EXT);
hdd_remove_ipa_header(name_ipa);
}
/* unregister the interface with IPA */
- ret = ipa_deregister_intf(adap_dev->dev->name);
+ ret = ipa_deregister_intf(adapter->dev->name);
if (ret)
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
- "%s: ipa_deregister_intf fail: %d", adap_dev->dev->name, ret);
+ "%s: ipa_deregister_intf fail: %d",
+ adapter->dev->name, ret);
+}
+
+static void hdd_ipa_cleanup_iface(struct hdd_ipa_priv *hdd_ipa,
+ struct hdd_ipa_iface_context *iface_context)
+{
+ hdd_ipa_clean_hdr(iface_context->adapter);
+
+ iface_context->adapter->ipa_context = NULL;
+ iface_context->adapter = NULL;
+ iface_context->tl_context = NULL;
+}
+
+
+static int hdd_ipa_setup_iface(struct hdd_ipa_priv *hdd_ipa,
+ hdd_adapter_t *adapter, uint8_t sta_id)
+{
+ struct hdd_ipa_iface_context *iface_context = NULL;
+ void *tl_context = NULL;
+ int i, ret = 0;
+
+ for (i = 0; i < HDD_IPA_MAX_IFACE; i++) {
+ if (hdd_ipa->iface_context[i].adapter == NULL) {
+ iface_context = &hdd_ipa->iface_context[i];
+ break;
+ }
+ }
+
+ if (iface_context == NULL) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "All the IPA interfaces are in use");
+ ret = -ENOMEM;
+ goto end;
+ }
+
+
+ adapter->ipa_context = iface_context;
+ iface_context->adapter = adapter;
+ iface_context->sta_id = sta_id;
+ tl_context = tl_shim_get_vdev_by_sta_id(hdd_ipa->hdd_ctx->pvosContext,
+ sta_id);
+
+ if (tl_context == NULL) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "Not able to get TL context sta_id: %d",
+ sta_id);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ iface_context->tl_context = tl_context;
+
+ ret = hdd_ipa_add_header_info(hdd_ipa, iface_context,
+ adapter->dev->dev_addr);
+
+ if (ret)
+ goto end;
+
+ /* Configure the TX and RX pipes filter rules */
+ ret = hdd_ipa_register_interface(hdd_ipa, iface_context);
+ if (ret)
+ goto cleanup_header;
+
+ return ret;
+
+cleanup_header:
+
+ hdd_ipa_clean_hdr(adapter);
+end:
+ if (iface_context)
+ hdd_ipa_cleanup_iface(hdd_ipa, iface_context);
+ return ret;
}
static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type)
{
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "msg type:%d, len:%d\n", type, len);
- adf_os_mem_free(buff);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "msg type:%d, len:%d", type, len);
+ ghdd_ipa->stats.free_msg++;
+ vos_mem_free(buff);
}
-int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
+int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
enum ipa_wlan_event type, uint8_t *mac_addr)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- hdd_adapter_t *adap_dev = Adapter;
struct ipa_msg_meta meta;
struct ipa_wlan_msg *msg;
struct ipa_wlan_msg_ex *msg_ex = NULL;
int ret;
- const char *hdd_ipa_event_name[IPA_EVENT_MAX] = {
+ const char *hdd_ipa_event_name[IPA_WLAN_EVENT_MAX] = {
__stringify(WLAN_CLIENT_CONNECT),
__stringify(WLAN_CLIENT_DISCONNECT),
__stringify(WLAN_CLIENT_POWER_SAVE_MODE),
@@ -1318,69 +1343,67 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
__stringify(WLAN_STA_DISCONNECT),
__stringify(WLAN_CLIENT_CONNECT_EX),
};
- struct ol_txrx_peer_t *peer;
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: %s evt, MAC: %pM sta_id: %d",
- adap_dev->dev->name, hdd_ipa_event_name[type],
- mac_addr, sta_id);
- if (type >= IPA_EVENT_MAX)
+ adapter->dev->name, hdd_ipa_event_name[type], mac_addr,
+ sta_id);
+
+ if (type >= IPA_WLAN_EVENT_MAX)
return -EINVAL;
if (WARN_ON(is_zero_ether_addr(mac_addr)))
return -EINVAL;
+ hdd_ipa->stats.event[type]++;
+
switch (type) {
case WLAN_STA_CONNECT:
case WLAN_AP_CONNECT:
- hdd_ipa_add_header_info(type, sta_id, mac_addr);
+ ret = hdd_ipa_setup_iface(hdd_ipa, adapter, sta_id);
+ if (ret)
+ goto end;
break;
case WLAN_STA_DISCONNECT:
- hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = NULL;
case WLAN_AP_DISCONNECT:
- hdd_ipa_clean_hdr(adap_dev, sta_id);
+ hdd_ipa_cleanup_iface(hdd_ipa,
+ adapter->ipa_context);
break;
case WLAN_CLIENT_CONNECT_EX:
- /* Register pipe map to txrx_vdev into hdd_ipa */
- peer = ol_txrx_peer_find_by_local_id(((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev))->pvosContext)->pdev_txrx_ctx, sta_id);
- if (!peer) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid peer");
- return -EINVAL;
- }
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%d %d", adap_dev->dev->ifindex, sta_id);
- if (hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] == NULL) {
- hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = peer->vdev; /* TODO: need to expand to AP+AP */
- }
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%d %d",
+ adapter->dev->ifindex, sta_id);
meta.msg_type = type;
meta.msg_len = (sizeof(struct ipa_wlan_msg_ex) +
sizeof(struct ipa_wlan_hdr_attrib_val));
- msg_ex = hdd_ipa_kzalloc (meta.msg_len);
+ msg_ex = vos_mem_malloc (meta.msg_len);
+
if (msg_ex == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "msg_ex allocation failed");
return -ENOMEM;
}
- strlcpy(msg_ex->name, adap_dev->dev->name, IPA_RESOURCE_NAME_MAX);
+ strlcpy(msg_ex->name, adapter->dev->name,
+ IPA_RESOURCE_NAME_MAX);
msg_ex->num_of_attribs = 1;
msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
msg_ex->attribs[0].offset = HDD_IPA_WLAN_HDR_DES_MAC_OFFSET;
memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr,
- IPA_MAC_ADDR_SIZE);
+ IPA_MAC_ADDR_SIZE);
ret = ipa_send_msg(&meta, msg_ex, hdd_ipa_msg_free_fn);
if (ret) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d : %d",
msg_ex->name, meta.msg_type, ret);
- adf_os_mem_free(msg_ex);
+ vos_mem_free(msg_ex);
return ret;
}
+ hdd_ipa->stats.send_msg++;
+
return 0;
case WLAN_CLIENT_DISCONNECT:
- /* TODO: need to expand to AP+AP */
- /* This will remove the vdev for rest of the connected clients */
- //hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = NULL;
break;
default:
@@ -1388,30 +1411,59 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
}
meta.msg_len = sizeof(struct ipa_wlan_msg);
- msg = hdd_ipa_kzalloc(meta.msg_len);
+ msg = vos_mem_malloc(meta.msg_len);
if (msg == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "msg allocation failed");
return -ENOMEM;
}
meta.msg_type = type;
- strlcpy(msg->name, adap_dev->dev->name, IPA_RESOURCE_NAME_MAX);
+ strlcpy(msg->name, adapter->dev->name, IPA_RESOURCE_NAME_MAX);
memcpy(msg->mac_addr, mac_addr, ETH_ALEN);
+
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d",
msg->name, meta.msg_type);
+
ret = ipa_send_msg(&meta, msg, hdd_ipa_msg_free_fn);
if (ret) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d fail:%d",
msg->name, meta.msg_type, ret);
- adf_os_mem_free(msg);
+ vos_mem_free(msg);
return ret;
}
+ hdd_ipa->stats.send_msg++;
+
+end:
return ret;
}
+static void hdd_ipa_rx_pipe_desc_free(void)
+{
+ struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
+ uint32_t i = 0, max_desc_cnt;
+ struct ipa_tx_data_desc *desc, *tmp;
+
+ max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO;
+
+ spin_lock_bh(&hdd_ipa->q_lock);
+ list_for_each_entry_safe(desc, tmp, &hdd_ipa->free_desc_head, link) {
+ list_del(&desc->link);
+ spin_unlock_bh(&hdd_ipa->q_lock);
+ vos_mem_free(desc);
+ spin_lock_bh(&hdd_ipa->q_lock);
+ i++;
+ }
+ spin_unlock_bh(&hdd_ipa->q_lock);
+
+ if (i != max_desc_cnt)
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "free desc leak");
+
+}
+
+
static int hdd_ipa_rx_pipe_desc_alloc(void)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
@@ -1424,46 +1476,34 @@ static int hdd_ipa_rx_pipe_desc_alloc(void)
max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO;
spin_lock_init(&hdd_ipa->q_lock);
- spin_lock_bh(&hdd_ipa->q_lock);
+
INIT_LIST_HEAD(&hdd_ipa->free_desc_head);
INIT_LIST_HEAD(&hdd_ipa->pend_desc_head);
hdd_ipa->stats.freeq_cnt = max_desc_cnt;
for (i = 0; i < max_desc_cnt; i++) {
- tmp_desc = hdd_ipa_kzalloc(sizeof(struct
+ tmp_desc = vos_mem_malloc(sizeof(struct
ipa_tx_data_desc));
if (!tmp_desc) {
- ret = -1;
- break;
+ ret = -ENOMEM;
+
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "Descriptor allocation failed\n");
+ goto fail;
}
+ spin_lock_bh(&hdd_ipa->q_lock);
list_add_tail(&tmp_desc->link, &hdd_ipa->free_desc_head);
+ spin_unlock_bh(&hdd_ipa->q_lock);
}
- spin_unlock_bh(&hdd_ipa->q_lock);
+
+
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
"Desc sz:%d h_desc_cnt:%d freeq_cnt:%llu",
hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize, hdd_ipa->hw_desc_cnt,
hdd_ipa->stats.freeq_cnt);
return ret;
-}
-
-static void hdd_ipa_rx_pipe_desc_free(void)
-{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- uint32_t i = 0, max_desc_cnt;
- struct ipa_tx_data_desc *desc, *tmp;
-
- max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO;
-
- spin_lock_bh(&hdd_ipa->q_lock);
- list_for_each_entry_safe(desc, tmp, &hdd_ipa->free_desc_head, link) {
- list_del(&desc->link);
- adf_os_mem_free(desc);
- i++;
- }
- spin_unlock_bh(&hdd_ipa->q_lock);
-
- if (i != max_desc_cnt)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "free mem leak");
-
+fail:
+ hdd_ipa_rx_pipe_desc_free();
+ return ret;
}
static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file,
@@ -1573,7 +1613,7 @@ static const struct file_operations fops_ipa_stats = {
};
-int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa)
+static int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa)
{
#ifdef WLAN_OPEN_SOURCE
hdd_ipa->debugfs_dir = debugfs_create_dir("cld",
@@ -1587,6 +1627,13 @@ int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa)
return 0;
}
+static void hdd_ipa_debugfs_remove(struct hdd_ipa_priv *hdd_ipa)
+{
+#ifdef WLAN_OPEN_SOURCE
+ debugfs_remove_recursive(hdd_ipa->debugfs_dir);
+#endif
+}
+
/**
* hdd_ipa_init() - Allocate hdd_ipa resources, ipa pipe resource and register
* wlan interface with IPA module.
@@ -1599,21 +1646,31 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
{
struct hdd_ipa_priv *hdd_ipa = NULL;
int ret, i;
- if (!hdd_ipa_is_enabled(hdd_ctx))
- return 0;
+ struct hdd_ipa_iface_context *iface_context = NULL;
- for (i = 0; i < HDD_IPA_WLAN_MAX_STA_ID; i++)
- wlan_sta_id_2_hdd_pipe_id[i] = 0xFF;
+ if (!hdd_ipa_is_enabled(hdd_ctx))
+ return VOS_STATUS_SUCCESS;
- hdd_ipa = hdd_ipa_kzalloc(sizeof(struct hdd_ipa_priv));
+ hdd_ipa = vos_mem_malloc(sizeof(struct hdd_ipa_priv));
if (!hdd_ipa) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "hdd_ipa allocation failed");
goto fail_setup_rm;
}
hdd_ctx->hdd_ipa = hdd_ipa;
ghdd_ipa = hdd_ipa;
hdd_ipa->hdd_ctx = hdd_ctx;
+ /* Create the interface context */
+ for (i = 0; i < HDD_IPA_MAX_IFACE; i++) {
+ iface_context = &hdd_ipa->iface_context[i];
+ iface_context->hdd_ipa = hdd_ipa;
+ iface_context->cons_client =
+ hdd_ipa_adapter_2_client[i].cons_client;
+ iface_context->prod_client =
+ hdd_ipa_adapter_2_client[i].prod_client;
+ iface_context->iface_id = i;
+ }
+
ret = hdd_ipa_setup_rm(hdd_ipa);
if (ret)
goto fail_setup_rm;
@@ -1622,8 +1679,6 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
if (ret)
goto fail_create_sys_pipe;
- atomic_set(&hdd_ipa->rm_state, HDD_IPA_RM_RELEASED);
-
ret = hdd_ipa_rx_pipe_desc_alloc();
if (ret)
goto fail_alloc_rx_pipe_desc;
@@ -1632,17 +1687,21 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
if (ret)
goto fail_alloc_rx_pipe_desc;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "IPA Init Done");
#ifndef HDD_IPA_USE_IPA_RM_TIMER
setup_timer(&hdd_ipa->rm_timer, hdd_ipa_rm_timer_handler,
(unsigned long) &hdd_ipa);
#endif
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "IPA Init Done");
+
return VOS_STATUS_SUCCESS;
fail_alloc_rx_pipe_desc:
hdd_ipa_rx_pipe_desc_free();
fail_create_sys_pipe:
hdd_ipa_destory_rm_resource(hdd_ipa);
fail_setup_rm:
+ if (hdd_ipa)
+ vos_mem_free(hdd_ipa);
+
return VOS_STATUS_E_FAILURE;
}
@@ -1653,6 +1712,8 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx)
if (!hdd_ipa_is_enabled(hdd_ctx))
return VOS_STATUS_SUCCESS;
+ hdd_ipa_debugfs_remove(hdd_ipa);
+
#ifndef HDD_IPA_USE_IPA_RM_TIMER
del_timer(&hdd_ipa->rm_timer);
#endif
@@ -1664,73 +1725,9 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx)
hdd_ipa_teardown_sys_pipe(hdd_ipa);
hdd_ipa_destory_rm_resource(hdd_ipa);
- adf_os_mem_free(hdd_ctx->hdd_ipa);
+ vos_mem_free(hdd_ipa);
+ hdd_ctx->hdd_ipa = NULL;
return VOS_STATUS_SUCCESS;
}
-
-#if 0
-/**
-* hdd_ipa_start_xmit() - This is a hack code for IPA loopback test
-*/
-int hdd_ipa_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
- hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
- uint8_t sta_id;
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
-
- v_MACADDR_t *pDestMacAddress = (v_MACADDR_t *)skb->data;
-
- if (vos_is_macaddr_broadcast(pDestMacAddress) ||
- vos_is_macaddr_group(pDestMacAddress)) {
- /* The BC/MC station ID is assigned during BSS starting phase.
- SAP will return the station ID used for BC/MC traffic. */
- sta_id = pHddApCtx->uBCStaId;
- hdd_softap_hard_start_xmit(skb, dev);
- return NETDEV_TX_OK;
- } else {
- sta_id = *(uint8_t *)(((uint8_t *)(skb->data)) - 1);
- if (sta_id == HDD_WLAN_INVALID_STA_ID) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "Failed to find right station");
- goto drop_pkt;
- } else if (FALSE == pAdapter->aStaInfo[sta_id].isUsed) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "STA %d is unregistered", sta_id);
- goto drop_pkt;
- }
-
- if ((WLANTL_STA_CONNECTED !=
- pAdapter->aStaInfo[sta_id].tlSTAState) &&
- (WLANTL_STA_AUTHENTICATED !=
- pAdapter->aStaInfo[sta_id].tlSTAState)) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "Station not connected yet");
- goto drop_pkt;
- } else if (WLANTL_STA_CONNECTED ==
- pAdapter->aStaInfo[sta_id].tlSTAState) {
- if (ntohs(skb->protocol) !=
- HDD_ETHERTYPE_802_1_X) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "NON-EAPOL packet in no-Auth state");
- goto drop_pkt;
- }
- }
- }
- if (hdd_ipa_is_ip_pkt(skb->data, HDD_IPA_IPV4)) {
- /* TX frame Counter at HDD entry from kernel network stack, before give frame to IPA Loopback */
- hdd_ipa->stats.ipa_lb_cnt++;
- ipa_tx_dp(IPA_CLIENT_WLAN1_CONS, skb, NULL);
- } else {
- hdd_softap_hard_start_xmit(skb, dev);
- }
-
- return NETDEV_TX_OK;
-drop_pkt:
- kfree_skb(skb);
- return NETDEV_TX_OK;
-}
-#endif
-
#endif
diff --git a/CORE/VOSS/src/vos_trace.c b/CORE/VOSS/src/vos_trace.c
index 5b5f33562506..ea81ece70c25 100644
--- a/CORE/VOSS/src/vos_trace.c
+++ b/CORE/VOSS/src/vos_trace.c
@@ -388,10 +388,15 @@ void vos_trace_hex_dump( VOS_MODULE_ID module, VOS_TRACE_LEVEL level,
{
char *buf = (char *)data;
int i;
+
+ if (!(gVosTraceInfo[module].moduleTraceLevel &
+ VOS_TRACE_LEVEL_TO_MODULE_BITMASK(level)))
+ return;
+
for (i=0; (i+7)<buf_len; i+=8)
{
vos_trace_msg( module, level,
- "%02x %02x %02x %02x %02x %02x %02x %02x \n",
+ "%02x %02x %02x %02x %02x %02x %02x %02x",
buf[i],
buf[i+1],
buf[i+2],