Пример #1
0
/*
 * mcs7830_apply_fixup() - identify an adapter and potentially apply fixups
 * @udev:	network device to identify and apply fixups to
 * Return: zero upon success (no errors emitted from here)
 *
 * this routine identifies the network adapter's chip revision, and applies
 * fixups for known issues
 */
static int mcs7830_apply_fixup(struct usb_device *udev)
{
	int rev;
	int i;
	uint8_t thr;

	rev = mcs7830_get_rev(udev);
	debug("%s() rev=%d\n", __func__, rev);

	/*
	 * rev C requires setting the pause threshold (the Linux driver
	 * is inconsistent, the implementation does it for "rev C
	 * exactly", the introductory comment says "rev C and above")
	 */
	if (rev == 2) {
		debug("%s: applying rev C fixup\n", __func__);
		thr = PAUSE_THRESHOLD_DEFAULT;
		for (i = 0; i < 2; i++) {
			(void)mcs7830_write_reg(udev, REG_PAUSE_THRESHOLD,
						sizeof(thr), &thr);
			mdelay(1);
		}
	}

	return 0;
}
Пример #2
0
/*
 * mcs7830_phy_emit_wait() - emit PHY read/write access, wait for its execution
 * @udev:	network device to talk to
 * @rwflag:	PHY_CMD1_READ or PHY_CMD1_WRITE opcode
 * @index:	number of the PHY register to read or write
 * Return: zero upon success, negative upon error
 */
static int mcs7830_phy_emit_wait(struct usb_device *udev,
				 uint8_t rwflag, uint8_t index)
{
	int rc;
	int retry;
	uint8_t cmd[2];

	/* send the PHY read/write request */
	cmd[0] = rwflag | PHY_CMD1_PHYADDR;
	cmd[1] = PHY_CMD2_PEND | (index & 0x1f);
	rc = mcs7830_write_reg(udev, REG_PHY_CMD, sizeof(cmd), cmd);
	if (rc < 0)
		return rc;

	/* wait for the response to become available (usually < 1ms) */
	retry = 10;
	do {
		rc = mcs7830_read_reg(udev, REG_PHY_CMD, sizeof(cmd), cmd);
		if (rc < 0)
			return rc;
		if (cmd[1] & PHY_CMD2_READY)
			return 0;
		if (!retry--)
			return -ETIMEDOUT;
		mdelay(1);
	} while (1);
	/* UNREACH */
}
Пример #3
0
static int mcs7830_write_mac_common(struct usb_device *udev,
				    unsigned char enetaddr[])
{
	int rc;

	debug("%s()\n", __func__);

	rc = mcs7830_write_reg(udev, REG_ETHER_ADDR, ETH_ALEN, enetaddr);
	if (rc < 0) {
		debug("writing MAC to adapter failed\n");
		return rc;
	}
	return 0;
}
Пример #4
0
/*
 * mcs7830_write_mchash() - write the network adapter's multicast filter
 * @udev:	network device to write to
 * @priv:	private data
 * Return: zero upon success, negative upon error
 *
 * the data which gets written is taken from the shadow multicast hashes
 * within the device driver's private data
 */
static int mcs7830_write_mchash(struct usb_device *udev,
				struct mcs7830_private *priv)
{
	int rc;

	debug("%s()\n", __func__);

	rc = mcs7830_write_reg(udev, REG_MULTICAST_HASH,
			       sizeof(priv->mchash), &priv->mchash);
	if (rc < 0) {
		debug("writing multicast hash to adapter failed\n");
		return rc;
	}

	return 0;
}
Пример #5
0
/*
 * mcs7830_write_config() - write to the network adapter's config register
 * @udev:	network device to write to
 * @priv:	private data
 * Return: zero upon success, negative upon error
 *
 * the data which gets written is taken from the shadow config register
 * within the device driver's private data
 */
static int mcs7830_write_config(struct usb_device *udev,
				struct mcs7830_private *priv)
{
	int rc;

	debug("%s()\n", __func__);

	rc = mcs7830_write_reg(udev, REG_CONFIG,
			       sizeof(priv->config), &priv->config);
	if (rc < 0) {
		debug("writing config to adapter failed\n");
		return rc;
	}

	return 0;
}
Пример #6
0
/*
 * mcs7830_write_mac() - write an ethernet adapter's MAC address
 * @eth:	network device to write to
 * Return: zero upon success, negative upon error
 *
 * this routine takes the MAC address from the ethernet interface's data
 * structure, and writes it into the ethernet adapter such that subsequent
 * exchange of ethernet frames uses this address
 */
static int mcs7830_write_mac(struct eth_device *eth)
{
	struct ueth_data *dev;
	int rc;

	debug("%s()\n", __func__);
	dev = eth->priv;

	if (sizeof(eth->enetaddr) != ETH_ALEN)
		return -EINVAL;
	rc = mcs7830_write_reg(dev, REG_ETHER_ADDR, ETH_ALEN, eth->enetaddr);
	if (rc < 0) {
		debug("writing MAC to adapter failed\n");
		return rc;
	}
	return 0;
}
Пример #7
0
/*
 * mcs7830_write_mchash() - write the network adapter's multicast filter
 * @eth:	network device to write to
 * Return: zero upon success, negative upon error
 *
 * the data which gets written is taken from the shadow multicast hashes
 * within the device driver's private data
 */
static int mcs7830_write_mchash(struct ueth_data *dev)
{
	struct mcs7830_private *priv;
	int rc;

	debug("%s()\n", __func__);
	priv = dev->dev_priv;

	rc = mcs7830_write_reg(dev, REG_MULTICAST_HASH,
			       sizeof(priv->mchash), &priv->mchash);
	if (rc < 0) {
		debug("writing multicast hash to adapter failed\n");
		return rc;
	}

	return 0;
}
Пример #8
0
/*
 * mcs7830_write_config() - write to the network adapter's config register
 * @eth:	network device to write to
 * Return: zero upon success, negative upon error
 *
 * the data which gets written is taken from the shadow config register
 * within the device driver's private data
 */
static int mcs7830_write_config(struct ueth_data *dev)
{
	struct mcs7830_private *priv;
	int rc;

	debug("%s()\n", __func__);
	priv = dev->dev_priv;

	rc = mcs7830_write_reg(dev, REG_CONFIG,
			       sizeof(priv->config), &priv->config);
	if (rc < 0) {
		debug("writing config to adapter failed\n");
		return rc;
	}

	return 0;
}
Пример #9
0
/*
 * mcs7830_write_phy() - write a PHY register of the network adapter
 * @dev:	network device to write to
 * @index:	index of the PHY register to write to
 * @val:	value to write to the PHY register
 * Return: zero upon success, negative upon error
 */
static int mcs7830_write_phy(struct ueth_data *dev, uint8_t index, uint16_t val)
{
	int rc;

	debug("%s(%s, %d, 0x%04X)\n", __func__, dev->eth_dev.name, index, val);

	/* setup the PHY data which is to get written */
	val = cpu_to_le16(val);
	rc = mcs7830_write_reg(dev, REG_PHY_DATA, sizeof(val), &val);
	if (rc < 0)
		return rc;

	/* issue the PHY write request and wait for its execution */
	rc = mcs7830_phy_emit_wait(dev, PHY_CMD1_WRITE, index);
	if (rc < 0)
		return rc;

	return 0;
}