/* * 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; }
/* * 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 */ }
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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }