1 /* 2 * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. 3 * 4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc. 5 * 6 * 7 * Permission to use, copy, modify, and/or distribute this software for 8 * any purpose with or without fee is hereby granted, provided that the 9 * above copyright notice and this permission notice appear in all 10 * copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 * PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 /* 23 * This file was originally distributed by Qualcomm Atheros, Inc. 24 * under proprietary terms before Copyright ownership was assigned 25 * to the Linux Foundation. 26 */ 27 28 /*======================================================================== 29 30 \file epping_main.c 31 32 \brief WLAN End Point Ping test tool implementation 33 34 ========================================================================*/ 35 36 /*-------------------------------------------------------------------------- 37 Include Files 38 ------------------------------------------------------------------------*/ 39 #include <cds_api.h> 40 #include <cds_sched.h> 41 #include <linux/etherdevice.h> 42 #include <linux/firmware.h> 43 #include <linux/delay.h> 44 #include <wni_api.h> 45 #include <wlan_ptt_sock_svc.h> 46 #include <linux/wireless.h> 47 #include <net/cfg80211.h> 48 #include <linux/rtnetlink.h> 49 #include <linux/semaphore.h> 50 #include <linux/delay.h> 51 #include <linux/ctype.h> 52 #include "epping_main.h" 53 #include "epping_internal.h" 54 55 int epping_cookie_init(epping_context_t *pEpping_ctx) 56 { 57 uint32_t i, j; 58 59 pEpping_ctx->cookie_list = NULL; 60 pEpping_ctx->cookie_count = 0; 61 for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { 62 pEpping_ctx->s_cookie_mem[i] = 63 qdf_mem_malloc(sizeof(struct epping_cookie) * 64 MAX_COOKIE_SLOT_SIZE); 65 if (pEpping_ctx->s_cookie_mem[i] == NULL) { 66 EPPING_LOG(QDF_TRACE_LEVEL_FATAL, 67 "%s: no mem for cookie (idx = %d)", __func__, 68 i); 69 goto error; 70 } 71 } 72 qdf_spinlock_create(&pEpping_ctx->cookie_lock); 73 74 for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { 75 struct epping_cookie *cookie_mem = pEpping_ctx->s_cookie_mem[i]; 76 for (j = 0; j < MAX_COOKIE_SLOT_SIZE; j++) { 77 epping_free_cookie(pEpping_ctx, &cookie_mem[j]); 78 } 79 } 80 return 0; 81 error: 82 for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { 83 if (pEpping_ctx->s_cookie_mem[i]) { 84 qdf_mem_free(pEpping_ctx->s_cookie_mem[i]); 85 pEpping_ctx->s_cookie_mem[i] = NULL; 86 } 87 } 88 return -ENOMEM; 89 } 90 91 /* cleanup cookie queue */ 92 void epping_cookie_cleanup(epping_context_t *pEpping_ctx) 93 { 94 int i; 95 qdf_spin_lock_bh(&pEpping_ctx->cookie_lock); 96 pEpping_ctx->cookie_list = NULL; 97 pEpping_ctx->cookie_count = 0; 98 qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock); 99 for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) { 100 if (pEpping_ctx->s_cookie_mem[i]) { 101 qdf_mem_free(pEpping_ctx->s_cookie_mem[i]); 102 pEpping_ctx->s_cookie_mem[i] = NULL; 103 } 104 } 105 } 106 107 void epping_free_cookie(epping_context_t *pEpping_ctx, 108 struct epping_cookie *cookie) 109 { 110 qdf_spin_lock_bh(&pEpping_ctx->cookie_lock); 111 cookie->next = pEpping_ctx->cookie_list; 112 pEpping_ctx->cookie_list = cookie; 113 pEpping_ctx->cookie_count++; 114 qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock); 115 } 116 117 struct epping_cookie *epping_alloc_cookie(epping_context_t *pEpping_ctx) 118 { 119 struct epping_cookie *cookie; 120 121 qdf_spin_lock_bh(&pEpping_ctx->cookie_lock); 122 cookie = pEpping_ctx->cookie_list; 123 if (cookie != NULL) { 124 pEpping_ctx->cookie_list = cookie->next; 125 pEpping_ctx->cookie_count--; 126 } 127 qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock); 128 return cookie; 129 } 130 131 void epping_get_dummy_mac_addr(tSirMacAddr macAddr) 132 { 133 macAddr[0] = 69; /* E */ 134 macAddr[1] = 80; /* P */ 135 macAddr[2] = 80; /* P */ 136 macAddr[3] = 73; /* I */ 137 macAddr[4] = 78; /* N */ 138 macAddr[5] = 71; /* G */ 139 } 140 141 void epping_hex_dump(void *data, int buf_len, const char *str) 142 { 143 char *buf = (char *)data; 144 int i; 145 146 printk("%s: E, %s\n", __func__, str); 147 for (i = 0; (i + 7) < buf_len; i += 8) { 148 printk("%02x %02x %02x %02x %02x %02x %02x %02x\n", 149 buf[i], 150 buf[i + 1], 151 buf[i + 2], 152 buf[i + 3], 153 buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]); 154 } 155 156 /* Dump the bytes in the last line */ 157 for (; i < buf_len; i++) { 158 printk("%02x ", buf[i]); 159 } 160 printk("\n%s: X %s\n", __func__, str); 161 } 162 163 void *epping_get_qdf_ctx(void) 164 { 165 qdf_device_t *qdf_ctx; 166 167 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 168 return qdf_ctx; 169 } 170 171 void epping_log_packet(epping_adapter_t *adapter, 172 EPPING_HEADER *eppingHdr, int ret, const char *str) 173 { 174 if (eppingHdr->Cmd_h & EPPING_LOG_MASK) { 175 EPPING_LOG(QDF_TRACE_LEVEL_FATAL, 176 "%s: cmd = %d, seqNo = %u, flag = 0x%x, ret = %d, " 177 "txCount = %lu, txDrop = %lu, txBytes = %lu," 178 "rxCount = %lu, rxDrop = %lu, rxBytes = %lu\n", 179 str, eppingHdr->Cmd_h, eppingHdr->SeqNo, 180 eppingHdr->CmdFlags_h, ret, 181 adapter->stats.tx_packets, 182 adapter->stats.tx_dropped, 183 adapter->stats.tx_bytes, 184 adapter->stats.rx_packets, 185 adapter->stats.rx_dropped, 186 adapter->stats.rx_bytes); 187 } 188 } 189 190 void epping_log_stats(epping_adapter_t *adapter, const char *str) 191 { 192 EPPING_LOG(QDF_TRACE_LEVEL_FATAL, 193 "%s: txCount = %lu, txDrop = %lu, tx_bytes = %lu, " 194 "rxCount = %lu, rxDrop = %lu, rx_bytes = %lu, tx_acks = %u\n", 195 str, 196 adapter->stats.tx_packets, 197 adapter->stats.tx_dropped, 198 adapter->stats.tx_bytes, 199 adapter->stats.rx_packets, 200 adapter->stats.rx_dropped, 201 adapter->stats.rx_bytes, 202 adapter->pEpping_ctx->total_tx_acks); 203 } 204 205 void epping_set_kperf_flag(epping_adapter_t *adapter, 206 HTC_ENDPOINT_ID eid, uint8_t kperf_flag) 207 { 208 adapter->pEpping_ctx->kperf_num_rx_recv[eid] = 0; 209 adapter->pEpping_ctx->kperf_num_tx_acks[eid] = 0; 210 } 211