📄 atheros_2_0_function.patch
字号:
+ A_UINT32 numargs;+ A_UINT32 length;+ A_UINT32 fraglen;++ count = fraglen = 0;+ buffer = (A_INT32 *)datap;+ length = (limit >> 2);++ if (len <= limit) {+ fraglen = len;+ } else {+ while (count < length) {+ numargs = DBGLOG_GET_NUMARGS(buffer[count]);+ fraglen = (count << 2);+ count += numargs + 1;+ }+ }++ return fraglen;+}++void+dbglog_parse_debug_logs(A_INT8 *datap, A_UINT32 len)+{+ A_INT32 *buffer;+ A_UINT32 count;+ A_UINT32 timestamp;+ A_UINT32 debugid;+ A_UINT32 moduleid;+ A_UINT32 numargs;+ A_UINT32 length;++ count = 0;+ buffer = (A_INT32 *)datap;+ length = (len >> 2);+ while (count < length) {+ debugid = DBGLOG_GET_DBGID(buffer[count]);+ moduleid = DBGLOG_GET_MODULEID(buffer[count]);+ numargs = DBGLOG_GET_NUMARGS(buffer[count]);+ timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]);+ switch (numargs) {+ case 0:+ AR_DEBUG_PRINTF("%d %d (%d)\n", moduleid, debugid, timestamp);+ break;++ case 1:+ AR_DEBUG_PRINTF("%d %d (%d): 0x%x\n", moduleid, debugid,+ timestamp, buffer[count+1]);+ break;++ case 2:+ AR_DEBUG_PRINTF("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid,+ timestamp, buffer[count+1], buffer[count+2]);+ break;++ default:+ AR_DEBUG_PRINTF("Invalid args: %d\n", numargs);+ }+ count += numargs + 1;+ }+}++int+ar6000_dbglog_get_debug_logs(AR_SOFTC_T *ar)+{+ struct dbglog_hdr_s debug_hdr;+ struct dbglog_buf_s debug_buf;+ A_UINT32 address;+ A_UINT32 length;+ A_UINT32 dropped;+ A_UINT32 firstbuf;+ A_UINT32 debug_hdr_ptr;++ if (!ar->dbglog_init_done) return A_ERROR;+++ AR6000_SPIN_LOCK(&ar->arLock, 0);++ if (ar->dbgLogFetchInProgress) {+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);+ return A_EBUSY;+ }++ /* block out others */+ ar->dbgLogFetchInProgress = TRUE;++ AR6000_SPIN_UNLOCK(&ar->arLock, 0);++ debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar);+ printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr);++ /* Get the contents of the ring buffer */+ if (debug_hdr_ptr) {+ address = debug_hdr_ptr;+ length = sizeof(struct dbglog_hdr_s);+ ar6000_ReadDataDiag(ar->arHifDevice, address,+ (A_UCHAR *)&debug_hdr, length);+ address = (A_UINT32)debug_hdr.dbuf;+ firstbuf = address;+ dropped = debug_hdr.dropped;+ length = sizeof(struct dbglog_buf_s);+ ar6000_ReadDataDiag(ar->arHifDevice, address,+ (A_UCHAR *)&debug_buf, length);++ do {+ address = (A_UINT32)debug_buf.buffer;+ length = debug_buf.length;+ if ((length) && (debug_buf.length <= debug_buf.bufsize)) {+ /* Rewind the index if it is about to overrun the buffer */+ if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) {+ ar->log_cnt = 0;+ }+ if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,+ (A_UCHAR *)&ar->log_buffer[ar->log_cnt], length))+ {+ break;+ }+ ar6000_dbglog_event(ar, dropped, &ar->log_buffer[ar->log_cnt], length);+ ar->log_cnt += length;+ } else {+ AR_DEBUG_PRINTF("Length: %d (Total size: %d)\n",+ debug_buf.length, debug_buf.bufsize);+ }++ address = (A_UINT32)debug_buf.next;+ length = sizeof(struct dbglog_buf_s);+ if(A_OK != ar6000_ReadDataDiag(ar->arHifDevice, address,+ (A_UCHAR *)&debug_buf, length))+ {+ break;+ }++ } while (address != firstbuf);+ }++ ar->dbgLogFetchInProgress = FALSE;++ return A_OK;+}++void+ar6000_dbglog_event(AR_SOFTC_T *ar, A_UINT32 dropped,+ A_INT8 *buffer, A_UINT32 length)+{+#ifdef REPORT_DEBUG_LOGS_TO_APP+ #define MAX_WIRELESS_EVENT_SIZE 252+ /*+ * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages.+ * There seems to be a limitation on the length of message that could be+ * transmitted to the user app via this mechanism.+ */+ A_UINT32 send, sent;++ sent = 0;+ send = dbglog_get_debug_fragment(&buffer[sent], length - sent,+ MAX_WIRELESS_EVENT_SIZE);+ while (send) {+ ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, &buffer[sent], send);+ sent += send;+ send = dbglog_get_debug_fragment(&buffer[sent], length - sent,+ MAX_WIRELESS_EVENT_SIZE);+ }+#else+ AR_DEBUG_PRINTF("Dropped logs: 0x%x\nDebug info length: %d\n",+ dropped, length);++ /* Interpret the debug logs */+ dbglog_parse_debug_logs(buffer, length);+#endif /* REPORT_DEBUG_LOGS_TO_APP */+}++++static int __init+ar6000_init_module(void)+{+ static int probed = 0;+ A_STATUS status;+ HTC_INIT_INFO initInfo;++ A_MEMZERO(&initInfo,sizeof(initInfo));+ initInfo.AddInstance = ar6000_avail_ev;+ initInfo.DeleteInstance = ar6000_unavail_ev;+ initInfo.TargetFailure = ar6000_target_failure;+++#ifdef DEBUG+ /* Set the debug flags if specified at load time */+ if(debugflags != 0)+ {+ g_dbg_flags = debugflags;+ }+#endif++ if (probed) {+ return -ENODEV;+ }+ probed++;++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL+ memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */++#ifdef CONFIG_HOST_GPIO_SUPPORT+ ar6000_gpio_init();+#endif /* CONFIG_HOST_GPIO_SUPPORT */++ status = HTCInit(&initInfo);+ if(status != A_OK)+ return -ENODEV;++ return 0;+}++static void __exit+ar6000_cleanup_module(void)+{+ int i = 0;+ struct net_device *ar6000_netdev;++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL+ /* Delete the Adaptive Power Control timer */+ if (timer_pending(&aptcTimer)) {+ del_timer_sync(&aptcTimer);+ }+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */++ for (i=0; i < MAX_AR6000; i++) {+ if (ar6000_devices[i] != NULL) {+ ar6000_netdev = ar6000_devices[i];+ ar6000_devices[i] = NULL;+ ar6000_destroy(ar6000_netdev, 1);+ }+ }++ /* shutting down HTC will cause the HIF layer to detach from the+ * underlying bus driver which will cause the subsequent deletion of+ * all HIF and HTC instances */+ HTCShutDown();++ AR_DEBUG_PRINTF("ar6000_cleanup: success\n");+}++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL+void+aptcTimerHandler(unsigned long arg)+{+ A_UINT32 numbytes;+ A_UINT32 throughput;+ AR_SOFTC_T *ar;+ A_STATUS status;++ ar = (AR_SOFTC_T *)arg;+ A_ASSERT(ar != NULL);+ A_ASSERT(!timer_pending(&aptcTimer));++ AR6000_SPIN_LOCK(&ar->arLock, 0);++ /* Get the number of bytes transferred */+ numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived;+ aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0;++ /* Calculate and decide based on throughput thresholds */+ throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */+ if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) {+ /* Enable Sleep and delete the timer */+ A_ASSERT(ar->arWmiReady == TRUE);+ AR6000_SPIN_UNLOCK(&ar->arLock, 0);+ status = wmi_powermode_cmd(ar->arWmi, REC_POWER);+ AR6000_SPIN_LOCK(&ar->arLock, 0);+ A_ASSERT(status == A_OK);+ aptcTR.timerScheduled = FALSE;+ } else {+ A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0);+ }++ AR6000_SPIN_UNLOCK(&ar->arLock, 0);+}+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */++++/* set HTC block size, assume BMI is already initialized */+A_STATUS ar6000_SetHTCBlockSize(AR_SOFTC_T *ar)+{+ A_STATUS status;+ A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX];++ do {+ /* get the block sizes */+ status = HIFConfigureDevice(ar->arHifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,+ blocksizes, sizeof(blocksizes));++ if (A_FAILED(status)) {+ AR_DEBUG_PRINTF("Failed to get block size info from HIF layer...\n");+ break;+ }+ /* note: we actually get the block size for mailbox 1, for SDIO the block+ * size on mailbox 0 is artificially set to 1 */+ /* must be a power of 2 */+ A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0);++ /* set the host interest area for the block size */+ status = BMIWriteMemory(ar->arHifDevice,+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_mbox_io_block_sz),+ (A_UCHAR *)&blocksizes[1],+ 4);++ if (A_FAILED(status)) {+ AR_DEBUG_PRINTF("BMIWriteMemory for IO block size failed \n");+ break;+ }++ AR_DEBUG_PRINTF("Block Size Set: %d (target address:0x%X)\n",+ blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(ar, hi_mbox_io_block_sz));++ /* set the host interest area for the mbox ISR yield limit */+ status = BMIWriteMemory(ar->arHifDevice,+ HOST_INTEREST_ITEM_ADDRESS(ar, hi_mbox_isr_yield_limit),+ (A_UCHAR *)&mbox_yield_limit,+ 4);++ if (A_FAILED(status)) {+ AR_DEBUG_PRINTF("BMIWriteMemory for yield limit failed \n");+ break;+ }++ } while (FALSE);++ return status;+}++/*+ * HTC Event handlers+ */+static void+ar6000_avail_ev(HTC_HANDLE HTCHandle)+{+ int i;+ struct net_device *dev;+ AR_SOFTC_T *ar;+ int device_index = 0;++ AR_DEBUG_PRINTF("ar6000_available\n");++ for (i=0; i < MAX_AR6000; i++) {+ if (ar6000_devices[i] == NULL) {+ break;+ }+ }++ if (i == MAX_AR6000) {+ AR_DEBUG_PRINTF("ar6000_available: max devices reached\n");+ return;+ }++ /* Save this. It gives a bit better readability especially since */+ /* we use another local "i" variable below. */+ device_index = i;++ A_ASSERT(HTCHandle != NULL);++ dev = alloc_etherdev(sizeof(AR_SOFTC_T));+ if (dev == NULL) {+ AR_DEBUG_PRINTF("ar6000_available: can't alloc etherdev\n");+ return;+ }++ ether_setup(dev);++ if (dev->priv == NULL) {+ printk(KERN_CRIT "ar6000_available: Could not allocate memory\n");+ return;+ }++ A_MEMZERO(dev->priv, sizeof(AR_SOFTC_T));++ ar = (AR_SOFTC_T *)dev->priv;+ ar->arNetDev = dev;+ ar->arHtcTarget = HTCHandle;+ ar->arHifDevice = HTCGetHifDevice(HTCHandle);+ ar->arWlanState = WLAN_ENABLED;+ ar->arDeviceIndex = device_index;++ A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev);+ ar->arHBChallengeResp.seqNum = 0;+ ar->arHBChallengeResp.outstanding = FALSE;+ ar->arHBChallengeResp.missCnt = 0;+ ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT;+ ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT;++ ar6000_init_control_info(ar);+ init_waitqueue_head(&arEvent);+ sema_init(&ar->arSem, 1);++#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL+ A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar);+#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */++ /*+ * If requested, perform some magic which requires no cooperation from+ * the Target. It causes the Target to ignore flash and execute to the+ * OS from ROM.+ *+ * This is intended to support recovery from a corrupted flash on Targets+ * that support flash.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -