diff options
| -rw-r--r-- | drivers/net/sis190.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index e374cf43fed0..ff4f24e5f59c 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/moduleparam.h> | 22 | #include <linux/moduleparam.h> |
| 23 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
| 24 | #include <linux/rtnetlink.h> | ||
| 24 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
| 25 | #include <linux/ethtool.h> | 26 | #include <linux/ethtool.h> |
| 26 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
| @@ -230,6 +231,7 @@ struct sis190_private { | |||
| 230 | struct work_struct phy_task; | 231 | struct work_struct phy_task; |
| 231 | struct timer_list timer; | 232 | struct timer_list timer; |
| 232 | u32 msg_enable; | 233 | u32 msg_enable; |
| 234 | struct mii_if_info mii_if; | ||
| 233 | }; | 235 | }; |
| 234 | 236 | ||
| 235 | const static struct { | 237 | const static struct { |
| @@ -308,6 +310,20 @@ static int mdio_read(void __iomem *ioaddr, int reg) | |||
| 308 | return (u16) (SIS_R32(GMIIControl) >> EhnMIIdataShift); | 310 | return (u16) (SIS_R32(GMIIControl) >> EhnMIIdataShift); |
| 309 | } | 311 | } |
| 310 | 312 | ||
| 313 | static void __mdio_write(struct net_device *dev, int phy_id, int reg, int val) | ||
| 314 | { | ||
| 315 | struct sis190_private *tp = netdev_priv(dev); | ||
| 316 | |||
| 317 | mdio_write(tp->mmio_addr, reg, val); | ||
| 318 | } | ||
| 319 | |||
| 320 | static int __mdio_read(struct net_device *dev, int phy_id, int reg) | ||
| 321 | { | ||
| 322 | struct sis190_private *tp = netdev_priv(dev); | ||
| 323 | |||
| 324 | return mdio_read(tp->mmio_addr, reg); | ||
| 325 | } | ||
| 326 | |||
| 311 | static int sis190_read_eeprom(void __iomem *ioaddr, u32 reg) | 327 | static int sis190_read_eeprom(void __iomem *ioaddr, u32 reg) |
| 312 | { | 328 | { |
| 313 | unsigned int i; | 329 | unsigned int i; |
| @@ -790,6 +806,8 @@ static void sis190_phy_task(void * data) | |||
| 790 | void __iomem *ioaddr = tp->mmio_addr; | 806 | void __iomem *ioaddr = tp->mmio_addr; |
| 791 | u16 val; | 807 | u16 val; |
| 792 | 808 | ||
| 809 | rtnl_lock(); | ||
| 810 | |||
| 793 | val = mdio_read(ioaddr, MII_BMCR); | 811 | val = mdio_read(ioaddr, MII_BMCR); |
| 794 | if (val & BMCR_RESET) { | 812 | if (val & BMCR_RESET) { |
| 795 | // FIXME: needlessly high ? -- FR 02/07/2005 | 813 | // FIXME: needlessly high ? -- FR 02/07/2005 |
| @@ -843,6 +861,8 @@ static void sis190_phy_task(void * data) | |||
| 843 | p->msg); | 861 | p->msg); |
| 844 | netif_carrier_on(dev); | 862 | netif_carrier_on(dev); |
| 845 | } | 863 | } |
| 864 | |||
| 865 | rtnl_unlock(); | ||
| 846 | } | 866 | } |
| 847 | 867 | ||
| 848 | static void sis190_phy_timer(unsigned long __opaque) | 868 | static void sis190_phy_timer(unsigned long __opaque) |
| @@ -1150,6 +1170,13 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) | |||
| 1150 | tp->pci_dev = pdev; | 1170 | tp->pci_dev = pdev; |
| 1151 | tp->mmio_addr = ioaddr; | 1171 | tp->mmio_addr = ioaddr; |
| 1152 | 1172 | ||
| 1173 | tp->mii_if.dev = dev; | ||
| 1174 | tp->mii_if.mdio_read = __mdio_read; | ||
| 1175 | tp->mii_if.mdio_write = __mdio_write; | ||
| 1176 | // tp->mii_if.phy_id = XXX; | ||
| 1177 | tp->mii_if.phy_id_mask = 0x1f; | ||
| 1178 | tp->mii_if.reg_num_mask = 0x1f; | ||
| 1179 | |||
| 1153 | sis190_irq_mask_and_ack(ioaddr); | 1180 | sis190_irq_mask_and_ack(ioaddr); |
| 1154 | 1181 | ||
| 1155 | sis190_soft_reset(ioaddr); | 1182 | sis190_soft_reset(ioaddr); |
| @@ -1216,6 +1243,20 @@ static void sis190_set_speed_auto(struct net_device *dev) | |||
| 1216 | BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET); | 1243 | BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET); |
| 1217 | } | 1244 | } |
| 1218 | 1245 | ||
| 1246 | static int sis190_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 1247 | { | ||
| 1248 | struct sis190_private *tp = netdev_priv(dev); | ||
| 1249 | |||
| 1250 | return mii_ethtool_gset(&tp->mii_if, cmd); | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | static int sis190_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 1254 | { | ||
| 1255 | struct sis190_private *tp = netdev_priv(dev); | ||
| 1256 | |||
| 1257 | return mii_ethtool_sset(&tp->mii_if, cmd); | ||
| 1258 | } | ||
| 1259 | |||
| 1219 | static void sis190_get_drvinfo(struct net_device *dev, | 1260 | static void sis190_get_drvinfo(struct net_device *dev, |
| 1220 | struct ethtool_drvinfo *info) | 1261 | struct ethtool_drvinfo *info) |
| 1221 | { | 1262 | { |
| @@ -1245,6 +1286,13 @@ static void sis190_get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
| 1245 | spin_unlock_irqrestore(&tp->lock, flags); | 1286 | spin_unlock_irqrestore(&tp->lock, flags); |
| 1246 | } | 1287 | } |
| 1247 | 1288 | ||
| 1289 | static int sis190_nway_reset(struct net_device *dev) | ||
| 1290 | { | ||
| 1291 | struct sis190_private *tp = netdev_priv(dev); | ||
| 1292 | |||
| 1293 | return mii_nway_restart(&tp->mii_if); | ||
| 1294 | } | ||
| 1295 | |||
| 1248 | static u32 sis190_get_msglevel(struct net_device *dev) | 1296 | static u32 sis190_get_msglevel(struct net_device *dev) |
| 1249 | { | 1297 | { |
| 1250 | struct sis190_private *tp = netdev_priv(dev); | 1298 | struct sis190_private *tp = netdev_priv(dev); |
| @@ -1260,14 +1308,25 @@ static void sis190_set_msglevel(struct net_device *dev, u32 value) | |||
| 1260 | } | 1308 | } |
| 1261 | 1309 | ||
| 1262 | static struct ethtool_ops sis190_ethtool_ops = { | 1310 | static struct ethtool_ops sis190_ethtool_ops = { |
| 1311 | .get_settings = sis190_get_settings, | ||
| 1312 | .set_settings = sis190_set_settings, | ||
| 1263 | .get_drvinfo = sis190_get_drvinfo, | 1313 | .get_drvinfo = sis190_get_drvinfo, |
| 1264 | .get_regs_len = sis190_get_regs_len, | 1314 | .get_regs_len = sis190_get_regs_len, |
| 1265 | .get_regs = sis190_get_regs, | 1315 | .get_regs = sis190_get_regs, |
| 1266 | .get_link = ethtool_op_get_link, | 1316 | .get_link = ethtool_op_get_link, |
| 1267 | .get_msglevel = sis190_get_msglevel, | 1317 | .get_msglevel = sis190_get_msglevel, |
| 1268 | .set_msglevel = sis190_set_msglevel, | 1318 | .set_msglevel = sis190_set_msglevel, |
| 1319 | .nway_reset = sis190_nway_reset, | ||
| 1269 | }; | 1320 | }; |
| 1270 | 1321 | ||
| 1322 | static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
| 1323 | { | ||
| 1324 | struct sis190_private *tp = netdev_priv(dev); | ||
| 1325 | |||
| 1326 | return !netif_running(dev) ? -EINVAL : | ||
| 1327 | generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL); | ||
| 1328 | } | ||
| 1329 | |||
| 1271 | static int __devinit sis190_init_one(struct pci_dev *pdev, | 1330 | static int __devinit sis190_init_one(struct pci_dev *pdev, |
| 1272 | const struct pci_device_id *ent) | 1331 | const struct pci_device_id *ent) |
| 1273 | { | 1332 | { |
| @@ -1308,6 +1367,7 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, | |||
| 1308 | 1367 | ||
| 1309 | dev->open = sis190_open; | 1368 | dev->open = sis190_open; |
| 1310 | dev->stop = sis190_close; | 1369 | dev->stop = sis190_close; |
| 1370 | dev->do_ioctl = sis190_ioctl; | ||
| 1311 | dev->get_stats = sis190_get_stats; | 1371 | dev->get_stats = sis190_get_stats; |
| 1312 | dev->tx_timeout = sis190_tx_timeout; | 1372 | dev->tx_timeout = sis190_tx_timeout; |
| 1313 | dev->watchdog_timeo = SIS190_TX_TIMEOUT; | 1373 | dev->watchdog_timeo = SIS190_TX_TIMEOUT; |
