Newer
Older
/* Advanced Micro Devices Inc. AMD8111E Linux Network Driver
* Copyright (C) 2004 Advanced Micro Devices
*
*
* Copyright 2001,2002 Jeff Garzik <jgarzik@mandrakesoft.com> [ 8139cp.c,tg3.c ]
* Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)[ tg3.c]
* Copyright 1996-1999 Thomas Bogendoerfer [ pcnet32.c ]
* Derived from the lance driver written 1993,1994,1995 by Donald Becker.
* Copyright 1993 United States Government as represented by the
* Director, National Security Agency.[ pcnet32.c ]
* Carsten Langgaard, carstenl@mips.com [ pcnet32.c ]
* Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
AMD8111 based 10/100 Ethernet Controller Driver.
Environment:
Kernel Mode
Revision History:
3.0.0
Initial Revision.
3.0.1
1. Dynamic interrupt coalescing.
2. Removed prev_stats.
3. MII support.
4. Dynamic IPG support
3.0.2 05/29/2003
1. Bug fix: Fixed failure to send jumbo packets larger than 4k.
2. Bug fix: Fixed VLAN support failure.
3. Bug fix: Fixed receive interrupt coalescing bug.
4. Dynamic IPG support is disabled by default.
3.0.3 06/05/2003
1. Bug fix: Fixed failure to close the interface if SMP is enabled.
3.0.4 12/09/2003
1. Added set_mac_address routine for bonding driver support.
2. Tested the driver for bonding support
3. Bug fix: Fixed mismach in actual receive buffer lenth and lenth
4. Modified amd8111e_rx() routine to receive all the received packets
in the first interrupt.
5. Bug fix: Corrected rx_errors reported in get_stats() function.
3.0.5 03/22/2004
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
#include <linux/dma-mapping.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
#define AMD8111E_VLAN_TAG_USED 1
#else
#define AMD8111E_VLAN_TAG_USED 0
#endif
#include "amd8111e.h"
#define MODULE_NAME "amd8111e"
#define MODULE_VERS "3.0.7"
MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version "MODULE_VERS);
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl);
module_param_array(speed_duplex, int, NULL, 0);
MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotiate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex");
module_param_array(coalesce, bool, NULL, 0);
MODULE_PARM_DESC(coalesce, "Enable or Disable interrupt coalescing, 1: Enable, 0: Disable");
module_param_array(dynamic_ipg, bool, NULL, 0);
MODULE_PARM_DESC(dynamic_ipg, "Enable or Disable dynamic IPG, 1: Enable, 0: Disable");
static DEFINE_PCI_DEVICE_TABLE(amd8111e_pci_tbl) = {
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD8111E_7462,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ 0, }
};
This function will read the PHY registers.
*/
static int amd8111e_read_phy(struct amd8111e_priv* lp, int phy_id, int reg, u32* val)
{
void __iomem *mmio = lp->mmio;
unsigned int reg_val;
unsigned int repeat= REPEAT_CNT;
reg_val = readl(mmio + PHY_ACCESS);
while (reg_val & PHY_CMD_ACTIVE)
reg_val = readl( mmio + PHY_ACCESS );
writel( PHY_RD_CMD | ((phy_id & 0x1f) << 21) |
((reg & 0x1f) << 16), mmio +PHY_ACCESS);
do{
reg_val = readl(mmio + PHY_ACCESS);
udelay(30); /* It takes 30 us to read/write data */
} while (--repeat && (reg_val & PHY_CMD_ACTIVE));
if(reg_val & PHY_RD_ERR)
goto err_phy_read;
/*
This function will write into PHY registers.
*/
static int amd8111e_write_phy(struct amd8111e_priv* lp,int phy_id, int reg, u32 val)
{
void __iomem *mmio = lp->mmio;
unsigned int reg_val;
reg_val = readl(mmio + PHY_ACCESS);
while (reg_val & PHY_CMD_ACTIVE)
reg_val = readl( mmio + PHY_ACCESS );
writel( PHY_WR_CMD | ((phy_id & 0x1f) << 21) |
((reg & 0x1f) << 16)|val, mmio + PHY_ACCESS);
do{
reg_val = readl(mmio + PHY_ACCESS);
udelay(30); /* It takes 30 us to read/write the data */
} while (--repeat && (reg_val & PHY_CMD_ACTIVE));
This is the mii register read function provided to the mii interface.
static int amd8111e_mdio_read(struct net_device * dev, int phy_id, int reg_num)
{
struct amd8111e_priv* lp = netdev_priv(dev);
unsigned int reg_val;
amd8111e_read_phy(lp,phy_id,reg_num,®_val);
return reg_val;
This is the mii register write function provided to the mii interface.
static void amd8111e_mdio_write(struct net_device * dev, int phy_id, int reg_num, int val)
{
Loading
Loading full blame...