adf_nbuf_t RxSgToSingleNetbuf(HTC_TARGET *target) { adf_nbuf_t skb; a_uint8_t *anbdata; a_uint8_t *anbdata_new; a_uint32_t anblen; adf_nbuf_t new_skb = NULL; a_uint32_t sg_queue_len; adf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue; sg_queue_len = adf_nbuf_queue_len(rx_sg_queue); if (sg_queue_len <= 1) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("RxSgToSingleNetbuf: invalid sg queue len %u\n")); goto _failed; } new_skb = adf_nbuf_alloc(target->ExpRxSgTotalLen, 0, 4, FALSE); if (new_skb == NULL) { AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("RxSgToSingleNetbuf: can't allocate %u size netbuf\n", target->ExpRxSgTotalLen)); goto _failed; } adf_nbuf_peek_header(new_skb, &anbdata_new, &anblen); skb = adf_nbuf_queue_remove(rx_sg_queue); do { adf_nbuf_peek_header(skb, &anbdata, &anblen); adf_os_mem_copy(anbdata_new, anbdata, adf_nbuf_len(skb)); adf_nbuf_put_tail(new_skb, adf_nbuf_len(skb)); anbdata_new += adf_nbuf_len(skb); adf_nbuf_free(skb); skb = adf_nbuf_queue_remove(rx_sg_queue); } while(skb != NULL); RESET_RX_SG_CONFIG(target); return new_skb; _failed: while ((skb = adf_nbuf_queue_remove(rx_sg_queue)) != NULL) { adf_nbuf_free(skb); } RESET_RX_SG_CONFIG(target); return NULL; }
/*flush all queued buffers for surpriseremove case*/ void htc_flush_surprise_remove(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int i; HTC_ENDPOINT *pEndpoint; #ifdef RX_SG_SUPPORT cdf_nbuf_t netbuf; cdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue; #endif AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_flush_surprise_remove \n")); /* cleanup endpoints */ for (i = 0; i < ENDPOINT_MAX; i++) { pEndpoint = &target->EndPoint[i]; htc_flush_rx_hold_queue(target, pEndpoint); htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL); } hif_flush_surprise_remove(target->hif_dev); #ifdef RX_SG_SUPPORT LOCK_HTC_RX(target); while ((netbuf = cdf_nbuf_queue_remove(rx_sg_queue)) != NULL) { cdf_nbuf_free(netbuf); } RESET_RX_SG_CONFIG(target); UNLOCK_HTC_RX(target); #endif reset_endpoint_states(target); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_flush_surprise_remove \n")); }
/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */ void htc_stop(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int i; HTC_ENDPOINT *pEndpoint; #ifdef RX_SG_SUPPORT cdf_nbuf_t netbuf; cdf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue; #endif AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+htc_stop \n")); /* cleanup endpoints */ for (i = 0; i < ENDPOINT_MAX; i++) { pEndpoint = &target->EndPoint[i]; htc_flush_rx_hold_queue(target, pEndpoint); htc_flush_endpoint_tx(target, pEndpoint, HTC_TX_PACKET_TAG_ALL); if (pEndpoint->ul_is_polled) { cdf_softirq_timer_cancel(&pEndpoint->ul_poll_timer); cdf_softirq_timer_free(&pEndpoint->ul_poll_timer); } } /* Note: htc_flush_endpoint_tx for all endpoints should be called before * hif_stop - otherwise htc_tx_completion_handler called from * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer, * might queue the packet again to HIF Layer - which could cause tx * buffer leak */ hif_stop(target->hif_dev); #ifdef RX_SG_SUPPORT LOCK_HTC_RX(target); while ((netbuf = cdf_nbuf_queue_remove(rx_sg_queue)) != NULL) { cdf_nbuf_free(netbuf); } RESET_RX_SG_CONFIG(target); UNLOCK_HTC_RX(target); #endif reset_endpoint_states(target); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-htc_stop \n")); }
/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */ void HTCStop(HTC_HANDLE HTCHandle) { HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); int i; HTC_ENDPOINT *pEndpoint; #ifdef RX_SG_SUPPORT adf_nbuf_t netbuf; adf_nbuf_queue_t *rx_sg_queue = &target->RxSgQueue; #endif AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n")); /* cleanup endpoints */ for (i = 0; i < ENDPOINT_MAX; i++) { pEndpoint = &target->EndPoint[i]; HTCFlushRxHoldQueue(target,pEndpoint); HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL); } /* Note: HTCFlushEndpointTX for all endpoints should be called before * HIFStop - otherwise HTCTxCompletionHandler called from * hif_send_buffer_cleanup_on_pipe for residual tx frames in HIF layer, * might queue the packet again to HIF Layer - which could cause tx * buffer leak */ HIFStop(target->hif_dev); #ifdef RX_SG_SUPPORT LOCK_HTC_RX(target); while ((netbuf = adf_nbuf_queue_remove(rx_sg_queue)) != NULL) { adf_nbuf_free(netbuf); } RESET_RX_SG_CONFIG(target); UNLOCK_HTC_RX(target); #endif ResetEndpointStates(target); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n")); }