| .. | .. |
|---|
| 1 | | -/* SPDX-License-Identifier: GPL-2.0 */ |
|---|
| 2 | 1 | /* |
|---|
| 3 | 2 | * IP Packet Parser Module. |
|---|
| 4 | 3 | * |
|---|
| 5 | | - * Copyright (C) 1999-2019, Broadcom Corporation |
|---|
| 6 | | - * |
|---|
| 4 | + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation |
|---|
| 5 | + * |
|---|
| 6 | + * Copyright (C) 1999-2017, Broadcom Corporation |
|---|
| 7 | + * |
|---|
| 7 | 8 | * Unless you and Broadcom execute a separate written software license |
|---|
| 8 | 9 | * agreement governing use of this software, this software is licensed to you |
|---|
| 9 | 10 | * under the terms of the GNU General Public License version 2 (the "GPL"), |
|---|
| 10 | 11 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
|---|
| 11 | 12 | * following added to such license: |
|---|
| 12 | | - * |
|---|
| 13 | + * |
|---|
| 13 | 14 | * As a special exception, the copyright holders of this software give you |
|---|
| 14 | 15 | * permission to link this software with independent modules, and to copy and |
|---|
| 15 | 16 | * distribute the resulting executable under terms of your choice, provided that |
|---|
| .. | .. |
|---|
| 17 | 18 | * the license of that module. An independent module is a module which is not |
|---|
| 18 | 19 | * derived from this software. The special exception does not apply to any |
|---|
| 19 | 20 | * modifications of the software. |
|---|
| 20 | | - * |
|---|
| 21 | + * |
|---|
| 21 | 22 | * Notwithstanding the above, under no circumstances may you combine this |
|---|
| 22 | 23 | * software in any way with any other Broadcom software provided under a license |
|---|
| 23 | 24 | * other than the GPL, without Broadcom's express prior written consent. |
|---|
| .. | .. |
|---|
| 25 | 26 | * |
|---|
| 26 | 27 | * <<Broadcom-WL-IPTag/Open:>> |
|---|
| 27 | 28 | * |
|---|
| 28 | | - * $Id: dhd_ip.c 709309 2019-01-17 09:04:00Z $ |
|---|
| 29 | + * $Id: dhd_ip.c 700444 2017-05-19 06:38:00Z $ |
|---|
| 29 | 30 | */ |
|---|
| 30 | 31 | #include <typedefs.h> |
|---|
| 31 | 32 | #include <osl.h> |
|---|
| 32 | 33 | |
|---|
| 33 | | -#include <proto/ethernet.h> |
|---|
| 34 | | -#include <proto/vlan.h> |
|---|
| 35 | | -#include <proto/802.3.h> |
|---|
| 36 | | -#include <proto/bcmip.h> |
|---|
| 34 | +#include <ethernet.h> |
|---|
| 35 | +#include <vlan.h> |
|---|
| 36 | +#include <802.3.h> |
|---|
| 37 | +#include <bcmip.h> |
|---|
| 37 | 38 | #include <bcmendian.h> |
|---|
| 38 | 39 | |
|---|
| 39 | 40 | #include <dhd_dbg.h> |
|---|
| 40 | 41 | |
|---|
| 41 | 42 | #include <dhd_ip.h> |
|---|
| 42 | 43 | |
|---|
| 43 | | -#ifdef DHDTCPACK_SUPPRESS |
|---|
| 44 | +#if defined(DHDTCPACK_SUPPRESS) || defined(DHDTCPSYNC_FLOOD_BLK) |
|---|
| 44 | 45 | #include <dhd_bus.h> |
|---|
| 45 | 46 | #include <dhd_proto.h> |
|---|
| 46 | | -#include <proto/bcmtcp.h> |
|---|
| 47 | | -#endif /* DHDTCPACK_SUPPRESS */ |
|---|
| 47 | +#include <bcmtcp.h> |
|---|
| 48 | +#endif /* DHDTCPACK_SUPPRESS || DHDTCPSYNC_FLOOD_BLK */ |
|---|
| 48 | 49 | |
|---|
| 49 | 50 | /* special values */ |
|---|
| 50 | 51 | /* 802.3 llc/snap header */ |
|---|
| .. | .. |
|---|
| 128 | 129 | int ifidx; |
|---|
| 129 | 130 | uint8 supp_cnt; |
|---|
| 130 | 131 | dhd_pub_t *dhdp; |
|---|
| 131 | | - struct timer_list timer; |
|---|
| 132 | +#ifndef TCPACK_SUPPRESS_HOLD_HRT |
|---|
| 133 | + timer_list_compat_t timer; |
|---|
| 134 | +#else |
|---|
| 135 | +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21)) |
|---|
| 136 | + struct tasklet_hrtimer timer; |
|---|
| 137 | +#else |
|---|
| 138 | + struct hrtimer timer; |
|---|
| 139 | +#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21) */ |
|---|
| 140 | +#endif /* TCPACK_SUPPRESS_HOLD_HRT */ |
|---|
| 132 | 141 | } tcpack_info_t; |
|---|
| 133 | 142 | |
|---|
| 134 | 143 | typedef struct _tdata_psh_info_t { |
|---|
| .. | .. |
|---|
| 182 | 191 | tcpack_sup_mod->tdata_psh_info_free = tdata_psh_info; |
|---|
| 183 | 192 | #ifdef DHDTCPACK_SUP_DBG |
|---|
| 184 | 193 | tcpack_sup_mod->psh_info_enq_num++; |
|---|
| 185 | | -#endif |
|---|
| 194 | +#endif // endif |
|---|
| 186 | 195 | } |
|---|
| 187 | 196 | |
|---|
| 188 | 197 | static tdata_psh_info_t* |
|---|
| .. | .. |
|---|
| 290 | 299 | } |
|---|
| 291 | 300 | #endif /* BCMSDIO */ |
|---|
| 292 | 301 | |
|---|
| 293 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) |
|---|
| 294 | | -static void dhd_tcpack_send(struct timer_list *t) |
|---|
| 295 | | -{ |
|---|
| 296 | | - tcpack_info_t *cur_tbl = from_timer(cur_tbl, t, timer); |
|---|
| 297 | | -#else |
|---|
| 302 | +#ifdef BCMPCIE |
|---|
| 303 | +#ifndef TCPACK_SUPPRESS_HOLD_HRT |
|---|
| 298 | 304 | static void dhd_tcpack_send(ulong data) |
|---|
| 305 | +#else |
|---|
| 306 | +static enum hrtimer_restart dhd_tcpack_send(struct hrtimer *timer) |
|---|
| 307 | +#endif /* TCPACK_SUPPRESS_HOLD_HRT */ |
|---|
| 299 | 308 | { |
|---|
| 300 | | - tcpack_info_t *cur_tbl = (tcpack_info_t *)data; |
|---|
| 301 | | -#endif |
|---|
| 302 | 309 | tcpack_sup_module_t *tcpack_sup_mod; |
|---|
| 310 | + tcpack_info_t *cur_tbl; |
|---|
| 303 | 311 | dhd_pub_t *dhdp; |
|---|
| 304 | 312 | int ifidx; |
|---|
| 305 | 313 | void* pkt; |
|---|
| 306 | 314 | unsigned long flags; |
|---|
| 307 | 315 | |
|---|
| 316 | +#ifndef TCPACK_SUPPRESS_HOLD_HRT |
|---|
| 317 | + cur_tbl = (tcpack_info_t *)data; |
|---|
| 318 | +#else |
|---|
| 319 | + cur_tbl = container_of(timer, tcpack_info_t, timer.timer); |
|---|
| 320 | +#endif /* TCPACK_SUPPRESS_HOLD_HRT */ |
|---|
| 321 | + |
|---|
| 308 | 322 | if (!cur_tbl) { |
|---|
| 309 | | - return; |
|---|
| 323 | + goto done; |
|---|
| 310 | 324 | } |
|---|
| 311 | 325 | |
|---|
| 312 | 326 | dhdp = cur_tbl->dhdp; |
|---|
| 313 | 327 | if (!dhdp) { |
|---|
| 314 | | - return; |
|---|
| 328 | + goto done; |
|---|
| 315 | 329 | } |
|---|
| 316 | 330 | |
|---|
| 317 | 331 | flags = dhd_os_tcpacklock(dhdp); |
|---|
| 332 | + |
|---|
| 333 | + if (unlikely(dhdp->tcpack_sup_mode != TCPACK_SUP_HOLD)) { |
|---|
| 334 | + dhd_os_tcpackunlock(dhdp, flags); |
|---|
| 335 | + goto done; |
|---|
| 336 | + } |
|---|
| 318 | 337 | |
|---|
| 319 | 338 | tcpack_sup_mod = dhdp->tcpack_sup_module; |
|---|
| 320 | 339 | if (!tcpack_sup_mod) { |
|---|
| 321 | 340 | DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", |
|---|
| 322 | 341 | __FUNCTION__, __LINE__)); |
|---|
| 323 | 342 | dhd_os_tcpackunlock(dhdp, flags); |
|---|
| 324 | | - return; |
|---|
| 343 | + goto done; |
|---|
| 325 | 344 | } |
|---|
| 326 | 345 | pkt = cur_tbl->pkt_in_q; |
|---|
| 327 | 346 | ifidx = cur_tbl->ifidx; |
|---|
| 328 | 347 | if (!pkt) { |
|---|
| 329 | 348 | dhd_os_tcpackunlock(dhdp, flags); |
|---|
| 330 | | - return; |
|---|
| 349 | + goto done; |
|---|
| 331 | 350 | } |
|---|
| 332 | 351 | cur_tbl->pkt_in_q = NULL; |
|---|
| 333 | 352 | cur_tbl->pkt_ether_hdr = NULL; |
|---|
| .. | .. |
|---|
| 341 | 360 | dhd_os_tcpackunlock(dhdp, flags); |
|---|
| 342 | 361 | |
|---|
| 343 | 362 | dhd_sendpkt(dhdp, ifidx, pkt); |
|---|
| 363 | + |
|---|
| 364 | +done: |
|---|
| 365 | +#ifndef TCPACK_SUPPRESS_HOLD_HRT |
|---|
| 366 | + return; |
|---|
| 367 | +#else |
|---|
| 368 | + return HRTIMER_NORESTART; |
|---|
| 369 | +#endif /* TCPACK_SUPPRESS_HOLD_HRT */ |
|---|
| 344 | 370 | } |
|---|
| 371 | +#endif /* BCMPCIE */ |
|---|
| 345 | 372 | |
|---|
| 346 | 373 | int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode) |
|---|
| 347 | 374 | { |
|---|
| 348 | 375 | int ret = BCME_OK; |
|---|
| 349 | 376 | unsigned long flags; |
|---|
| 377 | + tcpack_sup_module_t *tcpack_sup_module; |
|---|
| 378 | + uint8 invalid_mode = FALSE; |
|---|
| 379 | + int prev_mode; |
|---|
| 380 | + int i = 0; |
|---|
| 350 | 381 | |
|---|
| 351 | 382 | flags = dhd_os_tcpacklock(dhdp); |
|---|
| 383 | + tcpack_sup_module = dhdp->tcpack_sup_module; |
|---|
| 384 | + prev_mode = dhdp->tcpack_sup_mode; |
|---|
| 352 | 385 | |
|---|
| 353 | | - if (dhdp->tcpack_sup_mode == mode) { |
|---|
| 386 | + if (prev_mode == mode) { |
|---|
| 354 | 387 | DHD_ERROR(("%s %d: already set to %d\n", __FUNCTION__, __LINE__, mode)); |
|---|
| 355 | 388 | goto exit; |
|---|
| 356 | 389 | } |
|---|
| 357 | 390 | |
|---|
| 358 | | - if (mode >= TCPACK_SUP_LAST_MODE || |
|---|
| 359 | | -#ifndef BCMSDIO |
|---|
| 360 | | - mode == TCPACK_SUP_DELAYTX || |
|---|
| 361 | | -#endif /* !BCMSDIO */ |
|---|
| 362 | | - FALSE) { |
|---|
| 363 | | - DHD_ERROR(("%s %d: Invalid mode %d\n", __FUNCTION__, __LINE__, mode)); |
|---|
| 391 | + invalid_mode |= (mode >= TCPACK_SUP_LAST_MODE); |
|---|
| 392 | +#ifdef BCMSDIO |
|---|
| 393 | + invalid_mode |= (mode == TCPACK_SUP_HOLD); |
|---|
| 394 | +#endif /* BCMSDIO */ |
|---|
| 395 | +#ifdef BCMPCIE |
|---|
| 396 | + invalid_mode |= ((mode == TCPACK_SUP_REPLACE) || (mode == TCPACK_SUP_DELAYTX)); |
|---|
| 397 | +#endif /* BCMPCIE */ |
|---|
| 398 | + |
|---|
| 399 | + if (invalid_mode) { |
|---|
| 400 | + DHD_ERROR(("%s %d: Invalid TCP ACK Suppress mode %d\n", |
|---|
| 401 | + __FUNCTION__, __LINE__, mode)); |
|---|
| 364 | 402 | ret = BCME_BADARG; |
|---|
| 365 | 403 | goto exit; |
|---|
| 366 | 404 | } |
|---|
| 367 | 405 | |
|---|
| 368 | | - DHD_TRACE(("%s: %d -> %d\n", |
|---|
| 406 | + DHD_TRACE(("%s: TCP ACK Suppress mode %d -> mode %d\n", |
|---|
| 369 | 407 | __FUNCTION__, dhdp->tcpack_sup_mode, mode)); |
|---|
| 370 | 408 | |
|---|
| 409 | + /* Pre-process routines to change a new mode as per previous mode */ |
|---|
| 410 | + switch (prev_mode) { |
|---|
| 411 | + case TCPACK_SUP_OFF: |
|---|
| 412 | + if (tcpack_sup_module == NULL) { |
|---|
| 413 | + tcpack_sup_module = MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t)); |
|---|
| 414 | + if (tcpack_sup_module == NULL) { |
|---|
| 415 | + DHD_ERROR(("%s[%d]: Failed to allocate the new memory for " |
|---|
| 416 | + "tcpack_sup_module\n", __FUNCTION__, __LINE__)); |
|---|
| 417 | + dhdp->tcpack_sup_mode = TCPACK_SUP_OFF; |
|---|
| 418 | + ret = BCME_NOMEM; |
|---|
| 419 | + goto exit; |
|---|
| 420 | + } |
|---|
| 421 | + dhdp->tcpack_sup_module = tcpack_sup_module; |
|---|
| 422 | + } |
|---|
| 423 | + bzero(tcpack_sup_module, sizeof(tcpack_sup_module_t)); |
|---|
| 424 | + break; |
|---|
| 371 | 425 | #ifdef BCMSDIO |
|---|
| 372 | | - /* Old tcpack_sup_mode is TCPACK_SUP_DELAYTX */ |
|---|
| 373 | | - if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX) { |
|---|
| 374 | | - tcpack_sup_module_t *tcpack_sup_mod = dhdp->tcpack_sup_module; |
|---|
| 375 | | - /* We won't need tdata_psh_info pool and tcpddata_info_tbl anymore */ |
|---|
| 376 | | - _tdata_psh_info_pool_deinit(dhdp, tcpack_sup_mod); |
|---|
| 377 | | - tcpack_sup_mod->tcpdata_info_cnt = 0; |
|---|
| 378 | | - bzero(tcpack_sup_mod->tcpdata_info_tbl, |
|---|
| 379 | | - sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM); |
|---|
| 380 | | - /* For half duplex bus interface, tx precedes rx by default */ |
|---|
| 381 | | - if (dhdp->bus) |
|---|
| 382 | | - dhd_bus_set_dotxinrx(dhdp->bus, TRUE); |
|---|
| 383 | | - } |
|---|
| 426 | + case TCPACK_SUP_DELAYTX: |
|---|
| 427 | + if (tcpack_sup_module) { |
|---|
| 428 | + /* We won't need tdata_psh_info pool and |
|---|
| 429 | + * tcpddata_info_tbl anymore |
|---|
| 430 | + */ |
|---|
| 431 | + _tdata_psh_info_pool_deinit(dhdp, tcpack_sup_module); |
|---|
| 432 | + tcpack_sup_module->tcpdata_info_cnt = 0; |
|---|
| 433 | + bzero(tcpack_sup_module->tcpdata_info_tbl, |
|---|
| 434 | + sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM); |
|---|
| 435 | + } |
|---|
| 436 | + |
|---|
| 437 | + /* For half duplex bus interface, tx precedes rx by default */ |
|---|
| 438 | + if (dhdp->bus) { |
|---|
| 439 | + dhd_bus_set_dotxinrx(dhdp->bus, TRUE); |
|---|
| 440 | + } |
|---|
| 441 | + |
|---|
| 442 | + if (tcpack_sup_module == NULL) { |
|---|
| 443 | + DHD_ERROR(("%s[%d]: tcpack_sup_module should not be NULL\n", |
|---|
| 444 | + __FUNCTION__, __LINE__)); |
|---|
| 445 | + dhdp->tcpack_sup_mode = TCPACK_SUP_OFF; |
|---|
| 446 | + goto exit; |
|---|
| 447 | + } |
|---|
| 448 | + break; |
|---|
| 384 | 449 | #endif /* BCMSDIO */ |
|---|
| 450 | + } |
|---|
| 451 | + |
|---|
| 452 | + /* Update a new mode */ |
|---|
| 385 | 453 | dhdp->tcpack_sup_mode = mode; |
|---|
| 386 | 454 | |
|---|
| 387 | | - if (mode == TCPACK_SUP_OFF) { |
|---|
| 388 | | - ASSERT(dhdp->tcpack_sup_module != NULL); |
|---|
| 389 | | - /* Clean up timer/data structure for any remaining/pending packet or timer. */ |
|---|
| 390 | | - dhd_tcpack_info_tbl_clean(dhdp); |
|---|
| 391 | | - MFREE(dhdp->osh, dhdp->tcpack_sup_module, sizeof(tcpack_sup_module_t)); |
|---|
| 392 | | - dhdp->tcpack_sup_module = NULL; |
|---|
| 393 | | - goto exit; |
|---|
| 394 | | - } |
|---|
| 395 | | - |
|---|
| 396 | | - if (dhdp->tcpack_sup_module == NULL) { |
|---|
| 397 | | - tcpack_sup_module_t *tcpack_sup_mod = |
|---|
| 398 | | - MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t)); |
|---|
| 399 | | - if (tcpack_sup_mod == NULL) { |
|---|
| 400 | | - DHD_ERROR(("%s %d: No MEM\n", __FUNCTION__, __LINE__)); |
|---|
| 401 | | - dhdp->tcpack_sup_mode = TCPACK_SUP_OFF; |
|---|
| 402 | | - ret = BCME_NOMEM; |
|---|
| 403 | | - goto exit; |
|---|
| 404 | | - } |
|---|
| 405 | | - bzero(tcpack_sup_mod, sizeof(tcpack_sup_module_t)); |
|---|
| 406 | | - dhdp->tcpack_sup_module = tcpack_sup_mod; |
|---|
| 407 | | - } |
|---|
| 408 | | - |
|---|
| 409 | | -#ifdef BCMSDIO |
|---|
| 410 | | - if (mode == TCPACK_SUP_DELAYTX) { |
|---|
| 411 | | - ret = _tdata_psh_info_pool_init(dhdp, dhdp->tcpack_sup_module); |
|---|
| 412 | | - if (ret != BCME_OK) |
|---|
| 413 | | - DHD_ERROR(("%s %d: pool init fail with %d\n", __FUNCTION__, __LINE__, ret)); |
|---|
| 414 | | - else if (dhdp->bus) |
|---|
| 415 | | - dhd_bus_set_dotxinrx(dhdp->bus, FALSE); |
|---|
| 416 | | - } |
|---|
| 417 | | -#endif /* BCMSDIO */ |
|---|
| 418 | | - |
|---|
| 419 | | - if (mode == TCPACK_SUP_HOLD) { |
|---|
| 420 | | - int i; |
|---|
| 421 | | - tcpack_sup_module_t *tcpack_sup_mod = |
|---|
| 422 | | - (tcpack_sup_module_t *)dhdp->tcpack_sup_module; |
|---|
| 423 | | - dhdp->tcpack_sup_ratio = CUSTOM_TCPACK_SUPP_RATIO; |
|---|
| 424 | | - dhdp->tcpack_sup_delay = CUSTOM_TCPACK_DELAY_TIME; |
|---|
| 425 | | - for (i = 0; i < TCPACK_INFO_MAXNUM; i++) |
|---|
| 426 | | - { |
|---|
| 427 | | - tcpack_sup_mod->tcpack_info_tbl[i].dhdp = dhdp; |
|---|
| 428 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) |
|---|
| 429 | | - timer_setup((struct timer_list *)&tcpack_sup_mod->tcpack_info_tbl[i].timer, dhd_tcpack_send, 0); |
|---|
| 455 | + /* Process for a new mode */ |
|---|
| 456 | + switch (mode) { |
|---|
| 457 | + case TCPACK_SUP_OFF: |
|---|
| 458 | + ASSERT(tcpack_sup_module != NULL); |
|---|
| 459 | + /* Clean up timer/data structure for |
|---|
| 460 | + * any remaining/pending packet or timer. |
|---|
| 461 | + */ |
|---|
| 462 | + if (tcpack_sup_module) { |
|---|
| 463 | + /* Check if previous mode is TCAPACK_SUP_HOLD */ |
|---|
| 464 | + if (prev_mode == TCPACK_SUP_HOLD) { |
|---|
| 465 | + for (i = 0; i < TCPACK_INFO_MAXNUM; i++) { |
|---|
| 466 | + tcpack_info_t *tcpack_info_tbl = |
|---|
| 467 | + &tcpack_sup_module->tcpack_info_tbl[i]; |
|---|
| 468 | +#ifndef TCPACK_SUPPRESS_HOLD_HRT |
|---|
| 469 | + del_timer(&tcpack_info_tbl->timer); |
|---|
| 430 | 470 | #else |
|---|
| 431 | | - init_timer(&tcpack_sup_mod->tcpack_info_tbl[i].timer); |
|---|
| 432 | | - tcpack_sup_mod->tcpack_info_tbl[i].timer.data = |
|---|
| 433 | | - (ulong)&tcpack_sup_mod->tcpack_info_tbl[i]; |
|---|
| 434 | | - tcpack_sup_mod->tcpack_info_tbl[i].timer.function = dhd_tcpack_send; |
|---|
| 435 | | -#endif |
|---|
| 436 | | - } |
|---|
| 471 | + hrtimer_cancel(&tcpack_info_tbl->timer.timer); |
|---|
| 472 | +#endif /* TCPACK_SUPPRESS_HOLD_HRT */ |
|---|
| 473 | + if (tcpack_info_tbl->pkt_in_q) { |
|---|
| 474 | + PKTFREE(dhdp->osh, |
|---|
| 475 | + tcpack_info_tbl->pkt_in_q, TRUE); |
|---|
| 476 | + tcpack_info_tbl->pkt_in_q = NULL; |
|---|
| 477 | + } |
|---|
| 478 | + } |
|---|
| 479 | + } |
|---|
| 480 | + MFREE(dhdp->osh, tcpack_sup_module, sizeof(tcpack_sup_module_t)); |
|---|
| 481 | + dhdp->tcpack_sup_module = NULL; |
|---|
| 482 | + } else { |
|---|
| 483 | + DHD_ERROR(("%s[%d]: tcpack_sup_module should not be NULL\n", |
|---|
| 484 | + __FUNCTION__, __LINE__)); |
|---|
| 485 | + } |
|---|
| 486 | + break; |
|---|
| 487 | +#ifdef BCMSDIO |
|---|
| 488 | + case TCPACK_SUP_REPLACE: |
|---|
| 489 | + /* There is nothing to configure for this mode */ |
|---|
| 490 | + break; |
|---|
| 491 | + case TCPACK_SUP_DELAYTX: |
|---|
| 492 | + ret = _tdata_psh_info_pool_init(dhdp, tcpack_sup_module); |
|---|
| 493 | + if (ret != BCME_OK) { |
|---|
| 494 | + DHD_ERROR(("%s %d: pool init fail with %d\n", |
|---|
| 495 | + __FUNCTION__, __LINE__, ret)); |
|---|
| 496 | + break; |
|---|
| 497 | + } |
|---|
| 498 | + if (dhdp->bus) { |
|---|
| 499 | + dhd_bus_set_dotxinrx(dhdp->bus, FALSE); |
|---|
| 500 | + } |
|---|
| 501 | + break; |
|---|
| 502 | +#endif /* BCMSDIO */ |
|---|
| 503 | +#ifdef BCMPCIE |
|---|
| 504 | + case TCPACK_SUP_HOLD: |
|---|
| 505 | + dhdp->tcpack_sup_ratio = CUSTOM_TCPACK_SUPP_RATIO; |
|---|
| 506 | + dhdp->tcpack_sup_delay = CUSTOM_TCPACK_DELAY_TIME; |
|---|
| 507 | + for (i = 0; i < TCPACK_INFO_MAXNUM; i++) { |
|---|
| 508 | + tcpack_info_t *tcpack_info_tbl = |
|---|
| 509 | + &tcpack_sup_module->tcpack_info_tbl[i]; |
|---|
| 510 | + tcpack_info_tbl->dhdp = dhdp; |
|---|
| 511 | +#ifndef TCPACK_SUPPRESS_HOLD_HRT |
|---|
| 512 | + init_timer_compat(&tcpack_info_tbl->timer, |
|---|
| 513 | + dhd_tcpack_send, tcpack_info_tbl); |
|---|
| 514 | +#else |
|---|
| 515 | +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21)) |
|---|
| 516 | + tasklet_hrtimer_init(&tcpack_info_tbl->timer, |
|---|
| 517 | + dhd_tcpack_send, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
|---|
| 518 | +#else |
|---|
| 519 | + hrtimer_init(&tcpack_info_tbl->timer, CLOCK_MONOTONIC, |
|---|
| 520 | + HRTIMER_MODE_REL_SOFT); |
|---|
| 521 | +#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21) */ |
|---|
| 522 | +#endif /* TCPACK_SUPPRESS_HOLD_HRT */ |
|---|
| 523 | + } |
|---|
| 524 | + break; |
|---|
| 525 | +#endif /* BCMPCIE */ |
|---|
| 437 | 526 | } |
|---|
| 438 | 527 | |
|---|
| 439 | 528 | exit: |
|---|
| .. | .. |
|---|
| 480 | 569 | |
|---|
| 481 | 570 | if (dhdp->tcpack_sup_mode == TCPACK_SUP_HOLD) { |
|---|
| 482 | 571 | for (i = 0; i < TCPACK_INFO_MAXNUM; i++) { |
|---|
| 572 | +#ifndef TCPACK_SUPPRESS_HOLD_HRT |
|---|
| 483 | 573 | del_timer_sync(&tcpack_sup_mod->tcpack_info_tbl[i].timer); |
|---|
| 574 | +#else |
|---|
| 575 | + hrtimer_cancel(&tcpack_sup_mod->tcpack_info_tbl[i].timer.timer); |
|---|
| 576 | +#endif /* TCPACK_SUPPRESS_HOLD_HRT */ |
|---|
| 484 | 577 | } |
|---|
| 485 | 578 | } |
|---|
| 486 | 579 | |
|---|
| .. | .. |
|---|
| 649 | 742 | bool ret = FALSE; |
|---|
| 650 | 743 | bool set_dotxinrx = TRUE; |
|---|
| 651 | 744 | unsigned long flags; |
|---|
| 652 | | - |
|---|
| 653 | 745 | |
|---|
| 654 | 746 | if (dhdp->tcpack_sup_mode == TCPACK_SUP_OFF) |
|---|
| 655 | 747 | goto exit; |
|---|
| .. | .. |
|---|
| 1193 | 1285 | for (i = 0; i < TCPACK_INFO_MAXNUM; i++) { |
|---|
| 1194 | 1286 | void *oldpkt; /* TCPACK packet that is already in txq or DelayQ */ |
|---|
| 1195 | 1287 | uint8 *old_ether_hdr, *old_ip_hdr, *old_tcp_hdr; |
|---|
| 1196 | | - uint32 old_ip_hdr_len, old_tcp_hdr_len; |
|---|
| 1288 | + uint32 old_ip_hdr_len; |
|---|
| 1197 | 1289 | uint32 old_tcpack_num; /* TCP ACK number of old TCPACK packet in Q */ |
|---|
| 1198 | 1290 | |
|---|
| 1199 | 1291 | if ((oldpkt = tcpack_info_tbl[i].pkt_in_q) == NULL) { |
|---|
| .. | .. |
|---|
| 1215 | 1307 | old_ip_hdr = old_ether_hdr + ETHER_HDR_LEN; |
|---|
| 1216 | 1308 | old_ip_hdr_len = IPV4_HLEN(old_ip_hdr); |
|---|
| 1217 | 1309 | old_tcp_hdr = old_ip_hdr + old_ip_hdr_len; |
|---|
| 1218 | | - old_tcp_hdr_len = 4 * TCP_HDRLEN(old_tcp_hdr[TCP_HLEN_OFFSET]); |
|---|
| 1219 | 1310 | |
|---|
| 1220 | 1311 | DHD_TRACE(("%s %d: oldpkt %p[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR |
|---|
| 1221 | 1312 | " TCP port %d %d\n", __FUNCTION__, __LINE__, oldpkt, i, |
|---|
| .. | .. |
|---|
| 1254 | 1345 | dhd_os_tcpackunlock(dhdp, flags); |
|---|
| 1255 | 1346 | |
|---|
| 1256 | 1347 | if (!hold) { |
|---|
| 1348 | +#ifndef TCPACK_SUPPRESS_HOLD_HRT |
|---|
| 1257 | 1349 | del_timer_sync(&tcpack_info_tbl[i].timer); |
|---|
| 1350 | +#else |
|---|
| 1351 | + hrtimer_cancel(&tcpack_sup_mod->tcpack_info_tbl[i].timer.timer); |
|---|
| 1352 | +#endif /* TCPACK_SUPPRESS_HOLD_HRT */ |
|---|
| 1258 | 1353 | } |
|---|
| 1259 | 1354 | goto exit; |
|---|
| 1260 | 1355 | } |
|---|
| .. | .. |
|---|
| 1271 | 1366 | tcpack_info_tbl[free_slot].pkt_ether_hdr = new_ether_hdr; |
|---|
| 1272 | 1367 | tcpack_info_tbl[free_slot].ifidx = ifidx; |
|---|
| 1273 | 1368 | tcpack_info_tbl[free_slot].supp_cnt = 1; |
|---|
| 1369 | +#ifndef TCPACK_SUPPRESS_HOLD_HRT |
|---|
| 1274 | 1370 | mod_timer(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer, |
|---|
| 1275 | 1371 | jiffies + msecs_to_jiffies(dhdp->tcpack_sup_delay)); |
|---|
| 1372 | +#else |
|---|
| 1373 | +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 1, 21) |
|---|
| 1374 | + tasklet_hrtimer_start(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer, |
|---|
| 1375 | + ktime_set(0, dhdp->tcpack_sup_delay*1000000), HRTIMER_MODE_REL); |
|---|
| 1376 | +#else |
|---|
| 1377 | + hrtimer_start(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer, |
|---|
| 1378 | + ktime_set(0, dhdp->tcpack_sup_delay*1000000), HRTIMER_MODE_REL_SOFT); |
|---|
| 1379 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) */ |
|---|
| 1380 | +#endif /* TCPACK_SUPPRESS_HOLD_HRT */ |
|---|
| 1276 | 1381 | tcpack_sup_mod->tcpack_info_cnt++; |
|---|
| 1277 | 1382 | } else { |
|---|
| 1278 | 1383 | DHD_TRACE(("%s %d: No empty tcp ack info tbl\n", |
|---|
| .. | .. |
|---|
| 1284 | 1389 | return hold; |
|---|
| 1285 | 1390 | } |
|---|
| 1286 | 1391 | #endif /* DHDTCPACK_SUPPRESS */ |
|---|
| 1392 | + |
|---|
| 1393 | +#ifdef DHDTCPSYNC_FLOOD_BLK |
|---|
| 1394 | +tcp_hdr_flag_t |
|---|
| 1395 | +dhd_tcpdata_get_flag(dhd_pub_t *dhdp, void *pkt) |
|---|
| 1396 | +{ |
|---|
| 1397 | + uint8 *ether_hdr; /* Ethernet header of the new packet */ |
|---|
| 1398 | + uint16 ether_type; /* Ethernet type of the new packet */ |
|---|
| 1399 | + uint8 *ip_hdr; /* IP header of the new packet */ |
|---|
| 1400 | + uint8 *tcp_hdr; /* TCP header of the new packet */ |
|---|
| 1401 | + uint32 ip_hdr_len; /* IP header length of the new packet */ |
|---|
| 1402 | + uint32 cur_framelen; |
|---|
| 1403 | + uint8 flags; |
|---|
| 1404 | + |
|---|
| 1405 | + ether_hdr = PKTDATA(dhdp->osh, pkt); |
|---|
| 1406 | + cur_framelen = PKTLEN(dhdp->osh, pkt); |
|---|
| 1407 | + |
|---|
| 1408 | + ether_type = ether_hdr[12] << 8 | ether_hdr[13]; |
|---|
| 1409 | + |
|---|
| 1410 | + if (ether_type != ETHER_TYPE_IP) { |
|---|
| 1411 | + DHD_TRACE(("%s %d: Not a IP packet 0x%x\n", |
|---|
| 1412 | + __FUNCTION__, __LINE__, ether_type)); |
|---|
| 1413 | + return FLAG_OTHERS; |
|---|
| 1414 | + } |
|---|
| 1415 | + |
|---|
| 1416 | + ip_hdr = ether_hdr + ETHER_HDR_LEN; |
|---|
| 1417 | + cur_framelen -= ETHER_HDR_LEN; |
|---|
| 1418 | + |
|---|
| 1419 | + if (cur_framelen < IPV4_MIN_HEADER_LEN) { |
|---|
| 1420 | + return FLAG_OTHERS; |
|---|
| 1421 | + } |
|---|
| 1422 | + |
|---|
| 1423 | + ip_hdr_len = IPV4_HLEN(ip_hdr); |
|---|
| 1424 | + if (IP_VER(ip_hdr) != IP_VER_4 || IPV4_PROT(ip_hdr) != IP_PROT_TCP) { |
|---|
| 1425 | + DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n", |
|---|
| 1426 | + __FUNCTION__, __LINE__, IP_VER(ip_hdr), IPV4_PROT(ip_hdr))); |
|---|
| 1427 | + return FLAG_OTHERS; |
|---|
| 1428 | + } |
|---|
| 1429 | + |
|---|
| 1430 | + tcp_hdr = ip_hdr + ip_hdr_len; |
|---|
| 1431 | + |
|---|
| 1432 | + flags = (uint8)tcp_hdr[TCP_FLAGS_OFFSET]; |
|---|
| 1433 | + |
|---|
| 1434 | + if (flags & TCP_FLAG_SYN) { |
|---|
| 1435 | + if (flags & TCP_FLAG_ACK) { |
|---|
| 1436 | + return FLAG_SYNCACK; |
|---|
| 1437 | + } |
|---|
| 1438 | + return FLAG_SYNC; |
|---|
| 1439 | + } |
|---|
| 1440 | + return FLAG_OTHERS; |
|---|
| 1441 | +} |
|---|
| 1442 | +#endif /* DHDTCPSYNC_FLOOD_BLK */ |
|---|