/*------------------------------------------------------------------------ * ethInterrupt - decode and handle interrupt from an Ethernet device *------------------------------------------------------------------------ */ interrupt ethInterrupt(void) { struct ether *ethptr; /* ptr to control block */ struct ag71xx *nicptr; /* ptr to device CSRs */ uint32 status; uint32 mask; /* Initialize structure pointers */ ethptr = ðertab[0]; /* default physical Ethernet */ if (!ethptr) { return; } nicptr = ethptr->csr; if (!nicptr) { return; } /* Obtain status bits from device */ mask = nicptr->interruptMask; status = nicptr->interruptStatus & mask; /* Record status in ether struct */ ethptr->interruptStatus = status; if (status == 0) { return; } sched_cntl(DEFER_START); if (status & IRQ_TX_PKTSENT) { /* handle transmitter interrupt */ ethptr->txirq++; txPackets(ethptr, nicptr); } if (status & IRQ_RX_PKTRECV) { /* handle receiver interrupt */ ethptr->rxirq++; rxPackets(ethptr, nicptr); } /* Handle errors (transmit or receive overflow) */ if (status & IRQ_RX_OVERFLOW) { /* Clear interrupt and restart processing */ nicptr->rxStatus = RX_STAT_OVERFLOW; nicptr->rxControl = RX_CTRL_RXE; ethptr->errors++; } if ((status & IRQ_TX_UNDERFLOW) || (status & IRQ_TX_BUSERR) || (status & IRQ_RX_BUSERR)) { panic("Catastrophic Ethernet error"); } sched_cntl(DEFER_STOP); return; }
static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, jstring path, jint limitUid) { ScopedUtfChars path8(env, path); if (path8.c_str() == NULL) { return -1; } FILE *fp = fopen(path8.c_str(), "r"); if (fp == NULL) { return -1; } Vector<stats_line> lines; int lastIdx = 1; char buffer[384]; while (fgets(buffer, sizeof(buffer), fp) != NULL) { stats_line s; int64_t rawTag; if (sscanf(buffer, "%d %31s 0x%llx %u %u %llu %llu %llu %llu", &s.idx, s.iface, &rawTag, &s.uid, &s.set, &s.rxBytes, &s.rxPackets, &s.txBytes, &s.txPackets) == 9) { if (s.idx != lastIdx + 1) { ALOGE("inconsistent idx=%d after lastIdx=%d", s.idx, lastIdx); return -1; } lastIdx = s.idx; s.tag = rawTag >> 32; lines.push_back(s); } } if (fclose(fp) != 0) { return -1; } int size = lines.size(); ScopedLocalRef<jobjectArray> iface(env, env->NewObjectArray(size, gStringClass, NULL)); if (iface.get() == NULL) return -1; ScopedIntArrayRW uid(env, env->NewIntArray(size)); if (uid.get() == NULL) return -1; ScopedIntArrayRW set(env, env->NewIntArray(size)); if (set.get() == NULL) return -1; ScopedIntArrayRW tag(env, env->NewIntArray(size)); if (tag.get() == NULL) return -1; ScopedLongArrayRW rxBytes(env, env->NewLongArray(size)); if (rxBytes.get() == NULL) return -1; ScopedLongArrayRW rxPackets(env, env->NewLongArray(size)); if (rxPackets.get() == NULL) return -1; ScopedLongArrayRW txBytes(env, env->NewLongArray(size)); if (txBytes.get() == NULL) return -1; ScopedLongArrayRW txPackets(env, env->NewLongArray(size)); if (txPackets.get() == NULL) return -1; ScopedLongArrayRW operations(env, env->NewLongArray(size)); if (operations.get() == NULL) return -1; for (int i = 0; i < size; i++) { ScopedLocalRef<jstring> ifaceString(env, env->NewStringUTF(lines[i].iface)); env->SetObjectArrayElement(iface.get(), i, ifaceString.get()); uid[i] = lines[i].uid; set[i] = lines[i].set; tag[i] = lines[i].tag; rxBytes[i] = lines[i].rxBytes; rxPackets[i] = lines[i].rxPackets; txBytes[i] = lines[i].txBytes; txPackets[i] = lines[i].txPackets; } env->SetIntField(stats, gNetworkStatsClassInfo.size, size); env->SetObjectField(stats, gNetworkStatsClassInfo.iface, iface.get()); env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray()); env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray()); return 0; }
/** * Decode and handle hardware interrupt request from ethernet device. */ interrupt etherInterrupt(void) { // int ethnum; struct ether *ethptr; struct ag71xx *nicptr; uint status, mask; /* Initialize structure pointers */ ethptr = ðertab[0]; /* default physical ethernet for WRT54GL */ if (!ethptr) { return; } nicptr = ethptr->csr; if (!nicptr) { return; } mask = nicptr->interruptMask; status = nicptr->interruptStatus & mask; /* remember interrupt status in ether struct */ ethptr->interruptStatus = status; if (!status) { return; } resdefer = 1; /* defer rescheduling */ if (status & IRQ_TX_PKTSENT) { ethptr->txirq++; txPackets(ethptr, nicptr); } if (status & IRQ_RX_PKTRECV) { ethptr->rxirq++; rxPackets(ethptr, nicptr); } if (status & IRQ_RX_OVERFLOW) { // Clear interrupt, restart processing. nicptr->rxStatus = RX_STAT_OVERFLOW; nicptr->rxControl = RX_CTRL_RXE; ethptr->errors++; } if ((status & IRQ_TX_UNDERFLOW) || (status & IRQ_TX_BUSERR) || (status & IRQ_RX_BUSERR)) { kprintf("Ethernet ERROR 0x%08X\r\n", status); while (1) ; ethptr->errors++; // etherClose(ethptr->dev); } if (--resdefer > 0) { resdefer = 0; resched(); } return; }