int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode) { int ret = BCME_OK; dhd_os_tcpacklock(dhdp); if (dhdp->tcpack_sup_mode == mode) { DHD_ERROR(("%s %d: already set to %d\n", __FUNCTION__, __LINE__, mode)); goto exit; } if (mode >= TCPACK_SUP_LAST_MODE || #ifndef BCMSDIO mode == TCPACK_SUP_DELAYTX || #endif FALSE) { DHD_ERROR(("%s %d: Invalid mode %d\n", __FUNCTION__, __LINE__, mode)); ret = BCME_BADARG; goto exit; } DHD_TRACE(("%s: %d -> %d\n", __FUNCTION__, dhdp->tcpack_sup_mode, mode)); /* Old tcpack_sup_mode is TCPACK_SUP_DELAYTX */ if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX) { tcpack_sup_module_t *tcpack_sup_mod = dhdp->tcpack_sup_module; /* We won't need tdata_psh_info pool and tcpddata_info_tbl anymore */ _tdata_psh_info_pool_deinit(dhdp, tcpack_sup_mod); tcpack_sup_mod->tcpdata_info_cnt = 0; bzero(tcpack_sup_mod->tcpdata_info_tbl, sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM); /* For half duplex bus interface, tx precedes rx by default */ if (dhdp->bus) dhd_bus_set_dotxinrx(dhdp->bus, TRUE); } dhdp->tcpack_sup_mode = mode; if (mode == TCPACK_SUP_OFF) { ASSERT(dhdp->tcpack_sup_module != NULL); MFREE(dhdp->osh, dhdp->tcpack_sup_module, sizeof(tcpack_sup_module_t)); dhdp->tcpack_sup_module = NULL; goto exit; } if (dhdp->tcpack_sup_module == NULL) { tcpack_sup_module_t *tcpack_sup_mod = MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t)); if (tcpack_sup_mod == NULL) { DHD_ERROR(("%s %d: No MEM\n", __FUNCTION__, __LINE__)); dhdp->tcpack_sup_mode = TCPACK_SUP_OFF; ret = BCME_NOMEM; goto exit; } bzero(tcpack_sup_mod, sizeof(tcpack_sup_module_t)); dhdp->tcpack_sup_module = tcpack_sup_mod; } if (mode == TCPACK_SUP_DELAYTX) { ret = _tdata_psh_info_pool_init(dhdp, dhdp->tcpack_sup_module); if (ret != BCME_OK) DHD_ERROR(("%s %d: pool init fail with %d\n", __FUNCTION__, __LINE__, ret)); else if (dhdp->bus) dhd_bus_set_dotxinrx(dhdp->bus, FALSE); } exit: dhd_os_tcpackunlock(dhdp); return ret; }
int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode) { int ret = BCME_OK; unsigned long flags; flags = dhd_os_tcpacklock(dhdp); if (dhdp->tcpack_sup_mode == mode) { DHD_ERROR(("%s %d: already set to %d\n", __FUNCTION__, __LINE__, mode)); goto exit; } if (mode >= TCPACK_SUP_LAST_MODE || #ifndef BCMSDIO mode == TCPACK_SUP_DELAYTX || #endif /* !BCMSDIO */ FALSE) { DHD_ERROR(("%s %d: Invalid mode %d\n", __FUNCTION__, __LINE__, mode)); ret = BCME_BADARG; goto exit; } DHD_TRACE(("%s: %d -> %d\n", __FUNCTION__, dhdp->tcpack_sup_mode, mode)); #ifdef BCMSDIO /* Old tcpack_sup_mode is TCPACK_SUP_DELAYTX */ if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX) { tcpack_sup_module_t *tcpack_sup_mod = dhdp->tcpack_sup_module; /* We won't need tdata_psh_info pool and tcpddata_info_tbl anymore */ _tdata_psh_info_pool_deinit(dhdp, tcpack_sup_mod); tcpack_sup_mod->tcpdata_info_cnt = 0; bzero(tcpack_sup_mod->tcpdata_info_tbl, sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM); /* For half duplex bus interface, tx precedes rx by default */ if (dhdp->bus) dhd_bus_set_dotxinrx(dhdp->bus, TRUE); } #endif dhdp->tcpack_sup_mode = mode; if (mode == TCPACK_SUP_OFF) { ASSERT(dhdp->tcpack_sup_module != NULL); /* Clean up timer/data structure for any remaining/pending packet or timer. */ dhd_tcpack_info_tbl_clean(dhdp); MFREE(dhdp->osh, dhdp->tcpack_sup_module, sizeof(tcpack_sup_module_t)); dhdp->tcpack_sup_module = NULL; goto exit; } if (dhdp->tcpack_sup_module == NULL) { tcpack_sup_module_t *tcpack_sup_mod = MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t)); if (tcpack_sup_mod == NULL) { DHD_ERROR(("%s %d: No MEM\n", __FUNCTION__, __LINE__)); dhdp->tcpack_sup_mode = TCPACK_SUP_OFF; ret = BCME_NOMEM; goto exit; } bzero(tcpack_sup_mod, sizeof(tcpack_sup_module_t)); dhdp->tcpack_sup_module = tcpack_sup_mod; } #ifdef BCMSDIO if (mode == TCPACK_SUP_DELAYTX) { ret = _tdata_psh_info_pool_init(dhdp, dhdp->tcpack_sup_module); if (ret != BCME_OK) DHD_ERROR(("%s %d: pool init fail with %d\n", __FUNCTION__, __LINE__, ret)); else if (dhdp->bus) dhd_bus_set_dotxinrx(dhdp->bus, FALSE); } #endif /* BCMSDIO */ if (mode == TCPACK_SUP_HOLD) { int i; tcpack_sup_module_t *tcpack_sup_mod = (tcpack_sup_module_t *)dhdp->tcpack_sup_module; dhdp->tcpack_sup_ratio = TCPACK_SUPP_RATIO; dhdp->tcpack_sup_delay = TCPACK_DELAY_TIME; for (i = 0; i < TCPACK_INFO_MAXNUM; i++) { tcpack_sup_mod->tcpack_info_tbl[i].dhdp = dhdp; init_timer(&tcpack_sup_mod->tcpack_info_tbl[i].timer); tcpack_sup_mod->tcpack_info_tbl[i].timer.data = (ulong)&tcpack_sup_mod->tcpack_info_tbl[i]; tcpack_sup_mod->tcpack_info_tbl[i].timer.function = dhd_tcpack_send; } } exit: dhd_os_tcpackunlock(dhdp, flags); return ret; }