aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/atlx/Makefile1
-rw-r--r--drivers/net/atlx/atl1.c (renamed from drivers/net/atlx/atl1_main.c)1544
-rw-r--r--drivers/net/atlx/atl1.h603
-rw-r--r--drivers/net/atlx/atl1_ethtool.c505
-rw-r--r--drivers/net/atlx/atl1_hw.c720
-rw-r--r--drivers/net/atlx/atl1_hw.h946
-rw-r--r--drivers/net/atlx/atl1_param.c203
-rw-r--r--drivers/net/atlx/atlx.c433
-rw-r--r--drivers/net/atlx/atlx.h506
9 files changed, 2751 insertions, 2710 deletions
diff --git a/drivers/net/atlx/Makefile b/drivers/net/atlx/Makefile
index a6b707e4e69..ca45553a040 100644
--- a/drivers/net/atlx/Makefile
+++ b/drivers/net/atlx/Makefile
@@ -1,2 +1 @@
obj-$(CONFIG_ATL1) += atl1.o
-atl1-y += atl1_main.o atl1_hw.o atl1_ethtool.o atl1_param.o
diff --git a/drivers/net/atlx/atl1_main.c b/drivers/net/atlx/atl1.c
index 9200ee59d85..a84c97c75c7 100644
--- a/drivers/net/atlx/atl1_main.c
+++ b/drivers/net/atlx/atl1.c
@@ -1,6 +1,6 @@
/*
* Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
- * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
+ * Copyright(c) 2006 - 2007 Chris Snook <csnook@redhat.com>
* Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
*
* Derived from Intel e1000 driver
@@ -50,51 +50,46 @@
* SMP torture testing
*/
-#include <linux/types.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/skbuff.h>
+#include <asm/atomic.h>
+#include <asm/byteorder.h>
+
+#include <linux/compiler.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
-#include <linux/if_vlan.h>
-#include <linux/if_ether.h>
-#include <linux/irqreturn.h>
-#include <linux/workqueue.h>
-#include <linux/timer.h>
-#include <linux/jiffies.h>
#include <linux/hardirq.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/in.h>
#include <linux/interrupt.h>
+#include <linux/ip.h>
#include <linux/irqflags.h>
-#include <linux/dma-mapping.h>
+#include <linux/irqreturn.h>
+#include <linux/jiffies.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
#include <linux/pm.h>
-#include <linux/in.h>
-#include <linux/ip.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
#include <linux/tcp.h>
-#include <linux/compiler.h>
-#include <linux/delay.h>
-#include <linux/mii.h>
-#include <net/checksum.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
-#include <asm/atomic.h>
-#include <asm/byteorder.h>
+#include <net/checksum.h>
#include "atl1.h"
-#define DRIVER_VERSION "2.0.7"
-
-char atl1_driver_name[] = "atl1";
-static const char atl1_driver_string[] = "Attansic L1 Ethernet Network Driver";
-static const char atl1_copyright[] = "Copyright(c) 2005-2006 Attansic Corporation.";
-char atl1_driver_version[] = DRIVER_VERSION;
-
-MODULE_AUTHOR
- ("Attansic Corporation <xiong_huang@attansic.com>, Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
-MODULE_DESCRIPTION("Attansic 1000M Ethernet Network Driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
+/* Temporary hack for merging atl1 and atl2 */
+#include "atlx.c"
/*
* atl1_pci_tbl - PCI Device ID Table
@@ -104,7 +99,6 @@ static const struct pci_device_id atl1_pci_tbl[] = {
/* required last entry */
{0,}
};
-
MODULE_DEVICE_TABLE(pci, atl1_pci_tbl);
/*
@@ -125,7 +119,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
adapter->wol = 0;
adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7;
- adapter->ict = 50000; /* 100ms */
+ adapter->ict = 50000; /* 100ms */
adapter->link_speed = SPEED_0; /* hardware init */
adapter->link_duplex = FULL_DUPLEX;
@@ -206,24 +200,6 @@ static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
}
/*
- * atl1_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl1_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
- switch (cmd) {
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
- case SIOCSMIIREG:
- return atl1_mii_ioctl(netdev, ifr, cmd);
- default:
- return -EOPNOTSUPP;
- }
-}
-
-/*
* atl1_setup_mem_resources - allocate Tx / RX descriptor resources
* @adapter: board private structure
*
@@ -248,7 +224,8 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
rfd_ring->buffer_info =
(struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count);
- /* real ring DMA buffer
+ /*
+ * real ring DMA buffer
* each ring/block may need up to 8 bytes for alignment, hence the
* additional 40 bytes tacked onto the end.
*/
@@ -307,7 +284,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
((u8 *) adapter->cmb.cmb +
(sizeof(struct coals_msg_block) + offset));
- return ATL1_SUCCESS;
+ return 0;
err_nomem:
kfree(tpd_ring->buffer_info);
@@ -481,31 +458,6 @@ static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
iowrite32(value, hw->hw_addr + REG_MAC_CTRL);
}
-/*
- * atl1_set_mac - Change the Ethernet Address of the NIC
- * @netdev: network interface device structure
- * @p: pointer to an address structure
- *
- * Returns 0 on success, negative on failure
- */
-static int atl1_set_mac(struct net_device *netdev, void *p)
-{
- struct atl1_adapter *adapter = netdev_priv(netdev);
- struct sockaddr *addr = p;
-
- if (netif_running(netdev))
- return -EBUSY;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
-
- atl1_set_mac_addr(&adapter->hw);
- return 0;
-}
-
static u32 atl1_check_link(struct atl1_adapter *adapter)
{
struct atl1_hw *hw = &adapter->hw;
@@ -517,14 +469,16 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
/* MII_BMSR must read twice */
atl1_read_phy_reg(hw, MII_BMSR, &phy_data);
atl1_read_phy_reg(hw, MII_BMSR, &phy_data);
- if (!(phy_data & BMSR_LSTATUS)) { /* link down */
- if (netif_carrier_ok(netdev)) { /* old link state: Up */
+ if (!(phy_data & BMSR_LSTATUS)) {
+ /* link down */
+ if (netif_carrier_ok(netdev)) {
+ /* old link state: Up */
dev_info(&adapter->pdev->dev, "link is down\n");
adapter->link_speed = SPEED_0;
netif_carrier_off(netdev);
netif_stop_queue(netdev);
}
- return ATL1_SUCCESS;
+ return 0;
}
/* Link Up */
@@ -568,14 +522,15 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
adapter->link_duplex == FULL_DUPLEX ?
"full duplex" : "half duplex");
}
- if (!netif_carrier_ok(netdev)) { /* Link down -> Up */
+ if (!netif_carrier_ok(netdev)) {
+ /* Link down -> Up */
netif_carrier_on(netdev);
netif_wake_queue(netdev);
}
- return ATL1_SUCCESS;
+ return 0;
}
- /* change orignal link status */
+ /* change original link status */
if (netif_carrier_ok(netdev)) {
adapter->link_speed = SPEED_0;
netif_carrier_off(netdev);
@@ -596,12 +551,13 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
phy_data =
MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
break;
- default: /* MEDIA_TYPE_10M_HALF: */
+ default:
+ /* MEDIA_TYPE_10M_HALF: */
phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
break;
}
atl1_write_phy_reg(hw, MII_BMCR, phy_data);
- return ATL1_SUCCESS;
+ return 0;
}
/* auto-neg, insert timer to re-config phy */
@@ -610,71 +566,7 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
mod_timer(&adapter->phy_config_timer, jiffies + 3 * HZ);
}
- return ATL1_SUCCESS;
-}
-
-static void atl1_check_for_link(struct atl1_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdev;
- u16 phy_data = 0;
-
- spin_lock(&adapter->lock);
- adapter->phy_timer_pending = false;
- atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
- atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
- spin_unlock(&adapter->lock);
-
- /* notify upper layer link down ASAP */
- if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */
- if (netif_carrier_ok(netdev)) { /* old link state: Up */
- dev_info(&adapter->pdev->dev, "%s link is down\n",
- netdev->name);
- adapter->link_speed = SPEED_0;
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- }
- }
- schedule_work(&adapter->link_chg_task);
-}
-
-/*
- * atl1_set_multi - Multicast and Promiscuous mode set
- * @netdev: network interface device structure
- *
- * The set_multi entry point is called whenever the multicast address
- * list or the network interface flags are updated. This routine is
- * responsible for configuring the hardware for proper multicast,
- * promiscuous mode, and all-multi behavior.
- */
-static void atl1_set_multi(struct net_device *netdev)
-{
- struct atl1_adapter *adapter = netdev_priv(netdev);
- struct atl1_hw *hw = &adapter->hw;
- struct dev_mc_list *mc_ptr;
- u32 rctl;
- u32 hash_value;
-
- /* Check for Promiscuous and All Multicast modes */
- rctl = ioread32(hw->hw_addr + REG_MAC_CTRL);
- if (netdev->flags & IFF_PROMISC)
- rctl |= MAC_CTRL_PROMIS_EN;
- else if (netdev->flags & IFF_ALLMULTI) {
- rctl |= MAC_CTRL_MC_ALL_EN;
- rctl &= ~MAC_CTRL_PROMIS_EN;
- } else
- rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
-
- iowrite32(rctl, hw->hw_addr + REG_MAC_CTRL);
-
- /* clear the old settings from the multicast hash table */
- iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
- iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
-
- /* compute mc addresses' hash value ,and put it into hash table */
- for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
- hash_value = atl1_hash_mc_addr(hw, mc_ptr->dmi_addr);
- atl1_hash_set(hw, hash_value);
- }
+ return 0;
}
/*
@@ -974,37 +866,6 @@ static void atl1_via_workaround(struct atl1_adapter *adapter)
iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND);
}
-/*
- * atl1_irq_enable - Enable default interrupt generation settings
- * @adapter: board private structure
- */
-static void atl1_irq_enable(struct atl1_adapter *adapter)
-{
- iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
- ioread32(adapter->hw.hw_addr + REG_IMR);
-}
-
-/*
- * atl1_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- */
-static void atl1_irq_disable(struct atl1_adapter *adapter)
-{
- iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- ioread32(adapter->hw.hw_addr + REG_IMR);
- synchronize_irq(adapter->pdev->irq);
-}
-
-static void atl1_clear_phy_int(struct atl1_adapter *adapter)
-{
- u16 phy_data;
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->lock, flags);
- atl1_read_phy_reg(&adapter->hw, 19, &phy_data);
- spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
static void atl1_inc_smb(struct atl1_adapter *adapter)
{
struct stats_msg_block *smb = adapter->smb.smb;
@@ -1076,19 +937,6 @@ static void atl1_inc_smb(struct atl1_adapter *adapter)
adapter->soft_stats.tx_carrier_errors;
}
-/*
- * atl1_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
- */
-static struct net_device_stats *atl1_get_stats(struct net_device *netdev)
-{
- struct atl1_adapter *adapter = netdev_priv(netdev);
- return &adapter->net_stats;
-}
-
static void atl1_update_mailbox(struct atl1_adapter *adapter)
{
unsigned long flags;
@@ -1210,7 +1058,8 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
- if (unlikely(!skb)) { /* Better luck next round */
+ if (unlikely(!skb)) {
+ /* Better luck next round */
adapter->net_stats.rx_dropped++;
break;
}
@@ -1519,7 +1368,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
buffer_info = &tpd_ring->buffer_info[tpd_next_to_use];
if (unlikely(buffer_info->skb))
BUG();
- buffer_info->skb = NULL; /* put skb in last TPD */
+ /* put skb in last TPD */
+ buffer_info->skb = NULL;
if (tcp_seg) {
/* TSO/GSO */
@@ -1779,7 +1629,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
adapter->cmb.cmb->int_stats = 0;
if (status & ISR_GPHY) /* clear phy status */
- atl1_clear_phy_int(adapter);
+ atlx_clear_phy_int(adapter);
/* clear ISR status, and Enable CMB DMA/Disable Interrupt */
iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR);
@@ -1866,23 +1716,12 @@ static void atl1_phy_config(unsigned long data)
spin_lock_irqsave(&adapter->lock, flags);
adapter->phy_timer_pending = false;
atl1_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
- atl1_write_phy_reg(hw, MII_AT001_CR, hw->mii_1000t_ctrl_reg);
+ atl1_write_phy_reg(hw, MII_ATLX_CR, hw->mii_1000t_ctrl_reg);
atl1_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN);
spin_unlock_irqrestore(&adapter->lock, flags);
}
/*
- * atl1_tx_timeout - Respond to a Tx Hang
- * @netdev: network interface device structure
- */
-static void atl1_tx_timeout(struct net_device *netdev)
-{
- struct atl1_adapter *adapter = netdev_priv(netdev);
- /* Do the reset outside of interrupt context */
- schedule_work(&adapter->tx_timeout_task);
-}
-
-/*
* Orphaned vendor comment left intact here:
* <vendor comment>
* If TPD Buffer size equal to 0, PCIE DMAR_TO_INT
@@ -1904,58 +1743,11 @@ static void atl1_tx_timeout_task(struct work_struct *work)
netif_device_attach(netdev);
}
-/*
- * atl1_link_chg_task - deal with link change event Out of interrupt context
- */
-static void atl1_link_chg_task(struct work_struct *work)
-{
- struct atl1_adapter *adapter =
- container_of(work, struct atl1_adapter, link_chg_task);
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->lock, flags);
- atl1_check_link(adapter);
- spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static void atl1_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
-{
- struct atl1_adapter *adapter = netdev_priv(netdev);
- unsigned long flags;
- u32 ctrl;
-
- spin_lock_irqsave(&adapter->lock, flags);
- /* atl1_irq_disable(adapter); */
- adapter->vlgrp = grp;
-
- if (grp) {
- /* enable VLAN tag insert/strip */
- ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
- ctrl |= MAC_CTRL_RMV_VLAN;
- iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
- } else {
- /* disable VLAN tag insert/strip */
- ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
- ctrl &= ~MAC_CTRL_RMV_VLAN;
- iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
- }
-
- /* atl1_irq_enable(adapter); */
- spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static void atl1_restore_vlan(struct atl1_adapter *adapter)
-{
- atl1_vlan_rx_register(adapter->netdev, adapter->vlgrp);
-}
-
int atl1_reset(struct atl1_adapter *adapter)
{
int ret;
-
ret = atl1_reset_hw(&adapter->hw);
- if (ret != ATL1_SUCCESS)
+ if (ret)
return ret;
return atl1_init_hw(&adapter->hw);
}
@@ -1967,11 +1759,12 @@ s32 atl1_up(struct atl1_adapter *adapter)
int irq_flags = IRQF_SAMPLE_RANDOM;
/* hardware has been reset, we need to reload some things */
- atl1_set_multi(netdev);
+ atlx_set_multi(netdev);
atl1_init_ring_ptrs(adapter);
- atl1_restore_vlan(adapter);
+ atlx_restore_vlan(adapter);
err = atl1_alloc_rx_buffers(adapter);
- if (unlikely(!err)) /* no RX BUFFER allocated */
+ if (unlikely(!err))
+ /* no RX BUFFER allocated */
return -ENOMEM;
if (unlikely(atl1_configure(adapter))) {
@@ -1992,7 +1785,7 @@ s32 atl1_up(struct atl1_adapter *adapter)
goto err_up;
mod_timer(&adapter->watchdog_timer, jiffies);
- atl1_irq_enable(adapter);
+ atlx_irq_enable(adapter);
atl1_check_link(adapter);
return 0;
@@ -2011,7 +1804,7 @@ void atl1_down(struct atl1_adapter *adapter)
del_timer_sync(&adapter->phy_config_timer);
adapter->phy_timer_pending = false;
- atl1_irq_disable(adapter);
+ atlx_irq_disable(adapter);
free_irq(adapter->pdev->irq, netdev);
pci_disable_msi(adapter->pdev);
atl1_reset_hw(&adapter->hw);
@@ -2094,7 +1887,7 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
if (ctrl & BMSR_LSTATUS)
- wufc &= ~ATL1_WUFC_LNKC;
+ wufc &= ~ATLX_WUFC_LNKC;
/* reduce speed to 10/100M */
if (wufc) {
@@ -2102,15 +1895,15 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
/* if resume, let driver to re- setup link */
hw->phy_configured = false;
atl1_set_mac_addr(hw);
- atl1_set_multi(netdev);
+ atlx_set_multi(netdev);
ctrl = 0;
/* turn on magic packet wol */
- if (wufc & ATL1_WUFC_MAG)
+ if (wufc & ATLX_WUFC_MAG)
ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
/* turn on Link change WOL */
- if (wufc & ATL1_WUFC_LNKC)
+ if (wufc & ATLX_WUFC_LNKC)
ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
@@ -2118,13 +1911,13 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL);
ctrl &= ~MAC_CTRL_DBG;
ctrl &= ~MAC_CTRL_PROMIS_EN;
- if (wufc & ATL1_WUFC_MC)
+ if (wufc & ATLX_WUFC_MC)
ctrl |= MAC_CTRL_MC_ALL_EN;
else
ctrl &= ~MAC_CTRL_MC_ALL_EN;
/* turn on broadcast mode if wake on-BC is enabled */
- if (wufc & ATL1_WUFC_BC)
+ if (wufc & ATLX_WUFC_BC)
ctrl |= MAC_CTRL_BC_EN;
else
ctrl &= ~MAC_CTRL_BC_EN;
@@ -2152,12 +1945,13 @@ static int atl1_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct atl1_adapter *adapter = netdev_priv(netdev);
- u32 ret_val;
+ u32 err;
- pci_set_power_state(pdev, 0);
+ pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- ret_val = pci_enable_device(pdev);
+ /* FIXME: check and handle */
+ err = pci_enable_device(pdev);
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
@@ -2224,14 +2018,16 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
dev_err(&pdev->dev, "no usable DMA configuration\n");
goto err_dma;
}
- /* Mark all PCI regions associated with PCI device
+ /*
+ * Mark all PCI regions associated with PCI device
* pdev as being reserved by owner atl1_driver_name
*/
- err = pci_request_regions(pdev, atl1_driver_name);
+ err = pci_request_regions(pdev, ATLX_DRIVER_NAME);
if (err)
goto err_request_regions;
- /* Enables bus-mastering on the device and calls
+ /*
+ * Enables bus-mastering on the device and calls
* pcibios_set_master to do the needed arch specific settings
*/
pci_set_master(pdev);
@@ -2257,7 +2053,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
/* get device revision number */
adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr +
(REG_MASTER_CTRL + 2));
- dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
+ dev_info(&pdev->dev, "version %s\n", ATLX_DRIVER_VERSION);
/* set default ring resource counts */
adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD;
@@ -2272,17 +2068,17 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
netdev->open = &atl1_open;
netdev->stop = &atl1_close;
netdev->hard_start_xmit = &atl1_xmit_frame;
- netdev->get_stats = &atl1_get_stats;
- netdev->set_multicast_list = &atl1_set_multi;
+ netdev->get_stats = &atlx_get_stats;
+ netdev->set_multicast_list = &atlx_set_multi;
netdev->set_mac_address = &atl1_set_mac;
netdev->change_mtu = &atl1_change_mtu;
- netdev->do_ioctl = &atl1_ioctl;
- netdev->tx_timeout = &atl1_tx_timeout;
+ netdev->do_ioctl = &atlx_ioctl;
+ netdev->tx_timeout = &atlx_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
#ifdef CONFIG_NET_POLL_CONTROLLER
netdev->poll_controller = atl1_poll_controller;
#endif
- netdev->vlan_rx_register = atl1_vlan_rx_register;
+ netdev->vlan_rx_register = atlx_vlan_rx_register;
netdev->ethtool_ops = &atl1_ethtool_ops;
adapter->bd_number = cards_found;
@@ -2312,7 +2108,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
/* atl1_pcie_patch(adapter); */
/* really reset GPHY core */
- iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE);
+ iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
/*
* reset the controller to
@@ -2357,7 +2153,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
- INIT_WORK(&adapter->link_chg_task, atl1_link_chg_task);
+ INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
@@ -2400,7 +2196,8 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
adapter = netdev_priv(netdev);
- /* Some atl1 boards lack persistent storage for their MAC, and get it
+ /*
+ * Some atl1 boards lack persistent storage for their MAC, and get it
* from the BIOS during POST. If we've been messing with the MAC
* address, we need to save the permanent one.
*/
@@ -2410,7 +2207,7 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
atl1_set_mac_addr(&adapter->hw);
}
- iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE);
+ iowrite16(0, adapter->hw.hw_addr + REG_PHY_ENABLE);
unregister_netdev(netdev);
pci_iounmap(pdev, adapter->hw.hw_addr);
pci_release_regions(pdev);
@@ -2419,7 +2216,7 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
}
static struct pci_driver atl1_driver = {
- .name = atl1_driver_name,
+ .name = ATLX_DRIVER_NAME,
.id_table = atl1_pci_tbl,
.probe = atl1_probe,
.remove = __devexit_p(atl1_remove),
@@ -2451,3 +2248,1170 @@ static int __init atl1_init_module(void)
module_init(atl1_init_module);
module_exit(atl1_exit_module);
+
+struct atl1_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int sizeof_stat;
+ int stat_offset;
+};
+
+#define ATL1_STAT(m) \
+ sizeof(((struct atl1_adapter *)0)->m), offsetof(struct atl1_adapter, m)
+
+static struct atl1_stats atl1_gstrings_stats[] = {
+ {"rx_packets", ATL1_STAT(soft_stats.rx_packets)},
+ {"tx_packets", ATL1_STAT(soft_stats.tx_packets)},
+ {"rx_bytes", ATL1_STAT(soft_stats.rx_bytes)},
+ {"tx_bytes", ATL1_STAT(soft_stats.tx_bytes)},
+ {"rx_errors", ATL1_STAT(soft_stats.rx_errors)},
+ {"tx_errors", ATL1_STAT(soft_stats.tx_errors)},
+ {"rx_dropped", ATL1_STAT(net_stats.rx_dropped)},
+ {"tx_dropped", ATL1_STAT(net_stats.tx_dropped)},
+ {"multicast", ATL1_STAT(soft_stats.multicast)},
+ {"collisions", ATL1_STAT(soft_stats.collisions)},
+ {"rx_length_errors", ATL1_STAT(soft_stats.rx_length_errors)},
+ {"rx_over_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
+ {"rx_crc_errors", ATL1_STAT(soft_stats.rx_crc_errors)},
+ {"rx_frame_errors", ATL1_STAT(soft_stats.rx_frame_errors)},
+ {"rx_fifo_errors", ATL1_STAT(soft_stats.rx_fifo_errors)},
+ {"rx_missed_errors", ATL1_STAT(soft_stats.rx_missed_errors)},
+ {"tx_aborted_errors", ATL1_STAT(soft_stats.tx_aborted_errors)},
+ {"tx_carrier_errors", ATL1_STAT(soft_stats.tx_carrier_errors)},
+ {"tx_fifo_errors", ATL1_STAT(soft_stats.tx_fifo_errors)},
+ {"tx_window_errors", ATL1_STAT(soft_stats.tx_window_errors)},
+ {"tx_abort_exce_coll", ATL1_STAT(soft_stats.excecol)},
+ {"tx_abort_late_coll", ATL1_STAT(soft_stats.latecol)},
+ {"tx_deferred_ok", ATL1_STAT(soft_stats.deffer)},
+ {"tx_single_coll_ok", ATL1_STAT(soft_stats.scc)},
+ {"tx_multi_coll_ok", ATL1_STAT(soft_stats.mcc)},
+ {"tx_underun", ATL1_STAT(soft_stats.tx_underun)},
+ {"tx_trunc", ATL1_STAT(soft_stats.tx_trunc)},
+ {"tx_pause", ATL1_STAT(soft_stats.tx_pause)},
+ {"rx_pause", ATL1_STAT(soft_stats.rx_pause)},
+ {"rx_rrd_ov", ATL1_STAT(soft_stats.rx_rrd_ov)},
+ {"rx_trunc", ATL1_STAT(soft_stats.rx_trunc)}
+};
+
+static void atl1_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct atl1_adapter *adapter = netdev_priv(netdev);
+ int i;
+ char *p;
+
+ for (i = 0; i < ARRAY_SIZE(atl1_gstrings_stats); i++) {
+ p = (char *)adapter+atl1_gstrings_stats[i].stat_offset;
+ data[i] = (atl1_gstrings_stats[i].sizeof_stat ==
+ sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+ }
+
+}
+
+static int atl1_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return ARRAY_SIZE(atl1_gstrings_stats);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int atl1_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl1_adapter *adapter = netdev_priv(netdev);
+ struct atl1_hw *hw = &adapter->hw;
+
+ ecmd->supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_TP);
+ ecmd->advertising = ADVERTISED_TP;
+ if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+ hw->media_type == MEDIA_TYPE_1000M_FULL) {
+ ecmd->advertising |= ADVERTISED_Autoneg;
+ if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR) {
+ ecmd->advertising |= ADVERTISED_Autoneg;
+ ecmd->advertising |=
+ (ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_1000baseT_Full);
+ } else
+ ecmd->advertising |= (ADVERTISED_1000baseT_Full);
+ }
+ ecmd->port = PORT_TP;
+ ecmd->phy_address = 0;
+ ecmd->transceiver = XCVR_INTERNAL;
+
+ if (netif_carrier_ok(adapter->netdev)) {
+ u16 link_speed, link_duplex;
+ atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex);
+ ecmd->speed = link_speed;
+ if (link_duplex == FULL_DUPLEX)
+ ecmd->duplex = DUPLEX_FULL;
+ else
+ ecmd->duplex = DUPLEX_HALF;
+ } else {
+ ecmd->speed = -1;
+ ecmd->duplex = -1;
+ }
+ if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+ hw->media_type == MEDIA_TYPE_1000M_FULL)
+ ecmd->autoneg = AUTONEG_ENABLE;
+ else
+ ecmd->autoneg = AUTONEG_DISABLE;
+
+ return 0;
+}
+
+static int atl1_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct atl1_adapter *adapter = netdev_priv(netdev);
+ struct atl1_hw *hw = &adapter->hw;
+ u16 phy_data;
+ int ret_val = 0;
+ u16 old_media_type = hw->media_type;
+
+ if (netif_running(adapter->netdev)) {
+ dev_dbg(&adapter->pdev->dev, "ethtool shutting down adapter\n");
+ atl1_down(adapter);
+ }
+
+ if (ecmd->autoneg == AUTONEG_ENABLE)
+ hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
+ else {
+ if (ecmd->speed == SPEED_1000) {
+ if (ecmd->duplex != DUPLEX_FULL) {
+ dev_warn(&adapter->pdev->dev,
+ "can't force to 1000M half duplex\n");
+ ret_val = -EINVAL;
+ goto exit_sset;
+ }
+ hw->media_type = MEDIA_TYPE_1000M_FULL;
+ } else if (ecmd->speed == SPEED_100) {
+ if (ecmd->duplex == DUPLEX_FULL)
+ hw->media_type = MEDIA_TYPE_100M_FULL;
+ else
+ hw->media_type = MEDIA_TYPE_100M_HALF;
+ } else {
+ if (ecmd->duplex == DUPLEX_FULL)
+ hw->media_type = MEDIA_TYPE_10M_FULL;
+ else
+ hw->media_type = MEDIA_TYPE_10M_HALF;
+ }
+ }
+ switch (hw->media_type) {
+ case MEDIA_TYPE_AUTO_SENSOR:
+ ecmd->advertising =
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_Autoneg | ADVERTISED_TP;
+ break;
+ case MEDIA_TYPE_1000M_FULL:
+ ecmd->advertising =
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_Autoneg | ADVERTISED_TP;
+ break;
+ default:
+ ecmd->advertising = 0;
+ break;
+ }
+ if (atl1_phy_setup_autoneg_adv(hw)) {
+ ret_val = -EINVAL;
+ dev_warn(&adapter->pdev->dev,
+ "invalid ethtool speed/duplex setting\n");
+ goto exit_sset;
+ }
+ if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
+ hw->media_type == MEDIA_TYPE_1000M_FULL)
+ phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN;
+ else {
+ switch (hw->media_type) {
+ case MEDIA_TYPE_100M_FULL:
+ phy_data =
+ MII_CR_FULL_DUPLEX | MII_CR_SPEED_100 |
+ MII_CR_RESET;
+ break;
+ case MEDIA_TYPE_100M_HALF:
+ phy_data = MII_CR_SPEED_100 | MII_CR_RESET;
+ break;
+ case MEDIA_TYPE_10M_FULL:
+ phy_data =
+ MII_CR_FULL_DUPLEX | MII_CR_SPEED_10 | MII_CR_RESET;
+ break;
+ default:
+ /* MEDIA_TYPE_10M_HALF: */
+ phy_data = MII_CR_SPEED_10 | MII_CR_RESET;
+ break;
+ }
+ }
+ atl1_write_phy_reg(hw, MII_BMCR, phy_data);
+exit_sset:
+ if (ret_val)
+ hw->media_type = old_media_type;
+
+ if (netif_running(adapter->netdev)) {
+ dev_dbg(&adapter->pdev->dev, "ethtool starting adapter\n");
+ atl1_up(adapter);
+ } else if (!ret_val) {
+ dev_dbg(&adapter->pdev->dev, "ethtool resetting adapter\n");
+ atl1_reset(adapter);
+ }
+ return ret_val;
+}
+
+static void atl1_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct atl1_adapter *adapter = netdev_priv(netdev);
+
+ strncpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver));
+ strncpy(drvinfo->version, ATLX_DRIVER_VERSION,
+ sizeof(drvinfo->version));
+ strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+ strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
+ sizeof(drvinfo->bus_info));
+ drvinfo->eedump_len = ATL1_EEDUMP_LEN;
+}
+
+static void atl1_get_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ struct atl1_adapter *adapter = netdev_priv(netdev);
+
+ wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
+ wol->wolopts = 0;
+ if (adapter->wol & ATLX_WUFC_EX)
+ wol->wolopts |= WAKE_UCAST;
+ if (adapter->wol & ATLX_WUFC_MC)
+ wol->wolopts |= WAKE_MCAST;
+ if (adapter->wol & ATLX_WUFC_BC)
+ wol->wolopts |= WAKE_BCAST;
+ if (adapter->wol & ATLX_WUFC_MAG)
+ wol->wolopts |= WAKE_MAGIC;
+ return;
+}
+
+static int atl1_set_wol(struct net_device *netdev,
+ struct ethtool_wolinfo *wol)
+{
+ struct atl1_adapter *adapter = netdev_priv(netdev);
+
+ if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+ return -EOPNOTSUPP;
+ adapter->wol = 0;
+ if (wol->wolopts & WAKE_UCAST)
+ adapter->wol |= ATLX_WUFC_EX;
+ if (wol->wolopts & WAKE_MCAST)
+ adapter->wol |= ATLX_WUFC_MC;
+ if (wol->wolopts & WAKE_BCAST)
+ adapter->wol |= ATLX_WUFC_BC;
+ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= ATLX_WUFC_MAG;
+ return 0;
+}
+
+static void atl1_get_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+{
+ struct atl1_adapter *adapter = netdev_priv(netdev);
+ struct atl1_tpd_ring *txdr = &adapter->tpd_ring;
+ struct atl1_rfd_ring *rxdr = &adapter->rfd_ring;
+
+ ring->rx_max_pending = ATL1_MAX_RFD;
+ ring->tx_max_pending = ATL1_MAX_TPD;
+ ring->rx_mini_max_pending = 0;
+ ring->rx_jumbo_max_pending = 0;
+ ring->rx_pending = rxdr->count;
+ ring->tx_pending = txdr->count;
+ ring->rx_mini_pending = 0;
+ ring->rx_jumbo_pending = 0;
+}
+
+static int atl1_set_ringparam(struct net_device *netdev,
+ struct ethtool_ringparam *ring)
+{
+ struct atl1_adapter *adapter = netdev_priv(netdev);
+ struct atl1_tpd_ring *tpdr = &adapter->tpd_ring;
+ struct atl1_rrd_ring *rrdr = &adapter->rrd_ring;
+ struct atl1_rfd_ring *rfdr = &adapter->rfd_ring;
+
+ struct atl1_tpd_ring tpd_old, tpd_new;
+ struct atl1_rfd_ring rfd_old, rfd_new;
+ struct atl1_rrd_ring rrd_old, rrd_new;
+ struct atl1_ring_header rhdr_old, rhdr_new;
+ int err;
+
+ tpd_old = adapter->tpd_ring;
+ rfd_old = adapter->rfd_ring;
+ rrd_old = adapter->rrd_ring;
+ rhdr_old = adapter->ring_header;
+
+ if (netif_running(adapter->netdev))
+ atl1_down(adapter);
+
+ rfdr->count = (u16) max(ring->rx_pending, (u32) ATL1_MIN_RFD);
+ rfdr->count = rfdr->count > ATL1_MAX_RFD ? ATL1_MAX_RFD :
+ rfdr->count;
+ rfdr->count = (rfdr->count + 3) & ~3;
+ rrdr->count = rfdr->count;
+
+ tpdr->count = (u16) max(ring->tx_pending, (u32) ATL1_MIN_TPD);
+ tpdr->count = tpdr->count > ATL1_MAX_TPD ? ATL1_MAX_TPD :
+ tpdr->count;
+ tpdr->count = (tpdr->count + 3) & ~3;
+
+ if (netif_running(adapter->netdev)) {
+ /* try to get new resources before deleting old */
+ err = atl1_setup_ring_resources(adapter);
+ if (err)
+ goto err_setup_ring;
+
+ /*
+ * save the new, restore the old in order to free it,
+ * then restore the new back again
+ */
+
+ rfd_new = adapter->rfd_ring;
+ rrd_new = adapter->rrd_ring;
+ tpd_new = adapter->tpd_ring;
+ rhdr_new = adapter->ring_header;
+ adapter->rfd_ring = rfd_old;
+ adapter->rrd_ring = rrd_old;
+ adapter->tpd_ring = tpd_old;
+ adapter->ring_header = rhdr_old;
+ atl1_free_ring_resources(adapter);
+ adapter->rfd_ring = rfd_new;
+ adapter->rrd_ring = rrd_new;
+ adapter->tpd_ring = tpd_new;
+ adapter->ring_header = rhdr_new;
+
+ err = atl1_up(adapter);
+ if (err)
+ return err;
+ }
+ return 0;
+
+err_setup_ring:
+ adapter->rfd_ring = rfd_old;
+ adapter->rrd_ring = rrd_old;
+ adapter->tpd_ring = tpd_old;
+ adapter->ring_header = rhdr_old;
+ atl1_up(adapter);
+ return