/* Process the upper socket ioctl command */ static int dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { board_info_t *db = (board_info_t *)dev->priv; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) /* for kernel 2.6.7 */ struct mii_ioctl_data *data=(struct mii_ioctl_data *)&ifr->ifr_data; #endif int rc=0; DMFE_DBUG(0, "dmfe_do_ioctl()", 0); if (!netif_running(dev)) return -EINVAL; if (cmd == SIOCETHTOOL) rc = dmfe_ethtool_ioctl(dev, (void *) ifr->ifr_data); else { spin_lock_irq(&db->lock); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) /* for kernel 2.6.7 */ rc = generic_mii_ioctl(&db->mii, data, cmd, NULL); #else rc = generic_mii_ioctl(&db->mii, if_mii(ifr), cmd, NULL); #endif spin_unlock_irq(&db->lock); } return rc; }
/* optional */ static int ftmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { struct ftmac100 *priv = netdev_priv(netdev); struct mii_ioctl_data *data = if_mii(ifr); return generic_mii_ioctl(&priv->mii, data, cmd, NULL); }
/** * et131x_ioctl_mii - The function which handles MII IOCTLs * @netdev: device on which the query is being made * @reqbuf: the request-specific data buffer * @cmd: the command request code * * Returns 0 on success, errno on failure (as defined in errno.h) */ int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd) { int status = 0; struct et131x_adapter *etdev = netdev_priv(netdev); struct mii_ioctl_data *data = if_mii(reqbuf); switch (cmd) { case SIOCGMIIPHY: data->phy_id = etdev->Stats.xcvr_addr; break; case SIOCGMIIREG: if (!capable(CAP_NET_ADMIN)) status = -EPERM; else status = MiRead(etdev, data->reg_num, &data->val_out); break; case SIOCSMIIREG: if (!capable(CAP_NET_ADMIN)) status = -EPERM; else status = MiWrite(etdev, data->reg_num, data->val_in); break; default: status = -EOPNOTSUPP; } return status; }
static int eth_ioctl(struct net_device *dev, struct ifreq *req, int cmd) { struct port *port = netdev_priv(dev); if (!netif_running(dev)) return -EINVAL; return phy_mii_ioctl(port->phydev, if_mii(req), cmd); }
/** * phylink_mii_ioctl() - generic mii ioctl interface * @pl: a pointer to a &struct phylink returned from phylink_create() * @ifr: a pointer to a &struct ifreq for socket ioctls * @cmd: ioctl cmd to execute * * Perform the specified MII ioctl on the PHY attached to the phylink instance * specified by @pl. If no PHY is attached, emulate the presence of the PHY. * * Returns: zero on success or negative error code. * * %SIOCGMIIPHY: * read register from the current PHY. * %SIOCGMIIREG: * read register from the specified PHY. * %SIOCSMIIREG: * set a register on the specified PHY. */ int phylink_mii_ioctl(struct phylink *pl, struct ifreq *ifr, int cmd) { struct mii_ioctl_data *mii = if_mii(ifr); int ret; ASSERT_RTNL(); if (pl->phydev) { /* PHYs only exist for MLO_AN_PHY and SGMII */ switch (cmd) { case SIOCGMIIPHY: mii->phy_id = pl->phydev->mdio.addr; /* fall through */ case SIOCGMIIREG: ret = phylink_phy_read(pl, mii->phy_id, mii->reg_num); if (ret >= 0) { mii->val_out = ret; ret = 0; } break; case SIOCSMIIREG: ret = phylink_phy_write(pl, mii->phy_id, mii->reg_num, mii->val_in); break; default: ret = phy_mii_ioctl(pl->phydev, ifr, cmd); break; } } else { switch (cmd) { case SIOCGMIIPHY: mii->phy_id = 0; /* fall through */ case SIOCGMIIREG: ret = phylink_mii_read(pl, mii->phy_id, mii->reg_num); if (ret >= 0) { mii->val_out = ret; ret = 0; } break; case SIOCSMIIREG: ret = phylink_mii_write(pl, mii->phy_id, mii->reg_num, mii->val_in); break; default: ret = -EOPNOTSUPP; break; } } return ret; }
static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct au1000_private *aup = netdev_priv(dev); if (!netif_running(dev)) return -EINVAL; if (!aup->phy_dev) return -EINVAL; // PHY not controllable return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd); }
static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct dsa_slave_priv *p = netdev_priv(dev); struct mii_ioctl_data *mii_data = if_mii(ifr); if (p->phy != NULL) return phy_mii_ioctl(p->phy, mii_data, cmd); return -EOPNOTSUPP; }
/** * IOCTL support for PHY control * * @dev: Device to change * @rq: the request * @cmd: the command * Returns Zero on success */ int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct octeon_ethernet *priv = netdev_priv(dev); if (!netif_running(dev)) return -EINVAL; if (!priv->phydev) return -EINVAL; return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd); }
static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mii_ioctl_data *data = if_mii(ifr); struct b44 *bp = netdev_priv(dev); int err; spin_lock_irq(&bp->lock); err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL); spin_unlock_irq(&bp->lock); return err; }
static int bcm_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct bcm_enet_priv *priv; priv = netdev_priv(dev); if (priv->has_phy) { if (!priv->phydev) return -ENODEV; return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd); } else { struct mii_if_info mii; mii.dev = dev; mii.mdio_read = bcm_enet_mdio_read_mii; mii.mdio_write = bcm_enet_mdio_write_mii; mii.phy_id = 0; mii.phy_id_mask = 0x3f; mii.reg_num_mask = 0x1f; return generic_mii_ioctl(&mii, if_mii(rq), cmd, NULL); } }
int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct octeon_ethernet *priv = netdev_priv(dev); struct mii_ioctl_data *data = if_mii(rq); unsigned int duplex_chg; int ret; down(&mdio_sem); ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg); up(&mdio_sem); return ret; }
static void wpa_driver_roboswitch_mdio_write( struct wpa_driver_roboswitch_data *drv, u8 reg, u16 val) { struct mii_ioctl_data *mii = if_mii(&drv->ifr); mii->phy_id = ROBO_PHY_ADDR; mii->reg_num = reg; mii->val_in = val; if (ioctl(drv->fd, SIOCSMIIREG, &drv->ifr) < 0) { perror("ioctl[SIOCSMIIREG"); } }
static int enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct tangox_enet_priv *priv; int ret; priv = netdev_priv(dev); spin_lock_bh(&priv->mii); ret = generic_mii_ioctl(&priv->mii, if_mii(rq), cmd, NULL); spin_unlock_bh(&priv->mii); return ret; }
static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) { struct cp_private *cp = netdev_priv(dev); int rc; unsigned long flags; if (!netif_running(dev)) return -EINVAL; spin_lock_irqsave(&cp->lock, flags); rc = generic_mii_ioctl(&cp->mii_if, if_mii(rq), cmd, NULL); spin_unlock_irqrestore(&cp->lock, flags); return rc; }
static u16 wpa_driver_roboswitch_mdio_read( struct wpa_driver_roboswitch_data *drv, u8 reg) { struct mii_ioctl_data *mii = if_mii(&drv->ifr); mii->phy_id = ROBO_PHY_ADDR; mii->reg_num = reg; if (ioctl(drv->fd, SIOCGMIIREG, &drv->ifr) < 0) { perror("ioctl[SIOCGMIIREG]"); return 0x00; } return mii->val_out; }
/* ioctl to device funciotn*/ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) { struct sh_eth_private *mdp = netdev_priv(ndev); struct phy_device *phydev = mdp->phydev; if (!netif_running(ndev)) return -EINVAL; if (!phydev) return -ENODEV; return phy_mii_ioctl(phydev, if_mii(rq), cmd); }
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct mii_ioctl_data *data = if_mii(rq); struct am_net_private *np = netdev_priv(dev); char addr[MAX_ADDR_LEN]; if (debug > 0) printk("Ethernet Driver ioctl (%x) \n", cmd); switch (cmd) { case SIOCGMIIPHY: /* Get address of MII PHY in use. */ data->phy_id = ((struct am_net_private *)netdev_priv(dev))->phys[0] & 0x1f; /* Fall Through */ case SIOCGMIIREG: /* Read MII PHY register. */ spin_lock_irq(&np->lock); data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f); spin_unlock_irq(&np->lock); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ if (!capable(CAP_NET_ADMIN)) return -EPERM; spin_lock_irq(&np->lock); mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f,data->val_in); spin_unlock_irq(&np->lock); return 0; case SIOCSIFHWADDR: if (copy_from_user(&addr, (void __user *)rq->ifr_hwaddr.sa_data, MAX_ADDR_LEN)) { return -EFAULT; } if (debug > 0) printk("set mac addr to %02x:%02x:%02x:%02x:%02x:%02x\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); spin_lock_irq(&np->lock); memcpy(dev->dev_addr, &addr, MAX_ADDR_LEN); write_mac_addr(dev, addr); spin_unlock_irq(&np->lock); default: if (debug > 0) printk("Ethernet Driver unknow ioctl (%x) \n", cmd); return -EOPNOTSUPP; } return 0; }
static int ubi32_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct ubi32_eth_private *priv = netdev_priv(dev); struct mii_ioctl_data *data = if_mii(rq); printk(KERN_INFO "ioctl %s, %d\n", dev->name, cmd); switch (cmd) { case SIOCGMIIPHY: data->phy_id = 0; break; case SIOCGMIIREG: if ((data->reg_num & 0x1F) == MII_BMCR) { /* Make up MII control register value from what we know */ data->val_out = 0x0000 | ((priv->regs->status & UBI32_ETH_VP_STATUS_DUPLEX) ? BMCR_FULLDPLX : 0) | ((priv->regs->status & UBI32_ETH_VP_STATUS_SPEED100) ? BMCR_SPEED100 : 0) | ((priv->regs->status & UBI32_ETH_VP_STATUS_SPEED1000) ? BMCR_SPEED1000 : 0); } else if ((data->reg_num & 0x1F) == MII_BMSR) { /* Make up MII status register value from what we know */ data->val_out = (BMSR_100FULL|BMSR_100HALF|BMSR_10FULL|BMSR_10HALF) | ((priv->regs->status & UBI32_ETH_VP_STATUS_LINK) ? BMSR_LSTATUS : 0); } else { return -EIO; } break; case SIOCSMIIREG: return -EOPNOTSUPP; break; default: return -EOPNOTSUPP; } return 0; }
static int wrn_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct wrn_ep *ep = netdev_priv(dev); int res; u32 reg; switch (cmd) { case SIOCSHWTSTAMP: return wrn_tstamp_ioctl(dev, rq, cmd); case PRIV_IOCGCALIBRATE: return wrn_calib_ioctl(dev, rq, cmd); case PRIV_IOCGGETPHASE: return wrn_phase_ioctl(dev, rq, cmd); case PRIV_IOCREADREG: if (get_user(reg, (u32 *)rq->ifr_data) < 0) return -EFAULT; if (reg > sizeof(struct EP_WB) || reg & 3) return -EINVAL; reg = readl((void *)ep->ep_regs + reg); if (put_user(reg, (u32 *)rq->ifr_data) < 0) return -EFAULT; return 0; case PRIV_IOCPHYREG: /* this command allows to read and write a phy register */ if (get_user(reg, (u32 *)rq->ifr_data) < 0) return -EFAULT; if (reg & (1<<31)) { wrn_phy_write(dev, 0, (reg >> 16) & 0xff, reg & 0xffff); return 0; } reg = wrn_phy_read(dev, 0, (reg >> 16) & 0xff); if (put_user(reg, (u32 *)rq->ifr_data) < 0) return -EFAULT; return 0; default: spin_lock_irq(&ep->lock); res = generic_mii_ioctl(&ep->mii, if_mii(rq), cmd, NULL); spin_unlock_irq(&ep->lock); return res; }
/** * et131x_ioctl_mii - The function which handles MII IOCTLs * @netdev: device on which the query is being made * @reqbuf: the request-specific data buffer * @cmd: the command request code * * Returns 0 on success, errno on failure (as defined in errno.h) */ int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd) { int status = 0; struct et131x_adapter *pAdapter = netdev_priv(netdev); struct mii_ioctl_data *data = if_mii(reqbuf); DBG_ENTER(et131x_dbginfo); switch (cmd) { case SIOCGMIIPHY: DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIPHY\n"); data->phy_id = pAdapter->Stats.xcvr_addr; break; case SIOCGMIIREG: DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIREG\n"); if (!capable(CAP_NET_ADMIN)) { status = -EPERM; } else { status = MiRead(pAdapter, data->reg_num, &data->val_out); } break; case SIOCSMIIREG: DBG_VERBOSE(et131x_dbginfo, "SIOCSMIIREG\n"); if (!capable(CAP_NET_ADMIN)) { status = -EPERM; } else { status = MiWrite(pAdapter, data->reg_num, data->val_in); } break; default: status = -EOPNOTSUPP; } DBG_LEAVE(et131x_dbginfo); return status; }
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { pcnet_dev_t *info = PRIV(dev); struct mii_ioctl_data *data = if_mii(rq); unsigned int mii_addr = dev->base_addr + DLINK_GPIO; if (!(info->flags & (IS_DL10019|IS_DL10022))) return -EINVAL; switch (cmd) { case SIOCGMIIPHY: data->phy_id = info->phy_id; case SIOCGMIIREG: /* Read MII PHY register. */ data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f); return 0; case SIOCSMIIREG: /* Write MII PHY register. */ mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in); return 0; } return -EOPNOTSUPP; }
static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) { struct adapter *adapter = dev->priv; struct mii_ioctl_data *data = if_mii(req); switch (cmd) { case SIOCGMIIPHY: data->phy_id = adapter->port[dev->if_port].phy->addr; /* FALLTHRU */ case SIOCGMIIREG: { struct cphy *phy = adapter->port[dev->if_port].phy; u32 val; if (!phy->mdio_read) return -EOPNOTSUPP; phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f, &val); data->val_out = val; break; } case SIOCSMIIREG: { struct cphy *phy = adapter->port[dev->if_port].phy; if (!capable(CAP_NET_ADMIN)) return -EPERM; if (!phy->mdio_write) return -EOPNOTSUPP; phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f, data->val_in); break; } default: return -EOPNOTSUPP; } return 0; }
static int qf9700_ioctl(struct net_device *net, struct ifreq *rq, int cmd) { struct usbnet *dev = netdev_priv(net); return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); }
/** * cvm_oct_ioctl - IOCTL support for PHY control * @dev: Device to change * @rq: the request * @cmd: the command * * Returns Zero on success */ int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct octeon_ethernet *priv = netdev_priv(dev); cvmx_srio_tx_message_header_t tx_header; int ivalue; switch (cmd) { case CAVIUM_NET_IOCTL_SETPRIO: ivalue = rq->ifr_ifru.ifru_ivalue; if ((ivalue >= 0) && (ivalue < 4)) { tx_header.u64 = priv->srio_tx_header; tx_header.s.prio = ivalue; priv->srio_tx_header = tx_header.u64; return 0; } return -EINVAL; case CAVIUM_NET_IOCTL_GETPRIO: tx_header.u64 = priv->srio_tx_header; rq->ifr_ifru.ifru_ivalue = tx_header.s.prio; return 0; case CAVIUM_NET_IOCTL_SETIDSIZE: ivalue = rq->ifr_ifru.ifru_ivalue; if ((ivalue >= 0) && (ivalue < 2)) { tx_header.u64 = priv->srio_tx_header; tx_header.s.tt = ivalue; priv->srio_tx_header = tx_header.u64; return 0; } return -EINVAL; case CAVIUM_NET_IOCTL_GETIDSIZE: tx_header.u64 = priv->srio_tx_header; rq->ifr_ifru.ifru_ivalue = tx_header.s.tt; return 0; case CAVIUM_NET_IOCTL_SETSRCID: ivalue = rq->ifr_ifru.ifru_ivalue; if ((ivalue >= 0) && (ivalue < 2)) { tx_header.u64 = priv->srio_tx_header; tx_header.s.sis = ivalue; priv->srio_tx_header = tx_header.u64; return 0; } return -EINVAL; case CAVIUM_NET_IOCTL_GETSRCID: tx_header.u64 = priv->srio_tx_header; rq->ifr_ifru.ifru_ivalue = tx_header.s.sis; return 0; case CAVIUM_NET_IOCTL_SETLETTER: ivalue = rq->ifr_ifru.ifru_ivalue; if ((ivalue >= -1) && (ivalue < 4)) { tx_header.u64 = priv->srio_tx_header; tx_header.s.lns = (ivalue == -1); if (tx_header.s.lns) tx_header.s.letter = 0; else tx_header.s.letter = ivalue; priv->srio_tx_header = tx_header.u64; return 0; } return -EINVAL; case CAVIUM_NET_IOCTL_GETLETTER: tx_header.u64 = priv->srio_tx_header; if (tx_header.s.lns) rq->ifr_ifru.ifru_ivalue = -1; else rq->ifr_ifru.ifru_ivalue = tx_header.s.letter; return 0; case SIOCSHWTSTAMP: return cvm_oct_ioctl_hwtstamp(dev, rq, cmd); default: if (priv->phydev) return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd); return -EINVAL; } }
static void * wpa_driver_roboswitch_init(void *ctx, const char *ifname) { struct wpa_driver_roboswitch_data *drv; char *sep; u16 vlan = 0, _read[2]; drv = os_zalloc(sizeof(*drv)); if (drv == NULL) return NULL; drv->ctx = ctx; drv->own_addr[0] = '\0'; /* copy ifname and take a pointer to the second to last character */ sep = drv->ifname + os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)) - 2; /* find the '.' separating <interface> and <vlan> */ while (sep > drv->ifname && *sep != '.') sep--; if (sep <= drv->ifname) { wpa_printf(MSG_INFO, "%s: No <interface>.<vlan> pair in " "interface name %s", __func__, drv->ifname); os_free(drv); return NULL; } *sep = '\0'; while (*++sep) { if (*sep < '0' || *sep > '9') { wpa_printf(MSG_INFO, "%s: Invalid vlan specification " "in interface name %s", __func__, ifname); os_free(drv); return NULL; } vlan *= 10; vlan += *sep - '0'; if (vlan > ROBO_VLAN_MAX) { wpa_printf(MSG_INFO, "%s: VLAN out of range in " "interface name %s", __func__, ifname); os_free(drv); return NULL; } } drv->fd = socket(PF_INET, SOCK_DGRAM, 0); if (drv->fd < 0) { wpa_printf(MSG_INFO, "%s: Unable to create socket", __func__); os_free(drv); return NULL; } os_memset(&drv->ifr, 0, sizeof(drv->ifr)); os_strlcpy(drv->ifr.ifr_name, drv->ifname, IFNAMSIZ); if (ioctl(drv->fd, SIOCGMIIPHY, &drv->ifr) < 0) { wpa_printf(MSG_ERROR, "ioctl[SIOCGMIIPHY]: %s", strerror(errno)); os_free(drv); return NULL; } /* BCM63xx devices provide 0 here */ if (if_mii(&drv->ifr)->phy_id != ROBO_PHY_ADDR && if_mii(&drv->ifr)->phy_id != 0) { wpa_printf(MSG_INFO, "%s: Invalid phy address (not a " "RoboSwitch?)", __func__); os_free(drv); return NULL; } /* set and read back to see if the register can be used */ _read[0] = ROBO_VLAN_MAX; wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350, _read, 1); wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350, _read + 1, 1); drv->is_5350 = _read[0] == _read[1]; /* set the read bit */ vlan |= 1 << 13; wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE, drv->is_5350 ? ROBO_VLAN_ACCESS_5350 : ROBO_VLAN_ACCESS, &vlan, 1); wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_READ, _read, drv->is_5350 ? 2 : 1); if (!(drv->is_5350 ? _read[1] & (1 << 4) : _read[0] & (1 << 14))) { wpa_printf(MSG_INFO, "%s: Could not get port information for " "VLAN %d", __func__, vlan & ~(1 << 13)); os_free(drv); return NULL; } drv->ports = _read[0] & 0x001F; /* add the MII port */ drv->ports |= 1 << 8; if (wpa_driver_roboswitch_join(drv, drv->ports, pae_group_addr) < 0) { wpa_printf(MSG_INFO, "%s: Unable to join PAE group", __func__); os_free(drv); return NULL; } else { wpa_printf(MSG_DEBUG, "%s: Added PAE group address to " "RoboSwitch ARL", __func__); } return drv; }