bool RTL8139::disableAdapter( UInt32 currentLevel ) { bool success = false; ELG( 0, currentLevel, 'disA', "RTL8139::disableAdapter" ); DEBUG_LOG( "disableAdapter() ===>\n" ); DEBUG_LOG( "disable currentLevel %ld\n", currentLevel ); switch ( currentLevel ) { case kActivationLevel1: timerSrc->cancelTimeout(); // Stop the timer event source. initAdapter( kResetChip ); // Reset the hardware engine. phySetMedium( MEDIUM_INDEX_NONE ); // Power down the PHY if ( pciNub ) pciNub->close( this ); // Close our provider. success = true; break; case kActivationLevel2: disableHardwareInterrupts(); // KDP doesn't use interrupts. workLoop->disableAllInterrupts(); // Stop the transmit queue. outputPacket() will not get called // after this. KDP calls sendPacket() to send a packet in polled // mode and that is unaffected by the state of the output queue. fTransmitQueue->stop(); fTransmitQueue->flush(); setLinkStatus( kIONetworkLinkValid ); // Valid sans kIONetworkLinkActive success = true; break; }/* end SWITCH */ if ( false == success ) IOLog( "disable currentLevel %u failed\n", (unsigned int)currentLevel ); DEBUG_LOG( "disableAdapter() <===\n" ); return success; }/* end disableAdapter */
bool RTL8139::start( IOService *provider ) { OSObject *builtinProperty; bool success = false; ELG( IOThreadSelf(), provider, 'Strt', "RTL8139::start - this, provider." ); DEBUG_LOG( "start() ===>\n" ); do { if ( false == super::start( provider ) ) // Start our superclass first break; // Save a reference to our provider. pciNub = OSDynamicCast( IOPCIDevice, provider ); if ( 0 == pciNub ) break; pciNub->retain(); // Retain provider, released in free(). if ( false == pciNub->open( this ) ) // Open our provider. break; fBuiltin = false; builtinProperty = provider->getProperty( "built-in" ); if ( builtinProperty ) { fBuiltin = true; ELG( 0, 0, 'b-in', "RTL8139::start - found built-in property." ); } if ( false == initEventSources( provider ) ) break; // Allocate memory for descriptors. This function will leak memory // if called more than once. So don't do it. if ( false == allocateDescriptorMemory() ) break; // Get the virtual address mapping of CSR registers located at // Base Address Range 0 (0x10). csrMap = pciNub->mapDeviceMemoryWithRegister( kIOPCIConfigBaseAddress1 ); if ( 0 == csrMap ) break; csrBase = (volatile void*)csrMap->getVirtualAddress(); // Init PCI config space: if ( false == initPCIConfigSpace( pciNub ) ) break; // Reset chip to bring it to a known state. if ( initAdapter( kResetChip ) == false ) { IOLog( "%s: initAdapter() failed\n", getName() ); break; } registerEEPROM(); // Publish our media capabilities: phyProbeMediaCapability(); if ( false == publishMediumDictionary( mediumDict ) ) break; success = true; } while ( false ); // Close our provider, it will be re-opened on demand when // our enable() is called by a client. if ( pciNub ) pciNub->close( this ); do { if ( false == success ) break; success = false; // Allocate and attach an IOEthernetInterface instance. if ( false == attachInterface( (IONetworkInterface**)&netif, false) ) break; // Optional: this driver supports kernel debugging. attachDebuggerClient( &debugger ); // Trigger matching for clients of netif. netif->registerService(); success = true; } while ( false ); DEBUG_LOG( "start() <===\n" ); return success; }/* end start */
bool RTL8139::enableAdapter( UInt32 level ) { UInt16 isr; bool success = false; ELG( 0, level, 'enbA', "RTL8139::enableAdapter - level" ); DEBUG_LOG( "enableAdapter() ===>\n" ); DEBUG_LOG( "enable level %ld\n", level); switch ( level ) { case kActivationLevel1: // Open our provider (IOPCIDevice): if ( (0 == pciNub) || (false == pciNub->open( this )) ) break; // Perform a full initialization sequence: if ( initAdapter( kFullInitialization ) != true ) break; // Program the physical layer / transceiver: if ( selectMedium( getSelectedMedium() ) != kIOReturnSuccess ) break; // Start the periodic timer: timerSrc->setTimeoutMS( kWatchdogTimerPeriod ); // ??? do this in Level 2??? // Unless we wait and ack PUN/LinkChg interrupts, the receiver // will not work. This creates a problem when DB_HALT debug // flag is set, since we will break into the debugger right // away after this function returns. But we won't be able to // attach since the receiver is deaf. I have no idea why this // workaround (discovered through experimentation) is needed. for ( int i = 0; i < 100; i++ ) { isr = csrRead16( RTL_ISR ); if ( isr & R_ISR_PUN ) { csrWrite16( RTL_ISR, R_ISR_PUN ); ELG( i, isr, 'enbA', "RTL8139::enableAdapter - cleared PUN interrupt" ); DEBUG_LOG( "cleared PUN interrupt %x in %d\n", isr, i ); break; } IOSleep( 10 ); }/* end FOR */ success = true; break; case kActivationLevel2: workLoop->enableAllInterrupts(); success = true; break; }/* end SWITCH */ if ( false == success ) IOLog( "enable level %u failed\n", (unsigned int)level ); DEBUG_LOG( "enableAdapter() <===\n" ); return success; }/* end enableAdapter */
/** @main Application entry-point. */ int main(int argc, char* argv[]) { int c; strcpy(initcmd, DEF_CMD_INIT); while (true) { static struct option long_options[] = { {"adapter", required_argument, 0, 'a'}, {"remote-adapter", required_argument, 0, 'b'}, {"close", no_argument, 0, 'c'}, {"blink-on-receive", no_argument, 0, 'k'}, {"log-packets", no_argument, 0, 'p'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long (argc, argv, "a:b:ckpvV?", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 'a': tc_eth_adapter = optarg; break; case 'b': tc_eth_remoteAdapter = optarg; break; case 'c': exitReason = 0; break; case 'p': dbg_logPackets = true; break; case 'v': dbg_debugOut = true; break; case 'k': dbg_blinkOnReceive = true; break; case 'V': printf("Asus-TCCI (TrendChip Command Interpreter), version %s, build %s\n", VERSION, VERSION_BUILD); printf(" by %s. Sources and updates: %s\n", AUTHOR, URL); return EC_NORMAL; case 'h': /* getopt_long already printed an error message. */ printf("usage: %s -V|--version\n", argv[0]); printf("or: %s [-a|--adapter=\"%s\"] [-b|--remote-adapter=\"%s\"] [-c|--close] [-p|--log-packets] [-v|--verbose] [-k|--blink-on-receive] [<%s>]\n", argv[0], tc_eth_adapter, tc_eth_remoteAdapter, initcmd); return EC_NORMAL; default: return 9; } } /* Print any remaining command line arguments (not options). */ if (optind < argc) { initcmd[0] = '\0'; // Clear string while (optind < argc) strncat(initcmd, argv[optind++], sizeof(initcmd)); } debugf("-- Starting...\n"); // Initialize in-socket tc_eth_sockIn = socket(AF_INET, SOCK_DGRAM, 0); if (tc_eth_sockIn < 0) { errorf("-- E: Input socket init failed!\n"); return EC_APIFAIL; } /*debugf("-- dbg_debugOut = %d, dbg_logPackets = %d, tc_eth_adapter = \"%s\", initcmd = \"%s\"\n", dbg_debugOut, dbg_logPackets, tc_eth_adapter, initcmd);*/ // Initialize adapter eth_adapterId = if_nametoindex(tc_eth_adapter); initAdapter(tc_eth_adapter); // Initialize out-socket tc_eth_sockOut = socket(AF_PACKET,SOCK_RAW, htons(ETH_P_ALL)); if (tc_eth_sockOut < 0) { errorf("-- E: Output socket init failed!\n"); return EC_APIFAIL; } // Acquired MACs debugf("Remote (TrendChip) MAC: "); printmac(debugf, tc_eth_remoteMac); debugf("\nLocal (terminal) MAC: "); printmac(debugf, tc_eth_localMac); // Initial command execution debugf("\n-- Phase 2 - Perform init-command (%s)\n", initcmd); if (!tc_exec(initcmd)) return EC_NETFAIL; // Interactive shell char inbuff[TC_CMD_MAX_LEN]; fd_set rfds; struct timeval tv; int retval; while(exitReason < 0) { FD_ZERO(&rfds); FD_SET(0, &rfds); tv.tv_sec = 0; tv.tv_usec = 100000; //100ms retval = select(1, &rfds, NULL, NULL, &tv); if (retval == -1){ perror("-- select(stdin)"); return EC_APIFAIL; } else if (retval){ debugf("-- Gathering input... "); char* cmd = fgets(inbuff, TC_CMD_MAX_LEN, stdin); if (cmd[strlen(cmd)-1] == '\n') cmd[strlen(cmd)-1] = '\0'; // Trim the trailing '\n' char. debugf("Got '%s'\n", cmd); if (cmd[0] == '\0') {} // Do nothing on blank lines. else if (strcmp(cmd, "!q") == 0 || strcmp(cmd, "!quit") == 0) exitReason = EC_NORMAL; else if (strcmp(cmd, "!v") == 0 || strcmp(cmd, "!verbose") == 0) errorf("-- Verbose output is now %s.\n", (dbg_debugOut = !dbg_debugOut) ? "ON" : "OFF"); else if (strcmp(cmd, "!p") == 0 || strcmp(cmd, "!logpackets") == 0) errorf("-- Packet logging is now %s.\n", (dbg_logPackets = !dbg_logPackets) ? "ON" : "OFF"); else if (strcmp(cmd, "!k") == 0 || strcmp(cmd, "!blink") == 0) errorf("-- Blink-on-receive is now %s.\n", (dbg_blinkOnReceive = !dbg_blinkOnReceive) ? "ON" : "OFF"); else if (strcmp(cmd, "!h") == 0 || strcmp(cmd, "!help") == 0) errorf("-- Valid client commands: \n-- ![blin]k, !h[elp], ![log]p[ackets], !q[uit], !v[erbose].\n"); else if (cmd[0] == '!') errorf("-- Unrecognized client command. Please try \"!help\" if you aren't sure.\n"); else if (!tc_exec(cmd)) errorf("-- W: Command request fail!\n"); //exitReason = EC_NETFAIL; // I/O error? } if (!tc_listen()) exitReason = EC_NETFAIL; } if (tc_eth_sockIn) close(tc_eth_sockIn); else debugf("-- W: Input socket already closed!"); if (tc_eth_sockOut) close(tc_eth_sockOut); else debugf("-- W: Output socket already closed!"); debugf("-- Connection closed, reason = %d (-1).\n", exitReason); return exitReason-1; }