Example #1
0
status_t
ASIXDevice::SetPromiscuousMode(bool on)
{
	uint16 rxcontrol = 0;

	status_t result = ReadRXControlRegister(&rxcontrol);
	if (result != B_OK) {
		TRACE_ALWAYS("Error of reading RX Control:%#010x\n", result);
		return result;
	}

	if (on)
		rxcontrol |= RXCTL_PROMISCUOUS;
	else
		rxcontrol &= ~RXCTL_PROMISCUOUS;

	result = WriteRXControlRegister(rxcontrol);

	if (result != B_OK ) {
		TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n",
				rxcontrol, result);
	}

	TRACE_RET(result);
	return result;
}
status_t
AX88772Device::_SetupAX88772B()
{
	// Reload EEPROM
	size_t actualLength = 0;
	status_t result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_GPIOS, GPIO_RSE, 0, 0, 0, &actualLength);

	if (result != B_OK) {
		TRACE_ALWAYS("Error of reloading EEPROM: %#010x\n", result);
		return result;
	}

	result = _WakeupPHY();
	if (result != B_OK)
		return result;

	result = WriteRXControlRegister(0);
	if (result != B_OK) {
		TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", 0, result);
		return result;
	}

	fIPG[0] = 0x15;
	fIPG[1] = 0x16;
	fIPG[2] = 0x1A;

	return B_OK;
}
Example #3
0
status_t
AX88772Device::StartDevice()
{
	size_t actualLength = 0;
	status_t result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_IPGS, 0, 0, sizeof(fIPG), fIPG, &actualLength);

	if(result != B_OK) {
		TRACE_ALWAYS("Error of writing IPGs:%#010x\n", result);
		return result;
	}

	if(actualLength != sizeof(fIPG)) {
		TRACE_ALWAYS("Mismatch of written IPGs data. "
				"%d bytes of %d written.\n", actualLength, sizeof(fIPG));
	}

	uint16 rxcontrol = RXCTL_START | RXCTL_MULTICAST | RXCTL_BROADCAST;
	result = WriteRXControlRegister(rxcontrol);
	if(result != B_OK) {
		TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", rxcontrol, result);
	}

	TRACE_RET(result);
	return result;
}
Example #4
0
status_t
ASIXDevice::StopDevice()
{
	status_t result = WriteRXControlRegister(0);

	if (result != B_OK) {
		TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", 0, result);
	}

	TRACE_RET(result);
	return result;
}
status_t
AX88772Device::StartDevice()
{
	size_t actualLength = 0;
	status_t result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_IPGS, 0, 0, sizeof(fIPG), fIPG, &actualLength);

	if (result != B_OK) {
		TRACE_ALWAYS("Error of writing IPGs:%#010x\n", result);
		return result;
	}

	if (actualLength != sizeof(fIPG)) {
		TRACE_ALWAYS("Mismatch of written IPGs data. "
				"%d bytes of %d written.\n", actualLength, sizeof(fIPG));

	}
	// AX88772B uses different maximum frame burst configuration.
	if (fDeviceInfo.fType == DeviceInfo::AX88772B) {
		result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_RXCONTROL_CFG,
						AX88772B_MFBTable[AX88772B_MFB_2K].ByteCount,
						AX88772B_MFBTable[AX88772B_MFB_2K].Threshold,
						0, 0, &actualLength);

		if (result != B_OK) {
			TRACE_ALWAYS("Error of writing frame burst:%#010x\n", result);
			return result;
		}
	}

	uint16 rxcontrol = RXCTL_START | RXCTL_BROADCAST;
	result = WriteRXControlRegister(rxcontrol);
	if (result != B_OK) {
		TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n",
						rxcontrol, result);
	}

	TRACE_RET(result);
	return result;
}
Example #6
0
status_t
ASIXDevice::ModifyMulticastTable(bool join, ether_address_t* group)
{
	char groupName[6 * 3 + 1] = { 0 };
	sprintf(groupName, "%02x:%02x:%02x:%02x:%02x:%02x",
		group->ebyte[0], group->ebyte[1], group->ebyte[2],
		group->ebyte[3], group->ebyte[4], group->ebyte[5]);
	TRACE("%s multicast group %s\n", join ? "Joining" : "Leaving", groupName);

	uint32 hash = EthernetCRC32(group->ebyte, 6);
	bool isInTable = fMulticastHashes.Find(hash) != fMulticastHashes.End();

	if (isInTable && join)
		return B_OK; // already listed - nothing to do

	if (!isInTable && !join) {
		TRACE_ALWAYS("Cannot leave unlisted multicast group %s!\n", groupName);
		return B_ERROR;
	}

	const size_t hashLength = 8;
	uint8 hashTable[hashLength] = { 0 };

	if (join)
		fMulticastHashes.PushBack(hash);
	else
		fMulticastHashes.Remove(hash);

	for (int32 i = 0; i < fMulticastHashes.Count(); i++) {
		uint32 hash = fMulticastHashes[i] >> 26;
		hashTable[hash / 8] |= 1 << (hash % 8);
	}

	uint16 rxcontrol = 0;

	status_t result = ReadRXControlRegister(&rxcontrol);
	if (result != B_OK) {
		TRACE_ALWAYS("Error of reading RX Control:%#010x\n", result);
		return result;
	}

	if (fMulticastHashes.Count() > 0)
		rxcontrol |= RXCTL_MULTICAST;
	else
		rxcontrol &= ~RXCTL_MULTICAST;

	// write multicast hash table
	size_t actualLength = 0;
	result = gUSBModule->send_request(fDevice,
							USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
							WRITE_MF_ARRAY, 0, 0,
							hashLength, hashTable, &actualLength);
	if (result != B_OK) {
		TRACE_ALWAYS("Error writing hash table in MAR: %#010x.\n", result);
		return result;
	}

	if (actualLength != hashLength)
		TRACE_ALWAYS("Incomplete writing of hash table: %d bytes of %d\n",
						actualLength, hashLength);

	result = WriteRXControlRegister(rxcontrol);
	if (result != B_OK)
		TRACE_ALWAYS("Error writing %#02X to RXC:%#010x.\n", rxcontrol, result);

	return result;
}
status_t
AX88772Device::_SetupAX88772()
{
	size_t actualLength = 0;
	// enable GPIO2 - magic from FreeBSD's if_axe
	uint16 GPIOs = GPIO_OO_2EN | GPIO_IO_2 | GPIO_RSE;
	status_t result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_GPIOS, GPIOs, 0, 0, 0, &actualLength);

	if (result != B_OK) {
		TRACE_ALWAYS("Error of wrinting GPIOs: %#010x\n", result);
		return result;
	}

	// select PHY
	bool useEmbeddedPHY = fMII.PHYID() == PHYIDEmbedded;
	uint16 selectPHY = useEmbeddedPHY ?
					SW_PHY_SEL_STATUS_INT : SW_PHY_SEL_STATUS_EXT;

	result = gUSBModule->send_request(fDevice,
						USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
						WRITE_PHY_SEL, selectPHY, 0, 0, 0, &actualLength);
	snooze(10000);

	TRACE("Selecting %s PHY[%#02x].\n",
						useEmbeddedPHY ? "embedded" : "external", selectPHY);

	if (result != B_OK) {
		TRACE_ALWAYS("Error of selecting PHY:%#010x\n", result);
		return result;
	}

	struct SWReset {
		uint16 		reset;
		bigtime_t	delay;
	} resetCommands[] = {
	// EMBEDDED PHY
		// power down and reset state, pin reset state
		{ SW_RESET_CLR, 60000 },
		// power down/reset state, pin operating state
		{ SW_RESET_PRL | SW_RESET_IPPD, 150000 },
		// power up, reset
		{ SW_RESET_PRL, 0 },
		// power up, operating
		{ SW_RESET_PRL | SW_RESET_IPRL, 0 },
	// EXTERNAL PHY
		// power down/reset state, pin operating state
		{ SW_RESET_PRL | SW_RESET_IPPD, 0 }
	};

	size_t from = useEmbeddedPHY ? 0 : 4;
	size_t to   = useEmbeddedPHY ? 3 : 4;

	for (size_t i = from; i <= to; i++) {
		result = gUSBModule->send_request(fDevice,
					USB_REQTYPE_VENDOR | USB_REQTYPE_DEVICE_OUT,
					WRITE_SOFT_RESET, resetCommands[i].reset,
					0, 0, 0, &actualLength);

		snooze(resetCommands[i].delay);

		if (result != B_OK) {
			TRACE_ALWAYS("Error of SW reset command %d:[%#04x]: %#010x\n",
										i, resetCommands[i].reset, result);
			return result;
		}
	}

	snooze(150000);

	result = WriteRXControlRegister(0);
	if (result != B_OK) {
		TRACE_ALWAYS("Error of writing %#04x RX Control:%#010x\n", 0, result);
		return result;
	}

	return B_OK;
}