qcacmn: Add core\utils directory and files to qcacmn

As a part of UMAC convergence, move the core\utils logging to qcacmn.

CRs-Fixed: 1109855
Change-Id: I499a392f74f3e52e99df4d03e4a27bce6cf5be7c
Šī revīzija ir iekļauta:
Srinivas Girigowda
2017-02-16 16:04:29 -08:00
revīziju iesūtīja qcabuildsw
vecāks 6195152790
revīzija 60644c29e6
30 mainīti faili ar 15592 papildinājumiem un 0 dzēšanām

Parādīt failu

@@ -0,0 +1,199 @@
/*
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* 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.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
#ifndef EPPING_INTERNAL_H
#define EPPING_INTERNAL_H
/**===========================================================================
\file epping_internal.h
\brief Linux epping internal head file
==========================================================================*/
/*---------------------------------------------------------------------------
Include files
-------------------------------------------------------------------------*/
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/kthread.h>
#include <linux/semaphore.h>
#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK)
#include <linux/wakelock.h>
#endif
#include "htc_api.h"
#include "htc_packet.h"
#include "epping_test.h"
#include <qdf_atomic.h>
#include <sir_mac_prot_def.h>
#include <sir_debug.h>
#define EPPING_LOG_MASK (1<<EPPING_CMD_CAPTURE_RECV_CNT)
#define EPPING_STATS_LOG_COUNT 50000
#define EPPING_KTID_KILL_WAIT_TIME_MS 50
#define EPPING_FRAG_PER_MSDU 1
#ifndef EPPING_TXBUF
#define EPPING_TXBUF (512/EPPING_FRAG_PER_MSDU)
#endif
/*---------------------------------------------------------------------------
Preprocessor definitions and constants
-------------------------------------------------------------------------*/
#define EPPING_MAX_ADAPTERS 1
#define EPPING_LOG(level, args ...) QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args)
struct epping_cookie {
HTC_PACKET HtcPkt; /* HTC packet wrapper */
struct epping_cookie *next;
};
typedef enum {
EPPING_CTX_STATE_INITIAL = 0,
EPPING_CTX_STATE_HIF_INIT,
EPPING_CTX_STATE_STARTUP,
EPPING_CTX_STATE_STARTED,
EPPING_CTX_STATE_STOP
} epping_ctx_state_t;
#define EPPING_MAX_NUM_EPIDS 4
#define MAX_COOKIE_SLOTS_NUM 4
#define MAX_COOKIE_SLOT_SIZE 512
#define MAX_TX_PKT_DUP_NUM 4
#ifdef HIF_PCI
#define WLAN_EPPING_DELAY_TIMEOUT_US 10
#define EPPING_MAX_CE_NUMS 8
#define EPPING_MAX_WATER_MARK 8
typedef struct {
struct task_struct *pid;
void *arg;
bool done;
qdf_nbuf_t skb;
HTC_ENDPOINT_ID eid;
struct semaphore sem;
bool inited;
qdf_atomic_t atm;
} epping_poll_t;
#endif
typedef struct epping_context {
int32_t con_mode;
char *pwlan_module_name;
uint32_t target_type;
void *p_cds_context; /* CDS context */
struct device *parent_dev; /* Pointer to the parent device */
epping_ctx_state_t e_ctx_state;
bool wow_nack;
void *epping_adapter;
HTC_HANDLE HTCHandle;
HTC_ENDPOINT_ID EppingEndpoint[EPPING_MAX_NUM_EPIDS];
unsigned int kperf_num_rx_recv[EPPING_MAX_NUM_EPIDS];
unsigned int kperf_num_tx_acks[EPPING_MAX_NUM_EPIDS];
unsigned int total_rx_recv;
unsigned int total_tx_acks;
#ifdef HIF_PCI
epping_poll_t epping_poll[EPPING_MAX_NUM_EPIDS];
#endif
struct epping_cookie *cookie_list;
int cookie_count;
struct epping_cookie *s_cookie_mem[MAX_COOKIE_SLOTS_NUM];
qdf_spinlock_t cookie_lock;
} epping_context_t;
typedef enum {
EPPING_TX_TIMER_STOPPED,
EPPING_TX_TIMER_RUNNING
} epping_tx_timer_state_t;
typedef struct epping_adapter_s {
epping_context_t *pEpping_ctx;
enum tQDF_ADAPTER_MODE device_mode;
/** Handle to the network device */
struct net_device *dev;
struct qdf_mac_addr macAddressCurrent;
uint8_t sessionId;
/* for mboxping */
qdf_spinlock_t data_lock;
qdf_nbuf_queue_t nodrop_queue;
qdf_timer_t epping_timer;
epping_tx_timer_state_t epping_timer_state;
bool registered;
bool started;
struct net_device_stats stats;
} epping_adapter_t;
/* epping_helper signatures */
int epping_cookie_init(epping_context_t *pEpping_ctx);
void epping_cookie_cleanup(epping_context_t *pEpping_ctx);
void epping_free_cookie(epping_context_t *pEpping_ctx,
struct epping_cookie *cookie);
struct epping_cookie *epping_alloc_cookie(epping_context_t *pEpping_ctx);
void epping_get_dummy_mac_addr(tSirMacAddr macAddr);
void epping_hex_dump(void *data, int buf_len, const char *str);
void *epping_get_qdf_ctx(void);
void epping_log_packet(epping_adapter_t *pAdapter,
EPPING_HEADER *eppingHdr, int ret, const char *str);
void epping_log_stats(epping_adapter_t *pAdapter, const char *str);
void epping_set_kperf_flag(epping_adapter_t *pAdapter,
HTC_ENDPOINT_ID eid, A_UINT8 kperf_flag);
/* epping_tx signatures */
void epping_tx_timer_expire(epping_adapter_t *pAdapter);
void epping_tx_complete_multiple(void *ctx, HTC_PACKET_QUEUE *pPacketQueue);
int epping_tx_send(qdf_nbuf_t skb, epping_adapter_t *pAdapter);
#ifdef HIF_SDIO
HTC_SEND_FULL_ACTION epping_tx_queue_full(void *Context, HTC_PACKET *pPacket);
#endif
void epping_tx_dup_pkt(epping_adapter_t *pAdapter,
HTC_ENDPOINT_ID eid, qdf_nbuf_t skb);
/* epping_rx signatures */
void epping_rx(void *Context, HTC_PACKET *pPacket);
#ifdef HIF_SDIO
void epping_refill(void *ctx, HTC_ENDPOINT_ID Endpoint);
#endif
/* epping_txrx signatures */
epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx,
tSirMacAddr macAddr,
enum tQDF_ADAPTER_MODE device_mode);
void epping_destroy_adapter(epping_adapter_t *pAdapter);
int epping_connect_service(epping_context_t *pEpping_ctx);
#ifdef HIF_PCI
void epping_register_tx_copier(HTC_ENDPOINT_ID eid,
epping_context_t *pEpping_ctx);
void epping_unregister_tx_copier(HTC_ENDPOINT_ID eid,
epping_context_t *pEpping_ctx);
void epping_tx_copier_schedule(epping_context_t *pEpping_ctx,
HTC_ENDPOINT_ID eid, qdf_nbuf_t skb);
#endif /* HIF_PCI */
#endif /* end #ifndef EPPING_INTERNAL_H */

Parādīt failu

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* 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.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
#ifndef EPPING_MAIN_H
#define EPPING_MAIN_H
/**===========================================================================
\file epping_main.h
\brief Linux epping head file
==========================================================================*/
/*---------------------------------------------------------------------------
Include files
-------------------------------------------------------------------------*/
#include <qdf_lock.h>
#include <qdf_types.h>
/* epping_main signatures */
int epping_open(void);
void epping_close(void);
void epping_disable(void);
int epping_enable(struct device *parent_dev);
#endif /* end #ifndef EPPING_MAIN_H */

Parādīt failu

@@ -0,0 +1,210 @@
/*
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* 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.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/*========================================================================
\file epping_main.c
\brief WLAN End Point Ping test tool implementation
========================================================================*/
/*--------------------------------------------------------------------------
Include Files
------------------------------------------------------------------------*/
#include <cds_api.h>
#include <cds_sched.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <wni_api.h>
#include <wlan_ptt_sock_svc.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <linux/rtnetlink.h>
#include <linux/semaphore.h>
#include <linux/delay.h>
#include <linux/ctype.h>
#include "epping_main.h"
#include "epping_internal.h"
int epping_cookie_init(epping_context_t *pEpping_ctx)
{
A_UINT32 i, j;
pEpping_ctx->cookie_list = NULL;
pEpping_ctx->cookie_count = 0;
for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) {
pEpping_ctx->s_cookie_mem[i] =
qdf_mem_malloc(sizeof(struct epping_cookie) *
MAX_COOKIE_SLOT_SIZE);
if (pEpping_ctx->s_cookie_mem[i] == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: no mem for cookie (idx = %d)", __func__,
i);
goto error;
}
}
qdf_spinlock_create(&pEpping_ctx->cookie_lock);
for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) {
struct epping_cookie *cookie_mem = pEpping_ctx->s_cookie_mem[i];
for (j = 0; j < MAX_COOKIE_SLOT_SIZE; j++) {
epping_free_cookie(pEpping_ctx, &cookie_mem[j]);
}
}
return 0;
error:
for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) {
if (pEpping_ctx->s_cookie_mem[i]) {
qdf_mem_free(pEpping_ctx->s_cookie_mem[i]);
pEpping_ctx->s_cookie_mem[i] = NULL;
}
}
return -ENOMEM;
}
/* cleanup cookie queue */
void epping_cookie_cleanup(epping_context_t *pEpping_ctx)
{
int i;
qdf_spin_lock_bh(&pEpping_ctx->cookie_lock);
pEpping_ctx->cookie_list = NULL;
pEpping_ctx->cookie_count = 0;
qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock);
for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) {
if (pEpping_ctx->s_cookie_mem[i]) {
qdf_mem_free(pEpping_ctx->s_cookie_mem[i]);
pEpping_ctx->s_cookie_mem[i] = NULL;
}
}
}
void epping_free_cookie(epping_context_t *pEpping_ctx,
struct epping_cookie *cookie)
{
qdf_spin_lock_bh(&pEpping_ctx->cookie_lock);
cookie->next = pEpping_ctx->cookie_list;
pEpping_ctx->cookie_list = cookie;
pEpping_ctx->cookie_count++;
qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock);
}
struct epping_cookie *epping_alloc_cookie(epping_context_t *pEpping_ctx)
{
struct epping_cookie *cookie;
qdf_spin_lock_bh(&pEpping_ctx->cookie_lock);
cookie = pEpping_ctx->cookie_list;
if (cookie != NULL) {
pEpping_ctx->cookie_list = cookie->next;
pEpping_ctx->cookie_count--;
}
qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock);
return cookie;
}
void epping_get_dummy_mac_addr(tSirMacAddr macAddr)
{
macAddr[0] = 69; /* E */
macAddr[1] = 80; /* P */
macAddr[2] = 80; /* P */
macAddr[3] = 73; /* I */
macAddr[4] = 78; /* N */
macAddr[5] = 71; /* G */
}
void epping_hex_dump(void *data, int buf_len, const char *str)
{
char *buf = (char *)data;
int i;
printk("%s: E, %s\n", __func__, str);
for (i = 0; (i + 7) < buf_len; i += 8) {
printk("%02x %02x %02x %02x %02x %02x %02x %02x\n",
buf[i],
buf[i + 1],
buf[i + 2],
buf[i + 3],
buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
}
/* Dump the bytes in the last line */
for (; i < buf_len; i++) {
printk("%02x ", buf[i]);
}
printk("\n%s: X %s\n", __func__, str);
}
void *epping_get_qdf_ctx(void)
{
qdf_device_t *qdf_ctx;
qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
return qdf_ctx;
}
void epping_log_packet(epping_adapter_t *pAdapter,
EPPING_HEADER *eppingHdr, int ret, const char *str)
{
if (eppingHdr->Cmd_h & EPPING_LOG_MASK) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: cmd = %d, seqNo = %u, flag = 0x%x, ret = %d, "
"txCount = %lu, txDrop = %lu, txBytes = %lu,"
"rxCount = %lu, rxDrop = %lu, rxBytes = %lu\n",
str, eppingHdr->Cmd_h, eppingHdr->SeqNo,
eppingHdr->CmdFlags_h, ret,
pAdapter->stats.tx_packets,
pAdapter->stats.tx_dropped,
pAdapter->stats.tx_bytes,
pAdapter->stats.rx_packets,
pAdapter->stats.rx_dropped,
pAdapter->stats.rx_bytes);
}
}
void epping_log_stats(epping_adapter_t *pAdapter, const char *str)
{
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: txCount = %lu, txDrop = %lu, tx_bytes = %lu, "
"rxCount = %lu, rxDrop = %lu, rx_bytes = %lu, tx_acks = %u\n",
str,
pAdapter->stats.tx_packets,
pAdapter->stats.tx_dropped,
pAdapter->stats.tx_bytes,
pAdapter->stats.rx_packets,
pAdapter->stats.rx_dropped,
pAdapter->stats.rx_bytes,
pAdapter->pEpping_ctx->total_tx_acks);
}
void epping_set_kperf_flag(epping_adapter_t *pAdapter,
HTC_ENDPOINT_ID eid, A_UINT8 kperf_flag)
{
pAdapter->pEpping_ctx->kperf_num_rx_recv[eid] = 0;
pAdapter->pEpping_ctx->kperf_num_tx_acks[eid] = 0;
}

354
utils/epping/src/epping_main.c Parasts fails
Parādīt failu

@@ -0,0 +1,354 @@
/*
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* 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.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/*========================================================================
\file epping_main.c
\brief WLAN End Point Ping test tool implementation
========================================================================*/
/*--------------------------------------------------------------------------
Include Files
------------------------------------------------------------------------*/
#include <cds_api.h>
#include <cds_sched.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <wni_api.h>
#include <wlan_ptt_sock_svc.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <linux/rtnetlink.h>
#include <linux/semaphore.h>
#include <linux/ctype.h>
#include "bmi.h"
#include "ol_fw.h"
#include "ol_if_athvar.h"
#include "hif.h"
#include "epping_main.h"
#include "epping_internal.h"
#include "cds_concurrency.h"
#ifdef TIMER_MANAGER
#define TIMER_MANAGER_STR " +TIMER_MANAGER"
#else
#define TIMER_MANAGER_STR ""
#endif
#ifdef MEMORY_DEBUG
#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
#else
#define MEMORY_DEBUG_STR ""
#endif
#ifdef HIF_SDIO
#define WLAN_WAIT_TIME_WLANSTART 10000
#else
#define WLAN_WAIT_TIME_WLANSTART 2000
#endif
static struct epping_context *g_epping_ctx;
/**
* epping_open(): End point ping driver open Function
*
* This function is called by HDD to open epping module
*
*
* return - 0 for success, negative for failure
*/
int epping_open(void)
{
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
g_epping_ctx = qdf_mem_malloc(sizeof(*g_epping_ctx));
if (g_epping_ctx == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
"%s: cannot alloc epping context", __func__);
return -ENOMEM;
}
g_epping_ctx->con_mode = cds_get_conparam();
return 0;
}
/**
* epping_disable(): End point ping driver disable Function
*
* This is the driver disable function - called by HDD to
* disable epping module
*
* return: none
*/
void epping_disable(void)
{
epping_context_t *pEpping_ctx;
struct hif_opaque_softc *hif_ctx;
HTC_HANDLE htc_handle;
pEpping_ctx = g_epping_ctx;
if (pEpping_ctx == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: error: pEpping_ctx = NULL", __func__);
return;
}
if (pEpping_ctx->epping_adapter) {
epping_destroy_adapter(pEpping_ctx->epping_adapter);
pEpping_ctx->epping_adapter = NULL;
}
hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
if (hif_ctx == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: error: hif_ctx = NULL", __func__);
return;
}
hif_disable_isr(hif_ctx);
hif_reset_soc(hif_ctx);
htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
if (htc_handle == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: error: htc_handle = NULL", __func__);
return;
}
htc_stop(htc_handle);
epping_cookie_cleanup(pEpping_ctx);
htc_destroy(htc_handle);
}
/**
* epping_close(): End point ping driver close Function
*
* This is the driver close function - called by HDD to close epping module
*
* return: none
*/
void epping_close(void)
{
epping_context_t *to_free;
if (g_epping_ctx == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: error: g_epping_ctx = NULL", __func__);
return;
}
to_free = g_epping_ctx;
g_epping_ctx = NULL;
qdf_mem_free(to_free);
}
/**
* epping_target_suspend_acknowledge() - process wow ack/nack from fw
* @context: HTC_INIT_INFO->context
* @wow_nack: true when wow is rejected
*/
static void epping_target_suspend_acknowledge(void *context, bool wow_nack)
{
if (NULL == g_epping_ctx) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: epping_ctx is NULL", __func__);
return;
}
/* EPPING_TODO: do we need wow_nack? */
g_epping_ctx->wow_nack = wow_nack;
}
/**
* epping_update_ol_config - API to update ol configuration parameters
*
* Return: void
*/
static void epping_update_ol_config(void)
{
struct ol_config_info cfg;
struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
if (!ol_ctx)
return;
cfg.enable_self_recovery = 0;
cfg.enable_uart_print = 0;
cfg.enable_fw_log = 0;
cfg.enable_ramdump_collection = 0;
cfg.enable_lpass_support = 0;
ol_init_ini_config(ol_ctx, &cfg);
}
/**
* epping_enable(): End point ping driver enable Function
*
* This is the driver enable function - called by HDD to enable
* epping module
*
* return - 0 : success, negative: error
*/
int epping_enable(struct device *parent_dev)
{
int ret = 0;
epping_context_t *pEpping_ctx = NULL;
cds_context_type *p_cds_context = NULL;
qdf_device_t qdf_ctx;
HTC_INIT_INFO htcInfo;
struct hif_opaque_softc *scn;
tSirMacAddr adapter_macAddr;
struct hif_target_info *tgt_info;
struct ol_context *ol_ctx;
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
p_cds_context = cds_get_global_context();
if (p_cds_context == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: Failed cds_get_global_context", __func__);
ret = -1;
return ret;
}
pEpping_ctx = g_epping_ctx;
if (pEpping_ctx == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: Failed to get pEpping_ctx", __func__);
ret = -1;
return ret;
}
pEpping_ctx->parent_dev = (void *)parent_dev;
epping_get_dummy_mac_addr(adapter_macAddr);
/* Initialize the timer module */
qdf_timer_module_init();
scn = cds_get_context(QDF_MODULE_ID_HIF);
if (!scn) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
"%s: scn is null!", __func__);
return A_ERROR;
}
tgt_info = hif_get_target_info_handle(scn);
/* store target type and target version info in hdd ctx */
pEpping_ctx->target_type = tgt_info->target_type;
ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
if (!ol_ctx) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
"%s: ol_ctx is NULL", __func__);
return A_ERROR;
}
epping_update_ol_config();
#ifndef FEATURE_BMI_2
/* Initialize BMI and Download firmware */
if (bmi_download_firmware(ol_ctx)) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
"%s: BMI failed to download target", __func__);
bmi_cleanup(ol_ctx);
return A_ERROR;
}
#endif
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH,
"%s: bmi_download_firmware done", __func__);
htcInfo.pContext = ol_ctx;
htcInfo.TargetFailure = ol_target_failure;
htcInfo.TargetSendSuspendComplete = epping_target_suspend_acknowledge;
qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
/* Create HTC */
p_cds_context->htc_ctx = htc_create(scn, &htcInfo, qdf_ctx,
cds_get_conparam());
if (!p_cds_context->htc_ctx) {
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
"%s: Failed to Create HTC", __func__);
bmi_cleanup(ol_ctx);
return A_ERROR;
}
pEpping_ctx->HTCHandle =
cds_get_context(QDF_MODULE_ID_HTC);
if (pEpping_ctx->HTCHandle == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: HTCHandle is NULL", __func__);
return A_ERROR;
}
if (bmi_done(ol_ctx)) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: Failed to complete BMI phase", __func__);
goto error_end;
}
/* start HIF */
if (htc_wait_target(pEpping_ctx->HTCHandle) != A_OK) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: htc_wait_target error", __func__);
goto error_end;
}
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC ready", __func__);
ret = epping_connect_service(pEpping_ctx);
if (ret != 0) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: htc_wait_targetdone", __func__);
goto error_end;
}
if (htc_start(pEpping_ctx->HTCHandle) != A_OK) {
goto error_end;
}
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC started", __func__);
/* init the tx cookie resource */
ret = epping_cookie_init(pEpping_ctx);
if (ret == 0) {
pEpping_ctx->epping_adapter = epping_add_adapter(pEpping_ctx,
adapter_macAddr,
QDF_STA_MODE);
}
if (ret < 0 || pEpping_ctx->epping_adapter == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: epping_add_adaptererror error", __func__);
htc_stop(pEpping_ctx->HTCHandle);
epping_cookie_cleanup(pEpping_ctx);
goto error_end;
}
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Exit", __func__);
return ret;
error_end:
htc_destroy(p_cds_context->htc_ctx);
p_cds_context->htc_ctx = NULL;
bmi_cleanup(ol_ctx);
return A_ERROR;
}

162
utils/epping/src/epping_rx.c Parasts fails
Parādīt failu

@@ -0,0 +1,162 @@
/*
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* 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.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/*========================================================================
\file epping_rx.c
\brief WLAN End Point Ping test tool implementation
========================================================================*/
/*--------------------------------------------------------------------------
Include Files
------------------------------------------------------------------------*/
#include <cds_api.h>
#include <cds_sched.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <wni_api.h>
#include <wlan_ptt_sock_svc.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <linux/rtnetlink.h>
#include <linux/semaphore.h>
#include <linux/ctype.h>
#include "epping_main.h"
#include "epping_internal.h"
#include "epping_test.h"
#include <wlan_hdd_napi.h>
#define AR6000_MAX_RX_BUFFERS 16
#define AR6000_BUFFER_SIZE 1664
#define AR6000_MIN_HEAD_ROOM 64
static bool enb_rx_dump;
#ifdef HIF_SDIO
void epping_refill(void *ctx, HTC_ENDPOINT_ID Endpoint)
{
epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
void *osBuf;
int RxBuffers;
int buffersToRefill;
HTC_PACKET *pPacket;
HTC_PACKET_QUEUE queue;
buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
htc_get_num_recv_buffers(pEpping_ctx->HTCHandle, Endpoint);
if (buffersToRefill <= 0) {
/* fast return, nothing to fill */
return;
}
INIT_HTC_PACKET_QUEUE(&queue);
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
"%s: providing htc with %d buffers at eid=%d\n",
__func__, buffersToRefill, Endpoint);
for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
osBuf = qdf_nbuf_alloc(NULL, AR6000_BUFFER_SIZE,
AR6000_MIN_HEAD_ROOM, 4, false);
if (NULL == osBuf) {
break;
}
/* the HTC packet wrapper is at the head of the reserved area
* in the skb */
pPacket = (HTC_PACKET *) (A_NETBUF_HEAD(osBuf));
/* set re-fill info */
SET_HTC_PACKET_INFO_RX_REFILL(pPacket, osBuf,
qdf_nbuf_data(osBuf),
AR6000_BUFFER_SIZE, Endpoint);
SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, osBuf);
/* add to queue */
HTC_PACKET_ENQUEUE(&queue, pPacket);
}
if (!HTC_QUEUE_EMPTY(&queue)) {
/* add packets */
htc_add_receive_pkt_multiple(pEpping_ctx->HTCHandle, &queue);
}
}
#endif /* HIF_SDIO */
void epping_rx(void *ctx, HTC_PACKET *pPacket)
{
epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter;
struct net_device *dev = pAdapter->dev;
A_STATUS status = pPacket->Status;
HTC_ENDPOINT_ID eid = pPacket->Endpoint;
struct sk_buff *pktSkb = (struct sk_buff *)pPacket->pPktContext;
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
"%s: pAdapter = 0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d",
__func__, pAdapter, eid, pktSkb, pPacket->pBuffer,
pPacket->ActualLength, status);
if (status != A_OK) {
if (status != A_ECANCELED) {
printk("%s: RX ERR (%d)\n", __func__, status);
}
qdf_nbuf_free(pktSkb);
return;
}
/* deliver to up layer */
if (pktSkb) {
if (EPPING_ALIGNMENT_PAD > 0) {
A_NETBUF_PULL(pktSkb, EPPING_ALIGNMENT_PAD);
}
if (enb_rx_dump)
epping_hex_dump((void *)qdf_nbuf_data(pktSkb),
pktSkb->len, __func__);
pktSkb->dev = dev;
if ((pktSkb->dev->flags & IFF_UP) == IFF_UP) {
pktSkb->protocol = eth_type_trans(pktSkb, pktSkb->dev);
++pAdapter->stats.rx_packets;
pAdapter->stats.rx_bytes += pktSkb->len;
qdf_net_buf_debug_release_skb(pktSkb);
if (hdd_napi_enabled(HDD_NAPI_ANY))
netif_receive_skb(pktSkb);
else
netif_rx_ni(pktSkb);
if ((pAdapter->stats.rx_packets %
EPPING_STATS_LOG_COUNT) == 0) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: total_rx_pkts = %lu",
__func__,
pAdapter->stats.rx_packets);
}
} else {
++pAdapter->stats.rx_dropped;
qdf_nbuf_free(pktSkb);
}
}
}

405
utils/epping/src/epping_tx.c Parasts fails
Parādīt failu

@@ -0,0 +1,405 @@
/*
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* 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.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/*========================================================================
\file epping_tx.c
\brief WLAN End Point Ping test tool implementation
========================================================================*/
/*--------------------------------------------------------------------------
Include Files
------------------------------------------------------------------------*/
#include <cds_api.h>
#include <cds_sched.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <wni_api.h>
#include <wlan_ptt_sock_svc.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <linux/rtnetlink.h>
#include <linux/semaphore.h>
#include <linux/ctype.h>
#include "epping_main.h"
#include "epping_internal.h"
#include "epping_test.h"
#define TX_RETRY_TIMEOUT_IN_MS 1
static bool enb_tx_dump;
void epping_tx_dup_pkt(epping_adapter_t *pAdapter,
HTC_ENDPOINT_ID eid, qdf_nbuf_t skb)
{
struct epping_cookie *cookie = NULL;
int skb_len, ret;
qdf_nbuf_t new_skb;
cookie = epping_alloc_cookie(pAdapter->pEpping_ctx);
if (cookie == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: epping_alloc_cookie returns no resource\n",
__func__);
return;
}
new_skb = qdf_nbuf_copy(skb);
if (!new_skb) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: qdf_nbuf_copy returns no resource\n", __func__);
epping_free_cookie(pAdapter->pEpping_ctx, cookie);
return;
}
SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
cookie, qdf_nbuf_data(skb),
qdf_nbuf_len(new_skb), eid, 0);
SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, new_skb);
skb_len = (int)qdf_nbuf_len(new_skb);
/* send the packet */
ret = htc_send_pkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt);
if (ret != A_OK) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: htc_send_pkt failed, ret = %d\n", __func__, ret);
epping_free_cookie(pAdapter->pEpping_ctx, cookie);
qdf_nbuf_free(new_skb);
return;
}
pAdapter->stats.tx_bytes += skb_len;
++pAdapter->stats.tx_packets;
if (((pAdapter->stats.tx_packets +
pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 &&
(pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) {
epping_log_stats(pAdapter, __func__);
}
}
static int epping_tx_send_int(qdf_nbuf_t skb, epping_adapter_t *pAdapter)
{
EPPING_HEADER *eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb);
HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
struct epping_cookie *cookie = NULL;
A_UINT8 ac = 0;
A_STATUS ret = A_OK;
int skb_len;
EPPING_HEADER tmpHdr = *eppingHdr;
/* allocate resource for this packet */
cookie = epping_alloc_cookie(pAdapter->pEpping_ctx);
/* no resource */
if (cookie == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: epping_alloc_cookie returns no resource\n",
__func__);
return A_ERROR;
}
if (enb_tx_dump)
epping_hex_dump((void *)eppingHdr, skb->len, __func__);
/*
* a quirk of linux, the payload of the frame is 32-bit aligned and thus
* the addition of the HTC header will mis-align the start of the HTC
* frame, so we add some padding which will be stripped off in the target
*/
if (EPPING_ALIGNMENT_PAD > 0) {
A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
}
/* prepare ep/HTC information */
ac = eppingHdr->StreamNo_h;
eid = pAdapter->pEpping_ctx->EppingEndpoint[ac];
if (eid < 0 || eid >= EPPING_MAX_NUM_EPIDS) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: invalid eid = %d, ac = %d\n", __func__, eid,
ac);
return A_ERROR;
}
if (tmpHdr.Cmd_h == EPPING_CMD_RESET_RECV_CNT ||
tmpHdr.Cmd_h == EPPING_CMD_CONT_RX_START) {
epping_set_kperf_flag(pAdapter, eid, tmpHdr.CmdBuffer_t[0]);
}
SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
cookie, qdf_nbuf_data(skb), qdf_nbuf_len(skb),
eid, 0);
SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, skb);
skb_len = skb->len;
/* send the packet */
ret = htc_send_pkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt);
epping_log_packet(pAdapter, &tmpHdr, ret, __func__);
if (ret != A_OK) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: htc_send_pkt failed, status = %d\n", __func__,
ret);
epping_free_cookie(pAdapter->pEpping_ctx, cookie);
return A_ERROR;
}
pAdapter->stats.tx_bytes += skb_len;
++pAdapter->stats.tx_packets;
if (((pAdapter->stats.tx_packets +
pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 &&
(pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) {
epping_log_stats(pAdapter, __func__);
}
return 0;
}
void epping_tx_timer_expire(epping_adapter_t *pAdapter)
{
qdf_nbuf_t nodrop_skb;
EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: queue len: %d\n", __func__,
qdf_nbuf_queue_len(&pAdapter->nodrop_queue));
if (!qdf_nbuf_queue_len(&pAdapter->nodrop_queue)) {
/* nodrop queue is empty so no need to arm timer */
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
return;
}
/* try to flush nodrop queue */
while ((nodrop_skb = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue))) {
htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, true);
if (epping_tx_send_int(nodrop_skb, pAdapter)) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: nodrop: %p xmit fail in timer\n",
__func__, nodrop_skb);
/* fail to xmit so put the nodrop packet to the nodrop queue */
qdf_nbuf_queue_insert_head(&pAdapter->nodrop_queue,
nodrop_skb);
break;
} else {
htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, false);
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
"%s: nodrop: %p xmit ok in timer\n",
__func__, nodrop_skb);
}
}
/* if nodrop queue is not empty, continue to arm timer */
if (nodrop_skb) {
qdf_spin_lock_bh(&pAdapter->data_lock);
/* if nodrop queue is not empty, continue to arm timer */
if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) {
pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING;
qdf_timer_mod(&pAdapter->epping_timer,
TX_RETRY_TIMEOUT_IN_MS);
}
qdf_spin_unlock_bh(&pAdapter->data_lock);
} else {
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
}
}
int epping_tx_send(qdf_nbuf_t skb, epping_adapter_t *pAdapter)
{
qdf_nbuf_t nodrop_skb;
EPPING_HEADER *eppingHdr;
A_UINT8 ac = 0;
eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb);
if (!IS_EPPING_PACKET(eppingHdr)) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: Recived non endpoint ping packets\n", __func__);
/* no packet to send, cleanup */
qdf_nbuf_free(skb);
return -ENOMEM;
}
/* the stream ID is mapped to an access class */
ac = eppingHdr->StreamNo_h;
/* hard coded two ep ids */
if (ac != 0 && ac != 1) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: ac %d is not mapped to mboxping service\n",
__func__, ac);
qdf_nbuf_free(skb);
return -ENOMEM;
}
/*
* some EPPING packets cannot be dropped no matter what access class
* it was sent on. A special care has been taken:
* 1. when there is no TX resource, queue the control packets to
* a special queue
* 2. when there is TX resource, send the queued control packets first
* and then other packets
* 3. a timer launches to check if there is queued control packets and
* flush them
*/
/* check the nodrop queue first */
while ((nodrop_skb = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue))) {
htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, true);
if (epping_tx_send_int(nodrop_skb, pAdapter)) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: nodrop: %p xmit fail\n", __func__,
nodrop_skb);
/* fail to xmit so put the nodrop packet to the nodrop queue */
qdf_nbuf_queue_insert_head(&pAdapter->nodrop_queue,
nodrop_skb);
/* no cookie so free the current skb */
goto tx_fail;
} else {
htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, false);
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
"%s: nodrop: %p xmit ok\n", __func__,
nodrop_skb);
}
}
/* send the original packet */
if (epping_tx_send_int(skb, pAdapter))
goto tx_fail;
return 0;
tx_fail:
if (!IS_EPING_PACKET_NO_DROP(eppingHdr)) {
/* allow to drop the skb so drop it */
qdf_nbuf_free(skb);
++pAdapter->stats.tx_dropped;
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: Tx skb %p dropped, stats.tx_dropped = %ld\n",
__func__, skb, pAdapter->stats.tx_dropped);
return -ENOMEM;
} else {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: nodrop: %p queued\n", __func__, skb);
qdf_nbuf_queue_add(&pAdapter->nodrop_queue, skb);
qdf_spin_lock_bh(&pAdapter->data_lock);
if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) {
pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING;
qdf_timer_mod(&pAdapter->epping_timer,
TX_RETRY_TIMEOUT_IN_MS);
}
qdf_spin_unlock_bh(&pAdapter->data_lock);
}
return 0;
}
#ifdef HIF_SDIO
HTC_SEND_FULL_ACTION epping_tx_queue_full(void *Context, HTC_PACKET *pPacket)
{
/*
* Call netif_stop_queue frequently will impact the mboxping tx t-put.
* Return HTC_SEND_FULL_KEEP directly in epping_tx_queue_full to avoid.
*/
return HTC_SEND_FULL_KEEP;
}
#endif /* HIF_SDIO */
void epping_tx_complete_multiple(void *ctx, HTC_PACKET_QUEUE *pPacketQueue)
{
epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter;
struct net_device *dev = pAdapter->dev;
A_STATUS status;
HTC_ENDPOINT_ID eid;
qdf_nbuf_t pktSkb;
struct epping_cookie *cookie;
A_BOOL flushing = false;
qdf_nbuf_queue_t skb_queue;
HTC_PACKET *htc_pkt;
qdf_nbuf_queue_init(&skb_queue);
qdf_spin_lock_bh(&pAdapter->data_lock);
while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
htc_pkt = htc_packet_dequeue(pPacketQueue);
if (htc_pkt == NULL)
break;
status = htc_pkt->Status;
eid = htc_pkt->Endpoint;
pktSkb = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt);
cookie = htc_pkt->pPktContext;
if (!pktSkb) {
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
"%s: NULL skb from hc packet", __func__);
QDF_BUG(0);
} else {
if (htc_pkt->pBuffer != qdf_nbuf_data(pktSkb)) {
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
"%s: htc_pkt buffer not equal to skb->data",
__func__);
QDF_BUG(0);
}
/* add this to the list, use faster non-lock API */
qdf_nbuf_queue_add(&skb_queue, pktSkb);
if (A_SUCCESS(status)) {
if (htc_pkt->ActualLength !=
qdf_nbuf_len(pktSkb)) {
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
"%s: htc_pkt length not equal to skb->len",
__func__);
QDF_BUG(0);
}
}
}
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
"%s skb=%p data=%p len=0x%x eid=%d ",
__func__, pktSkb, htc_pkt->pBuffer,
htc_pkt->ActualLength, eid);
if (A_FAILED(status)) {
if (status == A_ECANCELED) {
/* a packet was flushed */
flushing = true;
}
if (status != A_NO_RESOURCE) {
printk("%s() -TX ERROR, status: 0x%x\n",
__func__, status);
}
} else {
EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: OK\n", __func__);
flushing = false;
}
epping_free_cookie(pAdapter->pEpping_ctx, cookie);
}
qdf_spin_unlock_bh(&pAdapter->data_lock);
/* free all skbs in our local list */
while (qdf_nbuf_queue_len(&skb_queue)) {
/* use non-lock version */
pktSkb = qdf_nbuf_queue_remove(&skb_queue);
if (pktSkb == NULL)
break;
qdf_nbuf_tx_free(pktSkb, QDF_NBUF_PKT_ERROR);
pEpping_ctx->total_tx_acks++;
}
if (!flushing) {
netif_wake_queue(dev);
}
}

470
utils/epping/src/epping_txrx.c Parasts fails
Parādīt failu

@@ -0,0 +1,470 @@
/*
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* 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.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/*========================================================================
\file epping_txrx.c
\brief WLAN End Point Ping test tool implementation
========================================================================*/
/*--------------------------------------------------------------------------
Include Files
------------------------------------------------------------------------*/
#include <cds_api.h>
#include <cds_sched.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <wni_api.h>
#include <wlan_ptt_sock_svc.h>
#include <linux/wireless.h>
#include <net/cfg80211.h>
#include <pld_common.h>
#include <linux/rtnetlink.h>
#include <linux/semaphore.h>
#include <linux/ctype.h>
#include "epping_main.h"
#include "epping_internal.h"
static int epping_start_adapter(epping_adapter_t *pAdapter);
static void epping_stop_adapter(epping_adapter_t *pAdapter);
static void epping_timer_expire(void *data)
{
struct net_device *dev = (struct net_device *)data;
epping_adapter_t *pAdapter;
if (dev == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: netdev = NULL", __func__);
return;
}
pAdapter = netdev_priv(dev);
if (pAdapter == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: adapter = NULL", __func__);
return;
}
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
epping_tx_timer_expire(pAdapter);
}
static int epping_ndev_open(struct net_device *dev)
{
epping_adapter_t *pAdapter;
int ret = 0;
pAdapter = netdev_priv(dev);
epping_start_adapter(pAdapter);
return ret;
}
static int epping_ndev_stop(struct net_device *dev)
{
epping_adapter_t *pAdapter;
int ret = 0;
pAdapter = netdev_priv(dev);
if (NULL == pAdapter) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: EPPING adapter context is Null", __func__);
ret = -ENODEV;
goto end;
}
epping_stop_adapter(pAdapter);
end:
return ret;
}
static void epping_ndev_uninit(struct net_device *dev)
{
epping_adapter_t *pAdapter;
pAdapter = netdev_priv(dev);
if (NULL == pAdapter) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: EPPING adapter context is Null", __func__);
goto end;
}
epping_stop_adapter(pAdapter);
end:
return;
}
static void epping_tx_queue_timeout(struct net_device *dev)
{
epping_adapter_t *pAdapter;
pAdapter = netdev_priv(dev);
if (NULL == pAdapter) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: EPPING adapter context is Null", __func__);
goto end;
}
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
"%s: Transmission timeout occurred, pAdapter->started= %d",
__func__, pAdapter->started);
/* Getting here implies we disabled the TX queues
* for too long. Since this is epping
* (not because of disassociation or low resource scenarios),
* try to restart the queue
*/
if (pAdapter->started)
netif_wake_queue(dev);
end:
return;
}
static int epping_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
epping_adapter_t *pAdapter;
int ret = 0;
pAdapter = netdev_priv(dev);
if (NULL == pAdapter) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: EPPING adapter context is Null", __func__);
ret = -ENODEV;
goto end;
}
ret = epping_tx_send(skb, pAdapter);
end:
return ret;
}
static struct net_device_stats *epping_get_stats(struct net_device *dev)
{
epping_adapter_t *pAdapter = netdev_priv(dev);
if (NULL == pAdapter) {
EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: pAdapter = NULL",
__func__);
return NULL;
}
return &pAdapter->stats;
}
static int epping_ndev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
epping_adapter_t *pAdapter;
int ret = 0;
pAdapter = netdev_priv(dev);
if (NULL == pAdapter) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: EPPING adapter context is Null", __func__);
ret = -ENODEV;
goto end;
}
if (dev != pAdapter->dev) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: HDD adapter/dev inconsistency", __func__);
ret = -ENODEV;
goto end;
}
if ((!ifr) || (!ifr->ifr_data)) {
ret = -EINVAL;
goto end;
}
switch (cmd) {
case (SIOCDEVPRIVATE + 1):
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
"%s: do not support ioctl %d (SIOCDEVPRIVATE + 1)",
__func__, cmd);
break;
default:
EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
__func__, cmd);
ret = -EINVAL;
break;
}
end:
return ret;
}
static int epping_set_mac_address(struct net_device *dev, void *addr)
{
epping_adapter_t *pAdapter = netdev_priv(dev);
struct sockaddr *psta_mac_addr = addr;
qdf_mem_copy(&pAdapter->macAddressCurrent,
psta_mac_addr->sa_data, ETH_ALEN);
qdf_mem_copy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
return 0;
}
static void epping_stop_adapter(epping_adapter_t *pAdapter)
{
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: qdf_ctx is NULL\n", __func__);
return;
}
if (pAdapter && pAdapter->started) {
EPPING_LOG(LOG1, FL("Disabling queues"));
netif_tx_disable(pAdapter->dev);
netif_carrier_off(pAdapter->dev);
pAdapter->started = false;
pld_request_bus_bandwidth(qdf_ctx->dev,
PLD_BUS_WIDTH_LOW);
}
}
static int epping_start_adapter(epping_adapter_t *pAdapter)
{
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: qdf_ctx is NULL", __func__);
return -EINVAL;
}
if (!pAdapter) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: pAdapter= NULL\n", __func__);
return -EINVAL;
}
if (!pAdapter->started) {
pld_request_bus_bandwidth(qdf_ctx->dev,
PLD_BUS_WIDTH_HIGH);
netif_carrier_on(pAdapter->dev);
EPPING_LOG(LOG1, FL("Enabling queues"));
netif_tx_start_all_queues(pAdapter->dev);
pAdapter->started = true;
} else {
EPPING_LOG(QDF_TRACE_LEVEL_WARN,
"%s: pAdapter %p already started\n", __func__,
pAdapter);
}
return 0;
}
static int epping_register_adapter(epping_adapter_t *pAdapter)
{
int ret = 0;
ret = register_netdev(pAdapter->dev);
if (ret != 0) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: unable to register device\n",
pAdapter->dev->name);
} else {
pAdapter->registered = true;
}
return ret;
}
static void epping_unregister_adapter(epping_adapter_t *pAdapter)
{
if (pAdapter) {
epping_stop_adapter(pAdapter);
if (pAdapter->registered) {
unregister_netdev(pAdapter->dev);
pAdapter->registered = false;
}
} else {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: pAdapter = NULL, unable to unregister device\n",
__func__);
}
}
void epping_destroy_adapter(epping_adapter_t *pAdapter)
{
struct net_device *dev = NULL;
epping_context_t *pEpping_ctx;
if (!pAdapter || !pAdapter->pEpping_ctx) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: pAdapter = NULL\n", __func__);
return;
}
dev = pAdapter->dev;
pEpping_ctx = pAdapter->pEpping_ctx;
epping_unregister_adapter(pAdapter);
qdf_spinlock_destroy(&pAdapter->data_lock);
qdf_timer_free(&pAdapter->epping_timer);
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
while (qdf_nbuf_queue_len(&pAdapter->nodrop_queue)) {
qdf_nbuf_t tmp_nbuf = NULL;
tmp_nbuf = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue);
if (tmp_nbuf)
qdf_nbuf_free(tmp_nbuf);
}
free_netdev(dev);
if (!pEpping_ctx)
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: pEpping_ctx = NULL\n", __func__);
else
pEpping_ctx->epping_adapter = NULL;
}
static struct net_device_ops epping_drv_ops = {
.ndo_open = epping_ndev_open,
.ndo_stop = epping_ndev_stop,
.ndo_uninit = epping_ndev_uninit,
.ndo_start_xmit = epping_hard_start_xmit,
.ndo_tx_timeout = epping_tx_queue_timeout,
.ndo_get_stats = epping_get_stats,
.ndo_do_ioctl = epping_ndev_ioctl,
.ndo_set_mac_address = epping_set_mac_address,
.ndo_select_queue = NULL,
};
#define EPPING_TX_QUEUE_MAX_LEN 128 /* need to be power of 2 */
epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx,
tSirMacAddr macAddr,
enum tQDF_ADAPTER_MODE device_mode)
{
struct net_device *dev;
epping_adapter_t *pAdapter;
dev = alloc_netdev(sizeof(epping_adapter_t), "wifi%d",
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
NET_NAME_UNKNOWN,
#endif
ether_setup);
if (dev == NULL) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"%s: Cannot allocate epping_adapter_t\n", __func__);
return NULL;
}
pAdapter = netdev_priv(dev);
qdf_mem_zero(pAdapter, sizeof(*pAdapter));
pAdapter->dev = dev;
pAdapter->pEpping_ctx = pEpping_ctx;
pAdapter->device_mode = device_mode; /* station, SAP, etc */
qdf_mem_copy(dev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
qdf_mem_copy(pAdapter->macAddressCurrent.bytes,
macAddr, sizeof(tSirMacAddr));
qdf_spinlock_create(&pAdapter->data_lock);
qdf_nbuf_queue_init(&pAdapter->nodrop_queue);
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
qdf_timer_init(epping_get_qdf_ctx(), &pAdapter->epping_timer,
epping_timer_expire, dev, QDF_TIMER_TYPE_SW);
dev->type = ARPHRD_IEEE80211;
dev->netdev_ops = &epping_drv_ops;
dev->watchdog_timeo = 5 * HZ; /* XXX */
dev->tx_queue_len = EPPING_TXBUF - 1; /* 1 for mgmt frame */
if (epping_register_adapter(pAdapter) == 0) {
EPPING_LOG(LOG1, FL("Disabling queues"));
netif_tx_disable(dev);
netif_carrier_off(dev);
return pAdapter;
} else {
epping_destroy_adapter(pAdapter);
return NULL;
}
}
int epping_connect_service(epping_context_t *pEpping_ctx)
{
int status, i;
HTC_SERVICE_CONNECT_REQ connect;
HTC_SERVICE_CONNECT_RESP response;
qdf_mem_zero(&connect, sizeof(connect));
qdf_mem_zero(&response, sizeof(response));
/* these fields are the same for all service endpoints */
connect.EpCallbacks.pContext = pEpping_ctx;
connect.EpCallbacks.EpTxCompleteMultiple = epping_tx_complete_multiple;
connect.EpCallbacks.EpRecv = epping_rx;
/* epping_tx_complete use Multiple version */
connect.EpCallbacks.EpTxComplete = NULL;
connect.MaxSendQueueDepth = 64;
#ifdef HIF_SDIO
connect.EpCallbacks.EpRecvRefill = epping_refill;
connect.EpCallbacks.EpSendFull =
epping_tx_queue_full /* ar6000_tx_queue_full */;
#elif defined(HIF_USB) || defined(HIF_PCI)
connect.EpCallbacks.EpRecvRefill = NULL /* provided by HIF */;
connect.EpCallbacks.EpSendFull = NULL /* provided by HIF */;
/* disable flow control for hw flow control */
connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
#endif
/* connect to service */
connect.service_id = WMI_DATA_BE_SVC;
status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response);
if (status != EOK) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"Failed to connect to Endpoint Ping BE service status:%d\n",
status);
return status;
} else {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"eppingtest BE endpoint:%d\n", response.Endpoint);
}
pEpping_ctx->EppingEndpoint[0] = response.Endpoint;
#if defined(HIF_PCI) || defined(HIF_USB)
connect.service_id = WMI_DATA_BK_SVC;
status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response);
if (status != EOK) {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"Failed to connect to Endpoint Ping BK service status:%d\n",
status);
return status;
} else {
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
"eppingtest BK endpoint:%d\n", response.Endpoint);
}
pEpping_ctx->EppingEndpoint[1] = response.Endpoint;
/* Since we do not create other two SVC use BK endpoint
* for rest ACs (2, 3) */
for (i = 2; i < EPPING_MAX_NUM_EPIDS; i++) {
pEpping_ctx->EppingEndpoint[i] = response.Endpoint;
}
#else
/* we only use one endpoint for high latenance bus.
* Map all AC's EPIDs to the same endpoint ID returned by HTC */
for (i = 0; i < EPPING_MAX_NUM_EPIDS; i++) {
pEpping_ctx->EppingEndpoint[i] = response.Endpoint;
}
#endif
return 0;
}