Commit 206fb666 authored by Scott Feldman's avatar Scott Feldman Committed by Jeff Garzik

[netdrvr e100] netpoll + fixes to speed/duplex forced settings

* Preserve forced speed/duplex settings during close/open sequence.
* Reset PHY when going from autoneg to forced speed/duplex settings
  using ethtool.
* Add netpoll support.
parent 00133d8e
......@@ -155,7 +155,7 @@
#define DRV_NAME "e100"
#define DRV_VERSION "3.0.11_dev"
#define DRV_VERSION "3.0.12_dev"
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2003 Intel Corporation"
#define PFX DRV_NAME ": "
......@@ -550,35 +550,6 @@ struct nic {
u32 pm_state[16];
};
static void e100_get_defaults(struct nic *nic)
{
struct param_range rfds = { .min = 64, .max = 256, .count = 64 };
struct param_range cbs = { .min = 64, .max = 256, .count = 64 };
pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->rev_id;
if(nic->mac == mac_unknown)
nic->mac = mac_82557_D100_A;
nic->params.rfds = rfds;
nic->params.cbs = cbs;
/* Quadwords to DMA into FIFO before starting frame transmit */
nic->tx_threshold = 0xE0;
nic->tx_command = cpu_to_le16(cb_tx | cb_i | cb_tx_sf |
((nic->mac >= mac_82558_D101_A4) ? cb_cid : 0));
/* Template for a freshly allocated RFD */
nic->blank_rfd.status = 0;
nic->blank_rfd.command = cpu_to_le16(cb_el);
nic->blank_rfd.link = 0;
nic->blank_rfd.rbd = 0xFFFFFFFF;
nic->blank_rfd.actual_size = 0;
nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
}
static inline void e100_write_flush(struct nic *nic)
{
/* Flush previous PCI writes through intermediate bridges
......@@ -893,6 +864,39 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
mdio_ctrl(netdev->priv, addr, mdi_write, reg, data);
}
static void e100_get_defaults(struct nic *nic)
{
struct param_range rfds = { .min = 64, .max = 256, .count = 64 };
struct param_range cbs = { .min = 64, .max = 256, .count = 64 };
pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->rev_id;
if(nic->mac == mac_unknown)
nic->mac = mac_82557_D100_A;
nic->params.rfds = rfds;
nic->params.cbs = cbs;
/* Quadwords to DMA into FIFO before starting frame transmit */
nic->tx_threshold = 0xE0;
nic->tx_command = cpu_to_le16(cb_tx | cb_i | cb_tx_sf |
((nic->mac >= mac_82558_D101_A4) ? cb_cid : 0));
/* Template for a freshly allocated RFD */
nic->blank_rfd.command = cpu_to_le16(cb_el);
nic->blank_rfd.rbd = 0xFFFFFFFF;
nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
/* MII setup */
nic->mii.phy_id_mask = 0x1F;
nic->mii.reg_num_mask = 0x1F;
nic->mii.dev = nic->netdev;
nic->mii.mdio_read = mdio_read;
nic->mii.mdio_write = mdio_write;
}
static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
{
struct config *config = &cb->u.config;
......@@ -989,16 +993,6 @@ static int e100_phy_init(struct nic *nic)
u32 addr;
u16 bmcr, stat, id_lo, id_hi, cong;
nic->mii.phy_id = 0;
nic->mii.advertising = 0;
nic->mii.phy_id_mask = 0x1F;
nic->mii.reg_num_mask = 0x1F;
nic->mii.dev = netdev;
nic->mii.full_duplex = 0;
nic->mii.force_media = 0;
nic->mii.mdio_read = mdio_read;
nic->mii.mdio_write = mdio_write;
/* Discover phy addr by searching addrs in order {1,0,2,..., 31} */
for(addr = 0; addr < 32; addr++) {
nic->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr;
......@@ -1038,10 +1032,10 @@ static int e100_phy_init(struct nic *nic)
mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
}
/* enable MDI/MDI-X auto-switching */
if(nic->mac >= mac_82550_D102)
/* enable/disable MDI/MDI-X auto-switching */
mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG,
NCONFIG_AUTO_SWITCH);
nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH);
return 0;
}
......@@ -1591,6 +1585,16 @@ static int e100_poll(struct net_device *netdev, int *budget)
}
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
static void e100_netpoll(struct net_device *netdev)
{
struct nic *nic = netdev->priv;
e100_disable_irq(nic);
e100_intr(nic->pdev->irq, netdev, NULL);
e100_enable_irq(nic);
}
#endif
static struct net_device_stats *e100_get_stats(struct net_device *netdev)
{
struct nic *nic = netdev->priv;
......@@ -1760,7 +1764,13 @@ static int e100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
static int e100_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
{
struct nic *nic = netdev->priv;
return mii_ethtool_sset(&nic->mii, cmd);
int err;
mdio_write(netdev, nic->mii.phy_id, MII_BMCR, BMCR_RESET);
err = mii_ethtool_sset(&nic->mii, cmd);
e100_exec_cb(nic, NULL, e100_configure);
return err;
}
static void e100_get_drvinfo(struct net_device *netdev,
......@@ -2116,6 +2126,9 @@ static int __devinit e100_probe(struct pci_dev *pdev,
netdev->poll = e100_poll;
netdev->weight = E100_NAPI_WEIGHT;
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
netdev->poll_controller = e100_netpoll;
#endif
nic = netdev->priv;
nic->netdev = netdev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment