📄 atheros_2_0_function.patch
字号:
+ break;+ }++ if ((ar->arNetworkType == ADHOC_NETWORK) &&+ ar->arIbssPsEnable && ar->arConnected) {+ /* flag to check adhoc mapping once we take the lock below: */+ checkAdHocPsMapping = TRUE;++ } else {+ /* get the stream mapping */+ if (ar->arWmmEnabled) {+ streamID = wmi_get_stream_id(ar->arWmi,+ wmi_implicit_create_pstream(ar->arWmi, skb, UPLINK_TRAFFIC, UNDEFINED_PRI));+ } else {+ streamID = WMI_BEST_EFFORT_PRI;+ }+ }++ } else {+ struct iphdr *ipHdr;+ /*+ * the endpoint is directly based on the TOS field in the IP+ * header **** only for testing ******+ */+ ipHdr = A_NETBUF_DATA(skb) + sizeof(ATH_MAC_HDR);+ /* here we map the TOS field to an endpoint number, this is for+ * the endpointping test application */+ streamID = IP_TOS_TO_WMI_PRI(ipHdr->tos);+ }++ } while (FALSE);++ /* did we succeed ? */+ if ((streamID == WMI_NOT_MAPPED) && !checkAdHocPsMapping) {+ /* cleanup and exit */+ A_NETBUF_FREE(skb);+ AR6000_STAT_INC(ar, tx_dropped);+ AR6000_STAT_INC(ar, tx_aborted_errors);+ return 0;+ }++ cookie = NULL;++ /* take the lock to protect driver data */+ AR6000_SPIN_LOCK(&ar->arLock, 0);++ do {++ if (checkAdHocPsMapping) {+ streamID = ar6000_ibss_map_epid(skb, dev, &mapNo);+ }++ A_ASSERT(streamID != WMI_NOT_MAPPED);++ /* validate that the endpoint is connected */+ if (arWMIStream2EndpointID(ar,streamID) == 0) {+ AR_DEBUG_PRINTF("Stream %d is NOT mapped!\n",streamID);+ break;+ }+ /* allocate resource for this packet */+ cookie = ar6000_alloc_cookie(ar);++ if (cookie != NULL) {+ /* update counts while the lock is held */+ ar->arTxPending[streamID]++;+ ar->arTotalTxDataPending++;+ }++ } while (FALSE);++ AR6000_SPIN_UNLOCK(&ar->arLock, 0);++ if (cookie != NULL) {+ cookie->arc_bp[0] = (A_UINT32)skb;+ cookie->arc_bp[1] = mapNo;+ SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,+ cookie,+ A_NETBUF_DATA(skb),+ A_NETBUF_LEN(skb),+ arWMIStream2EndpointID(ar,streamID),+ AR6K_DATA_PKT_TAG);++#ifdef DEBUG+ if (debugdriver >= 3) {+ ar6000_dump_skb(skb);+ }+#endif+ /* HTC interface is asynchronous, if this fails, cleanup will happen in+ * the ar6000_tx_complete callback */+ HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt);+ } else {+ /* no packet to send, cleanup */+ A_NETBUF_FREE(skb);+ AR6000_STAT_INC(ar, tx_dropped);+ AR6000_STAT_INC(ar, tx_aborted_errors);+ }++ return 0;+}++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL+static void+tvsub(register struct timeval *out, register struct timeval *in)+{+ if((out->tv_usec -= in->tv_usec) < 0) {+ out->tv_sec--;+ out->tv_usec += 1000000;+ }+ out->tv_sec -= in->tv_sec;+}++void+applyAPTCHeuristics(AR_SOFTC_T *ar)+{+ A_UINT32 duration;+ A_UINT32 numbytes;+ A_UINT32 throughput;+ struct timeval ts;+ A_STATUS status;++ AR6000_SPIN_LOCK(&ar->arLock, 0);++ if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) {+ do_gettimeofday(&ts);+ tvsub(&ts, &aptcTR.samplingTS);+ duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */+ numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;++ if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) {+ /* Initialize the time stamp and byte count */+ aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;+ do_gettimeofday(&aptcTR.samplingTS);++ /* Calculate and decide based on throughput thresholds */+ throughput = ((numbytes * 8) / duration);+ if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) {+ /* Disable Sleep and schedule a timer */+ A_ASSERT(ar->arWmiReady == TRUE);+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);+ status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER);+ AR6000_SPIN_LOCK(&ar->arLock, 0);+ A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);+ aptcTR.timerScheduled = TRUE;+ }+ }+ }++ AR6000_SPIN_UNLOCK(&ar->arLock, 0);+}+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */++static void ar6000_tx_queue_full(void *Context, HTC_ENDPOINT_ID Endpoint)+{+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;+++ if (Endpoint == arWMIStream2EndpointID(ar,WMI_CONTROL_PRI)) {+ if (!bypasswmi) {+ /* under normal WMI if this is getting full, then something is running rampant+ * the host should not be exhausting the WMI queue with too many commands+ * the only exception to this is during testing using endpointping */++ AR6000_SPIN_LOCK(&ar->arLock, 0);+ /* set flag to handle subsequent messages */+ ar->arWMIControlEpFull = TRUE;+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);+ AR_DEBUG_PRINTF("WMI Control Endpoint is FULL!!! \n");+ }+ } else {++ AR6000_SPIN_LOCK(&ar->arLock, 0);+ ar->arNetQueueStopped = TRUE;+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);+ /* one of the data endpoints queues is getting full..need to stop network stack+ * the queue will resume in ar6000_tx_complete() */+ netif_stop_queue(ar->arNetDev);+ }+++}+++static void+ar6000_tx_complete(void *Context, HTC_PACKET *pPacket)+{+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;+ void *cookie = (void *)pPacket->pPktContext;+ struct sk_buff *skb = NULL;+ A_UINT32 mapNo = 0;+ A_STATUS status;+ struct ar_cookie * ar_cookie;+ WMI_PRI_STREAM_ID streamID;+ A_BOOL wakeEvent = FALSE;++ status = pPacket->Status;+ ar_cookie = (struct ar_cookie *)cookie;+ skb = (struct sk_buff *)ar_cookie->arc_bp[0];+ streamID = arEndpoint2WMIStreamID(ar,pPacket->Endpoint);+ mapNo = ar_cookie->arc_bp[1];++ A_ASSERT(skb);+ A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(skb));++ if (A_SUCCESS(status)) {+ A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(skb));+ }++ AR_DEBUG2_PRINTF("ar6000_tx_complete skb=0x%x data=0x%x len=0x%x sid=%d ",+ (A_UINT32)skb, (A_UINT32)pPacket->pBuffer,+ pPacket->ActualLength,+ streamID);++ /* lock the driver as we update internal state */+ AR6000_SPIN_LOCK(&ar->arLock, 0);++ ar->arTxPending[streamID]--;++ if ((streamID != WMI_CONTROL_PRI) || bypasswmi) {+ ar->arTotalTxDataPending--;+ }++ if (streamID == WMI_CONTROL_PRI)+ {+ if (ar->arWMIControlEpFull) {+ /* since this packet completed, the WMI EP is no longer full */+ ar->arWMIControlEpFull = FALSE;+ }++ if (ar->arTxPending[streamID] == 0) {+ wakeEvent = TRUE;+ }+ }++ if (A_FAILED(status)) {+ AR_DEBUG_PRINTF("%s() -TX ERROR, status: 0x%x\n", __func__,+ status);+ AR6000_STAT_INC(ar, tx_errors);+ } else {+ AR_DEBUG2_PRINTF("OK\n");+ AR6000_STAT_INC(ar, tx_packets);+ ar->arNetStats.tx_bytes += A_NETBUF_LEN(skb);+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL+ aptcTR.bytesTransmitted += a_netbuf_to_len(skb);+ applyAPTCHeuristics(ar);+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */+ }++ // TODO this needs to be looked at+ if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable+ && (streamID != WMI_CONTROL_PRI) && mapNo)+ {+ mapNo --;+ ar->arNodeMap[mapNo].txPending --;++ if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) {+ A_UINT32 i;+ for (i = ar->arNodeNum; i > 0; i --) {+ if (!ar->arNodeMap[i - 1].txPending) {+ A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping));+ ar->arNodeNum --;+ } else {+ break;+ }+ }+ }+ }++ /* Freeing a cookie should not be contingent on either of */+ /* these flags, just if we have a cookie or not. */+ /* Can we even get here without a cookie? Fix later. */+ if (ar->arWmiReady == TRUE || (bypasswmi))+ {+ ar6000_free_cookie(ar, cookie);+ }++ if (ar->arNetQueueStopped) {+ ar->arNetQueueStopped = FALSE;+ }++ AR6000_SPIN_UNLOCK(&ar->arLock, 0);++ /* lock is released, we can freely call other kernel APIs */++ /* this indirectly frees the HTC_PACKET */+ A_NETBUF_FREE(skb);++ if ((ar->arConnected == TRUE) || (bypasswmi)) {+ if (status != A_ECANCELED) {+ /* don't wake the queue if we are flushing, other wise it will just+ * keep queueing packets, which will keep failing */+ netif_wake_queue(ar->arNetDev);+ }+ }++ if (wakeEvent) {+ wake_up(&arEvent);+ }++}++/*+ * Receive event handler. This is called by HTC when a packet is received+ */+int pktcount;+static void+ar6000_rx(void *Context, HTC_PACKET *pPacket)+{+ AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;+ struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext;+ int minHdrLen;+ A_STATUS status = pPacket->Status;+ WMI_PRI_STREAM_ID streamID = arEndpoint2WMIStreamID(ar,pPacket->Endpoint);+ HTC_ENDPOINT_ID ept = pPacket->Endpoint;++ A_ASSERT((status != A_OK) || (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN)));++ AR_DEBUG2_PRINTF("ar6000_rx ar=0x%x sid=%d, skb=0x%x, data=0x%x, len=0x%x ",+ (A_UINT32)ar, streamID, (A_UINT32)skb, (A_UINT32)pPacket->pBuffer,+ pPacket->ActualLength);+ if (status != A_OK) {+ AR_DEBUG2_PRINTF("ERR\n");+ } else {+ AR_DEBUG2_PRINTF("OK\n");+ }++ /* take lock to protect buffer counts+ * and adaptive power throughput state */+ AR6000_SPIN_LOCK(&ar->arLock, 0);++ ar->arRxBuffers[streamID]--;++ if (A_SUCCESS(status)) {+ AR6000_STAT_INC(ar, rx_packets);+ ar->arNetStats.rx_bytes += pPacket->ActualLength;+#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL+ aptcTR.bytesReceived += a_netbuf_to_len(skb);+ applyAPTCHeuristics(ar);+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */++ A_NETBUF_PUT(skb, pPacket->ActualLength + HTC_HEADER_LEN);+ A_NETBUF_PULL(skb, HTC_HEADER_LEN);++#ifdef DEBUG+ if (debugdriver >= 2) {+ ar6000_dump_skb(skb);+ }+#endif /* DEBUG */+ }++ AR6000_SPIN_UNLOCK(&ar->arLock, 0);++ if (status != A_OK) {+ AR6000_STAT_INC(ar, rx_errors);+ A_NETBUF_FREE(skb);+ } else if (ar->arWmiEnabled == TRUE) {+ if (streamID == WMI_CONTROL_PRI) {+ /*+ * this is a wmi control msg+ */+ wmi_control_rx(ar->arWmi, skb);+ } else {+ WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);+ if (WMI_DATA_HDR_IS_MSG_TYPE(dhdr, CNTL_MSGTYPE)) {+ /*+ * this is a wmi control msg+ */+ /* strip off WMI hdr */+ wmi_data_hdr_remove(ar->arWmi, skb);+ wmi_control_rx(ar->arWmi, skb);+ } else {+ /*+ * this is a wmi data packet+ */+ minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) ++ sizeof(ATH_LLC_SNAP_HDR);++ if ((pPacket->ActualLength < minHdrLen) ||+ (pPacket->ActualLength > AR6000_BUFFER_SIZE))+ {+ /*+ * packet is too short or too long+ */+ AR_DEBUG_PRINTF("TOO SHORT or TOO LONG\n");+ AR6000_STAT_INC(ar, rx_errors);+ AR6000_STAT_INC(ar, rx_length_errors);+ A_NETBUF_FREE(skb);+ } else {+ if (ar->arWmmEnabled) {+ wmi_implicit_create_pstream(ar->arWmi, skb,+ DNLINK_TRAFFIC, UNDEFINED_PRI);+ }+#if 0+ /* Access RSSI values here */+ AR_DEBUG_PRINTF("RSSI %d\n",+ ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi);+#endif+ wmi_data_hdr_remove(ar->arWmi, skb);+ wmi_dot3_2_dix(ar->arWmi, skb);++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)+ /*+ * extra push and memcpy, for eth_type_trans() of 2.4 kernel+ * will pull out hard_header_len bytes of the skb.+ */+ A_NETBUF_PUSH(skb, sizeof(WMI_DATA_HDR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -