1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: qdf_nbuf.c 22 * QCA driver framework(QDF) network buffer management APIs 23 */ 24 #include <linux/hashtable.h> 25 #include <linux/kernel.h> 26 #include <linux/version.h> 27 #include <linux/skbuff.h> 28 #include <linux/module.h> 29 #include <linux/proc_fs.h> 30 #include <linux/inetdevice.h> 31 #include <qdf_atomic.h> 32 #include <qdf_debugfs.h> 33 #include <qdf_lock.h> 34 #include <qdf_mem.h> 35 #include <qdf_module.h> 36 #include <qdf_nbuf.h> 37 #include <qdf_status.h> 38 #include "qdf_str.h" 39 #include <qdf_trace.h> 40 #include "qdf_tracker.h" 41 #include <qdf_types.h> 42 #include <net/ieee80211_radiotap.h> 43 #include <pld_common.h> 44 #include <qdf_crypto.h> 45 #include <linux/igmp.h> 46 #include <net/mld.h> 47 48 #if defined(FEATURE_TSO) 49 #include <net/ipv6.h> 50 #include <linux/ipv6.h> 51 #include <linux/tcp.h> 52 #include <linux/if_vlan.h> 53 #include <linux/ip.h> 54 #endif /* FEATURE_TSO */ 55 56 #ifdef IPA_OFFLOAD 57 #include <i_qdf_ipa_wdi3.h> 58 #endif /* IPA_OFFLOAD */ 59 #include "qdf_ssr_driver_dump.h" 60 61 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) 62 63 #define qdf_nbuf_users_inc atomic_inc 64 #define qdf_nbuf_users_dec atomic_dec 65 #define qdf_nbuf_users_set atomic_set 66 #define qdf_nbuf_users_read atomic_read 67 #else 68 #define qdf_nbuf_users_inc refcount_inc 69 #define qdf_nbuf_users_dec refcount_dec 70 #define qdf_nbuf_users_set refcount_set 71 #define qdf_nbuf_users_read refcount_read 72 #endif /* KERNEL_VERSION(4, 13, 0) */ 73 74 #define IEEE80211_RADIOTAP_VHT_BW_20 0 75 #define IEEE80211_RADIOTAP_VHT_BW_40 1 76 #define IEEE80211_RADIOTAP_VHT_BW_80 2 77 #define IEEE80211_RADIOTAP_VHT_BW_160 3 78 79 #define RADIOTAP_VHT_BW_20 0 80 #define RADIOTAP_VHT_BW_40 1 81 #define RADIOTAP_VHT_BW_80 4 82 #define RADIOTAP_VHT_BW_160 11 83 84 /* tx status */ 85 #define RADIOTAP_TX_STATUS_FAIL 1 86 #define RADIOTAP_TX_STATUS_NOACK 2 87 88 /* channel number to freq conversion */ 89 #define CHANNEL_NUM_14 14 90 #define CHANNEL_NUM_15 15 91 #define CHANNEL_NUM_27 27 92 #define CHANNEL_NUM_35 35 93 #define CHANNEL_NUM_182 182 94 #define CHANNEL_NUM_197 197 95 #define CHANNEL_FREQ_2484 2484 96 #define CHANNEL_FREQ_2407 2407 97 #define CHANNEL_FREQ_2512 2512 98 #define CHANNEL_FREQ_5000 5000 99 #define CHANNEL_FREQ_4000 4000 100 #define CHANNEL_FREQ_5150 5150 101 #define FREQ_MULTIPLIER_CONST_5MHZ 5 102 #define FREQ_MULTIPLIER_CONST_20MHZ 20 103 #define RADIOTAP_5G_SPECTRUM_CHANNEL 0x0100 104 #define RADIOTAP_2G_SPECTRUM_CHANNEL 0x0080 105 #define RADIOTAP_CCK_CHANNEL 0x0020 106 #define RADIOTAP_OFDM_CHANNEL 0x0040 107 108 #ifdef FEATURE_NBUFF_REPLENISH_TIMER 109 #include <qdf_mc_timer.h> 110 111 struct qdf_track_timer { 112 qdf_mc_timer_t track_timer; 113 qdf_atomic_t alloc_fail_cnt; 114 }; 115 116 static struct qdf_track_timer alloc_track_timer; 117 118 #define QDF_NBUF_ALLOC_EXPIRE_TIMER_MS 5000 119 #define QDF_NBUF_ALLOC_EXPIRE_CNT_THRESHOLD 50 120 #endif 121 122 #ifdef NBUF_MEMORY_DEBUG 123 /* SMMU crash indication*/ 124 static qdf_atomic_t smmu_crashed; 125 /* Number of nbuf not added to history*/ 126 unsigned long g_histroy_add_drop; 127 #endif 128 129 /* Packet Counter */ 130 static uint32_t nbuf_tx_mgmt[QDF_NBUF_TX_PKT_STATE_MAX]; 131 static uint32_t nbuf_tx_data[QDF_NBUF_TX_PKT_STATE_MAX]; 132 #ifdef QDF_NBUF_GLOBAL_COUNT 133 #define NBUF_DEBUGFS_NAME "nbuf_counters" 134 static qdf_atomic_t nbuf_count; 135 #endif 136 137 #if defined(NBUF_MEMORY_DEBUG) || defined(QDF_NBUF_GLOBAL_COUNT) 138 static bool is_initial_mem_debug_disabled; 139 #endif 140 141 /** 142 * __qdf_nbuf_get_ip_offset() - Get IPV4/V6 header offset 143 * @data: Pointer to network data buffer 144 * 145 * Get the IP header offset in case of 8021Q and 8021AD 146 * tag is present in L2 header. 147 * 148 * Return: IP header offset 149 */ __qdf_nbuf_get_ip_offset(uint8_t * data)150 static inline uint8_t __qdf_nbuf_get_ip_offset(uint8_t *data) 151 { 152 uint16_t ether_type; 153 154 ether_type = *(uint16_t *)(data + 155 QDF_NBUF_TRAC_ETH_TYPE_OFFSET); 156 157 if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) 158 return QDF_NBUF_TRAC_VLAN_IP_OFFSET; 159 else if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021AD))) 160 return QDF_NBUF_TRAC_DOUBLE_VLAN_IP_OFFSET; 161 162 return QDF_NBUF_TRAC_IP_OFFSET; 163 } 164 165 /** 166 * __qdf_nbuf_get_ether_type() - Get the ether type 167 * @data: Pointer to network data buffer 168 * 169 * Get the ether type in case of 8021Q and 8021AD tag 170 * is present in L2 header, e.g for the returned ether type 171 * value, if IPV4 data ether type 0x0800, return 0x0008. 172 * 173 * Return ether type. 174 */ __qdf_nbuf_get_ether_type(uint8_t * data)175 static inline uint16_t __qdf_nbuf_get_ether_type(uint8_t *data) 176 { 177 uint16_t ether_type; 178 179 ether_type = *(uint16_t *)(data + 180 QDF_NBUF_TRAC_ETH_TYPE_OFFSET); 181 182 if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) 183 ether_type = *(uint16_t *)(data + 184 QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET); 185 else if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021AD))) 186 ether_type = *(uint16_t *)(data + 187 QDF_NBUF_TRAC_DOUBLE_VLAN_ETH_TYPE_OFFSET); 188 189 return ether_type; 190 } 191 qdf_nbuf_tx_desc_count_display(void)192 void qdf_nbuf_tx_desc_count_display(void) 193 { 194 qdf_debug("Current Snapshot of the Driver:"); 195 qdf_debug("Data Packets:"); 196 qdf_debug("HDD %d TXRX_Q %d TXRX %d HTT %d", 197 nbuf_tx_data[QDF_NBUF_TX_PKT_HDD] - 198 (nbuf_tx_data[QDF_NBUF_TX_PKT_TXRX] + 199 nbuf_tx_data[QDF_NBUF_TX_PKT_TXRX_ENQUEUE] - 200 nbuf_tx_data[QDF_NBUF_TX_PKT_TXRX_DEQUEUE]), 201 nbuf_tx_data[QDF_NBUF_TX_PKT_TXRX_ENQUEUE] - 202 nbuf_tx_data[QDF_NBUF_TX_PKT_TXRX_DEQUEUE], 203 nbuf_tx_data[QDF_NBUF_TX_PKT_TXRX] - 204 nbuf_tx_data[QDF_NBUF_TX_PKT_HTT], 205 nbuf_tx_data[QDF_NBUF_TX_PKT_HTT] - 206 nbuf_tx_data[QDF_NBUF_TX_PKT_HTC]); 207 qdf_debug(" HTC %d HIF %d CE %d TX_COMP %d", 208 nbuf_tx_data[QDF_NBUF_TX_PKT_HTC] - 209 nbuf_tx_data[QDF_NBUF_TX_PKT_HIF], 210 nbuf_tx_data[QDF_NBUF_TX_PKT_HIF] - 211 nbuf_tx_data[QDF_NBUF_TX_PKT_CE], 212 nbuf_tx_data[QDF_NBUF_TX_PKT_CE] - 213 nbuf_tx_data[QDF_NBUF_TX_PKT_FREE], 214 nbuf_tx_data[QDF_NBUF_TX_PKT_FREE]); 215 qdf_debug("Mgmt Packets:"); 216 qdf_debug("TXRX_Q %d TXRX %d HTT %d HTC %d HIF %d CE %d TX_COMP %d", 217 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_TXRX_ENQUEUE] - 218 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_TXRX_DEQUEUE], 219 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_TXRX] - 220 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_HTT], 221 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_HTT] - 222 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_HTC], 223 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_HTC] - 224 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_HIF], 225 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_HIF] - 226 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_CE], 227 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_CE] - 228 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_FREE], 229 nbuf_tx_mgmt[QDF_NBUF_TX_PKT_FREE]); 230 } 231 qdf_export_symbol(qdf_nbuf_tx_desc_count_display); 232 233 /** 234 * qdf_nbuf_tx_desc_count_update() - Updates the layer packet counter 235 * @packet_type : packet type either mgmt/data 236 * @current_state : layer at which the packet currently present 237 * 238 * Return: none 239 */ qdf_nbuf_tx_desc_count_update(uint8_t packet_type,uint8_t current_state)240 static inline void qdf_nbuf_tx_desc_count_update(uint8_t packet_type, 241 uint8_t current_state) 242 { 243 switch (packet_type) { 244 case QDF_NBUF_TX_PKT_MGMT_TRACK: 245 nbuf_tx_mgmt[current_state]++; 246 break; 247 case QDF_NBUF_TX_PKT_DATA_TRACK: 248 nbuf_tx_data[current_state]++; 249 break; 250 default: 251 break; 252 } 253 } 254 qdf_nbuf_tx_desc_count_clear(void)255 void qdf_nbuf_tx_desc_count_clear(void) 256 { 257 memset(nbuf_tx_mgmt, 0, sizeof(nbuf_tx_mgmt)); 258 memset(nbuf_tx_data, 0, sizeof(nbuf_tx_data)); 259 } 260 qdf_export_symbol(qdf_nbuf_tx_desc_count_clear); 261 qdf_nbuf_set_state(qdf_nbuf_t nbuf,uint8_t current_state)262 void qdf_nbuf_set_state(qdf_nbuf_t nbuf, uint8_t current_state) 263 { 264 /* 265 * Only Mgmt, Data Packets are tracked. WMI messages 266 * such as scan commands are not tracked 267 */ 268 uint8_t packet_type; 269 270 packet_type = QDF_NBUF_CB_TX_PACKET_TRACK(nbuf); 271 272 if ((packet_type != QDF_NBUF_TX_PKT_DATA_TRACK) && 273 (packet_type != QDF_NBUF_TX_PKT_MGMT_TRACK)) { 274 return; 275 } 276 QDF_NBUF_CB_TX_PACKET_STATE(nbuf) = current_state; 277 qdf_nbuf_tx_desc_count_update(packet_type, 278 current_state); 279 } 280 qdf_export_symbol(qdf_nbuf_set_state); 281 282 #ifdef FEATURE_NBUFF_REPLENISH_TIMER 283 /** 284 * __qdf_nbuf_start_replenish_timer() - Start alloc fail replenish timer 285 * 286 * This function starts the alloc fail replenish timer. 287 * 288 * Return: void 289 */ __qdf_nbuf_start_replenish_timer(void)290 static inline void __qdf_nbuf_start_replenish_timer(void) 291 { 292 qdf_atomic_inc(&alloc_track_timer.alloc_fail_cnt); 293 if (qdf_mc_timer_get_current_state(&alloc_track_timer.track_timer) != 294 QDF_TIMER_STATE_RUNNING) 295 qdf_mc_timer_start(&alloc_track_timer.track_timer, 296 QDF_NBUF_ALLOC_EXPIRE_TIMER_MS); 297 } 298 299 /** 300 * __qdf_nbuf_stop_replenish_timer() - Stop alloc fail replenish timer 301 * 302 * This function stops the alloc fail replenish timer. 303 * 304 * Return: void 305 */ __qdf_nbuf_stop_replenish_timer(void)306 static inline void __qdf_nbuf_stop_replenish_timer(void) 307 { 308 if (qdf_atomic_read(&alloc_track_timer.alloc_fail_cnt) == 0) 309 return; 310 311 qdf_atomic_set(&alloc_track_timer.alloc_fail_cnt, 0); 312 if (qdf_mc_timer_get_current_state(&alloc_track_timer.track_timer) == 313 QDF_TIMER_STATE_RUNNING) 314 qdf_mc_timer_stop(&alloc_track_timer.track_timer); 315 } 316 317 /** 318 * qdf_replenish_expire_handler() - Replenish expire handler 319 * @arg: unused callback argument 320 * 321 * This function triggers when the alloc fail replenish timer expires. 322 * 323 * Return: void 324 */ qdf_replenish_expire_handler(void * arg)325 static void qdf_replenish_expire_handler(void *arg) 326 { 327 if (qdf_atomic_read(&alloc_track_timer.alloc_fail_cnt) > 328 QDF_NBUF_ALLOC_EXPIRE_CNT_THRESHOLD) { 329 qdf_print("ERROR: NBUF allocation timer expired Fail count %d", 330 qdf_atomic_read(&alloc_track_timer.alloc_fail_cnt)); 331 332 /* Error handling here */ 333 } 334 } 335 __qdf_nbuf_init_replenish_timer(void)336 void __qdf_nbuf_init_replenish_timer(void) 337 { 338 qdf_mc_timer_init(&alloc_track_timer.track_timer, QDF_TIMER_TYPE_SW, 339 qdf_replenish_expire_handler, NULL); 340 } 341 __qdf_nbuf_deinit_replenish_timer(void)342 void __qdf_nbuf_deinit_replenish_timer(void) 343 { 344 __qdf_nbuf_stop_replenish_timer(); 345 qdf_mc_timer_destroy(&alloc_track_timer.track_timer); 346 } 347 qdf_nbuf_stop_replenish_timer(void)348 void qdf_nbuf_stop_replenish_timer(void) 349 { 350 __qdf_nbuf_stop_replenish_timer(); 351 } 352 #else 353 __qdf_nbuf_start_replenish_timer(void)354 static inline void __qdf_nbuf_start_replenish_timer(void) {} __qdf_nbuf_stop_replenish_timer(void)355 static inline void __qdf_nbuf_stop_replenish_timer(void) {} qdf_nbuf_stop_replenish_timer(void)356 void qdf_nbuf_stop_replenish_timer(void) 357 { 358 } 359 #endif 360 361 /* globals do not need to be initialized to NULL/0 */ 362 qdf_nbuf_trace_update_t qdf_trace_update_cb; 363 qdf_nbuf_free_t nbuf_free_cb; 364 365 #ifdef QDF_NBUF_GLOBAL_COUNT 366 __qdf_nbuf_count_get(void)367 int __qdf_nbuf_count_get(void) 368 { 369 return qdf_atomic_read(&nbuf_count); 370 } 371 qdf_export_symbol(__qdf_nbuf_count_get); 372 __qdf_nbuf_count_inc(qdf_nbuf_t nbuf)373 void __qdf_nbuf_count_inc(qdf_nbuf_t nbuf) 374 { 375 int num_nbuf = 1; 376 qdf_nbuf_t ext_list; 377 378 if (qdf_likely(is_initial_mem_debug_disabled)) 379 return; 380 381 ext_list = qdf_nbuf_get_ext_list(nbuf); 382 383 /* Take care to account for frag_list */ 384 while (ext_list) { 385 ++num_nbuf; 386 ext_list = qdf_nbuf_queue_next(ext_list); 387 } 388 389 qdf_atomic_add(num_nbuf, &nbuf_count); 390 } 391 qdf_export_symbol(__qdf_nbuf_count_inc); 392 __qdf_nbuf_count_dec(__qdf_nbuf_t nbuf)393 void __qdf_nbuf_count_dec(__qdf_nbuf_t nbuf) 394 { 395 qdf_nbuf_t ext_list; 396 int num_nbuf; 397 398 if (qdf_likely(is_initial_mem_debug_disabled)) 399 return; 400 401 if (qdf_nbuf_get_users(nbuf) > 1) 402 return; 403 404 num_nbuf = 1; 405 406 /* Take care to account for frag_list */ 407 ext_list = qdf_nbuf_get_ext_list(nbuf); 408 while (ext_list) { 409 if (qdf_nbuf_get_users(ext_list) == 1) 410 ++num_nbuf; 411 ext_list = qdf_nbuf_queue_next(ext_list); 412 } 413 414 qdf_atomic_sub(num_nbuf, &nbuf_count); 415 } 416 qdf_export_symbol(__qdf_nbuf_count_dec); 417 #endif 418 419 #ifdef NBUF_FRAG_MEMORY_DEBUG qdf_nbuf_frag_count_inc(qdf_nbuf_t nbuf)420 void qdf_nbuf_frag_count_inc(qdf_nbuf_t nbuf) 421 { 422 qdf_nbuf_t ext_list; 423 uint32_t num_nr_frags; 424 uint32_t total_num_nr_frags; 425 426 if (qdf_likely(is_initial_mem_debug_disabled)) 427 return; 428 429 num_nr_frags = qdf_nbuf_get_nr_frags(nbuf); 430 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 431 432 total_num_nr_frags = num_nr_frags; 433 434 /* Take into account the frags attached to frag_list */ 435 ext_list = qdf_nbuf_get_ext_list(nbuf); 436 while (ext_list) { 437 num_nr_frags = qdf_nbuf_get_nr_frags(ext_list); 438 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 439 total_num_nr_frags += num_nr_frags; 440 ext_list = qdf_nbuf_queue_next(ext_list); 441 } 442 443 qdf_frag_count_inc(total_num_nr_frags); 444 } 445 446 qdf_export_symbol(qdf_nbuf_frag_count_inc); 447 qdf_nbuf_frag_count_dec(qdf_nbuf_t nbuf)448 void qdf_nbuf_frag_count_dec(qdf_nbuf_t nbuf) 449 { 450 qdf_nbuf_t ext_list; 451 uint32_t num_nr_frags; 452 uint32_t total_num_nr_frags; 453 454 if (qdf_likely(is_initial_mem_debug_disabled)) 455 return; 456 457 if (qdf_nbuf_get_users(nbuf) > 1) 458 return; 459 460 num_nr_frags = qdf_nbuf_get_nr_frags(nbuf); 461 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 462 463 total_num_nr_frags = num_nr_frags; 464 465 /* Take into account the frags attached to frag_list */ 466 ext_list = qdf_nbuf_get_ext_list(nbuf); 467 while (ext_list) { 468 if (qdf_nbuf_get_users(ext_list) == 1) { 469 num_nr_frags = qdf_nbuf_get_nr_frags(ext_list); 470 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 471 total_num_nr_frags += num_nr_frags; 472 } 473 ext_list = qdf_nbuf_queue_next(ext_list); 474 } 475 476 qdf_frag_count_dec(total_num_nr_frags); 477 } 478 479 qdf_export_symbol(qdf_nbuf_frag_count_dec); 480 481 #endif 482 483 static inline void qdf_nbuf_set_defaults(struct sk_buff * skb,int align,int reserve)484 qdf_nbuf_set_defaults(struct sk_buff *skb, int align, int reserve) 485 { 486 unsigned long offset; 487 488 memset(skb->cb, 0x0, sizeof(skb->cb)); 489 skb->dev = NULL; 490 491 /* 492 * The default is for netbuf fragments to be interpreted 493 * as wordstreams rather than bytestreams. 494 */ 495 QDF_NBUF_CB_TX_EXTRA_FRAG_WORDSTR_EFRAG(skb) = 1; 496 QDF_NBUF_CB_TX_EXTRA_FRAG_WORDSTR_NBUF(skb) = 1; 497 498 /* 499 * XXX:how about we reserve first then align 500 * Align & make sure that the tail & data are adjusted properly 501 */ 502 503 if (align) { 504 offset = ((unsigned long)skb->data) % align; 505 if (offset) 506 skb_reserve(skb, align - offset); 507 } 508 509 /* 510 * NOTE:alloc doesn't take responsibility if reserve unaligns the data 511 * pointer 512 */ 513 skb_reserve(skb, reserve); 514 qdf_nbuf_count_inc(skb); 515 } 516 517 #if defined(CONFIG_WIFI_EMULATION_WIFI_3_0) && defined(BUILD_X86) && \ 518 !defined(QCA_WIFI_QCN9000) __qdf_nbuf_alloc(qdf_device_t osdev,size_t size,int reserve,int align,int prio,const char * func,uint32_t line)519 struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve, 520 int align, int prio, const char *func, 521 uint32_t line) 522 { 523 struct sk_buff *skb; 524 uint32_t lowmem_alloc_tries = 0; 525 526 if (align) 527 size += (align - 1); 528 529 realloc: 530 skb = dev_alloc_skb(size); 531 532 if (skb) 533 goto skb_alloc; 534 535 skb = pld_nbuf_pre_alloc(size); 536 537 if (!skb) { 538 qdf_rl_nofl_err("NBUF alloc failed %zuB @ %s:%d", 539 size, func, line); 540 return NULL; 541 } 542 543 skb_alloc: 544 /* Hawkeye M2M emulation cannot handle memory addresses below 0x50000040 545 * Though we are trying to reserve low memory upfront to prevent this, 546 * we sometimes see SKBs allocated from low memory. 547 */ 548 if (virt_to_phys(qdf_nbuf_data(skb)) < 0x50000040) { 549 lowmem_alloc_tries++; 550 if (lowmem_alloc_tries > 100) { 551 qdf_nofl_err("NBUF alloc failed %zuB @ %s:%d", 552 size, func, line); 553 return NULL; 554 } else { 555 /* Not freeing to make sure it 556 * will not get allocated again 557 */ 558 goto realloc; 559 } 560 } 561 562 qdf_nbuf_set_defaults(skb, align, reserve); 563 564 return skb; 565 } 566 #else 567 568 #ifdef QCA_DP_NBUF_FAST_RECYCLE_CHECK __qdf_nbuf_alloc(qdf_device_t osdev,size_t size,int reserve,int align,int prio,const char * func,uint32_t line)569 struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve, 570 int align, int prio, const char *func, 571 uint32_t line) 572 { 573 return __qdf_nbuf_frag_alloc(osdev, size, reserve, align, prio, func, 574 line); 575 } 576 577 #else __qdf_nbuf_alloc(qdf_device_t osdev,size_t size,int reserve,int align,int prio,const char * func,uint32_t line)578 struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve, 579 int align, int prio, const char *func, 580 uint32_t line) 581 { 582 struct sk_buff *skb; 583 int flags = GFP_KERNEL; 584 585 if (align) 586 size += (align - 1); 587 588 if (in_interrupt() || irqs_disabled() || in_atomic()) 589 flags = GFP_ATOMIC; 590 591 skb = alloc_skb(size, flags); 592 593 if (skb) 594 goto skb_alloc; 595 596 skb = pld_nbuf_pre_alloc(size); 597 598 if (!skb) { 599 qdf_rl_nofl_err("NBUF alloc failed %zuB @ %s:%d", 600 size, func, line); 601 __qdf_nbuf_start_replenish_timer(); 602 return NULL; 603 } 604 605 __qdf_nbuf_stop_replenish_timer(); 606 607 skb_alloc: 608 qdf_nbuf_set_defaults(skb, align, reserve); 609 610 return skb; 611 } 612 #endif 613 614 #endif 615 qdf_export_symbol(__qdf_nbuf_alloc); 616 __qdf_nbuf_frag_alloc(qdf_device_t osdev,size_t size,int reserve,int align,int prio,const char * func,uint32_t line)617 struct sk_buff *__qdf_nbuf_frag_alloc(qdf_device_t osdev, size_t size, 618 int reserve, int align, int prio, 619 const char *func, uint32_t line) 620 { 621 struct sk_buff *skb; 622 int flags = GFP_KERNEL & ~__GFP_DIRECT_RECLAIM; 623 bool atomic = false; 624 625 if (align) 626 size += (align - 1); 627 628 if (in_interrupt() || irqs_disabled() || in_atomic()) { 629 atomic = true; 630 flags = GFP_ATOMIC; 631 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) 632 /* 633 * Observed that kcompactd burns out CPU to make order-3 page. 634 *__netdev_alloc_skb has 4k page fallback option just in case of 635 * failing high order page allocation so we don't need to be 636 * hard. Make kcompactd rest in piece. 637 */ 638 flags = flags & ~__GFP_KSWAPD_RECLAIM; 639 #endif 640 } 641 642 skb = __netdev_alloc_skb(NULL, size, flags); 643 if (skb) 644 goto skb_alloc; 645 646 /* 32k page frag alloc failed, try page slab allocation */ 647 if (likely(!atomic)) 648 flags |= __GFP_DIRECT_RECLAIM; 649 650 skb = alloc_skb(size, flags); 651 if (skb) 652 goto skb_alloc; 653 654 skb = pld_nbuf_pre_alloc(size); 655 656 if (!skb) { 657 qdf_rl_nofl_err("NBUF alloc failed %zuB @ %s:%d", 658 size, func, line); 659 __qdf_nbuf_start_replenish_timer(); 660 return NULL; 661 } 662 663 __qdf_nbuf_stop_replenish_timer(); 664 665 skb_alloc: 666 qdf_nbuf_set_defaults(skb, align, reserve); 667 668 return skb; 669 } 670 671 qdf_export_symbol(__qdf_nbuf_frag_alloc); 672 __qdf_nbuf_alloc_no_recycler(size_t size,int reserve,int align,const char * func,uint32_t line)673 __qdf_nbuf_t __qdf_nbuf_alloc_no_recycler(size_t size, int reserve, int align, 674 const char *func, uint32_t line) 675 { 676 qdf_nbuf_t nbuf; 677 unsigned long offset; 678 679 if (align) 680 size += (align - 1); 681 682 nbuf = alloc_skb(size, GFP_ATOMIC); 683 if (!nbuf) 684 goto ret_nbuf; 685 686 memset(nbuf->cb, 0x0, sizeof(nbuf->cb)); 687 688 skb_reserve(nbuf, reserve); 689 690 if (align) { 691 offset = ((unsigned long)nbuf->data) % align; 692 if (offset) 693 skb_reserve(nbuf, align - offset); 694 } 695 696 qdf_nbuf_count_inc(nbuf); 697 698 ret_nbuf: 699 return nbuf; 700 } 701 702 qdf_export_symbol(__qdf_nbuf_alloc_no_recycler); 703 __qdf_nbuf_free(struct sk_buff * skb)704 void __qdf_nbuf_free(struct sk_buff *skb) 705 { 706 if (pld_nbuf_pre_alloc_free(skb)) 707 return; 708 709 qdf_nbuf_frag_count_dec(skb); 710 711 qdf_nbuf_count_dec(skb); 712 if (nbuf_free_cb) 713 nbuf_free_cb(skb); 714 else 715 dev_kfree_skb_any(skb); 716 } 717 718 qdf_export_symbol(__qdf_nbuf_free); 719 __qdf_nbuf_clone(__qdf_nbuf_t skb)720 __qdf_nbuf_t __qdf_nbuf_clone(__qdf_nbuf_t skb) 721 { 722 qdf_nbuf_t skb_new = NULL; 723 724 skb_new = skb_clone(skb, GFP_ATOMIC); 725 if (skb_new) { 726 qdf_nbuf_frag_count_inc(skb_new); 727 qdf_nbuf_count_inc(skb_new); 728 } 729 return skb_new; 730 } 731 732 qdf_export_symbol(__qdf_nbuf_clone); 733 734 struct sk_buff * __qdf_nbuf_page_frag_alloc(qdf_device_t osdev,size_t size,int reserve,int align,__qdf_frag_cache_t * pf_cache,const char * func,uint32_t line)735 __qdf_nbuf_page_frag_alloc(qdf_device_t osdev, size_t size, int reserve, 736 int align, __qdf_frag_cache_t *pf_cache, 737 const char *func, uint32_t line) 738 { 739 struct sk_buff *skb; 740 qdf_frag_t frag_data; 741 size_t orig_size = size; 742 int flags = GFP_KERNEL; 743 744 if (align) 745 size += (align - 1); 746 747 size += NET_SKB_PAD; 748 size += SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); 749 size = SKB_DATA_ALIGN(size); 750 751 if (in_interrupt() || irqs_disabled() || in_atomic()) 752 flags = GFP_ATOMIC; 753 754 frag_data = page_frag_alloc(pf_cache, size, flags); 755 if (!frag_data) { 756 qdf_rl_nofl_err("page frag alloc failed %zuB @ %s:%d", 757 size, func, line); 758 return __qdf_nbuf_alloc(osdev, orig_size, reserve, align, 0, 759 func, line); 760 } 761 762 skb = build_skb(frag_data, size); 763 if (skb) { 764 skb_reserve(skb, NET_SKB_PAD); 765 goto skb_alloc; 766 } 767 768 /* Free the data allocated from pf_cache */ 769 page_frag_free(frag_data); 770 771 size = orig_size + align - 1; 772 773 skb = pld_nbuf_pre_alloc(size); 774 if (!skb) { 775 qdf_rl_nofl_err("NBUF alloc failed %zuB @ %s:%d", 776 size, func, line); 777 __qdf_nbuf_start_replenish_timer(); 778 return NULL; 779 } 780 781 __qdf_nbuf_stop_replenish_timer(); 782 783 skb_alloc: 784 qdf_nbuf_set_defaults(skb, align, reserve); 785 786 return skb; 787 } 788 789 qdf_export_symbol(__qdf_nbuf_page_frag_alloc); 790 791 #ifdef QCA_DP_TX_NBUF_LIST_FREE 792 void __qdf_nbuf_dev_kfree_list(__qdf_nbuf_queue_head_t * nbuf_queue_head)793 __qdf_nbuf_dev_kfree_list(__qdf_nbuf_queue_head_t *nbuf_queue_head) 794 { 795 dev_kfree_skb_list_fast(nbuf_queue_head); 796 } 797 #else 798 void __qdf_nbuf_dev_kfree_list(__qdf_nbuf_queue_head_t * nbuf_queue_head)799 __qdf_nbuf_dev_kfree_list(__qdf_nbuf_queue_head_t *nbuf_queue_head) 800 { 801 } 802 #endif 803 804 qdf_export_symbol(__qdf_nbuf_dev_kfree_list); 805 806 #ifdef NBUF_MEMORY_DEBUG 807 struct qdf_nbuf_event { 808 qdf_nbuf_t nbuf; 809 char func[QDF_MEM_FUNC_NAME_SIZE]; 810 uint32_t line; 811 enum qdf_nbuf_event_type type; 812 uint64_t timestamp; 813 qdf_dma_addr_t iova; 814 }; 815 816 #ifndef QDF_NBUF_HISTORY_SIZE 817 #define QDF_NBUF_HISTORY_SIZE 4096 818 #endif 819 static qdf_atomic_t qdf_nbuf_history_index; 820 static struct qdf_nbuf_event qdf_nbuf_history[QDF_NBUF_HISTORY_SIZE]; 821 qdf_nbuf_ssr_register_region(void)822 void qdf_nbuf_ssr_register_region(void) 823 { 824 qdf_ssr_driver_dump_register_region("qdf_nbuf_history", 825 qdf_nbuf_history, 826 sizeof(qdf_nbuf_history)); 827 } 828 829 qdf_export_symbol(qdf_nbuf_ssr_register_region); 830 qdf_nbuf_ssr_unregister_region(void)831 void qdf_nbuf_ssr_unregister_region(void) 832 { 833 qdf_ssr_driver_dump_unregister_region("qdf_nbuf_history"); 834 } 835 836 qdf_export_symbol(qdf_nbuf_ssr_unregister_region); 837 qdf_nbuf_circular_index_next(qdf_atomic_t * index,int size)838 static int32_t qdf_nbuf_circular_index_next(qdf_atomic_t *index, int size) 839 { 840 int32_t next = qdf_atomic_inc_return(index); 841 842 if (next == size) 843 qdf_atomic_sub(size, index); 844 845 return next % size; 846 } 847 848 void qdf_nbuf_history_add(qdf_nbuf_t nbuf,const char * func,uint32_t line,enum qdf_nbuf_event_type type)849 qdf_nbuf_history_add(qdf_nbuf_t nbuf, const char *func, uint32_t line, 850 enum qdf_nbuf_event_type type) 851 { 852 int32_t idx = qdf_nbuf_circular_index_next(&qdf_nbuf_history_index, 853 QDF_NBUF_HISTORY_SIZE); 854 struct qdf_nbuf_event *event = &qdf_nbuf_history[idx]; 855 856 if (qdf_atomic_read(&smmu_crashed)) { 857 g_histroy_add_drop++; 858 return; 859 } 860 861 event->nbuf = nbuf; 862 qdf_str_lcopy(event->func, func, QDF_MEM_FUNC_NAME_SIZE); 863 event->line = line; 864 event->type = type; 865 event->timestamp = qdf_get_log_timestamp(); 866 if (type == QDF_NBUF_MAP || type == QDF_NBUF_UNMAP || 867 type == QDF_NBUF_SMMU_MAP || type == QDF_NBUF_SMMU_UNMAP) 868 event->iova = QDF_NBUF_CB_PADDR(nbuf); 869 else 870 event->iova = 0; 871 } 872 qdf_set_smmu_fault_state(bool smmu_fault_state)873 void qdf_set_smmu_fault_state(bool smmu_fault_state) 874 { 875 qdf_atomic_set(&smmu_crashed, smmu_fault_state); 876 if (!smmu_fault_state) 877 g_histroy_add_drop = 0; 878 } 879 qdf_export_symbol(qdf_set_smmu_fault_state); 880 #endif /* NBUF_MEMORY_DEBUG */ 881 882 #ifdef NBUF_SMMU_MAP_UNMAP_DEBUG 883 #define qdf_nbuf_smmu_map_tracker_bits 11 /* 2048 buckets */ 884 qdf_tracker_declare(qdf_nbuf_smmu_map_tracker, qdf_nbuf_smmu_map_tracker_bits, 885 "nbuf map-no-unmap events", "nbuf map", "nbuf unmap"); 886 qdf_nbuf_smmu_map_tracking_init(void)887 static void qdf_nbuf_smmu_map_tracking_init(void) 888 { 889 qdf_tracker_init(&qdf_nbuf_smmu_map_tracker); 890 } 891 qdf_nbuf_smmu_map_tracking_deinit(void)892 static void qdf_nbuf_smmu_map_tracking_deinit(void) 893 { 894 qdf_tracker_deinit(&qdf_nbuf_smmu_map_tracker); 895 } 896 897 static QDF_STATUS qdf_nbuf_track_smmu_map(qdf_nbuf_t nbuf,const char * func,uint32_t line)898 qdf_nbuf_track_smmu_map(qdf_nbuf_t nbuf, const char *func, uint32_t line) 899 { 900 if (is_initial_mem_debug_disabled) 901 return QDF_STATUS_SUCCESS; 902 903 return qdf_tracker_track(&qdf_nbuf_smmu_map_tracker, nbuf, func, line); 904 } 905 906 static void qdf_nbuf_untrack_smmu_map(qdf_nbuf_t nbuf,const char * func,uint32_t line)907 qdf_nbuf_untrack_smmu_map(qdf_nbuf_t nbuf, const char *func, uint32_t line) 908 { 909 if (is_initial_mem_debug_disabled) 910 return; 911 912 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_SMMU_UNMAP); 913 qdf_tracker_untrack(&qdf_nbuf_smmu_map_tracker, nbuf, func, line); 914 } 915 qdf_nbuf_map_check_for_smmu_leaks(void)916 void qdf_nbuf_map_check_for_smmu_leaks(void) 917 { 918 qdf_tracker_check_for_leaks(&qdf_nbuf_smmu_map_tracker); 919 } 920 921 #ifdef IPA_OFFLOAD qdf_nbuf_smmu_map_debug(qdf_nbuf_t nbuf,uint8_t hdl,uint8_t num_buffers,qdf_mem_info_t * info,const char * func,uint32_t line)922 QDF_STATUS qdf_nbuf_smmu_map_debug(qdf_nbuf_t nbuf, 923 uint8_t hdl, 924 uint8_t num_buffers, 925 qdf_mem_info_t *info, 926 const char *func, 927 uint32_t line) 928 { 929 QDF_STATUS status; 930 931 status = qdf_nbuf_track_smmu_map(nbuf, func, line); 932 if (QDF_IS_STATUS_ERROR(status)) 933 return status; 934 935 status = __qdf_ipa_wdi_create_smmu_mapping(hdl, num_buffers, info); 936 937 if (QDF_IS_STATUS_ERROR(status)) { 938 qdf_nbuf_untrack_smmu_map(nbuf, func, line); 939 } else { 940 if (!is_initial_mem_debug_disabled) 941 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_MAP); 942 qdf_net_buf_debug_update_smmu_map_node(nbuf, info->iova, 943 info->pa, func, line); 944 } 945 946 return status; 947 } 948 949 qdf_export_symbol(qdf_nbuf_smmu_map_debug); 950 qdf_nbuf_smmu_unmap_debug(qdf_nbuf_t nbuf,uint8_t hdl,uint8_t num_buffers,qdf_mem_info_t * info,const char * func,uint32_t line)951 QDF_STATUS qdf_nbuf_smmu_unmap_debug(qdf_nbuf_t nbuf, 952 uint8_t hdl, 953 uint8_t num_buffers, 954 qdf_mem_info_t *info, 955 const char *func, 956 uint32_t line) 957 { 958 QDF_STATUS status; 959 960 qdf_nbuf_untrack_smmu_map(nbuf, func, line); 961 status = __qdf_ipa_wdi_release_smmu_mapping(hdl, num_buffers, info); 962 qdf_net_buf_debug_update_smmu_unmap_node(nbuf, info->iova, 963 info->pa, func, line); 964 return status; 965 } 966 967 qdf_export_symbol(qdf_nbuf_smmu_unmap_debug); 968 #endif /* IPA_OFFLOAD */ 969 qdf_nbuf_panic_on_free_if_smmu_mapped(qdf_nbuf_t nbuf,const char * func,uint32_t line)970 static void qdf_nbuf_panic_on_free_if_smmu_mapped(qdf_nbuf_t nbuf, 971 const char *func, 972 uint32_t line) 973 { 974 char map_func[QDF_TRACKER_FUNC_SIZE]; 975 uint32_t map_line; 976 977 if (!qdf_tracker_lookup(&qdf_nbuf_smmu_map_tracker, nbuf, 978 &map_func, &map_line)) 979 return; 980 981 QDF_MEMDEBUG_PANIC("Nbuf freed @ %s:%u while mapped from %s:%u", 982 func, line, map_func, map_line); 983 } 984 qdf_net_buf_update_smmu_params(QDF_NBUF_TRACK * p_node)985 static inline void qdf_net_buf_update_smmu_params(QDF_NBUF_TRACK *p_node) 986 { 987 p_node->smmu_unmap_line_num = 0; 988 p_node->is_nbuf_smmu_mapped = false; 989 p_node->smmu_map_line_num = 0; 990 p_node->smmu_map_func_name[0] = '\0'; 991 p_node->smmu_unmap_func_name[0] = '\0'; 992 p_node->smmu_unmap_iova_addr = 0; 993 p_node->smmu_unmap_pa_addr = 0; 994 p_node->smmu_map_iova_addr = 0; 995 p_node->smmu_map_pa_addr = 0; 996 } 997 #else /* !NBUF_SMMU_MAP_UNMAP_DEBUG */ 998 #ifdef NBUF_MEMORY_DEBUG qdf_nbuf_smmu_map_tracking_init(void)999 static void qdf_nbuf_smmu_map_tracking_init(void) 1000 { 1001 } 1002 qdf_nbuf_smmu_map_tracking_deinit(void)1003 static void qdf_nbuf_smmu_map_tracking_deinit(void) 1004 { 1005 } 1006 qdf_nbuf_panic_on_free_if_smmu_mapped(qdf_nbuf_t nbuf,const char * func,uint32_t line)1007 static void qdf_nbuf_panic_on_free_if_smmu_mapped(qdf_nbuf_t nbuf, 1008 const char *func, 1009 uint32_t line) 1010 { 1011 } 1012 qdf_net_buf_update_smmu_params(QDF_NBUF_TRACK * p_node)1013 static inline void qdf_net_buf_update_smmu_params(QDF_NBUF_TRACK *p_node) 1014 { 1015 } 1016 #endif /* NBUF_MEMORY_DEBUG */ 1017 1018 #ifdef IPA_OFFLOAD qdf_nbuf_smmu_map_debug(qdf_nbuf_t nbuf,uint8_t hdl,uint8_t num_buffers,qdf_mem_info_t * info,const char * func,uint32_t line)1019 QDF_STATUS qdf_nbuf_smmu_map_debug(qdf_nbuf_t nbuf, 1020 uint8_t hdl, 1021 uint8_t num_buffers, 1022 qdf_mem_info_t *info, 1023 const char *func, 1024 uint32_t line) 1025 { 1026 return __qdf_ipa_wdi_create_smmu_mapping(hdl, num_buffers, info); 1027 } 1028 1029 qdf_export_symbol(qdf_nbuf_smmu_map_debug); 1030 qdf_nbuf_smmu_unmap_debug(qdf_nbuf_t nbuf,uint8_t hdl,uint8_t num_buffers,qdf_mem_info_t * info,const char * func,uint32_t line)1031 QDF_STATUS qdf_nbuf_smmu_unmap_debug(qdf_nbuf_t nbuf, 1032 uint8_t hdl, 1033 uint8_t num_buffers, 1034 qdf_mem_info_t *info, 1035 const char *func, 1036 uint32_t line) 1037 { 1038 return __qdf_ipa_wdi_release_smmu_mapping(hdl, num_buffers, info); 1039 } 1040 1041 qdf_export_symbol(qdf_nbuf_smmu_unmap_debug); 1042 #endif /* IPA_OFFLOAD */ 1043 #endif /* NBUF_SMMU_MAP_UNMAP_DEBUG */ 1044 1045 #ifdef NBUF_MAP_UNMAP_DEBUG 1046 #define qdf_nbuf_map_tracker_bits 11 /* 2048 buckets */ 1047 qdf_tracker_declare(qdf_nbuf_map_tracker, qdf_nbuf_map_tracker_bits, 1048 "nbuf map-no-unmap events", "nbuf map", "nbuf unmap"); 1049 qdf_nbuf_map_tracking_init(void)1050 static void qdf_nbuf_map_tracking_init(void) 1051 { 1052 qdf_tracker_init(&qdf_nbuf_map_tracker); 1053 } 1054 qdf_nbuf_map_tracking_deinit(void)1055 static void qdf_nbuf_map_tracking_deinit(void) 1056 { 1057 qdf_tracker_deinit(&qdf_nbuf_map_tracker); 1058 } 1059 1060 static QDF_STATUS qdf_nbuf_track_map(qdf_nbuf_t nbuf,const char * func,uint32_t line)1061 qdf_nbuf_track_map(qdf_nbuf_t nbuf, const char *func, uint32_t line) 1062 { 1063 if (is_initial_mem_debug_disabled) 1064 return QDF_STATUS_SUCCESS; 1065 1066 return qdf_tracker_track(&qdf_nbuf_map_tracker, nbuf, func, line); 1067 } 1068 1069 static void qdf_nbuf_untrack_map(qdf_nbuf_t nbuf,const char * func,uint32_t line)1070 qdf_nbuf_untrack_map(qdf_nbuf_t nbuf, const char *func, uint32_t line) 1071 { 1072 if (is_initial_mem_debug_disabled) 1073 return; 1074 1075 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_UNMAP); 1076 qdf_tracker_untrack(&qdf_nbuf_map_tracker, nbuf, func, line); 1077 } 1078 qdf_nbuf_map_check_for_leaks(void)1079 void qdf_nbuf_map_check_for_leaks(void) 1080 { 1081 qdf_tracker_check_for_leaks(&qdf_nbuf_map_tracker); 1082 } 1083 qdf_nbuf_map_debug(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir,const char * func,uint32_t line)1084 QDF_STATUS qdf_nbuf_map_debug(qdf_device_t osdev, 1085 qdf_nbuf_t buf, 1086 qdf_dma_dir_t dir, 1087 const char *func, 1088 uint32_t line) 1089 { 1090 QDF_STATUS status; 1091 1092 status = qdf_nbuf_track_map(buf, func, line); 1093 if (QDF_IS_STATUS_ERROR(status)) 1094 return status; 1095 1096 status = __qdf_nbuf_map(osdev, buf, dir); 1097 if (QDF_IS_STATUS_ERROR(status)) { 1098 qdf_nbuf_untrack_map(buf, func, line); 1099 } else { 1100 if (!is_initial_mem_debug_disabled) 1101 qdf_nbuf_history_add(buf, func, line, QDF_NBUF_MAP); 1102 qdf_net_buf_debug_update_map_node(buf, func, line); 1103 } 1104 1105 return status; 1106 } 1107 1108 qdf_export_symbol(qdf_nbuf_map_debug); 1109 qdf_nbuf_unmap_debug(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir,const char * func,uint32_t line)1110 void qdf_nbuf_unmap_debug(qdf_device_t osdev, 1111 qdf_nbuf_t buf, 1112 qdf_dma_dir_t dir, 1113 const char *func, 1114 uint32_t line) 1115 { 1116 qdf_nbuf_untrack_map(buf, func, line); 1117 __qdf_nbuf_unmap_single(osdev, buf, dir); 1118 qdf_net_buf_debug_update_unmap_node(buf, func, line); 1119 } 1120 1121 qdf_export_symbol(qdf_nbuf_unmap_debug); 1122 qdf_nbuf_map_single_debug(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir,const char * func,uint32_t line)1123 QDF_STATUS qdf_nbuf_map_single_debug(qdf_device_t osdev, 1124 qdf_nbuf_t buf, 1125 qdf_dma_dir_t dir, 1126 const char *func, 1127 uint32_t line) 1128 { 1129 QDF_STATUS status; 1130 1131 status = qdf_nbuf_track_map(buf, func, line); 1132 if (QDF_IS_STATUS_ERROR(status)) 1133 return status; 1134 1135 status = __qdf_nbuf_map_single(osdev, buf, dir); 1136 if (QDF_IS_STATUS_ERROR(status)) { 1137 qdf_nbuf_untrack_map(buf, func, line); 1138 } else { 1139 if (!is_initial_mem_debug_disabled) 1140 qdf_nbuf_history_add(buf, func, line, QDF_NBUF_MAP); 1141 qdf_net_buf_debug_update_map_node(buf, func, line); 1142 } 1143 1144 return status; 1145 } 1146 1147 qdf_export_symbol(qdf_nbuf_map_single_debug); 1148 qdf_nbuf_unmap_single_debug(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir,const char * func,uint32_t line)1149 void qdf_nbuf_unmap_single_debug(qdf_device_t osdev, 1150 qdf_nbuf_t buf, 1151 qdf_dma_dir_t dir, 1152 const char *func, 1153 uint32_t line) 1154 { 1155 qdf_nbuf_untrack_map(buf, func, line); 1156 __qdf_nbuf_unmap_single(osdev, buf, dir); 1157 qdf_net_buf_debug_update_unmap_node(buf, func, line); 1158 } 1159 1160 qdf_export_symbol(qdf_nbuf_unmap_single_debug); 1161 qdf_nbuf_map_nbytes_debug(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir,int nbytes,const char * func,uint32_t line)1162 QDF_STATUS qdf_nbuf_map_nbytes_debug(qdf_device_t osdev, 1163 qdf_nbuf_t buf, 1164 qdf_dma_dir_t dir, 1165 int nbytes, 1166 const char *func, 1167 uint32_t line) 1168 { 1169 QDF_STATUS status; 1170 1171 status = qdf_nbuf_track_map(buf, func, line); 1172 if (QDF_IS_STATUS_ERROR(status)) 1173 return status; 1174 1175 status = __qdf_nbuf_map_nbytes(osdev, buf, dir, nbytes); 1176 if (QDF_IS_STATUS_ERROR(status)) { 1177 qdf_nbuf_untrack_map(buf, func, line); 1178 } else { 1179 if (!is_initial_mem_debug_disabled) 1180 qdf_nbuf_history_add(buf, func, line, QDF_NBUF_MAP); 1181 qdf_net_buf_debug_update_map_node(buf, func, line); 1182 } 1183 1184 return status; 1185 } 1186 1187 qdf_export_symbol(qdf_nbuf_map_nbytes_debug); 1188 qdf_nbuf_unmap_nbytes_debug(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir,int nbytes,const char * func,uint32_t line)1189 void qdf_nbuf_unmap_nbytes_debug(qdf_device_t osdev, 1190 qdf_nbuf_t buf, 1191 qdf_dma_dir_t dir, 1192 int nbytes, 1193 const char *func, 1194 uint32_t line) 1195 { 1196 qdf_nbuf_untrack_map(buf, func, line); 1197 __qdf_nbuf_unmap_nbytes(osdev, buf, dir, nbytes); 1198 qdf_net_buf_debug_update_unmap_node(buf, func, line); 1199 } 1200 1201 qdf_export_symbol(qdf_nbuf_unmap_nbytes_debug); 1202 qdf_nbuf_map_nbytes_single_debug(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir,int nbytes,const char * func,uint32_t line)1203 QDF_STATUS qdf_nbuf_map_nbytes_single_debug(qdf_device_t osdev, 1204 qdf_nbuf_t buf, 1205 qdf_dma_dir_t dir, 1206 int nbytes, 1207 const char *func, 1208 uint32_t line) 1209 { 1210 QDF_STATUS status; 1211 1212 status = qdf_nbuf_track_map(buf, func, line); 1213 if (QDF_IS_STATUS_ERROR(status)) 1214 return status; 1215 1216 status = __qdf_nbuf_map_nbytes_single(osdev, buf, dir, nbytes); 1217 if (QDF_IS_STATUS_ERROR(status)) { 1218 qdf_nbuf_untrack_map(buf, func, line); 1219 } else { 1220 if (!is_initial_mem_debug_disabled) 1221 qdf_nbuf_history_add(buf, func, line, QDF_NBUF_MAP); 1222 qdf_net_buf_debug_update_map_node(buf, func, line); 1223 } 1224 1225 return status; 1226 } 1227 1228 qdf_export_symbol(qdf_nbuf_map_nbytes_single_debug); 1229 qdf_nbuf_unmap_nbytes_single_debug(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir,int nbytes,const char * func,uint32_t line)1230 void qdf_nbuf_unmap_nbytes_single_debug(qdf_device_t osdev, 1231 qdf_nbuf_t buf, 1232 qdf_dma_dir_t dir, 1233 int nbytes, 1234 const char *func, 1235 uint32_t line) 1236 { 1237 qdf_nbuf_untrack_map(buf, func, line); 1238 __qdf_nbuf_unmap_nbytes_single(osdev, buf, dir, nbytes); 1239 qdf_net_buf_debug_update_unmap_node(buf, func, line); 1240 } 1241 1242 qdf_export_symbol(qdf_nbuf_unmap_nbytes_single_debug); 1243 qdf_nbuf_unmap_nbytes_single_paddr_debug(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_addr_t phy_addr,qdf_dma_dir_t dir,int nbytes,const char * func,uint32_t line)1244 void qdf_nbuf_unmap_nbytes_single_paddr_debug(qdf_device_t osdev, 1245 qdf_nbuf_t buf, 1246 qdf_dma_addr_t phy_addr, 1247 qdf_dma_dir_t dir, int nbytes, 1248 const char *func, uint32_t line) 1249 { 1250 qdf_nbuf_untrack_map(buf, func, line); 1251 __qdf_record_nbuf_nbytes(__qdf_nbuf_get_end_offset(buf), dir, false); 1252 __qdf_mem_unmap_nbytes_single(osdev, phy_addr, dir, nbytes); 1253 qdf_net_buf_debug_update_unmap_node(buf, func, line); 1254 } 1255 1256 qdf_export_symbol(qdf_nbuf_unmap_nbytes_single_paddr_debug); 1257 qdf_nbuf_panic_on_free_if_mapped(qdf_nbuf_t nbuf,const char * func,uint32_t line)1258 static void qdf_nbuf_panic_on_free_if_mapped(qdf_nbuf_t nbuf, 1259 const char *func, 1260 uint32_t line) 1261 { 1262 char map_func[QDF_TRACKER_FUNC_SIZE]; 1263 uint32_t map_line; 1264 1265 if (!qdf_tracker_lookup(&qdf_nbuf_map_tracker, nbuf, 1266 &map_func, &map_line)) 1267 return; 1268 1269 QDF_MEMDEBUG_PANIC("Nbuf freed @ %s:%u while mapped from %s:%u", 1270 func, line, map_func, map_line); 1271 } 1272 #else qdf_nbuf_map_tracking_init(void)1273 static inline void qdf_nbuf_map_tracking_init(void) 1274 { 1275 } 1276 qdf_nbuf_map_tracking_deinit(void)1277 static inline void qdf_nbuf_map_tracking_deinit(void) 1278 { 1279 } 1280 qdf_nbuf_panic_on_free_if_mapped(qdf_nbuf_t nbuf,const char * func,uint32_t line)1281 static inline void qdf_nbuf_panic_on_free_if_mapped(qdf_nbuf_t nbuf, 1282 const char *func, 1283 uint32_t line) 1284 { 1285 } 1286 #endif /* NBUF_MAP_UNMAP_DEBUG */ 1287 1288 #ifdef QDF_OS_DEBUG 1289 QDF_STATUS __qdf_nbuf_map(qdf_device_t osdev,struct sk_buff * skb,qdf_dma_dir_t dir)1290 __qdf_nbuf_map(qdf_device_t osdev, struct sk_buff *skb, qdf_dma_dir_t dir) 1291 { 1292 struct skb_shared_info *sh = skb_shinfo(skb); 1293 1294 qdf_assert((dir == QDF_DMA_TO_DEVICE) 1295 || (dir == QDF_DMA_FROM_DEVICE)); 1296 1297 /* 1298 * Assume there's only a single fragment. 1299 * To support multiple fragments, it would be necessary to change 1300 * qdf_nbuf_t to be a separate object that stores meta-info 1301 * (including the bus address for each fragment) and a pointer 1302 * to the underlying sk_buff. 1303 */ 1304 qdf_assert(sh->nr_frags == 0); 1305 1306 return __qdf_nbuf_map_single(osdev, skb, dir); 1307 } 1308 qdf_export_symbol(__qdf_nbuf_map); 1309 1310 #else 1311 QDF_STATUS __qdf_nbuf_map(qdf_device_t osdev,struct sk_buff * skb,qdf_dma_dir_t dir)1312 __qdf_nbuf_map(qdf_device_t osdev, struct sk_buff *skb, qdf_dma_dir_t dir) 1313 { 1314 return __qdf_nbuf_map_single(osdev, skb, dir); 1315 } 1316 qdf_export_symbol(__qdf_nbuf_map); 1317 #endif 1318 1319 void __qdf_nbuf_unmap(qdf_device_t osdev,struct sk_buff * skb,qdf_dma_dir_t dir)1320 __qdf_nbuf_unmap(qdf_device_t osdev, struct sk_buff *skb, 1321 qdf_dma_dir_t dir) 1322 { 1323 qdf_assert((dir == QDF_DMA_TO_DEVICE) 1324 || (dir == QDF_DMA_FROM_DEVICE)); 1325 1326 /* 1327 * Assume there's a single fragment. 1328 * If this is not true, the assertion in __qdf_nbuf_map will catch it. 1329 */ 1330 __qdf_nbuf_unmap_single(osdev, skb, dir); 1331 } 1332 qdf_export_symbol(__qdf_nbuf_unmap); 1333 1334 #if defined(A_SIMOS_DEVHOST) || defined(HIF_USB) || defined(HIF_SDIO) 1335 QDF_STATUS __qdf_nbuf_map_single(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir)1336 __qdf_nbuf_map_single(qdf_device_t osdev, qdf_nbuf_t buf, qdf_dma_dir_t dir) 1337 { 1338 qdf_dma_addr_t paddr; 1339 1340 QDF_NBUF_CB_PADDR(buf) = paddr = (uintptr_t)buf->data; 1341 BUILD_BUG_ON(sizeof(paddr) < sizeof(buf->data)); 1342 BUILD_BUG_ON(sizeof(QDF_NBUF_CB_PADDR(buf)) < sizeof(buf->data)); 1343 return QDF_STATUS_SUCCESS; 1344 } 1345 qdf_export_symbol(__qdf_nbuf_map_single); 1346 #else 1347 QDF_STATUS __qdf_nbuf_map_single(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir)1348 __qdf_nbuf_map_single(qdf_device_t osdev, qdf_nbuf_t buf, qdf_dma_dir_t dir) 1349 { 1350 qdf_dma_addr_t paddr; 1351 1352 /* assume that the OS only provides a single fragment */ 1353 QDF_NBUF_CB_PADDR(buf) = paddr = 1354 dma_map_single(osdev->dev, buf->data, 1355 skb_end_pointer(buf) - buf->data, 1356 __qdf_dma_dir_to_os(dir)); 1357 __qdf_record_nbuf_nbytes( 1358 __qdf_nbuf_get_end_offset(buf), dir, true); 1359 return dma_mapping_error(osdev->dev, paddr) 1360 ? QDF_STATUS_E_FAILURE 1361 : QDF_STATUS_SUCCESS; 1362 } 1363 qdf_export_symbol(__qdf_nbuf_map_single); 1364 #endif 1365 1366 #if defined(A_SIMOS_DEVHOST) || defined(HIF_USB) || defined(HIF_SDIO) __qdf_nbuf_unmap_single(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir)1367 void __qdf_nbuf_unmap_single(qdf_device_t osdev, qdf_nbuf_t buf, 1368 qdf_dma_dir_t dir) 1369 { 1370 } 1371 #else __qdf_nbuf_unmap_single(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir)1372 void __qdf_nbuf_unmap_single(qdf_device_t osdev, qdf_nbuf_t buf, 1373 qdf_dma_dir_t dir) 1374 { 1375 if (QDF_NBUF_CB_PADDR(buf)) { 1376 __qdf_record_nbuf_nbytes( 1377 __qdf_nbuf_get_end_offset(buf), dir, false); 1378 dma_unmap_single(osdev->dev, QDF_NBUF_CB_PADDR(buf), 1379 skb_end_pointer(buf) - buf->data, 1380 __qdf_dma_dir_to_os(dir)); 1381 } 1382 } 1383 #endif 1384 qdf_export_symbol(__qdf_nbuf_unmap_single); 1385 1386 QDF_STATUS __qdf_nbuf_set_rx_cksum(struct sk_buff * skb,qdf_nbuf_rx_cksum_t * cksum)1387 __qdf_nbuf_set_rx_cksum(struct sk_buff *skb, qdf_nbuf_rx_cksum_t *cksum) 1388 { 1389 switch (cksum->l4_result) { 1390 case QDF_NBUF_RX_CKSUM_NONE: 1391 skb->ip_summed = CHECKSUM_NONE; 1392 break; 1393 case QDF_NBUF_RX_CKSUM_TCP_UDP_UNNECESSARY: 1394 skb->ip_summed = CHECKSUM_UNNECESSARY; 1395 skb->csum_level = cksum->csum_level; 1396 break; 1397 case QDF_NBUF_RX_CKSUM_TCP_UDP_HW: 1398 skb->ip_summed = CHECKSUM_PARTIAL; 1399 skb->csum = cksum->val; 1400 break; 1401 default: 1402 pr_err("Unknown checksum type\n"); 1403 qdf_assert(0); 1404 return QDF_STATUS_E_NOSUPPORT; 1405 } 1406 return QDF_STATUS_SUCCESS; 1407 } 1408 qdf_export_symbol(__qdf_nbuf_set_rx_cksum); 1409 __qdf_nbuf_get_tx_cksum(struct sk_buff * skb)1410 qdf_nbuf_tx_cksum_t __qdf_nbuf_get_tx_cksum(struct sk_buff *skb) 1411 { 1412 switch (skb->ip_summed) { 1413 case CHECKSUM_NONE: 1414 return QDF_NBUF_TX_CKSUM_NONE; 1415 case CHECKSUM_PARTIAL: 1416 return QDF_NBUF_TX_CKSUM_TCP_UDP; 1417 case CHECKSUM_COMPLETE: 1418 return QDF_NBUF_TX_CKSUM_TCP_UDP_IP; 1419 default: 1420 return QDF_NBUF_TX_CKSUM_NONE; 1421 } 1422 } 1423 qdf_export_symbol(__qdf_nbuf_get_tx_cksum); 1424 __qdf_nbuf_get_tid(struct sk_buff * skb)1425 uint8_t __qdf_nbuf_get_tid(struct sk_buff *skb) 1426 { 1427 return skb->priority; 1428 } 1429 qdf_export_symbol(__qdf_nbuf_get_tid); 1430 __qdf_nbuf_set_tid(struct sk_buff * skb,uint8_t tid)1431 void __qdf_nbuf_set_tid(struct sk_buff *skb, uint8_t tid) 1432 { 1433 skb->priority = tid; 1434 } 1435 qdf_export_symbol(__qdf_nbuf_set_tid); 1436 __qdf_nbuf_get_exemption_type(struct sk_buff * skb)1437 uint8_t __qdf_nbuf_get_exemption_type(struct sk_buff *skb) 1438 { 1439 return QDF_NBUF_EXEMPT_NO_EXEMPTION; 1440 } 1441 qdf_export_symbol(__qdf_nbuf_get_exemption_type); 1442 __qdf_nbuf_reg_trace_cb(qdf_nbuf_trace_update_t cb_func_ptr)1443 void __qdf_nbuf_reg_trace_cb(qdf_nbuf_trace_update_t cb_func_ptr) 1444 { 1445 qdf_trace_update_cb = cb_func_ptr; 1446 } 1447 qdf_export_symbol(__qdf_nbuf_reg_trace_cb); 1448 1449 enum qdf_proto_subtype __qdf_nbuf_data_get_dhcp_subtype(uint8_t * data)1450 __qdf_nbuf_data_get_dhcp_subtype(uint8_t *data) 1451 { 1452 enum qdf_proto_subtype subtype = QDF_PROTO_INVALID; 1453 1454 if ((data[QDF_DHCP_OPTION53_OFFSET] == QDF_DHCP_OPTION53) && 1455 (data[QDF_DHCP_OPTION53_LENGTH_OFFSET] == 1456 QDF_DHCP_OPTION53_LENGTH)) { 1457 1458 switch (data[QDF_DHCP_OPTION53_STATUS_OFFSET]) { 1459 case QDF_DHCP_DISCOVER: 1460 subtype = QDF_PROTO_DHCP_DISCOVER; 1461 break; 1462 case QDF_DHCP_REQUEST: 1463 subtype = QDF_PROTO_DHCP_REQUEST; 1464 break; 1465 case QDF_DHCP_OFFER: 1466 subtype = QDF_PROTO_DHCP_OFFER; 1467 break; 1468 case QDF_DHCP_ACK: 1469 subtype = QDF_PROTO_DHCP_ACK; 1470 break; 1471 case QDF_DHCP_NAK: 1472 subtype = QDF_PROTO_DHCP_NACK; 1473 break; 1474 case QDF_DHCP_RELEASE: 1475 subtype = QDF_PROTO_DHCP_RELEASE; 1476 break; 1477 case QDF_DHCP_INFORM: 1478 subtype = QDF_PROTO_DHCP_INFORM; 1479 break; 1480 case QDF_DHCP_DECLINE: 1481 subtype = QDF_PROTO_DHCP_DECLINE; 1482 break; 1483 default: 1484 break; 1485 } 1486 } 1487 1488 return subtype; 1489 } 1490 1491 #define EAPOL_WPA_KEY_INFO_ACK BIT(7) 1492 #define EAPOL_WPA_KEY_INFO_MIC BIT(8) 1493 #define EAPOL_WPA_KEY_INFO_ENCR_KEY_DATA BIT(12) /* IEEE 802.11i/RSN only */ 1494 1495 /** 1496 * __qdf_nbuf_data_get_eapol_key() - Get EAPOL key 1497 * @data: Pointer to EAPOL packet data buffer 1498 * 1499 * We can distinguish M1/M3 from M2/M4 by the ack bit in the keyinfo field 1500 * The ralationship between the ack bit and EAPOL type is as follows: 1501 * 1502 * EAPOL type | M1 M2 M3 M4 1503 * -------------------------------------- 1504 * Ack | 1 0 1 0 1505 * -------------------------------------- 1506 * 1507 * Then, we can differentiate M1 from M3, M2 from M4 by below methods: 1508 * M2/M4: by keyDataLength or Nonce value being 0 for M4. 1509 * M1/M3: by the mic/encrKeyData bit in the keyinfo field. 1510 * 1511 * Return: subtype of the EAPOL packet. 1512 */ 1513 static inline enum qdf_proto_subtype __qdf_nbuf_data_get_eapol_key(uint8_t * data)1514 __qdf_nbuf_data_get_eapol_key(uint8_t *data) 1515 { 1516 uint16_t key_info, key_data_length; 1517 enum qdf_proto_subtype subtype; 1518 uint64_t *key_nonce; 1519 1520 key_info = qdf_ntohs((uint16_t)(*(uint16_t *) 1521 (data + EAPOL_KEY_INFO_OFFSET))); 1522 1523 key_data_length = qdf_ntohs((uint16_t)(*(uint16_t *) 1524 (data + EAPOL_KEY_DATA_LENGTH_OFFSET))); 1525 key_nonce = (uint64_t *)(data + EAPOL_WPA_KEY_NONCE_OFFSET); 1526 1527 if (key_info & EAPOL_WPA_KEY_INFO_ACK) 1528 if (key_info & 1529 (EAPOL_WPA_KEY_INFO_MIC | EAPOL_WPA_KEY_INFO_ENCR_KEY_DATA)) 1530 subtype = QDF_PROTO_EAPOL_M3; 1531 else 1532 subtype = QDF_PROTO_EAPOL_M1; 1533 else 1534 if (key_data_length == 0 || 1535 !((*key_nonce) || (*(key_nonce + 1)) || 1536 (*(key_nonce + 2)) || (*(key_nonce + 3)))) 1537 subtype = QDF_PROTO_EAPOL_M4; 1538 else 1539 subtype = QDF_PROTO_EAPOL_M2; 1540 1541 return subtype; 1542 } 1543 1544 /** 1545 * __qdf_nbuf_data_get_exp_msg_type() - Get EAP expanded msg type 1546 * @data: Pointer to EAPOL packet data buffer 1547 * @code: EAP code 1548 * 1549 * Return: subtype of the EAPOL packet. 1550 */ 1551 static inline enum qdf_proto_subtype __qdf_nbuf_data_get_exp_msg_type(uint8_t * data,uint8_t code)1552 __qdf_nbuf_data_get_exp_msg_type(uint8_t *data, uint8_t code) 1553 { 1554 uint8_t msg_type; 1555 uint8_t opcode = *(data + EAP_EXP_MSG_OPCODE_OFFSET); 1556 1557 switch (opcode) { 1558 case WSC_START: 1559 return QDF_PROTO_EAP_WSC_START; 1560 case WSC_ACK: 1561 return QDF_PROTO_EAP_WSC_ACK; 1562 case WSC_NACK: 1563 return QDF_PROTO_EAP_WSC_NACK; 1564 case WSC_MSG: 1565 msg_type = *(data + EAP_EXP_MSG_TYPE_OFFSET); 1566 switch (msg_type) { 1567 case EAP_EXP_TYPE_M1: 1568 return QDF_PROTO_EAP_M1; 1569 case EAP_EXP_TYPE_M2: 1570 return QDF_PROTO_EAP_M2; 1571 case EAP_EXP_TYPE_M3: 1572 return QDF_PROTO_EAP_M3; 1573 case EAP_EXP_TYPE_M4: 1574 return QDF_PROTO_EAP_M4; 1575 case EAP_EXP_TYPE_M5: 1576 return QDF_PROTO_EAP_M5; 1577 case EAP_EXP_TYPE_M6: 1578 return QDF_PROTO_EAP_M6; 1579 case EAP_EXP_TYPE_M7: 1580 return QDF_PROTO_EAP_M7; 1581 case EAP_EXP_TYPE_M8: 1582 return QDF_PROTO_EAP_M8; 1583 default: 1584 break; 1585 } 1586 break; 1587 case WSC_DONE: 1588 return QDF_PROTO_EAP_WSC_DONE; 1589 case WSC_FRAG_ACK: 1590 return QDF_PROTO_EAP_WSC_FRAG_ACK; 1591 default: 1592 break; 1593 } 1594 switch (code) { 1595 case QDF_EAP_REQUEST: 1596 return QDF_PROTO_EAP_REQUEST; 1597 case QDF_EAP_RESPONSE: 1598 return QDF_PROTO_EAP_RESPONSE; 1599 default: 1600 return QDF_PROTO_INVALID; 1601 } 1602 } 1603 1604 /** 1605 * __qdf_nbuf_data_get_eap_type() - Get EAP type 1606 * @data: Pointer to EAPOL packet data buffer 1607 * @code: EAP code 1608 * 1609 * Return: subtype of the EAPOL packet. 1610 */ 1611 static inline enum qdf_proto_subtype __qdf_nbuf_data_get_eap_type(uint8_t * data,uint8_t code)1612 __qdf_nbuf_data_get_eap_type(uint8_t *data, uint8_t code) 1613 { 1614 uint8_t type = *(data + EAP_TYPE_OFFSET); 1615 1616 switch (type) { 1617 case EAP_PACKET_TYPE_EXP: 1618 return __qdf_nbuf_data_get_exp_msg_type(data, code); 1619 case EAP_PACKET_TYPE_ID: 1620 switch (code) { 1621 case QDF_EAP_REQUEST: 1622 return QDF_PROTO_EAP_REQ_ID; 1623 case QDF_EAP_RESPONSE: 1624 return QDF_PROTO_EAP_RSP_ID; 1625 default: 1626 return QDF_PROTO_INVALID; 1627 } 1628 default: 1629 switch (code) { 1630 case QDF_EAP_REQUEST: 1631 return QDF_PROTO_EAP_REQUEST; 1632 case QDF_EAP_RESPONSE: 1633 return QDF_PROTO_EAP_RESPONSE; 1634 default: 1635 return QDF_PROTO_INVALID; 1636 } 1637 } 1638 } 1639 1640 /** 1641 * __qdf_nbuf_data_get_eap_code() - Get EAPOL code 1642 * @data: Pointer to EAPOL packet data buffer 1643 * 1644 * Return: subtype of the EAPOL packet. 1645 */ 1646 static inline enum qdf_proto_subtype __qdf_nbuf_data_get_eap_code(uint8_t * data)1647 __qdf_nbuf_data_get_eap_code(uint8_t *data) 1648 { 1649 uint8_t code = *(data + EAP_CODE_OFFSET); 1650 1651 switch (code) { 1652 case QDF_EAP_REQUEST: 1653 case QDF_EAP_RESPONSE: 1654 return __qdf_nbuf_data_get_eap_type(data, code); 1655 case QDF_EAP_SUCCESS: 1656 return QDF_PROTO_EAP_SUCCESS; 1657 case QDF_EAP_FAILURE: 1658 return QDF_PROTO_EAP_FAILURE; 1659 case QDF_EAP_INITIATE: 1660 return QDF_PROTO_EAP_INITIATE; 1661 case QDF_EAP_FINISH: 1662 return QDF_PROTO_EAP_FINISH; 1663 default: 1664 return QDF_PROTO_INVALID; 1665 } 1666 } 1667 1668 enum qdf_proto_subtype __qdf_nbuf_data_get_eapol_subtype(uint8_t * data)1669 __qdf_nbuf_data_get_eapol_subtype(uint8_t *data) 1670 { 1671 uint8_t pkt_type = *(data + EAPOL_PACKET_TYPE_OFFSET); 1672 1673 switch (pkt_type) { 1674 case EAPOL_PACKET_TYPE_EAP: 1675 return __qdf_nbuf_data_get_eap_code(data); 1676 case EAPOL_PACKET_TYPE_START: 1677 return QDF_PROTO_EAPOL_START; 1678 case EAPOL_PACKET_TYPE_LOGOFF: 1679 return QDF_PROTO_EAPOL_LOGOFF; 1680 case EAPOL_PACKET_TYPE_KEY: 1681 return __qdf_nbuf_data_get_eapol_key(data); 1682 case EAPOL_PACKET_TYPE_ASF: 1683 return QDF_PROTO_EAPOL_ASF; 1684 default: 1685 return QDF_PROTO_INVALID; 1686 } 1687 } 1688 1689 qdf_export_symbol(__qdf_nbuf_data_get_eapol_subtype); 1690 1691 enum qdf_proto_subtype __qdf_nbuf_data_get_arp_subtype(uint8_t * data)1692 __qdf_nbuf_data_get_arp_subtype(uint8_t *data) 1693 { 1694 uint16_t subtype; 1695 enum qdf_proto_subtype proto_subtype = QDF_PROTO_INVALID; 1696 1697 subtype = (uint16_t)(*(uint16_t *) 1698 (data + ARP_SUB_TYPE_OFFSET)); 1699 1700 switch (QDF_SWAP_U16(subtype)) { 1701 case ARP_REQUEST: 1702 proto_subtype = QDF_PROTO_ARP_REQ; 1703 break; 1704 case ARP_RESPONSE: 1705 proto_subtype = QDF_PROTO_ARP_RES; 1706 break; 1707 default: 1708 break; 1709 } 1710 1711 return proto_subtype; 1712 } 1713 1714 enum qdf_proto_subtype __qdf_nbuf_data_get_icmp_subtype(uint8_t * data)1715 __qdf_nbuf_data_get_icmp_subtype(uint8_t *data) 1716 { 1717 uint8_t subtype; 1718 enum qdf_proto_subtype proto_subtype = QDF_PROTO_INVALID; 1719 1720 subtype = (uint8_t)(*(uint8_t *) 1721 (data + ICMP_SUBTYPE_OFFSET)); 1722 1723 switch (subtype) { 1724 case ICMP_REQUEST: 1725 proto_subtype = QDF_PROTO_ICMP_REQ; 1726 break; 1727 case ICMP_RESPONSE: 1728 proto_subtype = QDF_PROTO_ICMP_RES; 1729 break; 1730 default: 1731 break; 1732 } 1733 1734 return proto_subtype; 1735 } 1736 1737 enum qdf_proto_subtype __qdf_nbuf_data_get_icmpv6_subtype(uint8_t * data)1738 __qdf_nbuf_data_get_icmpv6_subtype(uint8_t *data) 1739 { 1740 uint8_t subtype; 1741 enum qdf_proto_subtype proto_subtype = QDF_PROTO_INVALID; 1742 1743 subtype = (uint8_t)(*(uint8_t *) 1744 (data + ICMPV6_SUBTYPE_OFFSET)); 1745 1746 switch (subtype) { 1747 case ICMPV6_REQUEST: 1748 proto_subtype = QDF_PROTO_ICMPV6_REQ; 1749 break; 1750 case ICMPV6_RESPONSE: 1751 proto_subtype = QDF_PROTO_ICMPV6_RES; 1752 break; 1753 case ICMPV6_RS: 1754 proto_subtype = QDF_PROTO_ICMPV6_RS; 1755 break; 1756 case ICMPV6_RA: 1757 proto_subtype = QDF_PROTO_ICMPV6_RA; 1758 break; 1759 case ICMPV6_NS: 1760 proto_subtype = QDF_PROTO_ICMPV6_NS; 1761 break; 1762 case ICMPV6_NA: 1763 proto_subtype = QDF_PROTO_ICMPV6_NA; 1764 break; 1765 default: 1766 break; 1767 } 1768 1769 return proto_subtype; 1770 } 1771 1772 bool __qdf_nbuf_is_ipv4_last_fragment(struct sk_buff * skb)1773 __qdf_nbuf_is_ipv4_last_fragment(struct sk_buff *skb) 1774 { 1775 if (((ntohs(ip_hdr(skb)->frag_off) & ~IP_OFFSET) & IP_MF) == 0) 1776 return true; 1777 1778 return false; 1779 } 1780 1781 bool __qdf_nbuf_is_ipv4_fragment(struct sk_buff * skb)1782 __qdf_nbuf_is_ipv4_fragment(struct sk_buff *skb) 1783 { 1784 if (ntohs(ip_hdr(skb)->frag_off) & IP_MF) 1785 return true; 1786 1787 return false; 1788 } 1789 1790 void __qdf_nbuf_data_set_ipv4_tos(uint8_t * data,uint8_t tos)1791 __qdf_nbuf_data_set_ipv4_tos(uint8_t *data, uint8_t tos) 1792 { 1793 *(uint8_t *)(data + QDF_NBUF_TRAC_IPV4_TOS_OFFSET) = tos; 1794 } 1795 1796 uint8_t __qdf_nbuf_data_get_ipv4_tos(uint8_t * data)1797 __qdf_nbuf_data_get_ipv4_tos(uint8_t *data) 1798 { 1799 uint8_t tos; 1800 1801 tos = (uint8_t)(*(uint8_t *)(data + 1802 QDF_NBUF_TRAC_IPV4_TOS_OFFSET)); 1803 return tos; 1804 } 1805 1806 uint8_t __qdf_nbuf_data_get_ipv4_proto(uint8_t * data)1807 __qdf_nbuf_data_get_ipv4_proto(uint8_t *data) 1808 { 1809 uint8_t proto_type; 1810 1811 proto_type = (uint8_t)(*(uint8_t *)(data + 1812 QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); 1813 return proto_type; 1814 } 1815 1816 uint8_t __qdf_nbuf_data_get_ipv6_tc(uint8_t * data)1817 __qdf_nbuf_data_get_ipv6_tc(uint8_t *data) 1818 { 1819 struct ipv6hdr *hdr; 1820 1821 hdr = (struct ipv6hdr *)(data + QDF_NBUF_TRAC_IPV6_OFFSET); 1822 return ip6_tclass(ip6_flowinfo(hdr)); 1823 } 1824 1825 void __qdf_nbuf_data_set_ipv6_tc(uint8_t * data,uint8_t tc)1826 __qdf_nbuf_data_set_ipv6_tc(uint8_t *data, uint8_t tc) 1827 { 1828 struct ipv6hdr *hdr; 1829 1830 hdr = (struct ipv6hdr *)(data + QDF_NBUF_TRAC_IPV6_OFFSET); 1831 ip6_flow_hdr(hdr, tc, ip6_flowlabel(hdr)); 1832 } 1833 1834 uint8_t __qdf_nbuf_data_get_ipv6_proto(uint8_t * data)1835 __qdf_nbuf_data_get_ipv6_proto(uint8_t *data) 1836 { 1837 uint8_t proto_type; 1838 1839 proto_type = (uint8_t)(*(uint8_t *)(data + 1840 QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET)); 1841 return proto_type; 1842 } 1843 __qdf_nbuf_data_is_ipv4_pkt(uint8_t * data)1844 bool __qdf_nbuf_data_is_ipv4_pkt(uint8_t *data) 1845 { 1846 uint16_t ether_type; 1847 1848 ether_type = (uint16_t)(*(uint16_t *)(data + 1849 QDF_NBUF_TRAC_ETH_TYPE_OFFSET)); 1850 1851 if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE)) 1852 return true; 1853 else 1854 return false; 1855 } 1856 qdf_export_symbol(__qdf_nbuf_data_is_ipv4_pkt); 1857 __qdf_nbuf_data_is_ipv4_dhcp_pkt(uint8_t * data)1858 bool __qdf_nbuf_data_is_ipv4_dhcp_pkt(uint8_t *data) 1859 { 1860 uint16_t sport; 1861 uint16_t dport; 1862 uint8_t ipv4_offset; 1863 uint8_t ipv4_hdr_len; 1864 struct iphdr *iphdr; 1865 1866 if (__qdf_nbuf_get_ether_type(data) != 1867 QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE)) 1868 return false; 1869 1870 ipv4_offset = __qdf_nbuf_get_ip_offset(data); 1871 iphdr = (struct iphdr *)(data + ipv4_offset); 1872 ipv4_hdr_len = iphdr->ihl * QDF_NBUF_IPV4_HDR_SIZE_UNIT; 1873 1874 sport = *(uint16_t *)(data + ipv4_offset + ipv4_hdr_len); 1875 dport = *(uint16_t *)(data + ipv4_offset + ipv4_hdr_len + 1876 sizeof(uint16_t)); 1877 1878 if (((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP_SRV_PORT)) && 1879 (dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP_CLI_PORT))) || 1880 ((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP_CLI_PORT)) && 1881 (dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP_SRV_PORT)))) 1882 return true; 1883 else 1884 return false; 1885 } 1886 qdf_export_symbol(__qdf_nbuf_data_is_ipv4_dhcp_pkt); 1887 1888 /** 1889 * qdf_is_eapol_type() - check if packet is EAPOL 1890 * @type: Packet type 1891 * 1892 * This api is to check if frame is EAPOL packet type. 1893 * 1894 * Return: true if it is EAPOL frame 1895 * false otherwise. 1896 */ 1897 #ifdef BIG_ENDIAN_HOST qdf_is_eapol_type(uint16_t type)1898 static inline bool qdf_is_eapol_type(uint16_t type) 1899 { 1900 return (type == QDF_NBUF_TRAC_EAPOL_ETH_TYPE); 1901 } 1902 #else qdf_is_eapol_type(uint16_t type)1903 static inline bool qdf_is_eapol_type(uint16_t type) 1904 { 1905 return (type == QDF_SWAP_U16(QDF_NBUF_TRAC_EAPOL_ETH_TYPE)); 1906 } 1907 #endif 1908 __qdf_nbuf_data_is_ipv4_eapol_pkt(uint8_t * data)1909 bool __qdf_nbuf_data_is_ipv4_eapol_pkt(uint8_t *data) 1910 { 1911 uint16_t ether_type; 1912 1913 ether_type = __qdf_nbuf_get_ether_type(data); 1914 1915 return qdf_is_eapol_type(ether_type); 1916 } 1917 qdf_export_symbol(__qdf_nbuf_data_is_ipv4_eapol_pkt); 1918 __qdf_nbuf_is_ipv4_wapi_pkt(struct sk_buff * skb)1919 bool __qdf_nbuf_is_ipv4_wapi_pkt(struct sk_buff *skb) 1920 { 1921 uint16_t ether_type; 1922 1923 ether_type = (uint16_t)(*(uint16_t *)(skb->data + 1924 QDF_NBUF_TRAC_ETH_TYPE_OFFSET)); 1925 1926 if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_WAPI_ETH_TYPE)) 1927 return true; 1928 else 1929 return false; 1930 } 1931 qdf_export_symbol(__qdf_nbuf_is_ipv4_wapi_pkt); 1932 1933 /** 1934 * qdf_nbuf_is_ipv6_vlan_pkt() - check whether packet is vlan IPV6 1935 * @data: Pointer to network data buffer 1936 * 1937 * This api is for vlan header included ipv6 packet. 1938 * 1939 * Return: true if packet is vlan header included IPV6 1940 * false otherwise. 1941 */ qdf_nbuf_is_ipv6_vlan_pkt(uint8_t * data)1942 static bool qdf_nbuf_is_ipv6_vlan_pkt(uint8_t *data) 1943 { 1944 uint16_t ether_type; 1945 1946 ether_type = *(uint16_t *)(data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET); 1947 1948 if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) { 1949 ether_type = *(uint16_t *)(data + 1950 QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET); 1951 1952 if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV6_ETH_TYPE)) 1953 return true; 1954 } 1955 return false; 1956 } 1957 1958 /** 1959 * qdf_nbuf_is_ipv4_vlan_pkt() - check whether packet is vlan IPV4 1960 * @data: Pointer to network data buffer 1961 * 1962 * This api is for vlan header included ipv4 packet. 1963 * 1964 * Return: true if packet is vlan header included IPV4 1965 * false otherwise. 1966 */ qdf_nbuf_is_ipv4_vlan_pkt(uint8_t * data)1967 static bool qdf_nbuf_is_ipv4_vlan_pkt(uint8_t *data) 1968 { 1969 uint16_t ether_type; 1970 1971 ether_type = *(uint16_t *)(data + QDF_NBUF_TRAC_ETH_TYPE_OFFSET); 1972 1973 if (unlikely(ether_type == QDF_SWAP_U16(QDF_ETH_TYPE_8021Q))) { 1974 ether_type = *(uint16_t *)(data + 1975 QDF_NBUF_TRAC_VLAN_ETH_TYPE_OFFSET); 1976 1977 if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE)) 1978 return true; 1979 } 1980 return false; 1981 } 1982 __qdf_nbuf_data_is_ipv4_igmp_pkt(uint8_t * data)1983 bool __qdf_nbuf_data_is_ipv4_igmp_pkt(uint8_t *data) 1984 { 1985 uint8_t pkt_type; 1986 1987 if (__qdf_nbuf_data_is_ipv4_pkt(data)) { 1988 pkt_type = (uint8_t)(*(uint8_t *)(data + 1989 QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); 1990 goto is_igmp; 1991 } 1992 1993 if (qdf_nbuf_is_ipv4_vlan_pkt(data)) { 1994 pkt_type = (uint8_t)(*(uint8_t *)( 1995 data + 1996 QDF_NBUF_TRAC_VLAN_IPV4_PROTO_TYPE_OFFSET)); 1997 goto is_igmp; 1998 } 1999 2000 return false; 2001 is_igmp: 2002 if (pkt_type == QDF_NBUF_TRAC_IGMP_TYPE) 2003 return true; 2004 2005 return false; 2006 } 2007 2008 qdf_export_symbol(__qdf_nbuf_data_is_ipv4_igmp_pkt); 2009 __qdf_nbuf_data_is_ipv6_igmp_pkt(uint8_t * data)2010 bool __qdf_nbuf_data_is_ipv6_igmp_pkt(uint8_t *data) 2011 { 2012 uint8_t pkt_type; 2013 uint8_t next_hdr; 2014 2015 if (__qdf_nbuf_data_is_ipv6_pkt(data)) { 2016 pkt_type = (uint8_t)(*(uint8_t *)(data + 2017 QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET)); 2018 next_hdr = (uint8_t)(*(uint8_t *)( 2019 data + 2020 QDF_NBUF_TRAC_IPV6_OFFSET + 2021 QDF_NBUF_TRAC_IPV6_HEADER_SIZE)); 2022 goto is_mld; 2023 } 2024 2025 if (qdf_nbuf_is_ipv6_vlan_pkt(data)) { 2026 pkt_type = (uint8_t)(*(uint8_t *)( 2027 data + 2028 QDF_NBUF_TRAC_VLAN_IPV6_PROTO_TYPE_OFFSET)); 2029 next_hdr = (uint8_t)(*(uint8_t *)( 2030 data + 2031 QDF_NBUF_TRAC_VLAN_IPV6_OFFSET + 2032 QDF_NBUF_TRAC_IPV6_HEADER_SIZE)); 2033 goto is_mld; 2034 } 2035 2036 return false; 2037 is_mld: 2038 if (pkt_type == QDF_NBUF_TRAC_ICMPV6_TYPE) 2039 return true; 2040 if ((pkt_type == QDF_NBUF_TRAC_HOPOPTS_TYPE) && 2041 (next_hdr == QDF_NBUF_TRAC_ICMPV6_TYPE)) 2042 return true; 2043 2044 return false; 2045 } 2046 2047 qdf_export_symbol(__qdf_nbuf_data_is_ipv6_igmp_pkt); 2048 __qdf_nbuf_is_ipv4_igmp_leave_pkt(__qdf_nbuf_t buf)2049 bool __qdf_nbuf_is_ipv4_igmp_leave_pkt(__qdf_nbuf_t buf) 2050 { 2051 qdf_ether_header_t *eh = NULL; 2052 uint16_t ether_type; 2053 uint8_t eth_hdr_size = sizeof(qdf_ether_header_t); 2054 2055 eh = (qdf_ether_header_t *)qdf_nbuf_data(buf); 2056 ether_type = eh->ether_type; 2057 2058 if (ether_type == htons(ETH_P_8021Q)) { 2059 struct vlan_ethhdr *veth = 2060 (struct vlan_ethhdr *)qdf_nbuf_data(buf); 2061 ether_type = veth->h_vlan_encapsulated_proto; 2062 eth_hdr_size = sizeof(struct vlan_ethhdr); 2063 } 2064 2065 if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV4_ETH_TYPE)) { 2066 struct iphdr *iph = NULL; 2067 struct igmphdr *ih = NULL; 2068 2069 iph = (struct iphdr *)(qdf_nbuf_data(buf) + eth_hdr_size); 2070 ih = (struct igmphdr *)((uint8_t *)iph + iph->ihl * 4); 2071 switch (ih->type) { 2072 case IGMP_HOST_LEAVE_MESSAGE: 2073 return true; 2074 case IGMPV3_HOST_MEMBERSHIP_REPORT: 2075 { 2076 struct igmpv3_report *ihv3 = (struct igmpv3_report *)ih; 2077 struct igmpv3_grec *grec = NULL; 2078 int num = 0; 2079 int i = 0; 2080 int len = 0; 2081 int type = 0; 2082 2083 num = ntohs(ihv3->ngrec); 2084 for (i = 0; i < num; i++) { 2085 grec = (void *)((uint8_t *)(ihv3->grec) + len); 2086 type = grec->grec_type; 2087 if ((type == IGMPV3_MODE_IS_INCLUDE) || 2088 (type == IGMPV3_CHANGE_TO_INCLUDE)) 2089 return true; 2090 2091 len += sizeof(struct igmpv3_grec); 2092 len += ntohs(grec->grec_nsrcs) * 4; 2093 } 2094 break; 2095 } 2096 default: 2097 break; 2098 } 2099 } 2100 2101 return false; 2102 } 2103 2104 qdf_export_symbol(__qdf_nbuf_is_ipv4_igmp_leave_pkt); 2105 __qdf_nbuf_is_ipv6_igmp_leave_pkt(__qdf_nbuf_t buf)2106 bool __qdf_nbuf_is_ipv6_igmp_leave_pkt(__qdf_nbuf_t buf) 2107 { 2108 qdf_ether_header_t *eh = NULL; 2109 uint16_t ether_type; 2110 uint8_t eth_hdr_size = sizeof(qdf_ether_header_t); 2111 2112 eh = (qdf_ether_header_t *)qdf_nbuf_data(buf); 2113 ether_type = eh->ether_type; 2114 2115 if (ether_type == htons(ETH_P_8021Q)) { 2116 struct vlan_ethhdr *veth = 2117 (struct vlan_ethhdr *)qdf_nbuf_data(buf); 2118 ether_type = veth->h_vlan_encapsulated_proto; 2119 eth_hdr_size = sizeof(struct vlan_ethhdr); 2120 } 2121 2122 if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV6_ETH_TYPE)) { 2123 struct ipv6hdr *ip6h = NULL; 2124 struct icmp6hdr *icmp6h = NULL; 2125 uint8_t nexthdr; 2126 uint16_t frag_off = 0; 2127 int offset; 2128 qdf_nbuf_t buf_copy = NULL; 2129 2130 ip6h = (struct ipv6hdr *)(qdf_nbuf_data(buf) + eth_hdr_size); 2131 if (ip6h->nexthdr != IPPROTO_HOPOPTS || 2132 ip6h->payload_len == 0) 2133 return false; 2134 2135 buf_copy = qdf_nbuf_copy(buf); 2136 if (qdf_likely(!buf_copy)) 2137 return false; 2138 2139 nexthdr = ip6h->nexthdr; 2140 offset = ipv6_skip_exthdr(buf_copy, 2141 eth_hdr_size + sizeof(*ip6h), 2142 &nexthdr, 2143 &frag_off); 2144 qdf_nbuf_free(buf_copy); 2145 if (offset < 0 || nexthdr != IPPROTO_ICMPV6) 2146 return false; 2147 2148 icmp6h = (struct icmp6hdr *)(qdf_nbuf_data(buf) + offset); 2149 2150 switch (icmp6h->icmp6_type) { 2151 case ICMPV6_MGM_REDUCTION: 2152 return true; 2153 case ICMPV6_MLD2_REPORT: 2154 { 2155 struct mld2_report *mh = NULL; 2156 struct mld2_grec *grec = NULL; 2157 int num = 0; 2158 int i = 0; 2159 int len = 0; 2160 int type = -1; 2161 2162 mh = (struct mld2_report *)icmp6h; 2163 num = ntohs(mh->mld2r_ngrec); 2164 for (i = 0; i < num; i++) { 2165 grec = (void *)(((uint8_t *)mh->mld2r_grec) + 2166 len); 2167 type = grec->grec_type; 2168 if ((type == MLD2_MODE_IS_INCLUDE) || 2169 (type == MLD2_CHANGE_TO_INCLUDE)) 2170 return true; 2171 else if (type == MLD2_BLOCK_OLD_SOURCES) 2172 return true; 2173 2174 len += sizeof(struct mld2_grec); 2175 len += ntohs(grec->grec_nsrcs) * 2176 sizeof(struct in6_addr); 2177 } 2178 break; 2179 } 2180 default: 2181 break; 2182 } 2183 } 2184 2185 return false; 2186 } 2187 2188 qdf_export_symbol(__qdf_nbuf_is_ipv6_igmp_leave_pkt); 2189 __qdf_nbuf_is_ipv4_tdls_pkt(struct sk_buff * skb)2190 bool __qdf_nbuf_is_ipv4_tdls_pkt(struct sk_buff *skb) 2191 { 2192 uint16_t ether_type; 2193 2194 ether_type = *(uint16_t *)(skb->data + 2195 QDF_NBUF_TRAC_ETH_TYPE_OFFSET); 2196 2197 if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_TDLS_ETH_TYPE)) 2198 return true; 2199 else 2200 return false; 2201 } 2202 qdf_export_symbol(__qdf_nbuf_is_ipv4_tdls_pkt); 2203 __qdf_nbuf_data_is_ipv4_arp_pkt(uint8_t * data)2204 bool __qdf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data) 2205 { 2206 uint16_t ether_type; 2207 2208 ether_type = __qdf_nbuf_get_ether_type(data); 2209 2210 if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_ARP_ETH_TYPE)) 2211 return true; 2212 else 2213 return false; 2214 } 2215 qdf_export_symbol(__qdf_nbuf_data_is_ipv4_arp_pkt); 2216 __qdf_nbuf_data_is_arp_req(uint8_t * data)2217 bool __qdf_nbuf_data_is_arp_req(uint8_t *data) 2218 { 2219 uint16_t op_code; 2220 2221 op_code = (uint16_t)(*(uint16_t *)(data + 2222 QDF_NBUF_PKT_ARP_OPCODE_OFFSET)); 2223 2224 if (op_code == QDF_SWAP_U16(QDF_NBUF_PKT_ARPOP_REQ)) 2225 return true; 2226 return false; 2227 } 2228 __qdf_nbuf_data_is_arp_rsp(uint8_t * data)2229 bool __qdf_nbuf_data_is_arp_rsp(uint8_t *data) 2230 { 2231 uint16_t op_code; 2232 2233 op_code = (uint16_t)(*(uint16_t *)(data + 2234 QDF_NBUF_PKT_ARP_OPCODE_OFFSET)); 2235 2236 if (op_code == QDF_SWAP_U16(QDF_NBUF_PKT_ARPOP_REPLY)) 2237 return true; 2238 return false; 2239 } 2240 __qdf_nbuf_get_arp_src_ip(uint8_t * data)2241 uint32_t __qdf_nbuf_get_arp_src_ip(uint8_t *data) 2242 { 2243 uint32_t src_ip; 2244 2245 src_ip = (uint32_t)(*(uint32_t *)(data + 2246 QDF_NBUF_PKT_ARP_SRC_IP_OFFSET)); 2247 2248 return src_ip; 2249 } 2250 __qdf_nbuf_get_arp_tgt_ip(uint8_t * data)2251 uint32_t __qdf_nbuf_get_arp_tgt_ip(uint8_t *data) 2252 { 2253 uint32_t tgt_ip; 2254 2255 tgt_ip = (uint32_t)(*(uint32_t *)(data + 2256 QDF_NBUF_PKT_ARP_TGT_IP_OFFSET)); 2257 2258 return tgt_ip; 2259 } 2260 __qdf_nbuf_get_dns_domain_name(uint8_t * data,uint32_t len)2261 uint8_t *__qdf_nbuf_get_dns_domain_name(uint8_t *data, uint32_t len) 2262 { 2263 uint8_t *domain_name; 2264 2265 domain_name = (uint8_t *) 2266 (data + QDF_NBUF_PKT_DNS_NAME_OVER_UDP_OFFSET); 2267 return domain_name; 2268 } 2269 __qdf_nbuf_data_is_dns_query(uint8_t * data)2270 bool __qdf_nbuf_data_is_dns_query(uint8_t *data) 2271 { 2272 uint16_t op_code; 2273 uint16_t tgt_port; 2274 2275 tgt_port = (uint16_t)(*(uint16_t *)(data + 2276 QDF_NBUF_PKT_DNS_DST_PORT_OFFSET)); 2277 /* Standard DNS query always happen on Dest Port 53. */ 2278 if (tgt_port == QDF_SWAP_U16(QDF_NBUF_PKT_DNS_STANDARD_PORT)) { 2279 op_code = (uint16_t)(*(uint16_t *)(data + 2280 QDF_NBUF_PKT_DNS_OVER_UDP_OPCODE_OFFSET)); 2281 if ((QDF_SWAP_U16(op_code) & QDF_NBUF_PKT_DNSOP_BITMAP) == 2282 QDF_NBUF_PKT_DNSOP_STANDARD_QUERY) 2283 return true; 2284 } 2285 return false; 2286 } 2287 __qdf_nbuf_data_is_dns_response(uint8_t * data)2288 bool __qdf_nbuf_data_is_dns_response(uint8_t *data) 2289 { 2290 uint16_t op_code; 2291 uint16_t src_port; 2292 2293 src_port = (uint16_t)(*(uint16_t *)(data + 2294 QDF_NBUF_PKT_DNS_SRC_PORT_OFFSET)); 2295 /* Standard DNS response always comes on Src Port 53. */ 2296 if (src_port == QDF_SWAP_U16(QDF_NBUF_PKT_DNS_STANDARD_PORT)) { 2297 op_code = (uint16_t)(*(uint16_t *)(data + 2298 QDF_NBUF_PKT_DNS_OVER_UDP_OPCODE_OFFSET)); 2299 2300 if ((QDF_SWAP_U16(op_code) & QDF_NBUF_PKT_DNSOP_BITMAP) == 2301 QDF_NBUF_PKT_DNSOP_STANDARD_RESPONSE) 2302 return true; 2303 } 2304 return false; 2305 } 2306 __qdf_nbuf_data_is_tcp_fin(uint8_t * data)2307 bool __qdf_nbuf_data_is_tcp_fin(uint8_t *data) 2308 { 2309 uint8_t op_code; 2310 2311 op_code = (uint8_t)(*(uint8_t *)(data + 2312 QDF_NBUF_PKT_TCP_OPCODE_OFFSET)); 2313 2314 if (op_code == QDF_NBUF_PKT_TCPOP_FIN) 2315 return true; 2316 2317 return false; 2318 } 2319 __qdf_nbuf_data_is_tcp_fin_ack(uint8_t * data)2320 bool __qdf_nbuf_data_is_tcp_fin_ack(uint8_t *data) 2321 { 2322 uint8_t op_code; 2323 2324 op_code = (uint8_t)(*(uint8_t *)(data + 2325 QDF_NBUF_PKT_TCP_OPCODE_OFFSET)); 2326 2327 if (op_code == QDF_NBUF_PKT_TCPOP_FIN_ACK) 2328 return true; 2329 2330 return false; 2331 } 2332 __qdf_nbuf_data_is_tcp_syn(uint8_t * data)2333 bool __qdf_nbuf_data_is_tcp_syn(uint8_t *data) 2334 { 2335 uint8_t op_code; 2336 2337 op_code = (uint8_t)(*(uint8_t *)(data + 2338 QDF_NBUF_PKT_TCP_OPCODE_OFFSET)); 2339 2340 if (op_code == QDF_NBUF_PKT_TCPOP_SYN) 2341 return true; 2342 return false; 2343 } 2344 __qdf_nbuf_data_is_tcp_syn_ack(uint8_t * data)2345 bool __qdf_nbuf_data_is_tcp_syn_ack(uint8_t *data) 2346 { 2347 uint8_t op_code; 2348 2349 op_code = (uint8_t)(*(uint8_t *)(data + 2350 QDF_NBUF_PKT_TCP_OPCODE_OFFSET)); 2351 2352 if (op_code == QDF_NBUF_PKT_TCPOP_SYN_ACK) 2353 return true; 2354 return false; 2355 } 2356 __qdf_nbuf_data_is_tcp_rst(uint8_t * data)2357 bool __qdf_nbuf_data_is_tcp_rst(uint8_t *data) 2358 { 2359 uint8_t op_code; 2360 2361 op_code = (uint8_t)(*(uint8_t *)(data + 2362 QDF_NBUF_PKT_TCP_OPCODE_OFFSET)); 2363 2364 if (op_code == QDF_NBUF_PKT_TCPOP_RST) 2365 return true; 2366 2367 return false; 2368 } 2369 __qdf_nbuf_data_is_tcp_ack(uint8_t * data)2370 bool __qdf_nbuf_data_is_tcp_ack(uint8_t *data) 2371 { 2372 uint8_t op_code; 2373 2374 op_code = (uint8_t)(*(uint8_t *)(data + 2375 QDF_NBUF_PKT_TCP_OPCODE_OFFSET)); 2376 2377 if (op_code == QDF_NBUF_PKT_TCPOP_ACK) 2378 return true; 2379 return false; 2380 } 2381 __qdf_nbuf_data_get_tcp_src_port(uint8_t * data)2382 uint16_t __qdf_nbuf_data_get_tcp_src_port(uint8_t *data) 2383 { 2384 uint16_t src_port; 2385 2386 src_port = (uint16_t)(*(uint16_t *)(data + 2387 QDF_NBUF_PKT_TCP_SRC_PORT_OFFSET)); 2388 2389 return src_port; 2390 } 2391 __qdf_nbuf_data_get_tcp_dst_port(uint8_t * data)2392 uint16_t __qdf_nbuf_data_get_tcp_dst_port(uint8_t *data) 2393 { 2394 uint16_t tgt_port; 2395 2396 tgt_port = (uint16_t)(*(uint16_t *)(data + 2397 QDF_NBUF_PKT_TCP_DST_PORT_OFFSET)); 2398 2399 return tgt_port; 2400 } 2401 __qdf_nbuf_data_is_icmpv4_req(uint8_t * data)2402 bool __qdf_nbuf_data_is_icmpv4_req(uint8_t *data) 2403 { 2404 uint8_t op_code; 2405 2406 op_code = (uint8_t)(*(uint8_t *)(data + 2407 QDF_NBUF_PKT_ICMPv4_OPCODE_OFFSET)); 2408 2409 if (op_code == QDF_NBUF_PKT_ICMPv4OP_REQ) 2410 return true; 2411 return false; 2412 } 2413 __qdf_nbuf_data_is_icmpv4_rsp(uint8_t * data)2414 bool __qdf_nbuf_data_is_icmpv4_rsp(uint8_t *data) 2415 { 2416 uint8_t op_code; 2417 2418 op_code = (uint8_t)(*(uint8_t *)(data + 2419 QDF_NBUF_PKT_ICMPv4_OPCODE_OFFSET)); 2420 2421 if (op_code == QDF_NBUF_PKT_ICMPv4OP_REPLY) 2422 return true; 2423 return false; 2424 } 2425 __qdf_nbuf_data_is_icmpv4_redirect(uint8_t * data)2426 bool __qdf_nbuf_data_is_icmpv4_redirect(uint8_t *data) 2427 { 2428 uint8_t op_code; 2429 2430 op_code = (uint8_t)(*(uint8_t *)(data + 2431 QDF_NBUF_PKT_ICMPv4_OPCODE_OFFSET)); 2432 2433 if (op_code == QDF_NBUF_PKT_ICMPV4_REDIRECT) 2434 return true; 2435 return false; 2436 } 2437 2438 qdf_export_symbol(__qdf_nbuf_data_is_icmpv4_redirect); 2439 __qdf_nbuf_data_is_icmpv6_redirect(uint8_t * data)2440 bool __qdf_nbuf_data_is_icmpv6_redirect(uint8_t *data) 2441 { 2442 uint8_t subtype; 2443 2444 subtype = (uint8_t)(*(uint8_t *)(data + ICMPV6_SUBTYPE_OFFSET)); 2445 2446 if (subtype == ICMPV6_REDIRECT) 2447 return true; 2448 return false; 2449 } 2450 2451 qdf_export_symbol(__qdf_nbuf_data_is_icmpv6_redirect); 2452 __qdf_nbuf_get_icmpv4_src_ip(uint8_t * data)2453 uint32_t __qdf_nbuf_get_icmpv4_src_ip(uint8_t *data) 2454 { 2455 uint32_t src_ip; 2456 2457 src_ip = (uint32_t)(*(uint32_t *)(data + 2458 QDF_NBUF_PKT_ICMPv4_SRC_IP_OFFSET)); 2459 2460 return src_ip; 2461 } 2462 __qdf_nbuf_get_icmpv4_tgt_ip(uint8_t * data)2463 uint32_t __qdf_nbuf_get_icmpv4_tgt_ip(uint8_t *data) 2464 { 2465 uint32_t tgt_ip; 2466 2467 tgt_ip = (uint32_t)(*(uint32_t *)(data + 2468 QDF_NBUF_PKT_ICMPv4_TGT_IP_OFFSET)); 2469 2470 return tgt_ip; 2471 } 2472 __qdf_nbuf_data_is_ipv6_pkt(uint8_t * data)2473 bool __qdf_nbuf_data_is_ipv6_pkt(uint8_t *data) 2474 { 2475 uint16_t ether_type; 2476 2477 ether_type = (uint16_t)(*(uint16_t *)(data + 2478 QDF_NBUF_TRAC_ETH_TYPE_OFFSET)); 2479 2480 if (ether_type == QDF_SWAP_U16(QDF_NBUF_TRAC_IPV6_ETH_TYPE)) 2481 return true; 2482 else 2483 return false; 2484 } 2485 qdf_export_symbol(__qdf_nbuf_data_is_ipv6_pkt); 2486 __qdf_nbuf_data_is_ipv6_dhcp_pkt(uint8_t * data)2487 bool __qdf_nbuf_data_is_ipv6_dhcp_pkt(uint8_t *data) 2488 { 2489 uint16_t sport; 2490 uint16_t dport; 2491 uint8_t ipv6_offset; 2492 2493 if (!__qdf_nbuf_data_is_ipv6_pkt(data)) 2494 return false; 2495 2496 ipv6_offset = __qdf_nbuf_get_ip_offset(data); 2497 sport = *(uint16_t *)(data + ipv6_offset + 2498 QDF_NBUF_TRAC_IPV6_HEADER_SIZE); 2499 dport = *(uint16_t *)(data + ipv6_offset + 2500 QDF_NBUF_TRAC_IPV6_HEADER_SIZE + 2501 sizeof(uint16_t)); 2502 2503 if (((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_SRV_PORT)) && 2504 (dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_CLI_PORT))) || 2505 ((sport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_CLI_PORT)) && 2506 (dport == QDF_SWAP_U16(QDF_NBUF_TRAC_DHCP6_SRV_PORT)))) 2507 return true; 2508 else 2509 return false; 2510 } 2511 qdf_export_symbol(__qdf_nbuf_data_is_ipv6_dhcp_pkt); 2512 __qdf_nbuf_data_is_ipv6_mdns_pkt(uint8_t * data)2513 bool __qdf_nbuf_data_is_ipv6_mdns_pkt(uint8_t *data) 2514 { 2515 uint16_t sport; 2516 uint16_t dport; 2517 2518 sport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET + 2519 QDF_NBUF_TRAC_IPV6_HEADER_SIZE); 2520 dport = *(uint16_t *)(data + QDF_NBUF_TRAC_IPV6_OFFSET + 2521 QDF_NBUF_TRAC_IPV6_HEADER_SIZE + 2522 sizeof(uint16_t)); 2523 2524 if (sport == QDF_SWAP_U16(QDF_NBUF_TRAC_MDNS_SRC_N_DST_PORT) && 2525 dport == sport) 2526 return true; 2527 else 2528 return false; 2529 } 2530 2531 qdf_export_symbol(__qdf_nbuf_data_is_ipv6_mdns_pkt); 2532 __qdf_nbuf_data_is_ipv4_mcast_pkt(uint8_t * data)2533 bool __qdf_nbuf_data_is_ipv4_mcast_pkt(uint8_t *data) 2534 { 2535 if (__qdf_nbuf_data_is_ipv4_pkt(data)) { 2536 uint32_t *dst_addr = 2537 (uint32_t *)(data + QDF_NBUF_TRAC_IPV4_DEST_ADDR_OFFSET); 2538 2539 /* 2540 * Check first word of the IPV4 address and if it is 2541 * equal to 0xE then it represents multicast IP. 2542 */ 2543 if ((*dst_addr & QDF_NBUF_TRAC_IPV4_ADDR_BCAST_MASK) == 2544 QDF_NBUF_TRAC_IPV4_ADDR_MCAST_MASK) 2545 return true; 2546 else 2547 return false; 2548 } else 2549 return false; 2550 } 2551 __qdf_nbuf_data_is_ipv6_mcast_pkt(uint8_t * data)2552 bool __qdf_nbuf_data_is_ipv6_mcast_pkt(uint8_t *data) 2553 { 2554 if (__qdf_nbuf_data_is_ipv6_pkt(data)) { 2555 uint16_t *dst_addr; 2556 2557 dst_addr = (uint16_t *) 2558 (data + QDF_NBUF_TRAC_IPV6_DEST_ADDR_OFFSET); 2559 2560 /* 2561 * Check first byte of the IP address and if it 2562 * 0xFF00 then it is a IPV6 mcast packet. 2563 */ 2564 if (*dst_addr == 2565 QDF_SWAP_U16(QDF_NBUF_TRAC_IPV6_DEST_ADDR)) 2566 return true; 2567 else 2568 return false; 2569 } else 2570 return false; 2571 } 2572 __qdf_nbuf_data_is_icmp_pkt(uint8_t * data)2573 bool __qdf_nbuf_data_is_icmp_pkt(uint8_t *data) 2574 { 2575 if (__qdf_nbuf_data_is_ipv4_pkt(data)) { 2576 uint8_t pkt_type; 2577 2578 pkt_type = (uint8_t)(*(uint8_t *)(data + 2579 QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); 2580 2581 if (pkt_type == QDF_NBUF_TRAC_ICMP_TYPE) 2582 return true; 2583 else 2584 return false; 2585 } else 2586 return false; 2587 } 2588 2589 qdf_export_symbol(__qdf_nbuf_data_is_icmp_pkt); 2590 __qdf_nbuf_data_is_icmpv6_pkt(uint8_t * data)2591 bool __qdf_nbuf_data_is_icmpv6_pkt(uint8_t *data) 2592 { 2593 if (__qdf_nbuf_data_is_ipv6_pkt(data)) { 2594 uint8_t pkt_type; 2595 2596 pkt_type = (uint8_t)(*(uint8_t *)(data + 2597 QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET)); 2598 2599 if (pkt_type == QDF_NBUF_TRAC_ICMPV6_TYPE) 2600 return true; 2601 else 2602 return false; 2603 } else 2604 return false; 2605 } 2606 2607 qdf_export_symbol(__qdf_nbuf_data_is_icmpv6_pkt); 2608 __qdf_nbuf_data_is_ipv4_udp_pkt(uint8_t * data)2609 bool __qdf_nbuf_data_is_ipv4_udp_pkt(uint8_t *data) 2610 { 2611 if (__qdf_nbuf_data_is_ipv4_pkt(data)) { 2612 uint8_t pkt_type; 2613 2614 pkt_type = (uint8_t)(*(uint8_t *)(data + 2615 QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); 2616 2617 if (pkt_type == QDF_NBUF_TRAC_UDP_TYPE) 2618 return true; 2619 else 2620 return false; 2621 } else 2622 return false; 2623 } 2624 __qdf_nbuf_data_is_ipv4_tcp_pkt(uint8_t * data)2625 bool __qdf_nbuf_data_is_ipv4_tcp_pkt(uint8_t *data) 2626 { 2627 if (__qdf_nbuf_data_is_ipv4_pkt(data)) { 2628 uint8_t pkt_type; 2629 2630 pkt_type = (uint8_t)(*(uint8_t *)(data + 2631 QDF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); 2632 2633 if (pkt_type == QDF_NBUF_TRAC_TCP_TYPE) 2634 return true; 2635 else 2636 return false; 2637 } else 2638 return false; 2639 } 2640 __qdf_nbuf_data_is_ipv6_udp_pkt(uint8_t * data)2641 bool __qdf_nbuf_data_is_ipv6_udp_pkt(uint8_t *data) 2642 { 2643 if (__qdf_nbuf_data_is_ipv6_pkt(data)) { 2644 uint8_t pkt_type; 2645 2646 pkt_type = (uint8_t)(*(uint8_t *)(data + 2647 QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET)); 2648 2649 if (pkt_type == QDF_NBUF_TRAC_UDP_TYPE) 2650 return true; 2651 else 2652 return false; 2653 } else 2654 return false; 2655 } 2656 __qdf_nbuf_data_is_ipv6_tcp_pkt(uint8_t * data)2657 bool __qdf_nbuf_data_is_ipv6_tcp_pkt(uint8_t *data) 2658 { 2659 if (__qdf_nbuf_data_is_ipv6_pkt(data)) { 2660 uint8_t pkt_type; 2661 2662 pkt_type = (uint8_t)(*(uint8_t *)(data + 2663 QDF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET)); 2664 2665 if (pkt_type == QDF_NBUF_TRAC_TCP_TYPE) 2666 return true; 2667 else 2668 return false; 2669 } else 2670 return false; 2671 } 2672 __qdf_nbuf_is_bcast_pkt(qdf_nbuf_t nbuf)2673 bool __qdf_nbuf_is_bcast_pkt(qdf_nbuf_t nbuf) 2674 { 2675 struct ethhdr *eh = (struct ethhdr *)qdf_nbuf_data(nbuf); 2676 return qdf_is_macaddr_broadcast((struct qdf_mac_addr *)eh->h_dest); 2677 } 2678 qdf_export_symbol(__qdf_nbuf_is_bcast_pkt); 2679 __qdf_nbuf_is_mcast_replay(qdf_nbuf_t nbuf)2680 bool __qdf_nbuf_is_mcast_replay(qdf_nbuf_t nbuf) 2681 { 2682 struct sk_buff *skb = (struct sk_buff *)nbuf; 2683 struct ethhdr *eth = eth_hdr(skb); 2684 2685 if (qdf_likely(skb->pkt_type != PACKET_MULTICAST)) 2686 return false; 2687 2688 if (qdf_unlikely(ether_addr_equal(eth->h_source, skb->dev->dev_addr))) 2689 return true; 2690 2691 return false; 2692 } 2693 __qdf_nbuf_is_arp_local(struct sk_buff * skb)2694 bool __qdf_nbuf_is_arp_local(struct sk_buff *skb) 2695 { 2696 struct arphdr *arp; 2697 struct in_ifaddr **ifap = NULL; 2698 struct in_ifaddr *ifa = NULL; 2699 struct in_device *in_dev; 2700 unsigned char *arp_ptr; 2701 __be32 tip; 2702 2703 arp = (struct arphdr *)skb->data; 2704 if (arp->ar_op == htons(ARPOP_REQUEST)) { 2705 /* if fail to acquire rtnl lock, assume it's local arp */ 2706 if (!rtnl_trylock()) 2707 return true; 2708 2709 in_dev = __in_dev_get_rtnl(skb->dev); 2710 if (in_dev) { 2711 for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; 2712 ifap = &ifa->ifa_next) { 2713 if (!strcmp(skb->dev->name, ifa->ifa_label)) 2714 break; 2715 } 2716 } 2717 2718 if (ifa && ifa->ifa_local) { 2719 arp_ptr = (unsigned char *)(arp + 1); 2720 arp_ptr += (skb->dev->addr_len + 4 + 2721 skb->dev->addr_len); 2722 memcpy(&tip, arp_ptr, 4); 2723 qdf_debug("ARP packet: local IP: %x dest IP: %x", 2724 ifa->ifa_local, tip); 2725 if (ifa->ifa_local == tip) { 2726 rtnl_unlock(); 2727 return true; 2728 } 2729 } 2730 rtnl_unlock(); 2731 } 2732 2733 return false; 2734 } 2735 2736 /** 2737 * __qdf_nbuf_data_get_tcp_hdr_len() - get TCP header length 2738 * @data: pointer to data of network buffer 2739 * @tcp_hdr_len_offset: bytes offset for tcp header length of ethernet packets 2740 * 2741 * Return: TCP header length in unit of byte 2742 */ 2743 static inline __qdf_nbuf_data_get_tcp_hdr_len(uint8_t * data,uint8_t tcp_hdr_len_offset)2744 uint8_t __qdf_nbuf_data_get_tcp_hdr_len(uint8_t *data, 2745 uint8_t tcp_hdr_len_offset) 2746 { 2747 uint8_t tcp_hdr_len; 2748 2749 tcp_hdr_len = 2750 *((uint8_t *)(data + tcp_hdr_len_offset)); 2751 2752 tcp_hdr_len = ((tcp_hdr_len & QDF_NBUF_PKT_TCP_HDR_LEN_MASK) >> 2753 QDF_NBUF_PKT_TCP_HDR_LEN_LSB) * 2754 QDF_NBUF_PKT_TCP_HDR_LEN_UNIT; 2755 2756 return tcp_hdr_len; 2757 } 2758 __qdf_nbuf_is_ipv4_v6_pure_tcp_ack(struct sk_buff * skb)2759 bool __qdf_nbuf_is_ipv4_v6_pure_tcp_ack(struct sk_buff *skb) 2760 { 2761 bool is_tcp_ack = false; 2762 uint8_t op_code, tcp_hdr_len; 2763 uint16_t ip_payload_len; 2764 uint8_t *data = skb->data; 2765 2766 /* 2767 * If packet length > TCP ACK max length or it's nonlinearized, 2768 * then it must not be TCP ACK. 2769 */ 2770 if (qdf_nbuf_len(skb) > QDF_NBUF_PKT_TCP_ACK_MAX_LEN || 2771 qdf_nbuf_is_nonlinear(skb)) 2772 return false; 2773 2774 if (qdf_nbuf_is_ipv4_tcp_pkt(skb)) { 2775 ip_payload_len = 2776 QDF_SWAP_U16(*((uint16_t *)(data + 2777 QDF_NBUF_TRAC_IPV4_TOTAL_LEN_OFFSET))) 2778 - QDF_NBUF_TRAC_IPV4_HEADER_SIZE; 2779 2780 tcp_hdr_len = __qdf_nbuf_data_get_tcp_hdr_len( 2781 data, 2782 QDF_NBUF_PKT_IPV4_TCP_HDR_LEN_OFFSET); 2783 2784 op_code = (uint8_t)(*(uint8_t *)(data + 2785 QDF_NBUF_PKT_IPV4_TCP_OPCODE_OFFSET)); 2786 2787 if (ip_payload_len == tcp_hdr_len && 2788 op_code == QDF_NBUF_PKT_TCPOP_ACK) 2789 is_tcp_ack = true; 2790 2791 } else if (qdf_nbuf_is_ipv6_tcp_pkt(skb)) { 2792 ip_payload_len = 2793 QDF_SWAP_U16(*((uint16_t *)(data + 2794 QDF_NBUF_TRAC_IPV6_PAYLOAD_LEN_OFFSET))); 2795 2796 tcp_hdr_len = __qdf_nbuf_data_get_tcp_hdr_len( 2797 data, 2798 QDF_NBUF_PKT_IPV6_TCP_HDR_LEN_OFFSET); 2799 op_code = (uint8_t)(*(uint8_t *)(data + 2800 QDF_NBUF_PKT_IPV6_TCP_OPCODE_OFFSET)); 2801 2802 if (ip_payload_len == tcp_hdr_len && 2803 op_code == QDF_NBUF_PKT_TCPOP_ACK) 2804 is_tcp_ack = true; 2805 } 2806 2807 return is_tcp_ack; 2808 } 2809 2810 #ifdef QCA_DP_NBUF_FAST_RECYCLE_CHECK qdf_nbuf_fast_xmit(qdf_nbuf_t nbuf)2811 bool qdf_nbuf_fast_xmit(qdf_nbuf_t nbuf) 2812 { 2813 return nbuf->fast_xmit; 2814 } 2815 2816 qdf_export_symbol(qdf_nbuf_fast_xmit); 2817 qdf_nbuf_set_fast_xmit(qdf_nbuf_t nbuf,int value)2818 void qdf_nbuf_set_fast_xmit(qdf_nbuf_t nbuf, int value) 2819 { 2820 nbuf->fast_xmit = value; 2821 } 2822 2823 qdf_export_symbol(qdf_nbuf_set_fast_xmit); 2824 #else qdf_nbuf_fast_xmit(qdf_nbuf_t nbuf)2825 bool qdf_nbuf_fast_xmit(qdf_nbuf_t nbuf) 2826 { 2827 return false; 2828 } 2829 2830 qdf_export_symbol(qdf_nbuf_fast_xmit); 2831 qdf_nbuf_set_fast_xmit(qdf_nbuf_t nbuf,int value)2832 void qdf_nbuf_set_fast_xmit(qdf_nbuf_t nbuf, int value) 2833 { 2834 } 2835 2836 qdf_export_symbol(qdf_nbuf_set_fast_xmit); 2837 #endif 2838 2839 #ifdef NBUF_MEMORY_DEBUG 2840 2841 static spinlock_t g_qdf_net_buf_track_lock[QDF_NET_BUF_TRACK_MAX_SIZE]; 2842 2843 static QDF_NBUF_TRACK *gp_qdf_net_buf_track_tbl[QDF_NET_BUF_TRACK_MAX_SIZE]; 2844 static struct kmem_cache *nbuf_tracking_cache; 2845 static QDF_NBUF_TRACK *qdf_net_buf_track_free_list; 2846 static spinlock_t qdf_net_buf_track_free_list_lock; 2847 static uint32_t qdf_net_buf_track_free_list_count; 2848 static uint32_t qdf_net_buf_track_used_list_count; 2849 static uint32_t qdf_net_buf_track_max_used; 2850 static uint32_t qdf_net_buf_track_max_free; 2851 static uint32_t qdf_net_buf_track_max_allocated; 2852 static uint32_t qdf_net_buf_track_fail_count; 2853 2854 /** 2855 * update_max_used() - update qdf_net_buf_track_max_used tracking variable 2856 * 2857 * tracks the max number of network buffers that the wlan driver was tracking 2858 * at any one time. 2859 * 2860 * Return: none 2861 */ update_max_used(void)2862 static inline void update_max_used(void) 2863 { 2864 int sum; 2865 2866 if (qdf_net_buf_track_max_used < 2867 qdf_net_buf_track_used_list_count) 2868 qdf_net_buf_track_max_used = qdf_net_buf_track_used_list_count; 2869 sum = qdf_net_buf_track_free_list_count + 2870 qdf_net_buf_track_used_list_count; 2871 if (qdf_net_buf_track_max_allocated < sum) 2872 qdf_net_buf_track_max_allocated = sum; 2873 } 2874 2875 /** 2876 * update_max_free() - update qdf_net_buf_track_free_list_count 2877 * 2878 * tracks the max number tracking buffers kept in the freelist. 2879 * 2880 * Return: none 2881 */ update_max_free(void)2882 static inline void update_max_free(void) 2883 { 2884 if (qdf_net_buf_track_max_free < 2885 qdf_net_buf_track_free_list_count) 2886 qdf_net_buf_track_max_free = qdf_net_buf_track_free_list_count; 2887 } 2888 2889 /** 2890 * qdf_nbuf_track_alloc() - allocate a cookie to track nbufs allocated by wlan 2891 * 2892 * This function pulls from a freelist if possible and uses kmem_cache_alloc. 2893 * This function also ads fexibility to adjust the allocation and freelist 2894 * scheems. 2895 * 2896 * Return: a pointer to an unused QDF_NBUF_TRACK structure may not be zeroed. 2897 */ qdf_nbuf_track_alloc(void)2898 static QDF_NBUF_TRACK *qdf_nbuf_track_alloc(void) 2899 { 2900 int flags = GFP_KERNEL; 2901 unsigned long irq_flag; 2902 QDF_NBUF_TRACK *new_node = NULL; 2903 2904 spin_lock_irqsave(&qdf_net_buf_track_free_list_lock, irq_flag); 2905 qdf_net_buf_track_used_list_count++; 2906 if (qdf_net_buf_track_free_list) { 2907 new_node = qdf_net_buf_track_free_list; 2908 qdf_net_buf_track_free_list = 2909 qdf_net_buf_track_free_list->p_next; 2910 qdf_net_buf_track_free_list_count--; 2911 } 2912 update_max_used(); 2913 spin_unlock_irqrestore(&qdf_net_buf_track_free_list_lock, irq_flag); 2914 2915 if (new_node) 2916 return new_node; 2917 2918 if (in_interrupt() || irqs_disabled() || in_atomic()) 2919 flags = GFP_ATOMIC; 2920 2921 return kmem_cache_alloc(nbuf_tracking_cache, flags); 2922 } 2923 2924 /* FREEQ_POOLSIZE initial and minimum desired freelist poolsize */ 2925 #define FREEQ_POOLSIZE 2048 2926 2927 /** 2928 * qdf_nbuf_track_free() - free the nbuf tracking cookie. 2929 * @node: nbuf tracking node 2930 * 2931 * Matches calls to qdf_nbuf_track_alloc. 2932 * Either frees the tracking cookie to kernel or an internal 2933 * freelist based on the size of the freelist. 2934 * 2935 * Return: none 2936 */ qdf_nbuf_track_free(QDF_NBUF_TRACK * node)2937 static void qdf_nbuf_track_free(QDF_NBUF_TRACK *node) 2938 { 2939 unsigned long irq_flag; 2940 2941 if (!node) 2942 return; 2943 2944 /* Try to shrink the freelist if free_list_count > than FREEQ_POOLSIZE 2945 * only shrink the freelist if it is bigger than twice the number of 2946 * nbufs in use. If the driver is stalling in a consistent bursty 2947 * fashion, this will keep 3/4 of thee allocations from the free list 2948 * while also allowing the system to recover memory as less frantic 2949 * traffic occurs. 2950 */ 2951 2952 spin_lock_irqsave(&qdf_net_buf_track_free_list_lock, irq_flag); 2953 2954 qdf_net_buf_track_used_list_count--; 2955 if (qdf_net_buf_track_free_list_count > FREEQ_POOLSIZE && 2956 (qdf_net_buf_track_free_list_count > 2957 qdf_net_buf_track_used_list_count << 1)) { 2958 kmem_cache_free(nbuf_tracking_cache, node); 2959 } else { 2960 node->p_next = qdf_net_buf_track_free_list; 2961 qdf_net_buf_track_free_list = node; 2962 qdf_net_buf_track_free_list_count++; 2963 } 2964 update_max_free(); 2965 spin_unlock_irqrestore(&qdf_net_buf_track_free_list_lock, irq_flag); 2966 } 2967 2968 /** 2969 * qdf_nbuf_track_prefill() - prefill the nbuf tracking cookie freelist 2970 * 2971 * Removes a 'warmup time' characteristic of the freelist. Prefilling 2972 * the freelist first makes it performant for the first iperf udp burst 2973 * as well as steady state. 2974 * 2975 * Return: None 2976 */ qdf_nbuf_track_prefill(void)2977 static void qdf_nbuf_track_prefill(void) 2978 { 2979 int i; 2980 QDF_NBUF_TRACK *node, *head; 2981 2982 /* prepopulate the freelist */ 2983 head = NULL; 2984 for (i = 0; i < FREEQ_POOLSIZE; i++) { 2985 node = qdf_nbuf_track_alloc(); 2986 if (!node) 2987 continue; 2988 node->p_next = head; 2989 head = node; 2990 } 2991 while (head) { 2992 node = head->p_next; 2993 qdf_nbuf_track_free(head); 2994 head = node; 2995 } 2996 2997 /* prefilled buffers should not count as used */ 2998 qdf_net_buf_track_max_used = 0; 2999 } 3000 3001 /** 3002 * qdf_nbuf_track_memory_manager_create() - manager for nbuf tracking cookies 3003 * 3004 * This initializes the memory manager for the nbuf tracking cookies. Because 3005 * these cookies are all the same size and only used in this feature, we can 3006 * use a kmem_cache to provide tracking as well as to speed up allocations. 3007 * To avoid the overhead of allocating and freeing the buffers (including SLUB 3008 * features) a freelist is prepopulated here. 3009 * 3010 * Return: None 3011 */ qdf_nbuf_track_memory_manager_create(void)3012 static void qdf_nbuf_track_memory_manager_create(void) 3013 { 3014 spin_lock_init(&qdf_net_buf_track_free_list_lock); 3015 nbuf_tracking_cache = kmem_cache_create("qdf_nbuf_tracking_cache", 3016 sizeof(QDF_NBUF_TRACK), 3017 0, 0, NULL); 3018 3019 qdf_nbuf_track_prefill(); 3020 } 3021 3022 /** 3023 * qdf_nbuf_track_memory_manager_destroy() - manager for nbuf tracking cookies 3024 * 3025 * Empty the freelist and print out usage statistics when it is no longer 3026 * needed. Also the kmem_cache should be destroyed here so that it can warn if 3027 * any nbuf tracking cookies were leaked. 3028 * 3029 * Return: None 3030 */ qdf_nbuf_track_memory_manager_destroy(void)3031 static void qdf_nbuf_track_memory_manager_destroy(void) 3032 { 3033 QDF_NBUF_TRACK *node, *tmp; 3034 unsigned long irq_flag; 3035 3036 spin_lock_irqsave(&qdf_net_buf_track_free_list_lock, irq_flag); 3037 node = qdf_net_buf_track_free_list; 3038 3039 if (qdf_net_buf_track_max_used > FREEQ_POOLSIZE * 4) 3040 qdf_print("%s: unexpectedly large max_used count %d", 3041 __func__, qdf_net_buf_track_max_used); 3042 3043 if (qdf_net_buf_track_max_used < qdf_net_buf_track_max_allocated) 3044 qdf_print("%s: %d unused trackers were allocated", 3045 __func__, 3046 qdf_net_buf_track_max_allocated - 3047 qdf_net_buf_track_max_used); 3048 3049 if (qdf_net_buf_track_free_list_count > FREEQ_POOLSIZE && 3050 qdf_net_buf_track_free_list_count > 3*qdf_net_buf_track_max_used/4) 3051 qdf_print("%s: check freelist shrinking functionality", 3052 __func__); 3053 3054 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, 3055 "%s: %d residual freelist size", 3056 __func__, qdf_net_buf_track_free_list_count); 3057 3058 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, 3059 "%s: %d max freelist size observed", 3060 __func__, qdf_net_buf_track_max_free); 3061 3062 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, 3063 "%s: %d max buffers used observed", 3064 __func__, qdf_net_buf_track_max_used); 3065 3066 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, 3067 "%s: %d max buffers allocated observed", 3068 __func__, qdf_net_buf_track_max_allocated); 3069 3070 while (node) { 3071 tmp = node; 3072 node = node->p_next; 3073 kmem_cache_free(nbuf_tracking_cache, tmp); 3074 qdf_net_buf_track_free_list_count--; 3075 } 3076 3077 if (qdf_net_buf_track_free_list_count != 0) 3078 qdf_info("%d unfreed tracking memory lost in freelist", 3079 qdf_net_buf_track_free_list_count); 3080 3081 if (qdf_net_buf_track_used_list_count != 0) 3082 qdf_info("%d unfreed tracking memory still in use", 3083 qdf_net_buf_track_used_list_count); 3084 3085 spin_unlock_irqrestore(&qdf_net_buf_track_free_list_lock, irq_flag); 3086 kmem_cache_destroy(nbuf_tracking_cache); 3087 qdf_net_buf_track_free_list = NULL; 3088 } 3089 qdf_net_buf_debug_init(void)3090 void qdf_net_buf_debug_init(void) 3091 { 3092 uint32_t i; 3093 3094 is_initial_mem_debug_disabled = qdf_mem_debug_config_get(); 3095 3096 if (is_initial_mem_debug_disabled) 3097 return; 3098 3099 qdf_atomic_set(&qdf_nbuf_history_index, -1); 3100 3101 qdf_nbuf_map_tracking_init(); 3102 qdf_nbuf_smmu_map_tracking_init(); 3103 qdf_nbuf_track_memory_manager_create(); 3104 3105 for (i = 0; i < QDF_NET_BUF_TRACK_MAX_SIZE; i++) { 3106 gp_qdf_net_buf_track_tbl[i] = NULL; 3107 spin_lock_init(&g_qdf_net_buf_track_lock[i]); 3108 } 3109 } 3110 qdf_export_symbol(qdf_net_buf_debug_init); 3111 qdf_net_buf_debug_exit(void)3112 void qdf_net_buf_debug_exit(void) 3113 { 3114 uint32_t i; 3115 uint32_t count = 0; 3116 unsigned long irq_flag; 3117 QDF_NBUF_TRACK *p_node; 3118 QDF_NBUF_TRACK *p_prev; 3119 3120 if (is_initial_mem_debug_disabled) 3121 return; 3122 3123 for (i = 0; i < QDF_NET_BUF_TRACK_MAX_SIZE; i++) { 3124 spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); 3125 p_node = gp_qdf_net_buf_track_tbl[i]; 3126 while (p_node) { 3127 p_prev = p_node; 3128 p_node = p_node->p_next; 3129 count++; 3130 qdf_info("SKB buf memory Leak@ Func %s, @Line %d, size %zu, nbuf %pK", 3131 p_prev->func_name, p_prev->line_num, 3132 p_prev->size, p_prev->net_buf); 3133 qdf_info("SKB leak map %s, line %d, unmap %s line %d mapped=%d", 3134 p_prev->map_func_name, 3135 p_prev->map_line_num, 3136 p_prev->unmap_func_name, 3137 p_prev->unmap_line_num, 3138 p_prev->is_nbuf_mapped); 3139 qdf_nbuf_track_free(p_prev); 3140 } 3141 spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); 3142 } 3143 3144 qdf_nbuf_track_memory_manager_destroy(); 3145 qdf_nbuf_map_tracking_deinit(); 3146 qdf_nbuf_smmu_map_tracking_deinit(); 3147 3148 #ifdef CONFIG_HALT_KMEMLEAK 3149 if (count) { 3150 qdf_err("%d SKBs leaked .. please fix the SKB leak", count); 3151 QDF_BUG(0); 3152 } 3153 #endif 3154 } 3155 qdf_export_symbol(qdf_net_buf_debug_exit); 3156 3157 /** 3158 * qdf_net_buf_debug_hash() - hash network buffer pointer 3159 * @net_buf: network buffer 3160 * 3161 * Return: hash value 3162 */ qdf_net_buf_debug_hash(qdf_nbuf_t net_buf)3163 static uint32_t qdf_net_buf_debug_hash(qdf_nbuf_t net_buf) 3164 { 3165 uint32_t i; 3166 3167 i = (uint32_t) (((uintptr_t) net_buf) >> 4); 3168 i += (uint32_t) (((uintptr_t) net_buf) >> 14); 3169 i &= (QDF_NET_BUF_TRACK_MAX_SIZE - 1); 3170 3171 return i; 3172 } 3173 3174 /** 3175 * qdf_net_buf_debug_look_up() - look up network buffer in debug hash table 3176 * @net_buf: network buffer 3177 * 3178 * Return: If skb is found in hash table then return pointer to network buffer 3179 * else return %NULL 3180 */ qdf_net_buf_debug_look_up(qdf_nbuf_t net_buf)3181 static QDF_NBUF_TRACK *qdf_net_buf_debug_look_up(qdf_nbuf_t net_buf) 3182 { 3183 uint32_t i; 3184 QDF_NBUF_TRACK *p_node; 3185 3186 i = qdf_net_buf_debug_hash(net_buf); 3187 p_node = gp_qdf_net_buf_track_tbl[i]; 3188 3189 while (p_node) { 3190 if (p_node->net_buf == net_buf) 3191 return p_node; 3192 p_node = p_node->p_next; 3193 } 3194 3195 return NULL; 3196 } 3197 qdf_net_buf_debug_add_node(qdf_nbuf_t net_buf,size_t size,const char * func_name,uint32_t line_num)3198 void qdf_net_buf_debug_add_node(qdf_nbuf_t net_buf, size_t size, 3199 const char *func_name, uint32_t line_num) 3200 { 3201 uint32_t i; 3202 unsigned long irq_flag; 3203 QDF_NBUF_TRACK *p_node; 3204 QDF_NBUF_TRACK *new_node; 3205 3206 if (is_initial_mem_debug_disabled) 3207 return; 3208 3209 new_node = qdf_nbuf_track_alloc(); 3210 3211 i = qdf_net_buf_debug_hash(net_buf); 3212 spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); 3213 3214 p_node = qdf_net_buf_debug_look_up(net_buf); 3215 3216 if (p_node) { 3217 qdf_print("Double allocation of skb ! Already allocated from %pK %s %d current alloc from %pK %s %d", 3218 p_node->net_buf, p_node->func_name, p_node->line_num, 3219 net_buf, func_name, line_num); 3220 qdf_nbuf_track_free(new_node); 3221 } else { 3222 p_node = new_node; 3223 if (p_node) { 3224 p_node->net_buf = net_buf; 3225 qdf_str_lcopy(p_node->func_name, func_name, 3226 QDF_MEM_FUNC_NAME_SIZE); 3227 p_node->line_num = line_num; 3228 p_node->is_nbuf_mapped = false; 3229 p_node->map_line_num = 0; 3230 p_node->unmap_line_num = 0; 3231 p_node->map_func_name[0] = '\0'; 3232 p_node->unmap_func_name[0] = '\0'; 3233 p_node->size = size; 3234 p_node->time = qdf_get_log_timestamp(); 3235 qdf_net_buf_update_smmu_params(p_node); 3236 qdf_mem_skb_inc(size); 3237 p_node->p_next = gp_qdf_net_buf_track_tbl[i]; 3238 gp_qdf_net_buf_track_tbl[i] = p_node; 3239 } else { 3240 qdf_net_buf_track_fail_count++; 3241 qdf_print( 3242 "Mem alloc failed ! Could not track skb from %s %d of size %zu", 3243 func_name, line_num, size); 3244 } 3245 } 3246 3247 spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); 3248 } 3249 qdf_export_symbol(qdf_net_buf_debug_add_node); 3250 qdf_net_buf_debug_update_node(qdf_nbuf_t net_buf,const char * func_name,uint32_t line_num)3251 void qdf_net_buf_debug_update_node(qdf_nbuf_t net_buf, const char *func_name, 3252 uint32_t line_num) 3253 { 3254 uint32_t i; 3255 unsigned long irq_flag; 3256 QDF_NBUF_TRACK *p_node; 3257 3258 if (is_initial_mem_debug_disabled) 3259 return; 3260 3261 i = qdf_net_buf_debug_hash(net_buf); 3262 spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); 3263 3264 p_node = qdf_net_buf_debug_look_up(net_buf); 3265 3266 if (p_node) { 3267 qdf_str_lcopy(p_node->func_name, kbasename(func_name), 3268 QDF_MEM_FUNC_NAME_SIZE); 3269 p_node->line_num = line_num; 3270 } 3271 3272 spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); 3273 } 3274 3275 qdf_export_symbol(qdf_net_buf_debug_update_node); 3276 qdf_net_buf_debug_update_map_node(qdf_nbuf_t net_buf,const char * func_name,uint32_t line_num)3277 void qdf_net_buf_debug_update_map_node(qdf_nbuf_t net_buf, 3278 const char *func_name, 3279 uint32_t line_num) 3280 { 3281 uint32_t i; 3282 unsigned long irq_flag; 3283 QDF_NBUF_TRACK *p_node; 3284 3285 if (is_initial_mem_debug_disabled) 3286 return; 3287 3288 i = qdf_net_buf_debug_hash(net_buf); 3289 spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); 3290 3291 p_node = qdf_net_buf_debug_look_up(net_buf); 3292 3293 if (p_node) { 3294 qdf_str_lcopy(p_node->map_func_name, func_name, 3295 QDF_MEM_FUNC_NAME_SIZE); 3296 p_node->map_line_num = line_num; 3297 p_node->is_nbuf_mapped = true; 3298 } 3299 spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); 3300 } 3301 3302 #ifdef NBUF_SMMU_MAP_UNMAP_DEBUG qdf_net_buf_debug_update_smmu_map_node(qdf_nbuf_t nbuf,unsigned long iova,unsigned long pa,const char * func,uint32_t line)3303 void qdf_net_buf_debug_update_smmu_map_node(qdf_nbuf_t nbuf, 3304 unsigned long iova, 3305 unsigned long pa, 3306 const char *func, 3307 uint32_t line) 3308 { 3309 uint32_t i; 3310 unsigned long irq_flag; 3311 QDF_NBUF_TRACK *p_node; 3312 3313 if (is_initial_mem_debug_disabled) 3314 return; 3315 3316 i = qdf_net_buf_debug_hash(nbuf); 3317 spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); 3318 3319 p_node = qdf_net_buf_debug_look_up(nbuf); 3320 3321 if (p_node) { 3322 qdf_str_lcopy(p_node->smmu_map_func_name, func, 3323 QDF_MEM_FUNC_NAME_SIZE); 3324 p_node->smmu_map_line_num = line; 3325 p_node->is_nbuf_smmu_mapped = true; 3326 p_node->smmu_map_iova_addr = iova; 3327 p_node->smmu_map_pa_addr = pa; 3328 } 3329 spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); 3330 } 3331 qdf_net_buf_debug_update_smmu_unmap_node(qdf_nbuf_t nbuf,unsigned long iova,unsigned long pa,const char * func,uint32_t line)3332 void qdf_net_buf_debug_update_smmu_unmap_node(qdf_nbuf_t nbuf, 3333 unsigned long iova, 3334 unsigned long pa, 3335 const char *func, 3336 uint32_t line) 3337 { 3338 uint32_t i; 3339 unsigned long irq_flag; 3340 QDF_NBUF_TRACK *p_node; 3341 3342 if (is_initial_mem_debug_disabled) 3343 return; 3344 3345 i = qdf_net_buf_debug_hash(nbuf); 3346 spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); 3347 3348 p_node = qdf_net_buf_debug_look_up(nbuf); 3349 3350 if (p_node) { 3351 qdf_str_lcopy(p_node->smmu_unmap_func_name, func, 3352 QDF_MEM_FUNC_NAME_SIZE); 3353 p_node->smmu_unmap_line_num = line; 3354 p_node->is_nbuf_smmu_mapped = false; 3355 p_node->smmu_unmap_iova_addr = iova; 3356 p_node->smmu_unmap_pa_addr = pa; 3357 } 3358 spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); 3359 } 3360 #endif 3361 qdf_net_buf_debug_update_unmap_node(qdf_nbuf_t net_buf,const char * func_name,uint32_t line_num)3362 void qdf_net_buf_debug_update_unmap_node(qdf_nbuf_t net_buf, 3363 const char *func_name, 3364 uint32_t line_num) 3365 { 3366 uint32_t i; 3367 unsigned long irq_flag; 3368 QDF_NBUF_TRACK *p_node; 3369 3370 if (is_initial_mem_debug_disabled) 3371 return; 3372 3373 i = qdf_net_buf_debug_hash(net_buf); 3374 spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); 3375 3376 p_node = qdf_net_buf_debug_look_up(net_buf); 3377 3378 if (p_node) { 3379 qdf_str_lcopy(p_node->unmap_func_name, func_name, 3380 QDF_MEM_FUNC_NAME_SIZE); 3381 p_node->unmap_line_num = line_num; 3382 p_node->is_nbuf_mapped = false; 3383 } 3384 spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); 3385 } 3386 qdf_net_buf_debug_delete_node(qdf_nbuf_t net_buf)3387 void qdf_net_buf_debug_delete_node(qdf_nbuf_t net_buf) 3388 { 3389 uint32_t i; 3390 QDF_NBUF_TRACK *p_head; 3391 QDF_NBUF_TRACK *p_node = NULL; 3392 unsigned long irq_flag; 3393 QDF_NBUF_TRACK *p_prev; 3394 3395 if (is_initial_mem_debug_disabled) 3396 return; 3397 3398 i = qdf_net_buf_debug_hash(net_buf); 3399 spin_lock_irqsave(&g_qdf_net_buf_track_lock[i], irq_flag); 3400 3401 p_head = gp_qdf_net_buf_track_tbl[i]; 3402 3403 /* Unallocated SKB */ 3404 if (!p_head) 3405 goto done; 3406 3407 p_node = p_head; 3408 /* Found at head of the table */ 3409 if (p_head->net_buf == net_buf) { 3410 gp_qdf_net_buf_track_tbl[i] = p_node->p_next; 3411 goto done; 3412 } 3413 3414 /* Search in collision list */ 3415 while (p_node) { 3416 p_prev = p_node; 3417 p_node = p_node->p_next; 3418 if ((p_node) && (p_node->net_buf == net_buf)) { 3419 p_prev->p_next = p_node->p_next; 3420 break; 3421 } 3422 } 3423 3424 done: 3425 spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag); 3426 3427 if (p_node) { 3428 qdf_mem_skb_dec(p_node->size); 3429 qdf_nbuf_track_free(p_node); 3430 } else { 3431 if (qdf_net_buf_track_fail_count) { 3432 qdf_print("Untracked net_buf free: %pK with tracking failures count: %u", 3433 net_buf, qdf_net_buf_track_fail_count); 3434 } else 3435 QDF_MEMDEBUG_PANIC("Unallocated buffer ! Double free of net_buf %pK ?", 3436 net_buf); 3437 } 3438 } 3439 qdf_export_symbol(qdf_net_buf_debug_delete_node); 3440 qdf_net_buf_debug_acquire_skb(qdf_nbuf_t net_buf,const char * func_name,uint32_t line_num)3441 void qdf_net_buf_debug_acquire_skb(qdf_nbuf_t net_buf, 3442 const char *func_name, uint32_t line_num) 3443 { 3444 qdf_nbuf_t ext_list = qdf_nbuf_get_ext_list(net_buf); 3445 3446 if (is_initial_mem_debug_disabled) 3447 return; 3448 3449 while (ext_list) { 3450 /* 3451 * Take care to add if it is Jumbo packet connected using 3452 * frag_list 3453 */ 3454 qdf_nbuf_t next; 3455 3456 next = qdf_nbuf_queue_next(ext_list); 3457 qdf_net_buf_debug_add_node(ext_list, 0, func_name, line_num); 3458 ext_list = next; 3459 } 3460 qdf_net_buf_debug_add_node(net_buf, 0, func_name, line_num); 3461 } 3462 qdf_export_symbol(qdf_net_buf_debug_acquire_skb); 3463 qdf_net_buf_debug_release_skb(qdf_nbuf_t net_buf)3464 void qdf_net_buf_debug_release_skb(qdf_nbuf_t net_buf) 3465 { 3466 qdf_nbuf_t ext_list; 3467 3468 if (is_initial_mem_debug_disabled) 3469 return; 3470 3471 ext_list = qdf_nbuf_get_ext_list(net_buf); 3472 while (ext_list) { 3473 /* 3474 * Take care to free if it is Jumbo packet connected using 3475 * frag_list 3476 */ 3477 qdf_nbuf_t next; 3478 3479 next = qdf_nbuf_queue_next(ext_list); 3480 3481 if (qdf_nbuf_get_users(ext_list) > 1) { 3482 ext_list = next; 3483 continue; 3484 } 3485 3486 qdf_net_buf_debug_delete_node(ext_list); 3487 ext_list = next; 3488 } 3489 3490 if (qdf_nbuf_get_users(net_buf) > 1) 3491 return; 3492 3493 qdf_net_buf_debug_delete_node(net_buf); 3494 } 3495 qdf_export_symbol(qdf_net_buf_debug_release_skb); 3496 qdf_nbuf_alloc_debug(qdf_device_t osdev,qdf_size_t size,int reserve,int align,int prio,const char * func,uint32_t line)3497 qdf_nbuf_t qdf_nbuf_alloc_debug(qdf_device_t osdev, qdf_size_t size, 3498 int reserve, int align, int prio, 3499 const char *func, uint32_t line) 3500 { 3501 qdf_nbuf_t nbuf; 3502 3503 if (is_initial_mem_debug_disabled) 3504 return __qdf_nbuf_alloc(osdev, size, 3505 reserve, align, 3506 prio, func, line); 3507 3508 nbuf = __qdf_nbuf_alloc(osdev, size, reserve, align, prio, func, line); 3509 3510 /* Store SKB in internal QDF tracking table */ 3511 if (qdf_likely(nbuf)) { 3512 qdf_net_buf_debug_add_node(nbuf, size, func, line); 3513 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC); 3514 } else { 3515 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC_FAILURE); 3516 } 3517 3518 return nbuf; 3519 } 3520 qdf_export_symbol(qdf_nbuf_alloc_debug); 3521 qdf_nbuf_frag_alloc_debug(qdf_device_t osdev,qdf_size_t size,int reserve,int align,int prio,const char * func,uint32_t line)3522 qdf_nbuf_t qdf_nbuf_frag_alloc_debug(qdf_device_t osdev, qdf_size_t size, 3523 int reserve, int align, int prio, 3524 const char *func, uint32_t line) 3525 { 3526 qdf_nbuf_t nbuf; 3527 3528 if (is_initial_mem_debug_disabled) 3529 return __qdf_nbuf_frag_alloc(osdev, size, 3530 reserve, align, 3531 prio, func, line); 3532 3533 nbuf = __qdf_nbuf_frag_alloc(osdev, size, reserve, align, prio, 3534 func, line); 3535 3536 /* Store SKB in internal QDF tracking table */ 3537 if (qdf_likely(nbuf)) { 3538 qdf_net_buf_debug_add_node(nbuf, size, func, line); 3539 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC); 3540 } else { 3541 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC_FAILURE); 3542 } 3543 3544 return nbuf; 3545 } 3546 3547 qdf_export_symbol(qdf_nbuf_frag_alloc_debug); 3548 qdf_nbuf_alloc_no_recycler_debug(size_t size,int reserve,int align,const char * func,uint32_t line)3549 qdf_nbuf_t qdf_nbuf_alloc_no_recycler_debug(size_t size, int reserve, int align, 3550 const char *func, uint32_t line) 3551 { 3552 qdf_nbuf_t nbuf; 3553 3554 if (is_initial_mem_debug_disabled) 3555 return __qdf_nbuf_alloc_no_recycler(size, reserve, align, func, 3556 line); 3557 3558 nbuf = __qdf_nbuf_alloc_no_recycler(size, reserve, align, func, line); 3559 3560 /* Store SKB in internal QDF tracking table */ 3561 if (qdf_likely(nbuf)) { 3562 qdf_net_buf_debug_add_node(nbuf, size, func, line); 3563 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC); 3564 } else { 3565 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC_FAILURE); 3566 } 3567 3568 return nbuf; 3569 } 3570 3571 qdf_export_symbol(qdf_nbuf_alloc_no_recycler_debug); 3572 qdf_nbuf_free_debug(qdf_nbuf_t nbuf,const char * func,uint32_t line)3573 void qdf_nbuf_free_debug(qdf_nbuf_t nbuf, const char *func, uint32_t line) 3574 { 3575 qdf_nbuf_t ext_list; 3576 qdf_frag_t p_frag; 3577 uint32_t num_nr_frags; 3578 uint32_t idx = 0; 3579 3580 if (qdf_unlikely(!nbuf)) 3581 return; 3582 3583 if (is_initial_mem_debug_disabled) 3584 goto free_buf; 3585 3586 if (qdf_nbuf_get_users(nbuf) > 1) 3587 goto free_buf; 3588 3589 /* Remove SKB from internal QDF tracking table */ 3590 qdf_nbuf_panic_on_free_if_smmu_mapped(nbuf, func, line); 3591 qdf_nbuf_panic_on_free_if_mapped(nbuf, func, line); 3592 qdf_net_buf_debug_delete_node(nbuf); 3593 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_FREE); 3594 3595 /* Take care to delete the debug entries for frags */ 3596 num_nr_frags = qdf_nbuf_get_nr_frags(nbuf); 3597 3598 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 3599 3600 while (idx < num_nr_frags) { 3601 p_frag = qdf_nbuf_get_frag_addr(nbuf, idx); 3602 if (qdf_likely(p_frag)) 3603 qdf_frag_debug_refcount_dec(p_frag, func, line); 3604 idx++; 3605 } 3606 3607 /* 3608 * Take care to update the debug entries for frag_list and also 3609 * for the frags attached to frag_list 3610 */ 3611 ext_list = qdf_nbuf_get_ext_list(nbuf); 3612 while (ext_list) { 3613 if (qdf_nbuf_get_users(ext_list) == 1) { 3614 qdf_nbuf_panic_on_free_if_smmu_mapped(ext_list, func, 3615 line); 3616 qdf_nbuf_panic_on_free_if_mapped(ext_list, func, line); 3617 idx = 0; 3618 num_nr_frags = qdf_nbuf_get_nr_frags(ext_list); 3619 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 3620 while (idx < num_nr_frags) { 3621 p_frag = qdf_nbuf_get_frag_addr(ext_list, idx); 3622 if (qdf_likely(p_frag)) 3623 qdf_frag_debug_refcount_dec(p_frag, 3624 func, line); 3625 idx++; 3626 } 3627 qdf_net_buf_debug_delete_node(ext_list); 3628 } 3629 3630 ext_list = qdf_nbuf_queue_next(ext_list); 3631 } 3632 3633 free_buf: 3634 __qdf_nbuf_free(nbuf); 3635 } 3636 qdf_export_symbol(qdf_nbuf_free_debug); 3637 __qdf_nbuf_alloc_simple(qdf_device_t osdev,size_t size,const char * func,uint32_t line)3638 struct sk_buff *__qdf_nbuf_alloc_simple(qdf_device_t osdev, size_t size, 3639 const char *func, uint32_t line) 3640 { 3641 struct sk_buff *skb; 3642 int flags = GFP_KERNEL; 3643 3644 if (in_interrupt() || irqs_disabled() || in_atomic()) { 3645 flags = GFP_ATOMIC; 3646 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) 3647 /* 3648 * Observed that kcompactd burns out CPU to make order-3 page. 3649 *__netdev_alloc_skb has 4k page fallback option just in case of 3650 * failing high order page allocation so we don't need to be 3651 * hard. Make kcompactd rest in piece. 3652 */ 3653 flags = flags & ~__GFP_KSWAPD_RECLAIM; 3654 #endif 3655 } 3656 3657 skb = __netdev_alloc_skb(NULL, size, flags); 3658 3659 3660 if (qdf_likely(is_initial_mem_debug_disabled)) { 3661 if (qdf_likely(skb)) 3662 qdf_nbuf_count_inc(skb); 3663 } else { 3664 if (qdf_likely(skb)) { 3665 qdf_nbuf_count_inc(skb); 3666 qdf_net_buf_debug_add_node(skb, size, func, line); 3667 qdf_nbuf_history_add(skb, func, line, QDF_NBUF_ALLOC); 3668 } else { 3669 qdf_nbuf_history_add(skb, func, line, QDF_NBUF_ALLOC_FAILURE); 3670 } 3671 } 3672 3673 3674 return skb; 3675 } 3676 3677 qdf_export_symbol(__qdf_nbuf_alloc_simple); 3678 qdf_nbuf_free_debug_simple(qdf_nbuf_t nbuf,const char * func,uint32_t line)3679 void qdf_nbuf_free_debug_simple(qdf_nbuf_t nbuf, const char *func, 3680 uint32_t line) 3681 { 3682 if (qdf_likely(nbuf)) { 3683 if (is_initial_mem_debug_disabled) { 3684 dev_kfree_skb_any(nbuf); 3685 } else { 3686 qdf_nbuf_free_debug(nbuf, func, line); 3687 } 3688 } 3689 } 3690 3691 qdf_export_symbol(qdf_nbuf_free_debug_simple); 3692 qdf_nbuf_clone_debug(qdf_nbuf_t buf,const char * func,uint32_t line)3693 qdf_nbuf_t qdf_nbuf_clone_debug(qdf_nbuf_t buf, const char *func, uint32_t line) 3694 { 3695 uint32_t num_nr_frags; 3696 uint32_t idx = 0; 3697 qdf_nbuf_t ext_list; 3698 qdf_frag_t p_frag; 3699 3700 qdf_nbuf_t cloned_buf = __qdf_nbuf_clone(buf); 3701 3702 if (is_initial_mem_debug_disabled) 3703 return cloned_buf; 3704 3705 if (qdf_unlikely(!cloned_buf)) 3706 return NULL; 3707 3708 /* Take care to update the debug entries for frags */ 3709 num_nr_frags = qdf_nbuf_get_nr_frags(cloned_buf); 3710 3711 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 3712 3713 while (idx < num_nr_frags) { 3714 p_frag = qdf_nbuf_get_frag_addr(cloned_buf, idx); 3715 if (qdf_likely(p_frag)) 3716 qdf_frag_debug_refcount_inc(p_frag, func, line); 3717 idx++; 3718 } 3719 3720 /* Take care to update debug entries for frags attached to frag_list */ 3721 ext_list = qdf_nbuf_get_ext_list(cloned_buf); 3722 while (ext_list) { 3723 idx = 0; 3724 num_nr_frags = qdf_nbuf_get_nr_frags(ext_list); 3725 3726 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 3727 3728 while (idx < num_nr_frags) { 3729 p_frag = qdf_nbuf_get_frag_addr(ext_list, idx); 3730 if (qdf_likely(p_frag)) 3731 qdf_frag_debug_refcount_inc(p_frag, func, line); 3732 idx++; 3733 } 3734 ext_list = qdf_nbuf_queue_next(ext_list); 3735 } 3736 3737 /* Store SKB in internal QDF tracking table */ 3738 qdf_net_buf_debug_add_node(cloned_buf, 0, func, line); 3739 qdf_nbuf_history_add(cloned_buf, func, line, QDF_NBUF_ALLOC_CLONE); 3740 3741 return cloned_buf; 3742 } 3743 qdf_export_symbol(qdf_nbuf_clone_debug); 3744 3745 qdf_nbuf_t qdf_nbuf_page_frag_alloc_debug(qdf_device_t osdev,qdf_size_t size,int reserve,int align,__qdf_frag_cache_t * pf_cache,const char * func,uint32_t line)3746 qdf_nbuf_page_frag_alloc_debug(qdf_device_t osdev, qdf_size_t size, int reserve, 3747 int align, __qdf_frag_cache_t *pf_cache, 3748 const char *func, uint32_t line) 3749 { 3750 qdf_nbuf_t nbuf; 3751 3752 if (is_initial_mem_debug_disabled) 3753 return __qdf_nbuf_page_frag_alloc(osdev, size, reserve, align, 3754 pf_cache, func, line); 3755 3756 nbuf = __qdf_nbuf_page_frag_alloc(osdev, size, reserve, align, 3757 pf_cache, func, line); 3758 3759 /* Store SKB in internal QDF tracking table */ 3760 if (qdf_likely(nbuf)) { 3761 qdf_net_buf_debug_add_node(nbuf, size, func, line); 3762 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC); 3763 } else { 3764 qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC_FAILURE); 3765 } 3766 3767 return nbuf; 3768 } 3769 3770 qdf_export_symbol(qdf_nbuf_page_frag_alloc_debug); 3771 qdf_nbuf_copy_debug(qdf_nbuf_t buf,const char * func,uint32_t line)3772 qdf_nbuf_t qdf_nbuf_copy_debug(qdf_nbuf_t buf, const char *func, uint32_t line) 3773 { 3774 qdf_nbuf_t copied_buf = __qdf_nbuf_copy(buf); 3775 3776 if (is_initial_mem_debug_disabled) 3777 return copied_buf; 3778 3779 if (qdf_unlikely(!copied_buf)) 3780 return NULL; 3781 3782 /* Store SKB in internal QDF tracking table */ 3783 qdf_net_buf_debug_add_node(copied_buf, 0, func, line); 3784 qdf_nbuf_history_add(copied_buf, func, line, QDF_NBUF_ALLOC_COPY); 3785 3786 return copied_buf; 3787 } 3788 qdf_export_symbol(qdf_nbuf_copy_debug); 3789 3790 qdf_nbuf_t qdf_nbuf_copy_expand_debug(qdf_nbuf_t buf,int headroom,int tailroom,const char * func,uint32_t line)3791 qdf_nbuf_copy_expand_debug(qdf_nbuf_t buf, int headroom, int tailroom, 3792 const char *func, uint32_t line) 3793 { 3794 qdf_nbuf_t copied_buf = __qdf_nbuf_copy_expand(buf, headroom, tailroom); 3795 3796 if (qdf_unlikely(!copied_buf)) 3797 return NULL; 3798 3799 if (is_initial_mem_debug_disabled) 3800 return copied_buf; 3801 3802 /* Store SKB in internal QDF tracking table */ 3803 qdf_net_buf_debug_add_node(copied_buf, 0, func, line); 3804 qdf_nbuf_history_add(copied_buf, func, line, 3805 QDF_NBUF_ALLOC_COPY_EXPAND); 3806 3807 return copied_buf; 3808 } 3809 3810 qdf_export_symbol(qdf_nbuf_copy_expand_debug); 3811 3812 qdf_nbuf_t qdf_nbuf_unshare_debug(qdf_nbuf_t buf,const char * func_name,uint32_t line_num)3813 qdf_nbuf_unshare_debug(qdf_nbuf_t buf, const char *func_name, 3814 uint32_t line_num) 3815 { 3816 qdf_nbuf_t unshared_buf; 3817 qdf_frag_t p_frag; 3818 uint32_t num_nr_frags; 3819 uint32_t idx = 0; 3820 qdf_nbuf_t ext_list, next; 3821 3822 if (is_initial_mem_debug_disabled) 3823 return __qdf_nbuf_unshare(buf); 3824 3825 /* Not a shared buffer, nothing to do */ 3826 if (!qdf_nbuf_is_cloned(buf)) 3827 return buf; 3828 3829 if (qdf_nbuf_get_users(buf) > 1) 3830 goto unshare_buf; 3831 3832 /* Take care to delete the debug entries for frags */ 3833 num_nr_frags = qdf_nbuf_get_nr_frags(buf); 3834 3835 while (idx < num_nr_frags) { 3836 p_frag = qdf_nbuf_get_frag_addr(buf, idx); 3837 if (qdf_likely(p_frag)) 3838 qdf_frag_debug_refcount_dec(p_frag, func_name, 3839 line_num); 3840 idx++; 3841 } 3842 3843 qdf_net_buf_debug_delete_node(buf); 3844 3845 /* Take care of jumbo packet connected using frag_list and frags */ 3846 ext_list = qdf_nbuf_get_ext_list(buf); 3847 while (ext_list) { 3848 idx = 0; 3849 next = qdf_nbuf_queue_next(ext_list); 3850 num_nr_frags = qdf_nbuf_get_nr_frags(ext_list); 3851 3852 if (qdf_nbuf_get_users(ext_list) > 1) { 3853 ext_list = next; 3854 continue; 3855 } 3856 3857 while (idx < num_nr_frags) { 3858 p_frag = qdf_nbuf_get_frag_addr(ext_list, idx); 3859 if (qdf_likely(p_frag)) 3860 qdf_frag_debug_refcount_dec(p_frag, func_name, 3861 line_num); 3862 idx++; 3863 } 3864 3865 qdf_net_buf_debug_delete_node(ext_list); 3866 ext_list = next; 3867 } 3868 3869 unshare_buf: 3870 unshared_buf = __qdf_nbuf_unshare(buf); 3871 3872 if (qdf_likely(unshared_buf)) 3873 qdf_net_buf_debug_add_node(unshared_buf, 0, func_name, 3874 line_num); 3875 3876 return unshared_buf; 3877 } 3878 3879 qdf_export_symbol(qdf_nbuf_unshare_debug); 3880 3881 void qdf_nbuf_dev_kfree_list_debug(__qdf_nbuf_queue_head_t * nbuf_queue_head,const char * func,uint32_t line)3882 qdf_nbuf_dev_kfree_list_debug(__qdf_nbuf_queue_head_t *nbuf_queue_head, 3883 const char *func, uint32_t line) 3884 { 3885 qdf_nbuf_t buf; 3886 3887 if (qdf_nbuf_queue_empty(nbuf_queue_head)) 3888 return; 3889 3890 if (is_initial_mem_debug_disabled) 3891 return __qdf_nbuf_dev_kfree_list(nbuf_queue_head); 3892 3893 while ((buf = qdf_nbuf_queue_head_dequeue(nbuf_queue_head)) != NULL) 3894 qdf_nbuf_free_debug(buf, func, line); 3895 } 3896 3897 qdf_export_symbol(qdf_nbuf_dev_kfree_list_debug); 3898 #endif /* NBUF_MEMORY_DEBUG */ 3899 3900 #if defined(QCA_DP_NBUF_FAST_PPEDS) 3901 #if defined(NBUF_MEMORY_DEBUG) __qdf_nbuf_alloc_ppe_ds(qdf_device_t osdev,size_t size,const char * func,uint32_t line)3902 struct sk_buff *__qdf_nbuf_alloc_ppe_ds(qdf_device_t osdev, size_t size, 3903 const char *func, uint32_t line) 3904 { 3905 struct sk_buff *skb; 3906 int flags = GFP_KERNEL; 3907 3908 if (in_interrupt() || irqs_disabled() || in_atomic()) { 3909 flags = GFP_ATOMIC; 3910 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) 3911 /* 3912 * Observed that kcompactd burns out CPU to make order-3 3913 * page.__netdev_alloc_skb has 4k page fallback option 3914 * just in case of 3915 * failing high order page allocation so we don't need 3916 * to be hard. Make kcompactd rest in piece. 3917 */ 3918 flags = flags & ~__GFP_KSWAPD_RECLAIM; 3919 #endif 3920 } 3921 skb = __netdev_alloc_skb_no_skb_reset(NULL, size, flags); 3922 if (qdf_likely(is_initial_mem_debug_disabled)) { 3923 if (qdf_likely(skb)) 3924 qdf_nbuf_count_inc(skb); 3925 } else { 3926 if (qdf_likely(skb)) { 3927 qdf_nbuf_count_inc(skb); 3928 qdf_net_buf_debug_add_node(skb, size, func, line); 3929 qdf_nbuf_history_add(skb, func, line, 3930 QDF_NBUF_ALLOC); 3931 } else { 3932 qdf_nbuf_history_add(skb, func, line, 3933 QDF_NBUF_ALLOC_FAILURE); 3934 } 3935 } 3936 return skb; 3937 } 3938 #else __qdf_nbuf_alloc_ppe_ds(qdf_device_t osdev,size_t size,const char * func,uint32_t line)3939 struct sk_buff *__qdf_nbuf_alloc_ppe_ds(qdf_device_t osdev, size_t size, 3940 const char *func, uint32_t line) 3941 { 3942 struct sk_buff *skb; 3943 int flags = GFP_KERNEL; 3944 3945 if (in_interrupt() || irqs_disabled() || in_atomic()) { 3946 flags = GFP_ATOMIC; 3947 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) 3948 /* 3949 * Observed that kcompactd burns out CPU to make order-3 3950 * page.__netdev_alloc_skb has 4k page fallback option 3951 * just in case of 3952 * failing high order page allocation so we don't need 3953 * to be hard. Make kcompactd rest in piece. 3954 */ 3955 flags = flags & ~__GFP_KSWAPD_RECLAIM; 3956 #endif 3957 } 3958 skb = __netdev_alloc_skb_no_skb_reset(NULL, size, flags); 3959 if (qdf_likely(skb)) 3960 qdf_nbuf_count_inc(skb); 3961 3962 return skb; 3963 } 3964 #endif 3965 qdf_export_symbol(__qdf_nbuf_alloc_ppe_ds); 3966 #endif 3967 3968 #if defined(FEATURE_TSO) 3969 3970 /** 3971 * struct qdf_tso_cmn_seg_info_t - TSO common info structure 3972 * 3973 * @ethproto: ethernet type of the msdu 3974 * @ip_tcp_hdr_len: ip + tcp length for the msdu 3975 * @l2_len: L2 length for the msdu 3976 * @eit_hdr: pointer to EIT header 3977 * @eit_hdr_len: EIT header length for the msdu 3978 * @eit_hdr_dma_map_addr: dma addr for EIT header 3979 * @tcphdr: pointer to tcp header 3980 * @ipv4_csum_en: ipv4 checksum enable 3981 * @tcp_ipv4_csum_en: TCP ipv4 checksum enable 3982 * @tcp_ipv6_csum_en: TCP ipv6 checksum enable 3983 * @ip_id: IP id 3984 * @tcp_seq_num: TCP sequence number 3985 * 3986 * This structure holds the TSO common info that is common 3987 * across all the TCP segments of the jumbo packet. 3988 */ 3989 struct qdf_tso_cmn_seg_info_t { 3990 uint16_t ethproto; 3991 uint16_t ip_tcp_hdr_len; 3992 uint16_t l2_len; 3993 uint8_t *eit_hdr; 3994 uint32_t eit_hdr_len; 3995 qdf_dma_addr_t eit_hdr_dma_map_addr; 3996 struct tcphdr *tcphdr; 3997 uint16_t ipv4_csum_en; 3998 uint16_t tcp_ipv4_csum_en; 3999 uint16_t tcp_ipv6_csum_en; 4000 uint16_t ip_id; 4001 uint32_t tcp_seq_num; 4002 }; 4003 4004 /** 4005 * qdf_nbuf_adj_tso_frag() - adjustment for buffer address of tso fragment 4006 * @skb: network buffer 4007 * 4008 * Return: byte offset length of 8 bytes aligned. 4009 */ 4010 #ifdef FIX_TXDMA_LIMITATION qdf_nbuf_adj_tso_frag(struct sk_buff * skb)4011 static uint8_t qdf_nbuf_adj_tso_frag(struct sk_buff *skb) 4012 { 4013 uint32_t eit_hdr_len; 4014 uint8_t *eit_hdr; 4015 uint8_t byte_8_align_offset; 4016 4017 eit_hdr = skb->data; 4018 eit_hdr_len = (skb_transport_header(skb) 4019 - skb_mac_header(skb)) + tcp_hdrlen(skb); 4020 byte_8_align_offset = ((unsigned long)(eit_hdr) + eit_hdr_len) & 0x7L; 4021 if (qdf_unlikely(byte_8_align_offset)) { 4022 TSO_DEBUG("%pK,Len %d %d", 4023 eit_hdr, eit_hdr_len, byte_8_align_offset); 4024 if (unlikely(skb_headroom(skb) < byte_8_align_offset)) { 4025 TSO_DEBUG("[%d]Insufficient headroom,[%pK],[%pK],[%d]", 4026 __LINE__, skb->head, skb->data, 4027 byte_8_align_offset); 4028 return 0; 4029 } 4030 qdf_nbuf_push_head(skb, byte_8_align_offset); 4031 qdf_mem_move(skb->data, 4032 skb->data + byte_8_align_offset, 4033 eit_hdr_len); 4034 skb->len -= byte_8_align_offset; 4035 skb->mac_header -= byte_8_align_offset; 4036 skb->network_header -= byte_8_align_offset; 4037 skb->transport_header -= byte_8_align_offset; 4038 } 4039 return byte_8_align_offset; 4040 } 4041 #else qdf_nbuf_adj_tso_frag(struct sk_buff * skb)4042 static uint8_t qdf_nbuf_adj_tso_frag(struct sk_buff *skb) 4043 { 4044 return 0; 4045 } 4046 #endif 4047 4048 #ifdef CONFIG_WLAN_SYSFS_MEM_STATS qdf_record_nbuf_nbytes(uint32_t nbytes,qdf_dma_dir_t dir,bool is_mapped)4049 void qdf_record_nbuf_nbytes( 4050 uint32_t nbytes, qdf_dma_dir_t dir, bool is_mapped) 4051 { 4052 __qdf_record_nbuf_nbytes(nbytes, dir, is_mapped); 4053 } 4054 4055 qdf_export_symbol(qdf_record_nbuf_nbytes); 4056 4057 #endif /* CONFIG_WLAN_SYSFS_MEM_STATS */ 4058 4059 /** 4060 * qdf_nbuf_tso_map_frag() - Map TSO segment 4061 * @osdev: qdf device handle 4062 * @tso_frag_vaddr: addr of tso fragment 4063 * @nbytes: number of bytes 4064 * @dir: direction 4065 * 4066 * Map TSO segment and for MCL record the amount of memory mapped 4067 * 4068 * Return: DMA address of mapped TSO fragment in success and 4069 * NULL in case of DMA mapping failure 4070 */ qdf_nbuf_tso_map_frag(qdf_device_t osdev,void * tso_frag_vaddr,uint32_t nbytes,qdf_dma_dir_t dir)4071 static inline qdf_dma_addr_t qdf_nbuf_tso_map_frag( 4072 qdf_device_t osdev, void *tso_frag_vaddr, 4073 uint32_t nbytes, qdf_dma_dir_t dir) 4074 { 4075 qdf_dma_addr_t tso_frag_paddr = 0; 4076 4077 tso_frag_paddr = dma_map_single(osdev->dev, tso_frag_vaddr, 4078 nbytes, __qdf_dma_dir_to_os(dir)); 4079 if (unlikely(dma_mapping_error(osdev->dev, tso_frag_paddr))) { 4080 qdf_err("DMA mapping error!"); 4081 qdf_assert_always(0); 4082 return 0; 4083 } 4084 qdf_record_nbuf_nbytes(nbytes, dir, true); 4085 return tso_frag_paddr; 4086 } 4087 4088 /** 4089 * qdf_nbuf_tso_unmap_frag() - Unmap TSO segment 4090 * @osdev: qdf device handle 4091 * @tso_frag_paddr: DMA addr of tso fragment 4092 * @dir: direction 4093 * @nbytes: number of bytes 4094 * 4095 * Unmap TSO segment and for MCL record the amount of memory mapped 4096 * 4097 * Return: None 4098 */ qdf_nbuf_tso_unmap_frag(qdf_device_t osdev,qdf_dma_addr_t tso_frag_paddr,uint32_t nbytes,qdf_dma_dir_t dir)4099 static inline void qdf_nbuf_tso_unmap_frag( 4100 qdf_device_t osdev, qdf_dma_addr_t tso_frag_paddr, 4101 uint32_t nbytes, qdf_dma_dir_t dir) 4102 { 4103 qdf_record_nbuf_nbytes(nbytes, dir, false); 4104 dma_unmap_single(osdev->dev, tso_frag_paddr, 4105 nbytes, __qdf_dma_dir_to_os(dir)); 4106 } 4107 4108 /** 4109 * __qdf_nbuf_get_tso_cmn_seg_info() - get TSO common 4110 * information 4111 * @osdev: qdf device handle 4112 * @skb: skb buffer 4113 * @tso_info: Parameters common to all segments 4114 * 4115 * Get the TSO information that is common across all the TCP 4116 * segments of the jumbo packet 4117 * 4118 * Return: 0 - success 1 - failure 4119 */ __qdf_nbuf_get_tso_cmn_seg_info(qdf_device_t osdev,struct sk_buff * skb,struct qdf_tso_cmn_seg_info_t * tso_info)4120 static uint8_t __qdf_nbuf_get_tso_cmn_seg_info(qdf_device_t osdev, 4121 struct sk_buff *skb, 4122 struct qdf_tso_cmn_seg_info_t *tso_info) 4123 { 4124 /* Get ethernet type and ethernet header length */ 4125 tso_info->ethproto = vlan_get_protocol(skb); 4126 4127 /* Determine whether this is an IPv4 or IPv6 packet */ 4128 if (tso_info->ethproto == htons(ETH_P_IP)) { /* IPv4 */ 4129 /* for IPv4, get the IP ID and enable TCP and IP csum */ 4130 struct iphdr *ipv4_hdr = ip_hdr(skb); 4131 4132 tso_info->ip_id = ntohs(ipv4_hdr->id); 4133 tso_info->ipv4_csum_en = 1; 4134 tso_info->tcp_ipv4_csum_en = 1; 4135 if (qdf_unlikely(ipv4_hdr->protocol != IPPROTO_TCP)) { 4136 qdf_err("TSO IPV4 proto 0x%x not TCP", 4137 ipv4_hdr->protocol); 4138 return 1; 4139 } 4140 } else if (tso_info->ethproto == htons(ETH_P_IPV6)) { /* IPv6 */ 4141 /* for IPv6, enable TCP csum. No IP ID or IP csum */ 4142 tso_info->tcp_ipv6_csum_en = 1; 4143 } else { 4144 qdf_err("TSO: ethertype 0x%x is not supported!", 4145 tso_info->ethproto); 4146 return 1; 4147 } 4148 tso_info->l2_len = (skb_network_header(skb) - skb_mac_header(skb)); 4149 tso_info->tcphdr = tcp_hdr(skb); 4150 tso_info->tcp_seq_num = ntohl(tcp_hdr(skb)->seq); 4151 /* get pointer to the ethernet + IP + TCP header and their length */ 4152 tso_info->eit_hdr = skb->data; 4153 tso_info->eit_hdr_len = (skb_transport_header(skb) 4154 - skb_mac_header(skb)) + tcp_hdrlen(skb); 4155 tso_info->eit_hdr_dma_map_addr = qdf_nbuf_tso_map_frag( 4156 osdev, tso_info->eit_hdr, 4157 tso_info->eit_hdr_len, 4158 QDF_DMA_TO_DEVICE); 4159 if (qdf_unlikely(!tso_info->eit_hdr_dma_map_addr)) 4160 return 1; 4161 4162 if (tso_info->ethproto == htons(ETH_P_IP)) { 4163 /* include IPv4 header length for IPV4 (total length) */ 4164 tso_info->ip_tcp_hdr_len = 4165 tso_info->eit_hdr_len - tso_info->l2_len; 4166 } else if (tso_info->ethproto == htons(ETH_P_IPV6)) { 4167 /* exclude IPv6 header length for IPv6 (payload length) */ 4168 tso_info->ip_tcp_hdr_len = tcp_hdrlen(skb); 4169 } 4170 /* 4171 * The length of the payload (application layer data) is added to 4172 * tso_info->ip_tcp_hdr_len before passing it on to the msdu link ext 4173 * descriptor. 4174 */ 4175 4176 TSO_DEBUG("%s seq# %u eit hdr len %u l2 len %u skb len %u\n", __func__, 4177 tso_info->tcp_seq_num, 4178 tso_info->eit_hdr_len, 4179 tso_info->l2_len, 4180 skb->len); 4181 return 0; 4182 } 4183 4184 4185 /** 4186 * __qdf_nbuf_fill_tso_cmn_seg_info() - Init function for each TSO nbuf segment 4187 * 4188 * @curr_seg: Segment whose contents are initialized 4189 * @tso_cmn_info: Parameters common to all segments 4190 * 4191 * Return: None 4192 */ __qdf_nbuf_fill_tso_cmn_seg_info(struct qdf_tso_seg_elem_t * curr_seg,struct qdf_tso_cmn_seg_info_t * tso_cmn_info)4193 static inline void __qdf_nbuf_fill_tso_cmn_seg_info( 4194 struct qdf_tso_seg_elem_t *curr_seg, 4195 struct qdf_tso_cmn_seg_info_t *tso_cmn_info) 4196 { 4197 /* Initialize the flags to 0 */ 4198 memset(&curr_seg->seg, 0x0, sizeof(curr_seg->seg)); 4199 4200 /* 4201 * The following fields remain the same across all segments of 4202 * a jumbo packet 4203 */ 4204 curr_seg->seg.tso_flags.tso_enable = 1; 4205 curr_seg->seg.tso_flags.ipv4_checksum_en = 4206 tso_cmn_info->ipv4_csum_en; 4207 curr_seg->seg.tso_flags.tcp_ipv6_checksum_en = 4208 tso_cmn_info->tcp_ipv6_csum_en; 4209 curr_seg->seg.tso_flags.tcp_ipv4_checksum_en = 4210 tso_cmn_info->tcp_ipv4_csum_en; 4211 curr_seg->seg.tso_flags.tcp_flags_mask = 0x1FF; 4212 4213 /* The following fields change for the segments */ 4214 curr_seg->seg.tso_flags.ip_id = tso_cmn_info->ip_id; 4215 tso_cmn_info->ip_id++; 4216 4217 curr_seg->seg.tso_flags.syn = tso_cmn_info->tcphdr->syn; 4218 curr_seg->seg.tso_flags.rst = tso_cmn_info->tcphdr->rst; 4219 curr_seg->seg.tso_flags.ack = tso_cmn_info->tcphdr->ack; 4220 curr_seg->seg.tso_flags.urg = tso_cmn_info->tcphdr->urg; 4221 curr_seg->seg.tso_flags.ece = tso_cmn_info->tcphdr->ece; 4222 curr_seg->seg.tso_flags.cwr = tso_cmn_info->tcphdr->cwr; 4223 4224 curr_seg->seg.tso_flags.tcp_seq_num = tso_cmn_info->tcp_seq_num; 4225 4226 /* 4227 * First fragment for each segment always contains the ethernet, 4228 * IP and TCP header 4229 */ 4230 curr_seg->seg.tso_frags[0].vaddr = tso_cmn_info->eit_hdr; 4231 curr_seg->seg.tso_frags[0].length = tso_cmn_info->eit_hdr_len; 4232 curr_seg->seg.total_len = curr_seg->seg.tso_frags[0].length; 4233 curr_seg->seg.tso_frags[0].paddr = tso_cmn_info->eit_hdr_dma_map_addr; 4234 4235 TSO_DEBUG("%s %d eit hdr %pK eit_hdr_len %d tcp_seq_num %u tso_info->total_len %u\n", 4236 __func__, __LINE__, tso_cmn_info->eit_hdr, 4237 tso_cmn_info->eit_hdr_len, 4238 curr_seg->seg.tso_flags.tcp_seq_num, 4239 curr_seg->seg.total_len); 4240 qdf_tso_seg_dbg_record(curr_seg, TSOSEG_LOC_FILLCMNSEG); 4241 } 4242 __qdf_nbuf_get_tso_info(qdf_device_t osdev,struct sk_buff * skb,struct qdf_tso_info_t * tso_info)4243 uint32_t __qdf_nbuf_get_tso_info(qdf_device_t osdev, struct sk_buff *skb, 4244 struct qdf_tso_info_t *tso_info) 4245 { 4246 /* common across all segments */ 4247 struct qdf_tso_cmn_seg_info_t tso_cmn_info; 4248 /* segment specific */ 4249 void *tso_frag_vaddr; 4250 qdf_dma_addr_t tso_frag_paddr = 0; 4251 uint32_t num_seg = 0; 4252 struct qdf_tso_seg_elem_t *curr_seg; 4253 struct qdf_tso_num_seg_elem_t *total_num_seg; 4254 skb_frag_t *frag = NULL; 4255 uint32_t tso_frag_len = 0; /* tso segment's fragment length*/ 4256 uint32_t skb_frag_len = 0; /* skb's fragment length (contiguous memory)*/ 4257 uint32_t skb_proc = skb->len; /* bytes of skb pending processing */ 4258 uint32_t tso_seg_size = skb_shinfo(skb)->gso_size; 4259 int j = 0; /* skb fragment index */ 4260 uint8_t byte_8_align_offset; 4261 4262 memset(&tso_cmn_info, 0x0, sizeof(tso_cmn_info)); 4263 total_num_seg = tso_info->tso_num_seg_list; 4264 curr_seg = tso_info->tso_seg_list; 4265 total_num_seg->num_seg.tso_cmn_num_seg = 0; 4266 4267 byte_8_align_offset = qdf_nbuf_adj_tso_frag(skb); 4268 4269 if (qdf_unlikely(__qdf_nbuf_get_tso_cmn_seg_info(osdev, 4270 skb, &tso_cmn_info))) { 4271 qdf_warn("TSO: error getting common segment info"); 4272 return 0; 4273 } 4274 4275 /* length of the first chunk of data in the skb */ 4276 skb_frag_len = skb_headlen(skb); 4277 4278 /* the 0th tso segment's 0th fragment always contains the EIT header */ 4279 /* update the remaining skb fragment length and TSO segment length */ 4280 skb_frag_len -= tso_cmn_info.eit_hdr_len; 4281 skb_proc -= tso_cmn_info.eit_hdr_len; 4282 4283 /* get the address to the next tso fragment */ 4284 tso_frag_vaddr = skb->data + 4285 tso_cmn_info.eit_hdr_len + 4286 byte_8_align_offset; 4287 /* get the length of the next tso fragment */ 4288 tso_frag_len = min(skb_frag_len, tso_seg_size); 4289 4290 if (tso_frag_len != 0) { 4291 tso_frag_paddr = qdf_nbuf_tso_map_frag( 4292 osdev, tso_frag_vaddr, tso_frag_len, 4293 QDF_DMA_TO_DEVICE); 4294 if (qdf_unlikely(!tso_frag_paddr)) 4295 return 0; 4296 } 4297 4298 TSO_DEBUG("%s[%d] skb frag len %d tso frag len %d\n", __func__, 4299 __LINE__, skb_frag_len, tso_frag_len); 4300 num_seg = tso_info->num_segs; 4301 tso_info->num_segs = 0; 4302 tso_info->is_tso = 1; 4303 4304 while (num_seg && curr_seg) { 4305 int i = 1; /* tso fragment index */ 4306 uint8_t more_tso_frags = 1; 4307 4308 curr_seg->seg.num_frags = 0; 4309 tso_info->num_segs++; 4310 total_num_seg->num_seg.tso_cmn_num_seg++; 4311 4312 __qdf_nbuf_fill_tso_cmn_seg_info(curr_seg, 4313 &tso_cmn_info); 4314 4315 /* If TCP PSH flag is set, set it in the last or only segment */ 4316 if (num_seg == 1) 4317 curr_seg->seg.tso_flags.psh = tso_cmn_info.tcphdr->psh; 4318 4319 if (unlikely(skb_proc == 0)) 4320 return tso_info->num_segs; 4321 4322 curr_seg->seg.tso_flags.ip_len = tso_cmn_info.ip_tcp_hdr_len; 4323 curr_seg->seg.tso_flags.l2_len = tso_cmn_info.l2_len; 4324 /* frag len is added to ip_len in while loop below*/ 4325 4326 curr_seg->seg.num_frags++; 4327 4328 while (more_tso_frags) { 4329 if (tso_frag_len != 0) { 4330 curr_seg->seg.tso_frags[i].vaddr = 4331 tso_frag_vaddr; 4332 curr_seg->seg.tso_frags[i].length = 4333 tso_frag_len; 4334 curr_seg->seg.total_len += tso_frag_len; 4335 curr_seg->seg.tso_flags.ip_len += tso_frag_len; 4336 curr_seg->seg.num_frags++; 4337 skb_proc = skb_proc - tso_frag_len; 4338 4339 /* increment the TCP sequence number */ 4340 4341 tso_cmn_info.tcp_seq_num += tso_frag_len; 4342 curr_seg->seg.tso_frags[i].paddr = 4343 tso_frag_paddr; 4344 4345 qdf_assert_always(curr_seg->seg.tso_frags[i].paddr); 4346 } 4347 4348 TSO_DEBUG("%s[%d] frag %d frag len %d total_len %u vaddr %pK\n", 4349 __func__, __LINE__, 4350 i, 4351 tso_frag_len, 4352 curr_seg->seg.total_len, 4353 curr_seg->seg.tso_frags[i].vaddr); 4354 4355 /* if there is no more data left in the skb */ 4356 if (!skb_proc) 4357 return tso_info->num_segs; 4358 4359 /* get the next payload fragment information */ 4360 /* check if there are more fragments in this segment */ 4361 if (tso_frag_len < tso_seg_size) { 4362 more_tso_frags = 1; 4363 if (tso_frag_len != 0) { 4364 tso_seg_size = tso_seg_size - 4365 tso_frag_len; 4366 i++; 4367 if (curr_seg->seg.num_frags == 4368 FRAG_NUM_MAX) { 4369 more_tso_frags = 0; 4370 /* 4371 * reset i and the tso 4372 * payload size 4373 */ 4374 i = 1; 4375 tso_seg_size = 4376 skb_shinfo(skb)-> 4377 gso_size; 4378 } 4379 } 4380 } else { 4381 more_tso_frags = 0; 4382 /* reset i and the tso payload size */ 4383 i = 1; 4384 tso_seg_size = skb_shinfo(skb)->gso_size; 4385 } 4386 4387 /* if the next fragment is contiguous */ 4388 if ((tso_frag_len != 0) && (tso_frag_len < skb_frag_len)) { 4389 tso_frag_vaddr = tso_frag_vaddr + tso_frag_len; 4390 skb_frag_len = skb_frag_len - tso_frag_len; 4391 tso_frag_len = min(skb_frag_len, tso_seg_size); 4392 4393 } else { /* the next fragment is not contiguous */ 4394 if (skb_shinfo(skb)->nr_frags == 0) { 4395 qdf_info("TSO: nr_frags == 0!"); 4396 qdf_assert(0); 4397 return 0; 4398 } 4399 if (j >= skb_shinfo(skb)->nr_frags) { 4400 qdf_info("TSO: nr_frags %d j %d", 4401 skb_shinfo(skb)->nr_frags, j); 4402 qdf_assert(0); 4403 return 0; 4404 } 4405 frag = &skb_shinfo(skb)->frags[j]; 4406 skb_frag_len = skb_frag_size(frag); 4407 tso_frag_len = min(skb_frag_len, tso_seg_size); 4408 tso_frag_vaddr = skb_frag_address_safe(frag); 4409 j++; 4410 } 4411 4412 TSO_DEBUG("%s[%d] skb frag len %d tso frag %d len tso_seg_size %d\n", 4413 __func__, __LINE__, skb_frag_len, tso_frag_len, 4414 tso_seg_size); 4415 4416 if (!(tso_frag_vaddr)) { 4417 TSO_DEBUG("%s: Fragment virtual addr is NULL", 4418 __func__); 4419 return 0; 4420 } 4421 4422 tso_frag_paddr = qdf_nbuf_tso_map_frag( 4423 osdev, tso_frag_vaddr, 4424 tso_frag_len, 4425 QDF_DMA_TO_DEVICE); 4426 if (qdf_unlikely(!tso_frag_paddr)) 4427 return 0; 4428 } 4429 TSO_DEBUG("%s tcp_seq_num: %u", __func__, 4430 curr_seg->seg.tso_flags.tcp_seq_num); 4431 num_seg--; 4432 /* if TCP FIN flag was set, set it in the last segment */ 4433 if (!num_seg) 4434 curr_seg->seg.tso_flags.fin = tso_cmn_info.tcphdr->fin; 4435 4436 qdf_tso_seg_dbg_record(curr_seg, TSOSEG_LOC_GETINFO); 4437 curr_seg = curr_seg->next; 4438 } 4439 return tso_info->num_segs; 4440 } 4441 qdf_export_symbol(__qdf_nbuf_get_tso_info); 4442 __qdf_nbuf_unmap_tso_segment(qdf_device_t osdev,struct qdf_tso_seg_elem_t * tso_seg,bool is_last_seg)4443 void __qdf_nbuf_unmap_tso_segment(qdf_device_t osdev, 4444 struct qdf_tso_seg_elem_t *tso_seg, 4445 bool is_last_seg) 4446 { 4447 uint32_t num_frags = 0; 4448 4449 if (tso_seg->seg.num_frags > 0) 4450 num_frags = tso_seg->seg.num_frags - 1; 4451 4452 /*Num of frags in a tso seg cannot be less than 2 */ 4453 if (num_frags < 1) { 4454 /* 4455 * If Num of frags is 1 in a tso seg but is_last_seg true, 4456 * this may happen when qdf_nbuf_get_tso_info failed, 4457 * do dma unmap for the 0th frag in this seg. 4458 */ 4459 if (is_last_seg && tso_seg->seg.num_frags == 1) 4460 goto last_seg_free_first_frag; 4461 4462 qdf_assert(0); 4463 qdf_err("ERROR: num of frags in a tso segment is %d", 4464 (num_frags + 1)); 4465 return; 4466 } 4467 4468 while (num_frags) { 4469 /*Do dma unmap the tso seg except the 0th frag */ 4470 if (0 == tso_seg->seg.tso_frags[num_frags].paddr) { 4471 qdf_err("ERROR: TSO seg frag %d mapped physical address is NULL", 4472 num_frags); 4473 qdf_assert(0); 4474 return; 4475 } 4476 qdf_nbuf_tso_unmap_frag( 4477 osdev, 4478 tso_seg->seg.tso_frags[num_frags].paddr, 4479 tso_seg->seg.tso_frags[num_frags].length, 4480 QDF_DMA_TO_DEVICE); 4481 tso_seg->seg.tso_frags[num_frags].paddr = 0; 4482 num_frags--; 4483 qdf_tso_seg_dbg_record(tso_seg, TSOSEG_LOC_UNMAPTSO); 4484 } 4485 4486 last_seg_free_first_frag: 4487 if (is_last_seg) { 4488 /*Do dma unmap for the tso seg 0th frag */ 4489 if (0 == tso_seg->seg.tso_frags[0].paddr) { 4490 qdf_err("ERROR: TSO seg frag 0 mapped physical address is NULL"); 4491 qdf_assert(0); 4492 return; 4493 } 4494 qdf_nbuf_tso_unmap_frag(osdev, 4495 tso_seg->seg.tso_frags[0].paddr, 4496 tso_seg->seg.tso_frags[0].length, 4497 QDF_DMA_TO_DEVICE); 4498 tso_seg->seg.tso_frags[0].paddr = 0; 4499 qdf_tso_seg_dbg_record(tso_seg, TSOSEG_LOC_UNMAPLAST); 4500 } 4501 } 4502 qdf_export_symbol(__qdf_nbuf_unmap_tso_segment); 4503 __qdf_nbuf_get_tcp_payload_len(struct sk_buff * skb)4504 size_t __qdf_nbuf_get_tcp_payload_len(struct sk_buff *skb) 4505 { 4506 size_t packet_len; 4507 4508 packet_len = skb->len - 4509 ((skb_transport_header(skb) - skb_mac_header(skb)) + 4510 tcp_hdrlen(skb)); 4511 4512 return packet_len; 4513 } 4514 4515 qdf_export_symbol(__qdf_nbuf_get_tcp_payload_len); 4516 4517 #ifndef BUILD_X86 __qdf_nbuf_get_tso_num_seg(struct sk_buff * skb)4518 uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb) 4519 { 4520 uint32_t tso_seg_size = skb_shinfo(skb)->gso_size; 4521 uint32_t remainder, num_segs = 0; 4522 uint8_t skb_nr_frags = skb_shinfo(skb)->nr_frags; 4523 uint8_t frags_per_tso = 0; 4524 uint32_t skb_frag_len = 0; 4525 uint32_t eit_hdr_len = (skb_transport_header(skb) 4526 - skb_mac_header(skb)) + tcp_hdrlen(skb); 4527 skb_frag_t *frag = NULL; 4528 int j = 0; 4529 uint32_t temp_num_seg = 0; 4530 4531 /* length of the first chunk of data in the skb minus eit header*/ 4532 skb_frag_len = skb_headlen(skb) - eit_hdr_len; 4533 4534 /* Calculate num of segs for skb's first chunk of data*/ 4535 remainder = skb_frag_len % tso_seg_size; 4536 num_segs = skb_frag_len / tso_seg_size; 4537 /* 4538 * Remainder non-zero and nr_frags zero implies end of skb data. 4539 * In that case, one more tso seg is required to accommodate 4540 * remaining data, hence num_segs++. If nr_frags is non-zero, 4541 * then remaining data will be accommodated while doing the calculation 4542 * for nr_frags data. Hence, frags_per_tso++. 4543 */ 4544 if (remainder) { 4545 if (!skb_nr_frags) 4546 num_segs++; 4547 else 4548 frags_per_tso++; 4549 } 4550 4551 while (skb_nr_frags) { 4552 if (j >= skb_shinfo(skb)->nr_frags) { 4553 qdf_info("TSO: nr_frags %d j %d", 4554 skb_shinfo(skb)->nr_frags, j); 4555 qdf_assert(0); 4556 return 0; 4557 } 4558 /* 4559 * Calculate the number of tso seg for nr_frags data: 4560 * Get the length of each frag in skb_frag_len, add to 4561 * remainder.Get the number of segments by dividing it to 4562 * tso_seg_size and calculate the new remainder. 4563 * Decrement the nr_frags value and keep 4564 * looping all the skb_fragments. 4565 */ 4566 frag = &skb_shinfo(skb)->frags[j]; 4567 skb_frag_len = skb_frag_size(frag); 4568 temp_num_seg = num_segs; 4569 remainder += skb_frag_len; 4570 num_segs += remainder / tso_seg_size; 4571 remainder = remainder % tso_seg_size; 4572 skb_nr_frags--; 4573 if (remainder) { 4574 if (num_segs > temp_num_seg) 4575 frags_per_tso = 0; 4576 /* 4577 * increment the tso per frags whenever remainder is 4578 * positive. If frags_per_tso reaches the (max-1), 4579 * [First frags always have EIT header, therefore max-1] 4580 * increment the num_segs as no more data can be 4581 * accommodated in the curr tso seg. Reset the remainder 4582 * and frags per tso and keep looping. 4583 */ 4584 frags_per_tso++; 4585 if (frags_per_tso == FRAG_NUM_MAX - 1) { 4586 num_segs++; 4587 frags_per_tso = 0; 4588 remainder = 0; 4589 } 4590 /* 4591 * If this is the last skb frag and still remainder is 4592 * non-zero(frags_per_tso is not reached to the max-1) 4593 * then increment the num_segs to take care of the 4594 * remaining length. 4595 */ 4596 if (!skb_nr_frags && remainder) { 4597 num_segs++; 4598 frags_per_tso = 0; 4599 } 4600 } else { 4601 /* Whenever remainder is 0, reset the frags_per_tso. */ 4602 frags_per_tso = 0; 4603 } 4604 j++; 4605 } 4606 4607 return num_segs; 4608 } 4609 #elif !defined(QCA_WIFI_QCN9000) __qdf_nbuf_get_tso_num_seg(struct sk_buff * skb)4610 uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb) 4611 { 4612 uint32_t i, gso_size, tmp_len, num_segs = 0; 4613 skb_frag_t *frag = NULL; 4614 4615 /* 4616 * Check if the head SKB or any of frags are allocated in < 0x50000000 4617 * region which cannot be accessed by Target 4618 */ 4619 if (virt_to_phys(skb->data) < 0x50000040) { 4620 TSO_DEBUG("%s %d: Invalid Address nr_frags = %d, paddr = %pK \n", 4621 __func__, __LINE__, skb_shinfo(skb)->nr_frags, 4622 virt_to_phys(skb->data)); 4623 goto fail; 4624 4625 } 4626 4627 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 4628 frag = &skb_shinfo(skb)->frags[i]; 4629 4630 if (!frag) 4631 goto fail; 4632 4633 if (virt_to_phys(skb_frag_address_safe(frag)) < 0x50000040) 4634 goto fail; 4635 } 4636 4637 4638 gso_size = skb_shinfo(skb)->gso_size; 4639 tmp_len = skb->len - ((skb_transport_header(skb) - skb_mac_header(skb)) 4640 + tcp_hdrlen(skb)); 4641 while (tmp_len) { 4642 num_segs++; 4643 if (tmp_len > gso_size) 4644 tmp_len -= gso_size; 4645 else 4646 break; 4647 } 4648 4649 return num_segs; 4650 4651 /* 4652 * Do not free this frame, just do socket level accounting 4653 * so that this is not reused. 4654 */ 4655 fail: 4656 if (skb->sk) 4657 atomic_sub(skb->truesize, &(skb->sk->sk_wmem_alloc)); 4658 4659 return 0; 4660 } 4661 #else __qdf_nbuf_get_tso_num_seg(struct sk_buff * skb)4662 uint32_t __qdf_nbuf_get_tso_num_seg(struct sk_buff *skb) 4663 { 4664 uint32_t i, gso_size, tmp_len, num_segs = 0; 4665 skb_frag_t *frag = NULL; 4666 4667 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 4668 frag = &skb_shinfo(skb)->frags[i]; 4669 4670 if (!frag) 4671 goto fail; 4672 } 4673 4674 gso_size = skb_shinfo(skb)->gso_size; 4675 tmp_len = skb->len - ((skb_transport_header(skb) - skb_mac_header(skb)) 4676 + tcp_hdrlen(skb)); 4677 while (tmp_len) { 4678 num_segs++; 4679 if (tmp_len > gso_size) 4680 tmp_len -= gso_size; 4681 else 4682 break; 4683 } 4684 4685 return num_segs; 4686 4687 /* 4688 * Do not free this frame, just do socket level accounting 4689 * so that this is not reused. 4690 */ 4691 fail: 4692 if (skb->sk) 4693 atomic_sub(skb->truesize, &(skb->sk->sk_wmem_alloc)); 4694 4695 return 0; 4696 } 4697 #endif 4698 qdf_export_symbol(__qdf_nbuf_get_tso_num_seg); 4699 4700 #endif /* FEATURE_TSO */ 4701 __qdf_dmaaddr_to_32s(qdf_dma_addr_t dmaaddr,uint32_t * lo,uint32_t * hi)4702 void __qdf_dmaaddr_to_32s(qdf_dma_addr_t dmaaddr, 4703 uint32_t *lo, uint32_t *hi) 4704 { 4705 if (sizeof(dmaaddr) > sizeof(uint32_t)) { 4706 *lo = lower_32_bits(dmaaddr); 4707 *hi = upper_32_bits(dmaaddr); 4708 } else { 4709 *lo = dmaaddr; 4710 *hi = 0; 4711 } 4712 } 4713 4714 qdf_export_symbol(__qdf_dmaaddr_to_32s); 4715 __qdf_nbuf_inc_users(struct sk_buff * skb)4716 struct sk_buff *__qdf_nbuf_inc_users(struct sk_buff *skb) 4717 { 4718 qdf_nbuf_users_inc(&skb->users); 4719 return skb; 4720 } 4721 qdf_export_symbol(__qdf_nbuf_inc_users); 4722 __qdf_nbuf_get_users(struct sk_buff * skb)4723 int __qdf_nbuf_get_users(struct sk_buff *skb) 4724 { 4725 return qdf_nbuf_users_read(&skb->users); 4726 } 4727 qdf_export_symbol(__qdf_nbuf_get_users); 4728 __qdf_nbuf_ref(struct sk_buff * skb)4729 void __qdf_nbuf_ref(struct sk_buff *skb) 4730 { 4731 skb_get(skb); 4732 } 4733 qdf_export_symbol(__qdf_nbuf_ref); 4734 __qdf_nbuf_shared(struct sk_buff * skb)4735 int __qdf_nbuf_shared(struct sk_buff *skb) 4736 { 4737 return skb_shared(skb); 4738 } 4739 qdf_export_symbol(__qdf_nbuf_shared); 4740 4741 QDF_STATUS __qdf_nbuf_dmamap_create(qdf_device_t osdev,__qdf_dma_map_t * dmap)4742 __qdf_nbuf_dmamap_create(qdf_device_t osdev, __qdf_dma_map_t *dmap) 4743 { 4744 QDF_STATUS error = QDF_STATUS_SUCCESS; 4745 /* 4746 * driver can tell its SG capability, it must be handled. 4747 * Bounce buffers if they are there 4748 */ 4749 (*dmap) = kzalloc(sizeof(struct __qdf_dma_map), GFP_KERNEL); 4750 if (!(*dmap)) 4751 error = QDF_STATUS_E_NOMEM; 4752 4753 return error; 4754 } 4755 qdf_export_symbol(__qdf_nbuf_dmamap_create); 4756 4757 void __qdf_nbuf_dmamap_destroy(qdf_device_t osdev,__qdf_dma_map_t dmap)4758 __qdf_nbuf_dmamap_destroy(qdf_device_t osdev, __qdf_dma_map_t dmap) 4759 { 4760 kfree(dmap); 4761 } 4762 qdf_export_symbol(__qdf_nbuf_dmamap_destroy); 4763 4764 #ifdef QDF_OS_DEBUG 4765 QDF_STATUS __qdf_nbuf_map_nbytes(qdf_device_t osdev,struct sk_buff * skb,qdf_dma_dir_t dir,int nbytes)4766 __qdf_nbuf_map_nbytes( 4767 qdf_device_t osdev, 4768 struct sk_buff *skb, 4769 qdf_dma_dir_t dir, 4770 int nbytes) 4771 { 4772 struct skb_shared_info *sh = skb_shinfo(skb); 4773 4774 qdf_assert((dir == QDF_DMA_TO_DEVICE) || (dir == QDF_DMA_FROM_DEVICE)); 4775 4776 /* 4777 * Assume there's only a single fragment. 4778 * To support multiple fragments, it would be necessary to change 4779 * adf_nbuf_t to be a separate object that stores meta-info 4780 * (including the bus address for each fragment) and a pointer 4781 * to the underlying sk_buff. 4782 */ 4783 qdf_assert(sh->nr_frags == 0); 4784 4785 return __qdf_nbuf_map_nbytes_single(osdev, skb, dir, nbytes); 4786 } 4787 qdf_export_symbol(__qdf_nbuf_map_nbytes); 4788 #else 4789 QDF_STATUS __qdf_nbuf_map_nbytes(qdf_device_t osdev,struct sk_buff * skb,qdf_dma_dir_t dir,int nbytes)4790 __qdf_nbuf_map_nbytes( 4791 qdf_device_t osdev, 4792 struct sk_buff *skb, 4793 qdf_dma_dir_t dir, 4794 int nbytes) 4795 { 4796 return __qdf_nbuf_map_nbytes_single(osdev, skb, dir, nbytes); 4797 } 4798 qdf_export_symbol(__qdf_nbuf_map_nbytes); 4799 #endif 4800 void __qdf_nbuf_unmap_nbytes(qdf_device_t osdev,struct sk_buff * skb,qdf_dma_dir_t dir,int nbytes)4801 __qdf_nbuf_unmap_nbytes( 4802 qdf_device_t osdev, 4803 struct sk_buff *skb, 4804 qdf_dma_dir_t dir, 4805 int nbytes) 4806 { 4807 qdf_assert((dir == QDF_DMA_TO_DEVICE) || (dir == QDF_DMA_FROM_DEVICE)); 4808 4809 /* 4810 * Assume there's a single fragment. 4811 * If this is not true, the assertion in __adf_nbuf_map will catch it. 4812 */ 4813 __qdf_nbuf_unmap_nbytes_single(osdev, skb, dir, nbytes); 4814 } 4815 qdf_export_symbol(__qdf_nbuf_unmap_nbytes); 4816 4817 void __qdf_nbuf_dma_map_info(__qdf_dma_map_t bmap,qdf_dmamap_info_t * sg)4818 __qdf_nbuf_dma_map_info(__qdf_dma_map_t bmap, qdf_dmamap_info_t *sg) 4819 { 4820 qdf_assert(bmap->mapped); 4821 qdf_assert(bmap->nsegs <= QDF_MAX_SCATTER); 4822 4823 memcpy(sg->dma_segs, bmap->seg, bmap->nsegs * 4824 sizeof(struct __qdf_segment)); 4825 sg->nsegs = bmap->nsegs; 4826 } 4827 qdf_export_symbol(__qdf_nbuf_dma_map_info); 4828 4829 #if defined(__QDF_SUPPORT_FRAG_MEM) 4830 void __qdf_nbuf_frag_info(struct sk_buff * skb,qdf_sglist_t * sg)4831 __qdf_nbuf_frag_info(struct sk_buff *skb, qdf_sglist_t *sg) 4832 { 4833 qdf_assert(skb); 4834 sg->sg_segs[0].vaddr = skb->data; 4835 sg->sg_segs[0].len = skb->len; 4836 sg->nsegs = 1; 4837 4838 for (int i = 1; i <= sh->nr_frags; i++) { 4839 skb_frag_t *f = &sh->frags[i - 1]; 4840 4841 sg->sg_segs[i].vaddr = (uint8_t *)(page_address(f->page) + 4842 f->page_offset); 4843 sg->sg_segs[i].len = f->size; 4844 4845 qdf_assert(i < QDF_MAX_SGLIST); 4846 } 4847 sg->nsegs += i; 4848 4849 } 4850 qdf_export_symbol(__qdf_nbuf_frag_info); 4851 #else 4852 #ifdef QDF_OS_DEBUG 4853 void __qdf_nbuf_frag_info(struct sk_buff * skb,qdf_sglist_t * sg)4854 __qdf_nbuf_frag_info(struct sk_buff *skb, qdf_sglist_t *sg) 4855 { 4856 4857 struct skb_shared_info *sh = skb_shinfo(skb); 4858 4859 qdf_assert(skb); 4860 sg->sg_segs[0].vaddr = skb->data; 4861 sg->sg_segs[0].len = skb->len; 4862 sg->nsegs = 1; 4863 4864 qdf_assert(sh->nr_frags == 0); 4865 } 4866 qdf_export_symbol(__qdf_nbuf_frag_info); 4867 #else 4868 void __qdf_nbuf_frag_info(struct sk_buff * skb,qdf_sglist_t * sg)4869 __qdf_nbuf_frag_info(struct sk_buff *skb, qdf_sglist_t *sg) 4870 { 4871 sg->sg_segs[0].vaddr = skb->data; 4872 sg->sg_segs[0].len = skb->len; 4873 sg->nsegs = 1; 4874 } 4875 qdf_export_symbol(__qdf_nbuf_frag_info); 4876 #endif 4877 #endif 4878 uint32_t __qdf_nbuf_get_frag_size(__qdf_nbuf_t nbuf,uint32_t cur_frag)4879 __qdf_nbuf_get_frag_size(__qdf_nbuf_t nbuf, uint32_t cur_frag) 4880 { 4881 struct skb_shared_info *sh = skb_shinfo(nbuf); 4882 const skb_frag_t *frag = sh->frags + cur_frag; 4883 4884 return skb_frag_size(frag); 4885 } 4886 qdf_export_symbol(__qdf_nbuf_get_frag_size); 4887 4888 #ifdef A_SIMOS_DEVHOST __qdf_nbuf_frag_map(qdf_device_t osdev,__qdf_nbuf_t nbuf,int offset,qdf_dma_dir_t dir,int cur_frag)4889 QDF_STATUS __qdf_nbuf_frag_map( 4890 qdf_device_t osdev, __qdf_nbuf_t nbuf, 4891 int offset, qdf_dma_dir_t dir, int cur_frag) 4892 { 4893 int32_t paddr, frag_len; 4894 4895 QDF_NBUF_CB_PADDR(nbuf) = paddr = nbuf->data; 4896 return QDF_STATUS_SUCCESS; 4897 } 4898 qdf_export_symbol(__qdf_nbuf_frag_map); 4899 #else __qdf_nbuf_frag_map(qdf_device_t osdev,__qdf_nbuf_t nbuf,int offset,qdf_dma_dir_t dir,int cur_frag)4900 QDF_STATUS __qdf_nbuf_frag_map( 4901 qdf_device_t osdev, __qdf_nbuf_t nbuf, 4902 int offset, qdf_dma_dir_t dir, int cur_frag) 4903 { 4904 dma_addr_t paddr, frag_len; 4905 struct skb_shared_info *sh = skb_shinfo(nbuf); 4906 const skb_frag_t *frag = sh->frags + cur_frag; 4907 4908 frag_len = skb_frag_size(frag); 4909 4910 QDF_NBUF_CB_TX_EXTRA_FRAG_PADDR(nbuf) = paddr = 4911 skb_frag_dma_map(osdev->dev, frag, offset, frag_len, 4912 __qdf_dma_dir_to_os(dir)); 4913 return dma_mapping_error(osdev->dev, paddr) ? 4914 QDF_STATUS_E_FAULT : QDF_STATUS_SUCCESS; 4915 } 4916 qdf_export_symbol(__qdf_nbuf_frag_map); 4917 #endif 4918 void __qdf_nbuf_dmamap_set_cb(__qdf_dma_map_t dmap,void * cb,void * arg)4919 __qdf_nbuf_dmamap_set_cb(__qdf_dma_map_t dmap, void *cb, void *arg) 4920 { 4921 return; 4922 } 4923 qdf_export_symbol(__qdf_nbuf_dmamap_set_cb); 4924 4925 /** 4926 * __qdf_nbuf_sync_single_for_cpu() - nbuf sync 4927 * @osdev: os device 4928 * @buf: sk buff 4929 * @dir: direction 4930 * 4931 * Return: none 4932 */ 4933 #if defined(A_SIMOS_DEVHOST) __qdf_nbuf_sync_single_for_cpu(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir)4934 static void __qdf_nbuf_sync_single_for_cpu( 4935 qdf_device_t osdev, qdf_nbuf_t buf, qdf_dma_dir_t dir) 4936 { 4937 return; 4938 } 4939 #else __qdf_nbuf_sync_single_for_cpu(qdf_device_t osdev,qdf_nbuf_t buf,qdf_dma_dir_t dir)4940 static void __qdf_nbuf_sync_single_for_cpu( 4941 qdf_device_t osdev, qdf_nbuf_t buf, qdf_dma_dir_t dir) 4942 { 4943 if (0 == QDF_NBUF_CB_PADDR(buf)) { 4944 qdf_err("ERROR: NBUF mapped physical address is NULL"); 4945 return; 4946 } 4947 dma_sync_single_for_cpu(osdev->dev, QDF_NBUF_CB_PADDR(buf), 4948 skb_end_offset(buf) - skb_headroom(buf), 4949 __qdf_dma_dir_to_os(dir)); 4950 } 4951 #endif 4952 4953 void __qdf_nbuf_sync_for_cpu(qdf_device_t osdev,struct sk_buff * skb,qdf_dma_dir_t dir)4954 __qdf_nbuf_sync_for_cpu(qdf_device_t osdev, 4955 struct sk_buff *skb, qdf_dma_dir_t dir) 4956 { 4957 qdf_assert( 4958 (dir == QDF_DMA_TO_DEVICE) || (dir == QDF_DMA_FROM_DEVICE)); 4959 4960 /* 4961 * Assume there's a single fragment. 4962 * If this is not true, the assertion in __adf_nbuf_map will catch it. 4963 */ 4964 __qdf_nbuf_sync_single_for_cpu(osdev, skb, dir); 4965 } 4966 qdf_export_symbol(__qdf_nbuf_sync_for_cpu); 4967 4968 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) 4969 /** 4970 * qdf_nbuf_update_radiotap_vht_flags() - Update radiotap header VHT flags 4971 * @rx_status: Pointer to rx_status. 4972 * @rtap_buf: Buf to which VHT info has to be updated. 4973 * @rtap_len: Current length of radiotap buffer 4974 * 4975 * Return: Length of radiotap after VHT flags updated. 4976 */ qdf_nbuf_update_radiotap_vht_flags(struct mon_rx_status * rx_status,int8_t * rtap_buf,uint32_t rtap_len)4977 static unsigned int qdf_nbuf_update_radiotap_vht_flags( 4978 struct mon_rx_status *rx_status, 4979 int8_t *rtap_buf, 4980 uint32_t rtap_len) 4981 { 4982 uint16_t vht_flags = 0; 4983 struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; 4984 4985 rtap_len = qdf_align(rtap_len, 2); 4986 4987 /* IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 */ 4988 vht_flags |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC | 4989 IEEE80211_RADIOTAP_VHT_KNOWN_GI | 4990 IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM | 4991 IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED | 4992 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH | 4993 IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID; 4994 put_unaligned_le16(vht_flags, &rtap_buf[rtap_len]); 4995 rtap_len += 2; 4996 4997 rtap_buf[rtap_len] |= 4998 (rx_status->is_stbc ? 4999 IEEE80211_RADIOTAP_VHT_FLAG_STBC : 0) | 5000 (rx_status->sgi ? IEEE80211_RADIOTAP_VHT_FLAG_SGI : 0) | 5001 (rx_status->ldpc ? 5002 IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM : 0) | 5003 (rx_status->beamformed ? 5004 IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED : 0); 5005 rtap_len += 1; 5006 5007 if (!rx_user_status) { 5008 switch (rx_status->vht_flag_values2) { 5009 case IEEE80211_RADIOTAP_VHT_BW_20: 5010 rtap_buf[rtap_len] = RADIOTAP_VHT_BW_20; 5011 break; 5012 case IEEE80211_RADIOTAP_VHT_BW_40: 5013 rtap_buf[rtap_len] = RADIOTAP_VHT_BW_40; 5014 break; 5015 case IEEE80211_RADIOTAP_VHT_BW_80: 5016 rtap_buf[rtap_len] = RADIOTAP_VHT_BW_80; 5017 break; 5018 case IEEE80211_RADIOTAP_VHT_BW_160: 5019 rtap_buf[rtap_len] = RADIOTAP_VHT_BW_160; 5020 break; 5021 } 5022 rtap_len += 1; 5023 rtap_buf[rtap_len] = (rx_status->vht_flag_values3[0]); 5024 rtap_len += 1; 5025 rtap_buf[rtap_len] = (rx_status->vht_flag_values3[1]); 5026 rtap_len += 1; 5027 rtap_buf[rtap_len] = (rx_status->vht_flag_values3[2]); 5028 rtap_len += 1; 5029 rtap_buf[rtap_len] = (rx_status->vht_flag_values3[3]); 5030 rtap_len += 1; 5031 rtap_buf[rtap_len] = (rx_status->vht_flag_values4); 5032 rtap_len += 1; 5033 rtap_buf[rtap_len] = (rx_status->vht_flag_values5); 5034 rtap_len += 1; 5035 put_unaligned_le16(rx_status->vht_flag_values6, 5036 &rtap_buf[rtap_len]); 5037 rtap_len += 2; 5038 } else { 5039 switch (rx_user_status->vht_flag_values2) { 5040 case IEEE80211_RADIOTAP_VHT_BW_20: 5041 rtap_buf[rtap_len] = RADIOTAP_VHT_BW_20; 5042 break; 5043 case IEEE80211_RADIOTAP_VHT_BW_40: 5044 rtap_buf[rtap_len] = RADIOTAP_VHT_BW_40; 5045 break; 5046 case IEEE80211_RADIOTAP_VHT_BW_80: 5047 rtap_buf[rtap_len] = RADIOTAP_VHT_BW_80; 5048 break; 5049 case IEEE80211_RADIOTAP_VHT_BW_160: 5050 rtap_buf[rtap_len] = RADIOTAP_VHT_BW_160; 5051 break; 5052 } 5053 rtap_len += 1; 5054 rtap_buf[rtap_len] = (rx_user_status->vht_flag_values3[0]); 5055 rtap_len += 1; 5056 rtap_buf[rtap_len] = (rx_user_status->vht_flag_values3[1]); 5057 rtap_len += 1; 5058 rtap_buf[rtap_len] = (rx_user_status->vht_flag_values3[2]); 5059 rtap_len += 1; 5060 rtap_buf[rtap_len] = (rx_user_status->vht_flag_values3[3]); 5061 rtap_len += 1; 5062 rtap_buf[rtap_len] = (rx_user_status->vht_flag_values4); 5063 rtap_len += 1; 5064 rtap_buf[rtap_len] = (rx_user_status->vht_flag_values5); 5065 rtap_len += 1; 5066 put_unaligned_le16(rx_user_status->vht_flag_values6, 5067 &rtap_buf[rtap_len]); 5068 rtap_len += 2; 5069 } 5070 5071 return rtap_len; 5072 } 5073 5074 /** 5075 * qdf_nbuf_update_radiotap_he_flags() - Update radiotap header from rx_status 5076 * @rx_status: Pointer to rx_status. 5077 * @rtap_buf: buffer to which radiotap has to be updated 5078 * @rtap_len: radiotap length 5079 * 5080 * API update high-efficiency (11ax) fields in the radiotap header 5081 * 5082 * Return: length of rtap_len updated. 5083 */ 5084 static unsigned int qdf_nbuf_update_radiotap_he_flags(struct mon_rx_status * rx_status,int8_t * rtap_buf,uint32_t rtap_len)5085 qdf_nbuf_update_radiotap_he_flags(struct mon_rx_status *rx_status, 5086 int8_t *rtap_buf, uint32_t rtap_len) 5087 { 5088 /* 5089 * IEEE80211_RADIOTAP_HE u16, u16, u16, u16, u16, u16 5090 * Enable all "known" HE radiotap flags for now 5091 */ 5092 struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; 5093 5094 rtap_len = qdf_align(rtap_len, 2); 5095 5096 if (!rx_user_status) { 5097 put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]); 5098 rtap_len += 2; 5099 5100 put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]); 5101 rtap_len += 2; 5102 5103 put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]); 5104 rtap_len += 2; 5105 5106 put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]); 5107 rtap_len += 2; 5108 5109 put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]); 5110 rtap_len += 2; 5111 5112 put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]); 5113 rtap_len += 2; 5114 } else { 5115 put_unaligned_le16(rx_user_status->he_data1 | 5116 rx_status->he_data1, &rtap_buf[rtap_len]); 5117 rtap_len += 2; 5118 5119 put_unaligned_le16(rx_user_status->he_data2 | 5120 rx_status->he_data2, &rtap_buf[rtap_len]); 5121 rtap_len += 2; 5122 5123 put_unaligned_le16(rx_user_status->he_data3 | 5124 rx_status->he_data3, &rtap_buf[rtap_len]); 5125 rtap_len += 2; 5126 5127 put_unaligned_le16(rx_user_status->he_data4 | 5128 rx_status->he_data4, &rtap_buf[rtap_len]); 5129 rtap_len += 2; 5130 5131 put_unaligned_le16(rx_user_status->he_data5 | 5132 rx_status->he_data5, &rtap_buf[rtap_len]); 5133 rtap_len += 2; 5134 5135 put_unaligned_le16(rx_user_status->he_data6 | 5136 rx_status->he_data6, &rtap_buf[rtap_len]); 5137 rtap_len += 2; 5138 } 5139 5140 return rtap_len; 5141 } 5142 5143 5144 /** 5145 * qdf_nbuf_update_radiotap_he_mu_flags() - update he-mu radiotap flags 5146 * @rx_status: Pointer to rx_status. 5147 * @rtap_buf: buffer to which radiotap has to be updated 5148 * @rtap_len: radiotap length 5149 * 5150 * API update HE-MU fields in the radiotap header 5151 * 5152 * Return: length of rtap_len updated. 5153 */ 5154 static unsigned int qdf_nbuf_update_radiotap_he_mu_flags(struct mon_rx_status * rx_status,int8_t * rtap_buf,uint32_t rtap_len)5155 qdf_nbuf_update_radiotap_he_mu_flags(struct mon_rx_status *rx_status, 5156 int8_t *rtap_buf, uint32_t rtap_len) 5157 { 5158 struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; 5159 5160 rtap_len = qdf_align(rtap_len, 2); 5161 5162 /* 5163 * IEEE80211_RADIOTAP_HE_MU u16, u16, u8[4] 5164 * Enable all "known" he-mu radiotap flags for now 5165 */ 5166 5167 if (!rx_user_status) { 5168 put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]); 5169 rtap_len += 2; 5170 5171 put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]); 5172 rtap_len += 2; 5173 5174 rtap_buf[rtap_len] = rx_status->he_RU[0]; 5175 rtap_len += 1; 5176 5177 rtap_buf[rtap_len] = rx_status->he_RU[1]; 5178 rtap_len += 1; 5179 5180 rtap_buf[rtap_len] = rx_status->he_RU[2]; 5181 rtap_len += 1; 5182 5183 rtap_buf[rtap_len] = rx_status->he_RU[3]; 5184 rtap_len += 1; 5185 } else { 5186 put_unaligned_le16(rx_user_status->he_flags1, 5187 &rtap_buf[rtap_len]); 5188 rtap_len += 2; 5189 5190 put_unaligned_le16(rx_user_status->he_flags2, 5191 &rtap_buf[rtap_len]); 5192 rtap_len += 2; 5193 5194 rtap_buf[rtap_len] = rx_user_status->he_RU[0]; 5195 rtap_len += 1; 5196 5197 rtap_buf[rtap_len] = rx_user_status->he_RU[1]; 5198 rtap_len += 1; 5199 5200 rtap_buf[rtap_len] = rx_user_status->he_RU[2]; 5201 rtap_len += 1; 5202 5203 rtap_buf[rtap_len] = rx_user_status->he_RU[3]; 5204 rtap_len += 1; 5205 qdf_debug("he_flags %x %x he-RU %x %x %x %x", 5206 rx_user_status->he_flags1, 5207 rx_user_status->he_flags2, rx_user_status->he_RU[0], 5208 rx_user_status->he_RU[1], rx_user_status->he_RU[2], 5209 rx_user_status->he_RU[3]); 5210 } 5211 5212 return rtap_len; 5213 } 5214 5215 /** 5216 * qdf_nbuf_update_radiotap_he_mu_other_flags() - update he_mu_other flags 5217 * @rx_status: Pointer to rx_status. 5218 * @rtap_buf: buffer to which radiotap has to be updated 5219 * @rtap_len: radiotap length 5220 * 5221 * API update he-mu-other fields in the radiotap header 5222 * 5223 * Return: length of rtap_len updated. 5224 */ 5225 static unsigned int qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status * rx_status,int8_t * rtap_buf,uint32_t rtap_len)5226 qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status, 5227 int8_t *rtap_buf, uint32_t rtap_len) 5228 { 5229 struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; 5230 5231 rtap_len = qdf_align(rtap_len, 2); 5232 5233 /* 5234 * IEEE80211_RADIOTAP_HE-MU-OTHER u16, u16, u8, u8 5235 * Enable all "known" he-mu-other radiotap flags for now 5236 */ 5237 if (!rx_user_status) { 5238 put_unaligned_le16(rx_status->he_per_user_1, 5239 &rtap_buf[rtap_len]); 5240 rtap_len += 2; 5241 5242 put_unaligned_le16(rx_status->he_per_user_2, 5243 &rtap_buf[rtap_len]); 5244 rtap_len += 2; 5245 5246 rtap_buf[rtap_len] = rx_status->he_per_user_position; 5247 rtap_len += 1; 5248 5249 rtap_buf[rtap_len] = rx_status->he_per_user_known; 5250 rtap_len += 1; 5251 } else { 5252 put_unaligned_le16(rx_user_status->he_per_user_1, 5253 &rtap_buf[rtap_len]); 5254 rtap_len += 2; 5255 5256 put_unaligned_le16(rx_user_status->he_per_user_2, 5257 &rtap_buf[rtap_len]); 5258 rtap_len += 2; 5259 5260 rtap_buf[rtap_len] = rx_user_status->he_per_user_position; 5261 rtap_len += 1; 5262 5263 rtap_buf[rtap_len] = rx_user_status->he_per_user_known; 5264 rtap_len += 1; 5265 } 5266 5267 return rtap_len; 5268 } 5269 5270 /** 5271 * qdf_nbuf_update_radiotap_usig_flags() - Update radiotap header with USIG data 5272 * from rx_status 5273 * @rx_status: Pointer to rx_status. 5274 * @rtap_buf: buffer to which radiotap has to be updated 5275 * @rtap_len: radiotap length 5276 * 5277 * API update Extra High Throughput (11be) fields in the radiotap header 5278 * 5279 * Return: length of rtap_len updated. 5280 */ 5281 static unsigned int qdf_nbuf_update_radiotap_usig_flags(struct mon_rx_status * rx_status,int8_t * rtap_buf,uint32_t rtap_len)5282 qdf_nbuf_update_radiotap_usig_flags(struct mon_rx_status *rx_status, 5283 int8_t *rtap_buf, uint32_t rtap_len) 5284 { 5285 /* 5286 * IEEE80211_RADIOTAP_USIG: 5287 * u32, u32, u32 5288 */ 5289 rtap_len = qdf_align(rtap_len, 4); 5290 5291 put_unaligned_le32(rx_status->usig_common, &rtap_buf[rtap_len]); 5292 rtap_len += 4; 5293 5294 put_unaligned_le32(rx_status->usig_value, &rtap_buf[rtap_len]); 5295 rtap_len += 4; 5296 5297 put_unaligned_le32(rx_status->usig_mask, &rtap_buf[rtap_len]); 5298 rtap_len += 4; 5299 5300 qdf_rl_debug("U-SIG data %x %x %x", 5301 rx_status->usig_common, rx_status->usig_value, 5302 rx_status->usig_mask); 5303 5304 return rtap_len; 5305 } 5306 5307 /** 5308 * qdf_nbuf_update_radiotap_eht_flags() - Update radiotap header with EHT data 5309 * from rx_status 5310 * @rx_status: Pointer to rx_status. 5311 * @rtap_buf: buffer to which radiotap has to be updated 5312 * @rtap_len: radiotap length 5313 * 5314 * API update Extra High Throughput (11be) fields in the radiotap header 5315 * 5316 * Return: length of rtap_len updated. 5317 */ 5318 static unsigned int qdf_nbuf_update_radiotap_eht_flags(struct mon_rx_status * rx_status,int8_t * rtap_buf,uint32_t rtap_len)5319 qdf_nbuf_update_radiotap_eht_flags(struct mon_rx_status *rx_status, 5320 int8_t *rtap_buf, uint32_t rtap_len) 5321 { 5322 struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; 5323 /* 5324 * IEEE80211_RADIOTAP_EHT: 5325 * u32, u32, u32, u32, u32, u32, u32, u16, [u32, u32, u32] 5326 */ 5327 rtap_len = qdf_align(rtap_len, 4); 5328 5329 if (!rx_user_status) { 5330 put_unaligned_le32(rx_status->eht_known, &rtap_buf[rtap_len]); 5331 rtap_len += 4; 5332 5333 put_unaligned_le32(rx_status->eht_data[0], &rtap_buf[rtap_len]); 5334 rtap_len += 4; 5335 5336 put_unaligned_le32(rx_status->eht_data[1], &rtap_buf[rtap_len]); 5337 rtap_len += 4; 5338 } else { 5339 put_unaligned_le32(rx_status->eht_known | 5340 rx_user_status->eht_known, 5341 &rtap_buf[rtap_len]); 5342 rtap_len += 4; 5343 5344 put_unaligned_le32(rx_status->eht_data[0] | 5345 rx_user_status->eht_data[0], 5346 &rtap_buf[rtap_len]); 5347 rtap_len += 4; 5348 5349 put_unaligned_le32(rx_status->eht_data[1] | 5350 rx_user_status->eht_data[1], 5351 &rtap_buf[rtap_len]); 5352 rtap_len += 4; 5353 } 5354 5355 put_unaligned_le32(rx_status->eht_data[2], &rtap_buf[rtap_len]); 5356 rtap_len += 4; 5357 5358 put_unaligned_le32(rx_status->eht_data[3], &rtap_buf[rtap_len]); 5359 rtap_len += 4; 5360 5361 put_unaligned_le32(rx_status->eht_data[4], &rtap_buf[rtap_len]); 5362 rtap_len += 4; 5363 5364 put_unaligned_le32(rx_status->eht_data[5], &rtap_buf[rtap_len]); 5365 rtap_len += 4; 5366 5367 if (!rx_user_status) { 5368 qdf_rl_debug("EHT data %x %x %x %x %x %x %x", 5369 rx_status->eht_known, rx_status->eht_data[0], 5370 rx_status->eht_data[1], rx_status->eht_data[2], 5371 rx_status->eht_data[3], rx_status->eht_data[4], 5372 rx_status->eht_data[5]); 5373 } else { 5374 put_unaligned_le32(rx_user_status->eht_user_info, &rtap_buf[rtap_len]); 5375 rtap_len += 4; 5376 5377 qdf_rl_debug("EHT data %x %x %x %x %x %x %x", 5378 rx_status->eht_known | rx_user_status->eht_known, 5379 rx_status->eht_data[0] | 5380 rx_user_status->eht_data[0], 5381 rx_status->eht_data[1] | 5382 rx_user_status->eht_data[1], 5383 rx_status->eht_data[2], rx_status->eht_data[3], 5384 rx_status->eht_data[4], rx_status->eht_data[5]); 5385 } 5386 5387 return rtap_len; 5388 } 5389 5390 #define IEEE80211_RADIOTAP_TX_STATUS 0 5391 #define IEEE80211_RADIOTAP_RETRY_COUNT 1 5392 #define IEEE80211_RADIOTAP_EXTENSION2 2 5393 uint8_t ATH_OUI[] = {0x00, 0x03, 0x7f}; /* Atheros OUI */ 5394 5395 /** 5396 * qdf_nbuf_update_radiotap_ampdu_flags() - Update radiotap header ampdu flags 5397 * @rx_status: Pointer to rx_status. 5398 * @rtap_buf: Buf to which AMPDU info has to be updated. 5399 * @rtap_len: Current length of radiotap buffer 5400 * 5401 * Return: Length of radiotap after AMPDU flags updated. 5402 */ qdf_nbuf_update_radiotap_ampdu_flags(struct mon_rx_status * rx_status,uint8_t * rtap_buf,uint32_t rtap_len)5403 static unsigned int qdf_nbuf_update_radiotap_ampdu_flags( 5404 struct mon_rx_status *rx_status, 5405 uint8_t *rtap_buf, 5406 uint32_t rtap_len) 5407 { 5408 /* 5409 * IEEE80211_RADIOTAP_AMPDU_STATUS u32 u16 u8 u8 5410 * First 32 bits of AMPDU represents the reference number 5411 */ 5412 5413 uint32_t ampdu_reference_num = rx_status->ppdu_id; 5414 uint16_t ampdu_flags = 0; 5415 uint16_t ampdu_reserved_flags = 0; 5416 5417 rtap_len = qdf_align(rtap_len, 4); 5418 5419 put_unaligned_le32(ampdu_reference_num, &rtap_buf[rtap_len]); 5420 rtap_len += 4; 5421 put_unaligned_le16(ampdu_flags, &rtap_buf[rtap_len]); 5422 rtap_len += 2; 5423 put_unaligned_le16(ampdu_reserved_flags, &rtap_buf[rtap_len]); 5424 rtap_len += 2; 5425 5426 return rtap_len; 5427 } 5428 5429 #ifdef DP_MON_RSSI_IN_DBM 5430 #define QDF_MON_STATUS_GET_RSSI_IN_DBM(rx_status) \ 5431 (rx_status->rssi_comb) 5432 #else 5433 #ifdef QCA_RSSI_DB2DBM 5434 #define QDF_MON_STATUS_GET_RSSI_IN_DBM(rx_status) \ 5435 (((rx_status)->rssi_dbm_conv_support) ? \ 5436 ((rx_status)->rssi_comb + (rx_status)->rssi_offset) :\ 5437 ((rx_status)->rssi_comb + (rx_status)->chan_noise_floor)) 5438 #else 5439 #define QDF_MON_STATUS_GET_RSSI_IN_DBM(rx_status) \ 5440 (rx_status->rssi_comb + rx_status->chan_noise_floor) 5441 #endif 5442 #endif 5443 5444 /** 5445 * qdf_nbuf_update_radiotap_tx_flags() - Update radiotap header tx flags 5446 * @rx_status: Pointer to rx_status. 5447 * @rtap_buf: Buf to which tx info has to be updated. 5448 * @rtap_len: Current length of radiotap buffer 5449 * 5450 * Return: Length of radiotap after tx flags updated. 5451 */ qdf_nbuf_update_radiotap_tx_flags(struct mon_rx_status * rx_status,uint8_t * rtap_buf,uint32_t rtap_len)5452 static unsigned int qdf_nbuf_update_radiotap_tx_flags( 5453 struct mon_rx_status *rx_status, 5454 uint8_t *rtap_buf, 5455 uint32_t rtap_len) 5456 { 5457 /* 5458 * IEEE80211_RADIOTAP_TX_FLAGS u16 5459 */ 5460 5461 uint16_t tx_flags = 0; 5462 5463 rtap_len = qdf_align(rtap_len, 2); 5464 5465 switch (rx_status->tx_status) { 5466 case RADIOTAP_TX_STATUS_FAIL: 5467 tx_flags |= IEEE80211_RADIOTAP_F_TX_FAIL; 5468 break; 5469 case RADIOTAP_TX_STATUS_NOACK: 5470 tx_flags |= IEEE80211_RADIOTAP_F_TX_NOACK; 5471 break; 5472 } 5473 put_unaligned_le16(tx_flags, &rtap_buf[rtap_len]); 5474 rtap_len += 2; 5475 5476 return rtap_len; 5477 } 5478 qdf_nbuf_update_radiotap(struct mon_rx_status * rx_status,qdf_nbuf_t nbuf,uint32_t headroom_sz)5479 unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, 5480 qdf_nbuf_t nbuf, uint32_t headroom_sz) 5481 { 5482 uint8_t rtap_buf[RADIOTAP_HEADER_LEN] = {0}; 5483 struct ieee80211_radiotap_header *rthdr = 5484 (struct ieee80211_radiotap_header *)rtap_buf; 5485 uint32_t rtap_hdr_len = sizeof(struct ieee80211_radiotap_header); 5486 uint32_t rtap_len = rtap_hdr_len; 5487 uint8_t length = rtap_len; 5488 struct qdf_radiotap_vendor_ns_ath *radiotap_vendor_ns_ath; 5489 struct qdf_radiotap_ext2 *rtap_ext2; 5490 struct mon_rx_user_status *rx_user_status = rx_status->rx_user_status; 5491 5492 /* per user info */ 5493 qdf_le32_t *it_present; 5494 uint32_t it_present_val; 5495 bool radiotap_ext1_hdr_present = false; 5496 5497 it_present = &rthdr->it_present; 5498 5499 /* Adding Extended Header space */ 5500 if (rx_status->add_rtap_ext || rx_status->add_rtap_ext2 || 5501 rx_status->usig_flags || rx_status->eht_flags) { 5502 rtap_hdr_len += RADIOTAP_HEADER_EXT_LEN; 5503 rtap_len = rtap_hdr_len; 5504 radiotap_ext1_hdr_present = true; 5505 } 5506 5507 length = rtap_len; 5508 5509 /* IEEE80211_RADIOTAP_TSFT __le64 microseconds*/ 5510 it_present_val = (1 << IEEE80211_RADIOTAP_TSFT); 5511 put_unaligned_le64(rx_status->tsft, &rtap_buf[rtap_len]); 5512 rtap_len += 8; 5513 5514 /* IEEE80211_RADIOTAP_FLAGS u8 */ 5515 it_present_val |= (1 << IEEE80211_RADIOTAP_FLAGS); 5516 5517 if (rx_status->rs_fcs_err) 5518 rx_status->rtap_flags |= IEEE80211_RADIOTAP_F_BADFCS; 5519 5520 rtap_buf[rtap_len] = rx_status->rtap_flags; 5521 rtap_len += 1; 5522 5523 /* IEEE80211_RADIOTAP_RATE u8 500kb/s */ 5524 if (!rx_status->ht_flags && !rx_status->vht_flags && 5525 !rx_status->he_flags && !rx_status->eht_flags) { 5526 it_present_val |= (1 << IEEE80211_RADIOTAP_RATE); 5527 rtap_buf[rtap_len] = rx_status->rate; 5528 } else 5529 rtap_buf[rtap_len] = 0; 5530 rtap_len += 1; 5531 5532 /* IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap */ 5533 it_present_val |= (1 << IEEE80211_RADIOTAP_CHANNEL); 5534 put_unaligned_le16(rx_status->chan_freq, &rtap_buf[rtap_len]); 5535 rtap_len += 2; 5536 /* Channel flags. */ 5537 if (rx_status->chan_freq > CHANNEL_FREQ_5150) 5538 rx_status->chan_flags = RADIOTAP_5G_SPECTRUM_CHANNEL; 5539 else 5540 rx_status->chan_flags = RADIOTAP_2G_SPECTRUM_CHANNEL; 5541 if (rx_status->cck_flag) 5542 rx_status->chan_flags |= RADIOTAP_CCK_CHANNEL; 5543 if (rx_status->ofdm_flag) 5544 rx_status->chan_flags |= RADIOTAP_OFDM_CHANNEL; 5545 put_unaligned_le16(rx_status->chan_flags, &rtap_buf[rtap_len]); 5546 rtap_len += 2; 5547 5548 /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from one milliwatt 5549 * (dBm) 5550 */ 5551 it_present_val |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); 5552 /* 5553 * rssi_comb is int dB, need to convert it to dBm. 5554 * normalize value to noise floor of -96 dBm 5555 */ 5556 rtap_buf[rtap_len] = QDF_MON_STATUS_GET_RSSI_IN_DBM(rx_status); 5557 rtap_len += 1; 5558 5559 /* RX signal noise floor */ 5560 it_present_val |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); 5561 rtap_buf[rtap_len] = (uint8_t)rx_status->chan_noise_floor; 5562 rtap_len += 1; 5563 5564 /* IEEE80211_RADIOTAP_ANTENNA u8 antenna index */ 5565 it_present_val |= (1 << IEEE80211_RADIOTAP_ANTENNA); 5566 rtap_buf[rtap_len] = rx_status->nr_ant; 5567 rtap_len += 1; 5568 5569 if ((rtap_len - length) > RADIOTAP_FIXED_HEADER_LEN) { 5570 qdf_print("length is greater than RADIOTAP_FIXED_HEADER_LEN"); 5571 return 0; 5572 } 5573 5574 /* update tx flags for pkt capture*/ 5575 if (rx_status->add_rtap_ext) { 5576 it_present_val |= 5577 cpu_to_le32(1 << IEEE80211_RADIOTAP_TX_FLAGS); 5578 rtap_len = qdf_nbuf_update_radiotap_tx_flags(rx_status, 5579 rtap_buf, 5580 rtap_len); 5581 5582 if ((rtap_len - length) > RADIOTAP_TX_FLAGS_LEN) { 5583 qdf_print("length is greater than RADIOTAP_TX_FLAGS_LEN"); 5584 return 0; 5585 } 5586 } 5587 5588 if (rx_status->ht_flags) { 5589 length = rtap_len; 5590 /* IEEE80211_RADIOTAP_VHT u8, u8, u8 */ 5591 it_present_val |= (1 << IEEE80211_RADIOTAP_MCS); 5592 rtap_buf[rtap_len] = IEEE80211_RADIOTAP_MCS_HAVE_BW | 5593 IEEE80211_RADIOTAP_MCS_HAVE_MCS | 5594 IEEE80211_RADIOTAP_MCS_HAVE_GI; 5595 rtap_len += 1; 5596 5597 if (rx_status->sgi) 5598 rtap_buf[rtap_len] |= IEEE80211_RADIOTAP_MCS_SGI; 5599 if (rx_status->bw) 5600 rtap_buf[rtap_len] |= IEEE80211_RADIOTAP_MCS_BW_40; 5601 else 5602 rtap_buf[rtap_len] |= IEEE80211_RADIOTAP_MCS_BW_20; 5603 rtap_len += 1; 5604 5605 rtap_buf[rtap_len] = rx_status->ht_mcs; 5606 rtap_len += 1; 5607 5608 if ((rtap_len - length) > RADIOTAP_HT_FLAGS_LEN) { 5609 qdf_print("length is greater than RADIOTAP_HT_FLAGS_LEN"); 5610 return 0; 5611 } 5612 } 5613 5614 if (rx_status->rs_flags & IEEE80211_AMPDU_FLAG) { 5615 /* IEEE80211_RADIOTAP_AMPDU_STATUS u32 u16 u8 u8 */ 5616 it_present_val |= (1 << IEEE80211_RADIOTAP_AMPDU_STATUS); 5617 rtap_len = qdf_nbuf_update_radiotap_ampdu_flags(rx_status, 5618 rtap_buf, 5619 rtap_len); 5620 } 5621 5622 if (rx_status->vht_flags) { 5623 length = rtap_len; 5624 /* IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16 */ 5625 it_present_val |= (1 << IEEE80211_RADIOTAP_VHT); 5626 rtap_len = qdf_nbuf_update_radiotap_vht_flags(rx_status, 5627 rtap_buf, 5628 rtap_len); 5629 5630 if ((rtap_len - length) > RADIOTAP_VHT_FLAGS_LEN) { 5631 qdf_print("length is greater than RADIOTAP_VHT_FLAGS_LEN"); 5632 return 0; 5633 } 5634 } 5635 5636 if (rx_status->he_flags) { 5637 length = rtap_len; 5638 /* IEEE80211_RADIOTAP_HE */ 5639 it_present_val |= (1 << IEEE80211_RADIOTAP_HE); 5640 rtap_len = qdf_nbuf_update_radiotap_he_flags(rx_status, 5641 rtap_buf, 5642 rtap_len); 5643 5644 if ((rtap_len - length) > RADIOTAP_HE_FLAGS_LEN) { 5645 qdf_print("length is greater than RADIOTAP_HE_FLAGS_LEN"); 5646 return 0; 5647 } 5648 } 5649 5650 if (rx_status->he_mu_flags) { 5651 length = rtap_len; 5652 /* IEEE80211_RADIOTAP_HE-MU */ 5653 it_present_val |= (1 << IEEE80211_RADIOTAP_HE_MU); 5654 rtap_len = qdf_nbuf_update_radiotap_he_mu_flags(rx_status, 5655 rtap_buf, 5656 rtap_len); 5657 5658 if ((rtap_len - length) > RADIOTAP_HE_MU_FLAGS_LEN) { 5659 qdf_print("length is greater than RADIOTAP_HE_MU_FLAGS_LEN"); 5660 return 0; 5661 } 5662 } 5663 5664 if (rx_status->he_mu_other_flags) { 5665 length = rtap_len; 5666 /* IEEE80211_RADIOTAP_HE-MU-OTHER */ 5667 it_present_val |= (1 << IEEE80211_RADIOTAP_HE_MU_OTHER); 5668 rtap_len = 5669 qdf_nbuf_update_radiotap_he_mu_other_flags(rx_status, 5670 rtap_buf, 5671 rtap_len); 5672 5673 if ((rtap_len - length) > RADIOTAP_HE_MU_OTHER_FLAGS_LEN) { 5674 qdf_print("length is greater than RADIOTAP_HE_MU_OTHER_FLAGS_LEN"); 5675 return 0; 5676 } 5677 } 5678 5679 rtap_len = qdf_align(rtap_len, 2); 5680 /* 5681 * Radiotap Vendor Namespace 5682 */ 5683 it_present_val |= (1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE); 5684 radiotap_vendor_ns_ath = (struct qdf_radiotap_vendor_ns_ath *) 5685 (rtap_buf + rtap_len); 5686 /* 5687 * Copy Atheros OUI - 3 bytes (4th byte is 0) 5688 */ 5689 qdf_mem_copy(radiotap_vendor_ns_ath->hdr.oui, ATH_OUI, sizeof(ATH_OUI)); 5690 /* 5691 * Name space selector = 0 5692 * We only will have one namespace for now 5693 */ 5694 radiotap_vendor_ns_ath->hdr.selector = 0; 5695 radiotap_vendor_ns_ath->hdr.skip_length = cpu_to_le16( 5696 sizeof(*radiotap_vendor_ns_ath) - 5697 sizeof(radiotap_vendor_ns_ath->hdr)); 5698 radiotap_vendor_ns_ath->device_id = cpu_to_le32(rx_status->device_id); 5699 radiotap_vendor_ns_ath->lsig = cpu_to_le32(rx_status->l_sig_a_info); 5700 radiotap_vendor_ns_ath->lsig_b = cpu_to_le32(rx_status->l_sig_b_info); 5701 radiotap_vendor_ns_ath->ppdu_start_timestamp = 5702 cpu_to_le32(rx_status->ppdu_timestamp); 5703 rtap_len += sizeof(*radiotap_vendor_ns_ath); 5704 5705 /* Move to next it_present */ 5706 if (radiotap_ext1_hdr_present) { 5707 it_present_val |= (1 << IEEE80211_RADIOTAP_EXT); 5708 put_unaligned_le32(it_present_val, it_present); 5709 it_present_val = 0; 5710 it_present++; 5711 } 5712 5713 /* Add Extension to Radiotap Header & corresponding data */ 5714 if (rx_status->add_rtap_ext) { 5715 it_present_val |= (1 << IEEE80211_RADIOTAP_TX_STATUS); 5716 it_present_val |= (1 << IEEE80211_RADIOTAP_RETRY_COUNT); 5717 5718 rtap_buf[rtap_len] = rx_status->tx_status; 5719 rtap_len += 1; 5720 rtap_buf[rtap_len] = rx_status->tx_retry_cnt; 5721 rtap_len += 1; 5722 } 5723 5724 /* Add Extension2 to Radiotap Header */ 5725 if (rx_status->add_rtap_ext2) { 5726 it_present_val |= (1 << IEEE80211_RADIOTAP_EXTENSION2); 5727 5728 rtap_ext2 = (struct qdf_radiotap_ext2 *)(rtap_buf + rtap_len); 5729 rtap_ext2->ppdu_id = rx_status->ppdu_id; 5730 rtap_ext2->prev_ppdu_id = rx_status->prev_ppdu_id; 5731 if (!rx_user_status) { 5732 rtap_ext2->tid = rx_status->tid; 5733 rtap_ext2->start_seq = rx_status->start_seq; 5734 qdf_mem_copy(rtap_ext2->ba_bitmap, 5735 rx_status->ba_bitmap, 5736 8 * (sizeof(uint32_t))); 5737 } else { 5738 uint8_t ba_bitmap_sz = rx_user_status->ba_bitmap_sz; 5739 5740 /* set default bitmap sz if not set */ 5741 ba_bitmap_sz = ba_bitmap_sz ? ba_bitmap_sz : 8; 5742 rtap_ext2->tid = rx_user_status->tid; 5743 rtap_ext2->start_seq = rx_user_status->start_seq; 5744 qdf_mem_copy(rtap_ext2->ba_bitmap, 5745 rx_user_status->ba_bitmap, 5746 ba_bitmap_sz * (sizeof(uint32_t))); 5747 } 5748 5749 rtap_len += sizeof(*rtap_ext2); 5750 } 5751 5752 if (rx_status->usig_flags) { 5753 length = rtap_len; 5754 /* IEEE80211_RADIOTAP_USIG */ 5755 it_present_val |= (1 << IEEE80211_RADIOTAP_EXT1_USIG); 5756 rtap_len = qdf_nbuf_update_radiotap_usig_flags(rx_status, 5757 rtap_buf, 5758 rtap_len); 5759 5760 if ((rtap_len - length) > RADIOTAP_EHT_FLAGS_LEN) { 5761 qdf_print("length is greater than RADIOTAP_EHT_FLAGS_LEN"); 5762 return 0; 5763 } 5764 } 5765 5766 if (rx_status->eht_flags) { 5767 length = rtap_len; 5768 /* IEEE80211_RADIOTAP_EHT */ 5769 it_present_val |= (1 << IEEE80211_RADIOTAP_EXT1_EHT); 5770 rtap_len = qdf_nbuf_update_radiotap_eht_flags(rx_status, 5771 rtap_buf, 5772 rtap_len); 5773 5774 if ((rtap_len - length) > RADIOTAP_EHT_FLAGS_LEN) { 5775 qdf_print("length is greater than RADIOTAP_EHT_FLAGS_LEN"); 5776 return 0; 5777 } 5778 } 5779 5780 put_unaligned_le32(it_present_val, it_present); 5781 rthdr->it_len = cpu_to_le16(rtap_len); 5782 5783 if (headroom_sz < rtap_len) { 5784 qdf_debug("DEBUG: Not enough space to update radiotap"); 5785 return 0; 5786 } 5787 5788 qdf_nbuf_push_head(nbuf, rtap_len); 5789 qdf_mem_copy(qdf_nbuf_data(nbuf), rtap_buf, rtap_len); 5790 return rtap_len; 5791 } 5792 #else qdf_nbuf_update_radiotap_vht_flags(struct mon_rx_status * rx_status,int8_t * rtap_buf,uint32_t rtap_len)5793 static unsigned int qdf_nbuf_update_radiotap_vht_flags( 5794 struct mon_rx_status *rx_status, 5795 int8_t *rtap_buf, 5796 uint32_t rtap_len) 5797 { 5798 qdf_err("ERROR: struct ieee80211_radiotap_header not supported"); 5799 return 0; 5800 } 5801 qdf_nbuf_update_radiotap_he_flags(struct mon_rx_status * rx_status,int8_t * rtap_buf,uint32_t rtap_len)5802 unsigned int qdf_nbuf_update_radiotap_he_flags(struct mon_rx_status *rx_status, 5803 int8_t *rtap_buf, uint32_t rtap_len) 5804 { 5805 qdf_err("ERROR: struct ieee80211_radiotap_header not supported"); 5806 return 0; 5807 } 5808 qdf_nbuf_update_radiotap_ampdu_flags(struct mon_rx_status * rx_status,uint8_t * rtap_buf,uint32_t rtap_len)5809 static unsigned int qdf_nbuf_update_radiotap_ampdu_flags( 5810 struct mon_rx_status *rx_status, 5811 uint8_t *rtap_buf, 5812 uint32_t rtap_len) 5813 { 5814 qdf_err("ERROR: struct ieee80211_radiotap_header not supported"); 5815 return 0; 5816 } 5817 qdf_nbuf_update_radiotap(struct mon_rx_status * rx_status,qdf_nbuf_t nbuf,uint32_t headroom_sz)5818 unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, 5819 qdf_nbuf_t nbuf, uint32_t headroom_sz) 5820 { 5821 qdf_err("ERROR: struct ieee80211_radiotap_header not supported"); 5822 return 0; 5823 } 5824 #endif 5825 qdf_export_symbol(qdf_nbuf_update_radiotap); 5826 __qdf_nbuf_reg_free_cb(qdf_nbuf_free_t cb_func_ptr)5827 void __qdf_nbuf_reg_free_cb(qdf_nbuf_free_t cb_func_ptr) 5828 { 5829 nbuf_free_cb = cb_func_ptr; 5830 } 5831 5832 qdf_export_symbol(__qdf_nbuf_reg_free_cb); 5833 qdf_nbuf_classify_pkt(struct sk_buff * skb)5834 void qdf_nbuf_classify_pkt(struct sk_buff *skb) 5835 { 5836 struct ethhdr *eh = (struct ethhdr *)skb->data; 5837 5838 /* check destination mac address is broadcast/multicast */ 5839 if (is_broadcast_ether_addr((uint8_t *)eh)) 5840 QDF_NBUF_CB_SET_BCAST(skb); 5841 else if (is_multicast_ether_addr((uint8_t *)eh)) 5842 QDF_NBUF_CB_SET_MCAST(skb); 5843 5844 if (qdf_nbuf_is_ipv4_arp_pkt(skb)) 5845 QDF_NBUF_CB_GET_PACKET_TYPE(skb) = 5846 QDF_NBUF_CB_PACKET_TYPE_ARP; 5847 else if (qdf_nbuf_is_ipv4_dhcp_pkt(skb)) 5848 QDF_NBUF_CB_GET_PACKET_TYPE(skb) = 5849 QDF_NBUF_CB_PACKET_TYPE_DHCP; 5850 else if (qdf_nbuf_is_ipv4_eapol_pkt(skb)) 5851 QDF_NBUF_CB_GET_PACKET_TYPE(skb) = 5852 QDF_NBUF_CB_PACKET_TYPE_EAPOL; 5853 else if (qdf_nbuf_is_ipv4_wapi_pkt(skb)) 5854 QDF_NBUF_CB_GET_PACKET_TYPE(skb) = 5855 QDF_NBUF_CB_PACKET_TYPE_WAPI; 5856 } 5857 qdf_export_symbol(qdf_nbuf_classify_pkt); 5858 __qdf_nbuf_init(__qdf_nbuf_t nbuf)5859 void __qdf_nbuf_init(__qdf_nbuf_t nbuf) 5860 { 5861 qdf_nbuf_users_set(&nbuf->users, 1); 5862 nbuf->data = nbuf->head + NET_SKB_PAD; 5863 skb_reset_tail_pointer(nbuf); 5864 } 5865 qdf_export_symbol(__qdf_nbuf_init); 5866 5867 #ifdef WLAN_FEATURE_FASTPATH qdf_nbuf_init_fast(qdf_nbuf_t nbuf)5868 void qdf_nbuf_init_fast(qdf_nbuf_t nbuf) 5869 { 5870 qdf_nbuf_users_set(&nbuf->users, 1); 5871 skb_reset_tail_pointer(nbuf); 5872 } 5873 qdf_export_symbol(qdf_nbuf_init_fast); 5874 #endif /* WLAN_FEATURE_FASTPATH */ 5875 5876 5877 #ifdef QDF_NBUF_GLOBAL_COUNT __qdf_nbuf_mod_init(void)5878 void __qdf_nbuf_mod_init(void) 5879 { 5880 is_initial_mem_debug_disabled = qdf_mem_debug_config_get(); 5881 qdf_atomic_init(&nbuf_count); 5882 qdf_debugfs_create_atomic(NBUF_DEBUGFS_NAME, S_IRUSR, NULL, &nbuf_count); 5883 } 5884 __qdf_nbuf_mod_exit(void)5885 void __qdf_nbuf_mod_exit(void) 5886 { 5887 } 5888 #endif 5889 5890 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) __qdf_nbuf_move_frag_page_offset(__qdf_nbuf_t nbuf,uint8_t idx,int offset)5891 QDF_STATUS __qdf_nbuf_move_frag_page_offset(__qdf_nbuf_t nbuf, uint8_t idx, 5892 int offset) 5893 { 5894 unsigned int frag_offset; 5895 skb_frag_t *frag; 5896 5897 if (qdf_unlikely(idx >= __qdf_nbuf_get_nr_frags(nbuf))) 5898 return QDF_STATUS_E_FAILURE; 5899 5900 frag = &skb_shinfo(nbuf)->frags[idx]; 5901 frag_offset = skb_frag_off(frag); 5902 5903 frag_offset += offset; 5904 skb_frag_off_set(frag, frag_offset); 5905 5906 __qdf_nbuf_trim_add_frag_size(nbuf, idx, -(offset), 0); 5907 5908 return QDF_STATUS_SUCCESS; 5909 } 5910 5911 #else __qdf_nbuf_move_frag_page_offset(__qdf_nbuf_t nbuf,uint8_t idx,int offset)5912 QDF_STATUS __qdf_nbuf_move_frag_page_offset(__qdf_nbuf_t nbuf, uint8_t idx, 5913 int offset) 5914 { 5915 uint16_t frag_offset; 5916 skb_frag_t *frag; 5917 5918 if (qdf_unlikely(idx >= __qdf_nbuf_get_nr_frags(nbuf))) 5919 return QDF_STATUS_E_FAILURE; 5920 5921 frag = &skb_shinfo(nbuf)->frags[idx]; 5922 frag_offset = frag->page_offset; 5923 5924 frag_offset += offset; 5925 frag->page_offset = frag_offset; 5926 5927 __qdf_nbuf_trim_add_frag_size(nbuf, idx, -(offset), 0); 5928 5929 return QDF_STATUS_SUCCESS; 5930 } 5931 #endif 5932 5933 qdf_export_symbol(__qdf_nbuf_move_frag_page_offset); 5934 __qdf_nbuf_remove_frag(__qdf_nbuf_t nbuf,uint16_t idx,uint16_t truesize)5935 void __qdf_nbuf_remove_frag(__qdf_nbuf_t nbuf, 5936 uint16_t idx, 5937 uint16_t truesize) 5938 { 5939 struct page *page; 5940 uint16_t frag_len; 5941 5942 page = skb_frag_page(&skb_shinfo(nbuf)->frags[idx]); 5943 5944 if (qdf_unlikely(!page)) 5945 return; 5946 5947 frag_len = qdf_nbuf_get_frag_size_by_idx(nbuf, idx); 5948 put_page(page); 5949 nbuf->len -= frag_len; 5950 nbuf->data_len -= frag_len; 5951 nbuf->truesize -= truesize; 5952 skb_shinfo(nbuf)->nr_frags--; 5953 } 5954 5955 qdf_export_symbol(__qdf_nbuf_remove_frag); 5956 __qdf_nbuf_add_rx_frag(__qdf_frag_t buf,__qdf_nbuf_t nbuf,int offset,int frag_len,unsigned int truesize,bool take_frag_ref)5957 void __qdf_nbuf_add_rx_frag(__qdf_frag_t buf, __qdf_nbuf_t nbuf, 5958 int offset, int frag_len, 5959 unsigned int truesize, bool take_frag_ref) 5960 { 5961 struct page *page; 5962 int frag_offset; 5963 uint8_t nr_frag; 5964 5965 nr_frag = __qdf_nbuf_get_nr_frags(nbuf); 5966 qdf_assert_always(nr_frag < QDF_NBUF_MAX_FRAGS); 5967 5968 page = virt_to_head_page(buf); 5969 frag_offset = buf - page_address(page); 5970 5971 skb_add_rx_frag(nbuf, nr_frag, page, 5972 (frag_offset + offset), 5973 frag_len, truesize); 5974 5975 if (unlikely(take_frag_ref)) { 5976 qdf_frag_count_inc(QDF_NBUF_FRAG_DEBUG_COUNT_ONE); 5977 skb_frag_ref(nbuf, nr_frag); 5978 } 5979 } 5980 5981 qdf_export_symbol(__qdf_nbuf_add_rx_frag); 5982 5983 #ifdef NBUF_FRAG_MEMORY_DEBUG 5984 qdf_nbuf_move_frag_page_offset_debug(qdf_nbuf_t nbuf,uint8_t idx,int offset,const char * func,uint32_t line)5985 QDF_STATUS qdf_nbuf_move_frag_page_offset_debug(qdf_nbuf_t nbuf, uint8_t idx, 5986 int offset, const char *func, 5987 uint32_t line) 5988 { 5989 QDF_STATUS result; 5990 qdf_frag_t p_fragp, n_fragp; 5991 5992 p_fragp = qdf_nbuf_get_frag_addr(nbuf, idx); 5993 result = __qdf_nbuf_move_frag_page_offset(nbuf, idx, offset); 5994 5995 if (qdf_likely(is_initial_mem_debug_disabled)) 5996 return result; 5997 5998 n_fragp = qdf_nbuf_get_frag_addr(nbuf, idx); 5999 6000 /* 6001 * Update frag address in frag debug tracker 6002 * when frag offset is successfully changed in skb 6003 */ 6004 if (result == QDF_STATUS_SUCCESS) 6005 qdf_frag_debug_update_addr(p_fragp, n_fragp, func, line); 6006 6007 return result; 6008 } 6009 6010 qdf_export_symbol(qdf_nbuf_move_frag_page_offset_debug); 6011 qdf_nbuf_add_rx_frag_debug(qdf_frag_t buf,qdf_nbuf_t nbuf,int offset,int frag_len,unsigned int truesize,bool take_frag_ref,const char * func,uint32_t line)6012 void qdf_nbuf_add_rx_frag_debug(qdf_frag_t buf, qdf_nbuf_t nbuf, 6013 int offset, int frag_len, 6014 unsigned int truesize, bool take_frag_ref, 6015 const char *func, uint32_t line) 6016 { 6017 qdf_frag_t fragp; 6018 uint32_t num_nr_frags; 6019 6020 __qdf_nbuf_add_rx_frag(buf, nbuf, offset, 6021 frag_len, truesize, take_frag_ref); 6022 6023 if (qdf_likely(is_initial_mem_debug_disabled)) 6024 return; 6025 6026 num_nr_frags = qdf_nbuf_get_nr_frags(nbuf); 6027 6028 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 6029 6030 fragp = qdf_nbuf_get_frag_addr(nbuf, num_nr_frags - 1); 6031 6032 /* Update frag address in frag debug tracking table */ 6033 if (fragp != buf && !take_frag_ref) 6034 qdf_frag_debug_update_addr(buf, fragp, func, line); 6035 6036 /* Update frag refcount in frag debug tracking table */ 6037 qdf_frag_debug_refcount_inc(fragp, func, line); 6038 } 6039 6040 qdf_export_symbol(qdf_nbuf_add_rx_frag_debug); 6041 qdf_net_buf_debug_acquire_frag(qdf_nbuf_t buf,const char * func,uint32_t line)6042 void qdf_net_buf_debug_acquire_frag(qdf_nbuf_t buf, const char *func, 6043 uint32_t line) 6044 { 6045 uint32_t num_nr_frags; 6046 uint32_t idx = 0; 6047 qdf_nbuf_t ext_list; 6048 qdf_frag_t p_frag; 6049 6050 if (qdf_likely(is_initial_mem_debug_disabled)) 6051 return; 6052 6053 if (qdf_unlikely(!buf)) 6054 return; 6055 6056 /* Take care to update the refcount in the debug entries for frags */ 6057 num_nr_frags = qdf_nbuf_get_nr_frags(buf); 6058 6059 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 6060 6061 while (idx < num_nr_frags) { 6062 p_frag = qdf_nbuf_get_frag_addr(buf, idx); 6063 if (qdf_likely(p_frag)) 6064 qdf_frag_debug_refcount_inc(p_frag, func, line); 6065 idx++; 6066 } 6067 6068 /* 6069 * Take care to update the refcount in the debug entries for the 6070 * frags attached to frag_list 6071 */ 6072 ext_list = qdf_nbuf_get_ext_list(buf); 6073 while (ext_list) { 6074 idx = 0; 6075 num_nr_frags = qdf_nbuf_get_nr_frags(ext_list); 6076 6077 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 6078 6079 while (idx < num_nr_frags) { 6080 p_frag = qdf_nbuf_get_frag_addr(ext_list, idx); 6081 if (qdf_likely(p_frag)) 6082 qdf_frag_debug_refcount_inc(p_frag, func, line); 6083 idx++; 6084 } 6085 ext_list = qdf_nbuf_queue_next(ext_list); 6086 } 6087 } 6088 6089 qdf_export_symbol(qdf_net_buf_debug_acquire_frag); 6090 qdf_net_buf_debug_release_frag(qdf_nbuf_t buf,const char * func,uint32_t line)6091 void qdf_net_buf_debug_release_frag(qdf_nbuf_t buf, const char *func, 6092 uint32_t line) 6093 { 6094 uint32_t num_nr_frags; 6095 qdf_nbuf_t ext_list; 6096 uint32_t idx = 0; 6097 qdf_frag_t p_frag; 6098 6099 if (qdf_likely(is_initial_mem_debug_disabled)) 6100 return; 6101 6102 if (qdf_unlikely(!buf)) 6103 return; 6104 6105 /* 6106 * Decrement refcount for frag debug nodes only when last user 6107 * of nbuf calls this API so as to avoid decrementing refcount 6108 * on every call expect the last one in case where nbuf has multiple 6109 * users 6110 */ 6111 if (qdf_nbuf_get_users(buf) > 1) 6112 return; 6113 6114 /* Take care to update the refcount in the debug entries for frags */ 6115 num_nr_frags = qdf_nbuf_get_nr_frags(buf); 6116 6117 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 6118 6119 while (idx < num_nr_frags) { 6120 p_frag = qdf_nbuf_get_frag_addr(buf, idx); 6121 if (qdf_likely(p_frag)) 6122 qdf_frag_debug_refcount_dec(p_frag, func, line); 6123 idx++; 6124 } 6125 6126 /* Take care to update debug entries for frags attached to frag_list */ 6127 ext_list = qdf_nbuf_get_ext_list(buf); 6128 while (ext_list) { 6129 if (qdf_nbuf_get_users(ext_list) == 1) { 6130 idx = 0; 6131 num_nr_frags = qdf_nbuf_get_nr_frags(ext_list); 6132 qdf_assert_always(num_nr_frags <= QDF_NBUF_MAX_FRAGS); 6133 while (idx < num_nr_frags) { 6134 p_frag = qdf_nbuf_get_frag_addr(ext_list, idx); 6135 if (qdf_likely(p_frag)) 6136 qdf_frag_debug_refcount_dec(p_frag, 6137 func, line); 6138 idx++; 6139 } 6140 } 6141 ext_list = qdf_nbuf_queue_next(ext_list); 6142 } 6143 } 6144 6145 qdf_export_symbol(qdf_net_buf_debug_release_frag); 6146 6147 QDF_STATUS qdf_nbuf_remove_frag_debug(qdf_nbuf_t nbuf,uint16_t idx,uint16_t truesize,const char * func,uint32_t line)6148 qdf_nbuf_remove_frag_debug(qdf_nbuf_t nbuf, 6149 uint16_t idx, 6150 uint16_t truesize, 6151 const char *func, 6152 uint32_t line) 6153 { 6154 uint16_t num_frags; 6155 qdf_frag_t frag; 6156 6157 if (qdf_unlikely(!nbuf)) 6158 return QDF_STATUS_E_INVAL; 6159 6160 num_frags = qdf_nbuf_get_nr_frags(nbuf); 6161 if (idx >= num_frags) 6162 return QDF_STATUS_E_INVAL; 6163 6164 if (qdf_likely(is_initial_mem_debug_disabled)) { 6165 __qdf_nbuf_remove_frag(nbuf, idx, truesize); 6166 return QDF_STATUS_SUCCESS; 6167 } 6168 6169 frag = qdf_nbuf_get_frag_addr(nbuf, idx); 6170 if (qdf_likely(frag)) 6171 qdf_frag_debug_refcount_dec(frag, func, line); 6172 6173 __qdf_nbuf_remove_frag(nbuf, idx, truesize); 6174 6175 return QDF_STATUS_SUCCESS; 6176 } 6177 6178 qdf_export_symbol(qdf_nbuf_remove_frag_debug); 6179 6180 #endif /* NBUF_FRAG_MEMORY_DEBUG */ 6181 qdf_get_nbuf_valid_frag(qdf_nbuf_t nbuf)6182 qdf_nbuf_t qdf_get_nbuf_valid_frag(qdf_nbuf_t nbuf) 6183 { 6184 qdf_nbuf_t last_nbuf; 6185 uint32_t num_frags; 6186 6187 if (qdf_unlikely(!nbuf)) 6188 return NULL; 6189 6190 num_frags = qdf_nbuf_get_nr_frags(nbuf); 6191 6192 /* Check nbuf has enough memory to store frag memory */ 6193 if (num_frags < QDF_NBUF_MAX_FRAGS) 6194 return nbuf; 6195 6196 if (!__qdf_nbuf_has_fraglist(nbuf)) 6197 return NULL; 6198 6199 last_nbuf = __qdf_nbuf_get_last_frag_list_nbuf(nbuf); 6200 if (qdf_unlikely(!last_nbuf)) 6201 return NULL; 6202 6203 num_frags = qdf_nbuf_get_nr_frags(last_nbuf); 6204 if (num_frags < QDF_NBUF_MAX_FRAGS) 6205 return last_nbuf; 6206 6207 return NULL; 6208 } 6209 6210 qdf_export_symbol(qdf_get_nbuf_valid_frag); 6211 6212 QDF_STATUS qdf_nbuf_add_frag_debug(qdf_device_t osdev,qdf_frag_t buf,qdf_nbuf_t nbuf,int offset,int frag_len,unsigned int truesize,bool take_frag_ref,unsigned int minsize,const char * func,uint32_t line)6213 qdf_nbuf_add_frag_debug(qdf_device_t osdev, qdf_frag_t buf, 6214 qdf_nbuf_t nbuf, int offset, 6215 int frag_len, unsigned int truesize, 6216 bool take_frag_ref, unsigned int minsize, 6217 const char *func, uint32_t line) 6218 { 6219 qdf_nbuf_t cur_nbuf; 6220 qdf_nbuf_t this_nbuf; 6221 6222 cur_nbuf = nbuf; 6223 this_nbuf = nbuf; 6224 6225 if (qdf_unlikely(!frag_len || !buf)) { 6226 qdf_nofl_err("%s : %d frag[ buf[%pK] len[%d]] not valid\n", 6227 func, line, 6228 buf, frag_len); 6229 return QDF_STATUS_E_INVAL; 6230 } 6231 6232 this_nbuf = qdf_get_nbuf_valid_frag(this_nbuf); 6233 6234 if (this_nbuf) { 6235 cur_nbuf = this_nbuf; 6236 } else { 6237 /* allocate a dummy mpdu buffer of 64 bytes headroom */ 6238 this_nbuf = qdf_nbuf_alloc(osdev, minsize, minsize, 4, false); 6239 if (qdf_unlikely(!this_nbuf)) { 6240 qdf_nofl_err("%s : %d no memory to allocate\n", 6241 func, line); 6242 return QDF_STATUS_E_NOMEM; 6243 } 6244 } 6245 6246 qdf_nbuf_add_rx_frag(buf, this_nbuf, offset, frag_len, truesize, 6247 take_frag_ref); 6248 6249 if (this_nbuf != cur_nbuf) { 6250 /* add new skb to frag list */ 6251 qdf_nbuf_append_ext_list(nbuf, this_nbuf, 6252 qdf_nbuf_len(this_nbuf)); 6253 } 6254 6255 return QDF_STATUS_SUCCESS; 6256 } 6257 6258 qdf_export_symbol(qdf_nbuf_add_frag_debug); 6259 6260 #ifdef MEMORY_DEBUG qdf_nbuf_acquire_track_lock(uint32_t index,unsigned long irq_flag)6261 void qdf_nbuf_acquire_track_lock(uint32_t index, 6262 unsigned long irq_flag) 6263 { 6264 spin_lock_irqsave(&g_qdf_net_buf_track_lock[index], 6265 irq_flag); 6266 } 6267 qdf_nbuf_release_track_lock(uint32_t index,unsigned long irq_flag)6268 void qdf_nbuf_release_track_lock(uint32_t index, 6269 unsigned long irq_flag) 6270 { 6271 spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[index], 6272 irq_flag); 6273 } 6274 qdf_nbuf_get_track_tbl(uint32_t index)6275 QDF_NBUF_TRACK *qdf_nbuf_get_track_tbl(uint32_t index) 6276 { 6277 return gp_qdf_net_buf_track_tbl[index]; 6278 } 6279 #endif /* MEMORY_DEBUG */ 6280 6281 #ifdef ENHANCED_OS_ABSTRACTION qdf_nbuf_set_timestamp(qdf_nbuf_t buf)6282 void qdf_nbuf_set_timestamp(qdf_nbuf_t buf) 6283 { 6284 __qdf_nbuf_set_timestamp(buf); 6285 } 6286 6287 qdf_export_symbol(qdf_nbuf_set_timestamp); 6288 qdf_nbuf_get_timestamp(qdf_nbuf_t buf)6289 uint64_t qdf_nbuf_get_timestamp(qdf_nbuf_t buf) 6290 { 6291 return __qdf_nbuf_get_timestamp(buf); 6292 } 6293 6294 qdf_export_symbol(qdf_nbuf_get_timestamp); 6295 qdf_nbuf_get_timestamp_us(qdf_nbuf_t buf)6296 uint64_t qdf_nbuf_get_timestamp_us(qdf_nbuf_t buf) 6297 { 6298 return __qdf_nbuf_get_timestamp_us(buf); 6299 } 6300 6301 qdf_export_symbol(qdf_nbuf_get_timestamp_us); 6302 qdf_nbuf_get_timedelta_us(qdf_nbuf_t buf)6303 uint64_t qdf_nbuf_get_timedelta_us(qdf_nbuf_t buf) 6304 { 6305 return __qdf_nbuf_get_timedelta_us(buf); 6306 } 6307 6308 qdf_export_symbol(qdf_nbuf_get_timedelta_us); 6309 qdf_nbuf_get_timedelta_ms(qdf_nbuf_t buf)6310 uint64_t qdf_nbuf_get_timedelta_ms(qdf_nbuf_t buf) 6311 { 6312 return __qdf_nbuf_get_timedelta_ms(buf); 6313 } 6314 6315 qdf_export_symbol(qdf_nbuf_get_timedelta_ms); 6316 qdf_nbuf_net_timedelta(qdf_ktime_t t)6317 qdf_ktime_t qdf_nbuf_net_timedelta(qdf_ktime_t t) 6318 { 6319 return __qdf_nbuf_net_timedelta(t); 6320 } 6321 6322 qdf_export_symbol(qdf_nbuf_net_timedelta); 6323 #endif 6324