Exemplo n.º 1
0
IOReturn HoRNDIS::enable(IONetworkInterface *netif) {
	IONetworkMedium	*medium;
	IOReturn rtn = kIOReturnSuccess;

	if (fNetifEnabled) {
		LOG(V_ERROR, "already enabled?");
		return kIOReturnSuccess;
	}
	
	if (!allocateResources())
		return kIOReturnNoMemory;
	
	if (!fMediumDict)
		if (!createMediumTables()) {
			rtn = kIOReturnNoMemory;
			goto bailout;
		}
	setCurrentMedium(IONetworkMedium::medium(kIOMediumEthernetAuto, 480 * 1000000));
	
	/* Kick off the first read. */
	inbuf.comp.target = this;
	inbuf.comp.action = dataReadComplete;
	inbuf.comp.parameter = NULL;
	
	rtn = fInPipe->Read(inbuf.mdp, &inbuf.comp, NULL);
	if (rtn != kIOReturnSuccess)
		goto bailout;

	/* Tell the world that the link is up... */
	medium = IONetworkMedium::getMediumWithType(fMediumDict, kIOMediumEthernetAuto);
	setLinkStatus(kIONetworkLinkActive | kIONetworkLinkValid, medium, 480 * 1000000);
	
	/* ... and then listen for packets! */
	getOutputQueue()->setCapacity(TRANSMIT_QUEUE_SIZE);
	getOutputQueue()->start();
	LOG(V_DEBUG, "txqueue started");
	
	/* Tell the other end to start transmitting. */
	if (!rndisSetPacketFilter(RNDIS_DEFAULT_FILTER))
		goto bailout;
	
	/* Now we can say we're alive. */
	fNetifEnabled = true;
	
	return kIOReturnSuccess;
	
bailout:
	LOG(V_ERROR, "setting up the pipes failed");
	releaseResources();
	return rtn;
}
Exemplo n.º 2
0
bool
MolEnet::start( IOService * provider )
{
	IOPhysicalAddress tx_phys, rx_phys;
	IOPhysicalAddress tx_of_phys, rx_of_phys;
	int i, result;

	if( !super::start(provider) )
		return false;

	if( OSI_Enet2Open() ) {
		is_open = 1;
		return false;
	}
	
	//transmitQueue = OSDynamicCast( IOGatedOutputQueue, getOutputQueue() );
	transmitQueue = OSDynamicCast( IOBasicOutputQueue, getOutputQueue() );
	if( !transmitQueue ) {
		printm("MolEnet: output queue initialization failed\n");
		return false;
	}
	transmitQueue->retain();

	// Allocate a IOMbufBigMemoryCursor instance. Currently, the maximum
	// number of segments is set to 2. The maximum length for each segment
	// is set to the maximum ethernet frame size (plus padding).

	txMBufCursor = IOMbufBigMemoryCursor::withSpecification( NETWORK_BUFSIZE, 2 );
	rxMBufCursor = IOMbufBigMemoryCursor::withSpecification( NETWORK_BUFSIZE, 2 );
	if( !txMBufCursor || !rxMBufCursor ) {
		printm("MolEnet: IOMbufBigMemoryCursor allocation failure\n");
		return false;
	}

	// Get a reference to the IOWorkLoop in our superclass.
	IOWorkLoop * myWorkLoop = getWorkLoop();
	assert(myWorkLoop);

	// Allocate a IOInterruptEventSources.
	_irq = IOInterruptEventSource::interruptEventSource( this, 
				     (IOInterruptEventAction)&MolEnet::rxIRQ, provider, 0);
	
        if( !_irq || (myWorkLoop->addEventSource(_irq) != kIOReturnSuccess )) {
		printm("MolEnet: _irq init failure\n");
		return false;
	}

	// Allocate the ring descriptors
	rx_ring = (enet2_ring_t*)IOMallocContiguous( 2 * RX_NUM_EL * sizeof(enet2_ring_t), 
						     sizeof(enet2_ring_t), &rx_phys );
	tx_ring = (enet2_ring_t*)IOMallocContiguous( 2 * TX_NUM_EL * sizeof(enet2_ring_t),
						     sizeof(enet2_ring_t), &tx_phys );		
	if( !rx_ring || !tx_ring )
		return false;

	rx_of_ring = rx_ring + RX_NUM_EL;
	tx_of_ring = tx_ring + TX_NUM_EL;
	rx_of_phys = rx_phys + sizeof(enet2_ring_t) * RX_NUM_EL;
	tx_of_phys = tx_phys + sizeof(enet2_ring_t) * TX_NUM_EL;

	// Allocate receive buffers
	for( i=0; i<RX_NUM_EL; i++ ) {
		if( !(rxMBuf[i]=allocatePacket( NETWORK_BUFSIZE )) ) {
			printm("MolEnet: packet allocation failed\n");
			return false;
		}
		// reserve 2 bytes before the actual packet
		rxMBuf[i]->m_data += 2;
		rxMBuf[i]->m_len -= 2;
	}

	OSI_Enet2Cntrl( kEnet2Reset );
	result = OSI_Enet2RingSetup( kEnet2SetupRXRing, rx_phys, RX_NUM_EL )
		|| OSI_Enet2RingSetup( kEnet2SetupTXRing, tx_phys, TX_NUM_EL )
		|| OSI_Enet2RingSetup( kEnet2SetupRXOverflowRing, rx_of_phys, RX_NUM_EL )
		|| OSI_Enet2RingSetup( kEnet2SetupTXOverflowRing, tx_of_phys, TX_NUM_EL );
	if( result )
		return false;

	if( !resetAndEnable(false) )
		return false;

	// Create a table of supported media types.
	if( !createMediumTables() )
		return false;

	// Attach an IOEthernetInterface client.
	if( !attachInterface( (IONetworkInterface**)&networkInterface, false ) )
		return false;

	// Ready to service interface requests.
	networkInterface->registerService();

	printm("Ethernet driver 1.1\n");
	return true;
}