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