Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6

* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (35 commits)
  xen-netfront: rearrange netfront structure to separate tx and rx
  netdev: convert non-obvious instances to use ARRAY_SIZE()
  ucc_geth: Fix build break introduced by commit 09f75cd7bf
  gianfar: Fix regression caused by new napi interface
  gianfar: Cleanup compile warning caused by 0795af57
  gianfar: Fix compile regression caused by bea3348e
  add new prom.h for AU1x00
  update AU1000 get_ethernet_addr()
  MIPSsim: General cleanup
  Jazzsonic: Fix warning about unused variable.
  Remove msic_dcr_read() in axon_msi.c
  Use dcr_host_t.base in dcr_unmap()
  Add dcr_host_t.base in dcr_read()/dcr_write()
  Use dcr_host_t.base in ibm_emac_mal
  Update ibm_newemac to use dcr_host_t.base
  tehuti: possible leak in bdx_probe
  TC35815: Fix build
  SAA9730: Fix build
  AR7 ethernet
  myri10ge: update driver version to 1.3.2-1.287
  ...
This commit is contained in:
Linus Torvalds 2007-10-15 13:30:35 -07:00
commit 43d39ae0cf
51 changed files with 1914 additions and 325 deletions

View File

@ -281,6 +281,39 @@ downdelay
will be rounded down to the nearest multiple. The default
value is 0.
fail_over_mac
Specifies whether active-backup mode should set all slaves to
the same MAC address (the traditional behavior), or, when
enabled, change the bond's MAC address when changing the
active interface (i.e., fail over the MAC address itself).
Fail over MAC is useful for devices that cannot ever alter
their MAC address, or for devices that refuse incoming
broadcasts with their own source MAC (which interferes with
the ARP monitor).
The down side of fail over MAC is that every device on the
network must be updated via gratuitous ARP, vs. just updating
a switch or set of switches (which often takes place for any
traffic, not just ARP traffic, if the switch snoops incoming
traffic to update its tables) for the traditional method. If
the gratuitous ARP is lost, communication may be disrupted.
When fail over MAC is used in conjuction with the mii monitor,
devices which assert link up prior to being able to actually
transmit and receive are particularly susecptible to loss of
the gratuitous ARP, and an appropriate updelay setting may be
required.
A value of 0 disables fail over MAC, and is the default. A
value of 1 enables fail over MAC. This option is enabled
automatically if the first slave added cannot change its MAC
address. This option may be modified via sysfs only when no
slaves are present in the bond.
This option was added in bonding version 3.2.0.
lacp_rate
Option specifying the rate in which we'll ask our link partner

View File

@ -33,7 +33,6 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@ -41,18 +40,16 @@
#include <asm/bootinfo.h>
/* #define DEBUG_CMDLINE */
extern int prom_argc;
extern char **prom_argv, **prom_envp;
int prom_argc;
char **prom_argv;
char **prom_envp;
char * __init_or_module prom_getcmdline(void)
{
return &(arcs_cmdline[0]);
}
void prom_init_cmdline(void)
void prom_init_cmdline(void)
{
char *cp;
int actr;
@ -61,7 +58,7 @@ void prom_init_cmdline(void)
cp = &(arcs_cmdline[0]);
while(actr < prom_argc) {
strcpy(cp, prom_argv[actr]);
strcpy(cp, prom_argv[actr]);
cp += strlen(prom_argv[actr]);
*cp++ = ' ';
actr++;
@ -70,10 +67,8 @@ void prom_init_cmdline(void)
--cp;
if (prom_argc > 1)
*cp = '\0';
}
char *prom_getenv(char *envname)
{
/*
@ -95,21 +90,23 @@ char *prom_getenv(char *envname)
}
env++;
}
return NULL;
}
inline unsigned char str2hexnum(unsigned char c)
static inline unsigned char str2hexnum(unsigned char c)
{
if(c >= '0' && c <= '9')
if (c >= '0' && c <= '9')
return c - '0';
if(c >= 'a' && c <= 'f')
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if(c >= 'A' && c <= 'F')
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return 0; /* foo */
}
inline void str2eaddr(unsigned char *ea, unsigned char *str)
static inline void str2eaddr(unsigned char *ea, unsigned char *str)
{
int i;
@ -124,35 +121,29 @@ inline void str2eaddr(unsigned char *ea, unsigned char *str)
}
}
int get_ethernet_addr(char *ethernet_addr)
int prom_get_ethernet_addr(char *ethernet_addr)
{
char *ethaddr_str;
char *ethaddr_str;
char *argptr;
ethaddr_str = prom_getenv("ethaddr");
/* Check the environment variables first */
ethaddr_str = prom_getenv("ethaddr");
if (!ethaddr_str) {
printk("ethaddr not set in boot prom\n");
return -1;
/* Check command line */
argptr = prom_getcmdline();
ethaddr_str = strstr(argptr, "ethaddr=");
if (!ethaddr_str)
return -1;
ethaddr_str += strlen("ethaddr=");
}
str2eaddr(ethernet_addr, ethaddr_str);
#if 0
{
int i;
printk("get_ethernet_addr: ");
for (i=0; i<5; i++)
printk("%02x:", (unsigned char)*(ethernet_addr+i));
printk("%02x\n", *(ethernet_addr+i));
}
#endif
return 0;
}
EXPORT_SYMBOL(prom_get_ethernet_addr);
void __init prom_free_prom_memory(void)
{
}
EXPORT_SYMBOL(prom_getcmdline);
EXPORT_SYMBOL(get_ethernet_addr);
EXPORT_SYMBOL(str2eaddr);

View File

@ -40,10 +40,11 @@
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/time.h>
extern char * prom_getcmdline(void);
#include <au1000.h>
#include <prom.h>
extern void __init board_setup(void);
extern void au1000_restart(char *);
extern void au1000_halt(void);

View File

@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
int prom_argc;
char **prom_argv, **prom_envp;
extern void __init prom_init_cmdline(void);
extern char *prom_getenv(char *envname);
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{

View File

@ -34,13 +34,11 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
int prom_argc;
char **prom_argv, **prom_envp;
extern void __init prom_init_cmdline(void);
extern char *prom_getenv(char *envname);
#include <prom.h>
const char *get_system_type(void)
{

View File

@ -30,15 +30,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
int prom_argc;
char **prom_argv, **prom_envp;
extern void __init prom_init_cmdline(void);
extern char *prom_getenv(char *envname);
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{

View File

@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
int prom_argc;
char **prom_argv, **prom_envp;
extern void __init prom_init_cmdline(void);
extern char *prom_getenv(char *envname);
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{

View File

@ -41,8 +41,10 @@
#include <asm/mipsregs.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <au1000.h>
#include <au1xxx_dbdma.h>
#include <prom.h>
#ifdef CONFIG_MIPS_PB1200
#include <asm/mach-pb1x00/pb1200.h>

View File

@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
int prom_argc;
char **prom_argv, **prom_envp;
extern void __init prom_init_cmdline(void);
extern char *prom_getenv(char *envname);
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{

View File

@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
int prom_argc;
char **prom_argv, **prom_envp;
extern void __init prom_init_cmdline(void);
extern char *prom_getenv(char *envname);
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{

View File

@ -31,15 +31,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
int prom_argc;
char **prom_argv, **prom_envp;
extern void __init prom_init_cmdline(void);
extern char *prom_getenv(char *envname);
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{

View File

@ -30,15 +30,13 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/bootmem.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <linux/string.h>
#include <linux/kernel.h>
int prom_argc;
char **prom_argv, **prom_envp;
extern void __init prom_init_cmdline(void);
extern char *prom_getenv(char *envname);
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{

View File

@ -77,12 +77,7 @@ static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
{
pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
dcr_write(msic->dcr_host, msic->dcr_host.base + dcr_n, val);
}
static u32 msic_dcr_read(struct axon_msic *msic, unsigned int dcr_n)
{
return dcr_read(msic->dcr_host, msic->dcr_host.base + dcr_n);
dcr_write(msic->dcr_host, dcr_n, val);
}
static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
@ -91,7 +86,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
u32 write_offset, msi;
int idx;
write_offset = msic_dcr_read(msic, MSIC_WRITE_OFFSET_REG);
write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG);
pr_debug("axon_msi: original write_offset 0x%x\n", write_offset);
/* write_offset doesn't wrap properly, so we have to mask it */
@ -306,7 +301,7 @@ static int axon_msi_notify_reboot(struct notifier_block *nb,
list_for_each_entry(msic, &axon_msic_list, list) {
pr_debug("axon_msi: disabling %s\n",
msic->irq_host->of_node->full_name);
tmp = msic_dcr_read(msic, MSIC_CTRL_REG);
tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
}

View File

@ -126,13 +126,13 @@ dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
}
EXPORT_SYMBOL_GPL(dcr_map);
void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c)
void dcr_unmap(dcr_host_t host, unsigned int dcr_c)
{
dcr_host_t h = host;
if (h.token == NULL)
return;
h.token += dcr_n * h.stride;
h.token += host.base * h.stride;
iounmap(h.token);
h.token = NULL;
}

View File

@ -156,7 +156,7 @@ static inline u32 _mpic_read(enum mpic_reg_type type,
switch(type) {
#ifdef CONFIG_PPC_DCR
case mpic_access_dcr:
return dcr_read(rb->dhost, rb->dhost.base + reg);
return dcr_read(rb->dhost, reg);
#endif
case mpic_access_mmio_be:
return in_be32(rb->base + (reg >> 2));
@ -173,7 +173,7 @@ static inline void _mpic_write(enum mpic_reg_type type,
switch(type) {
#ifdef CONFIG_PPC_DCR
case mpic_access_dcr:
return dcr_write(rb->dhost, rb->dhost.base + reg, value);
return dcr_write(rb->dhost, reg, value);
#endif
case mpic_access_mmio_be:
return out_be32(rb->base + (reg >> 2), value);

View File

@ -349,6 +349,7 @@ struct ipoib_neigh {
struct sk_buff_head queue;
struct neighbour *neighbour;
struct net_device *dev;
struct list_head list;
};
@ -365,7 +366,8 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh)
INFINIBAND_ALEN, sizeof(void *));
}
struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh);
struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
struct net_device *dev);
void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
extern struct workqueue_struct *ipoib_workqueue;

View File

@ -517,7 +517,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
struct ipoib_path *path;
struct ipoib_neigh *neigh;
neigh = ipoib_neigh_alloc(skb->dst->neighbour);
neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
if (!neigh) {
++dev->stats.tx_dropped;
dev_kfree_skb_any(skb);
@ -692,9 +692,10 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto out;
}
} else if (neigh->ah) {
if (unlikely(memcmp(&neigh->dgid.raw,
if (unlikely((memcmp(&neigh->dgid.raw,
skb->dst->neighbour->ha + 4,
sizeof(union ib_gid)))) {
sizeof(union ib_gid))) ||
(neigh->dev != dev))) {
spin_lock(&priv->lock);
/*
* It's safe to call ipoib_put_ah() inside
@ -817,6 +818,13 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
unsigned long flags;
struct ipoib_ah *ah = NULL;
neigh = *to_ipoib_neigh(n);
if (neigh) {
priv = netdev_priv(neigh->dev);
ipoib_dbg(priv, "neigh_destructor for bonding device: %s\n",
n->dev->name);
} else
return;
ipoib_dbg(priv,
"neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
IPOIB_QPN(n->ha),
@ -824,13 +832,10 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
spin_lock_irqsave(&priv->lock, flags);
neigh = *to_ipoib_neigh(n);
if (neigh) {
if (neigh->ah)
ah = neigh->ah;
list_del(&neigh->list);
ipoib_neigh_free(n->dev, neigh);
}
if (neigh->ah)
ah = neigh->ah;
list_del(&neigh->list);
ipoib_neigh_free(n->dev, neigh);
spin_unlock_irqrestore(&priv->lock, flags);
@ -838,7 +843,8 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
ipoib_put_ah(ah);
}
struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour,
struct net_device *dev)
{
struct ipoib_neigh *neigh;
@ -847,6 +853,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
return NULL;
neigh->neighbour = neighbour;
neigh->dev = dev;
*to_ipoib_neigh(neighbour) = neigh;
skb_queue_head_init(&neigh->queue);
ipoib_cm_set(neigh, NULL);

View File

@ -705,7 +705,8 @@ out:
if (skb->dst &&
skb->dst->neighbour &&
!*to_ipoib_neigh(skb->dst->neighbour)) {
struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour);
struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour,
skb->dev);
if (neigh) {
kref_get(&mcast->ah->ref);

View File

@ -1780,6 +1780,15 @@ config SC92031
To compile this driver as a module, choose M here: the module
will be called sc92031. This is recommended.
config CPMAC
tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
depends on NET_ETHERNET && EXPERIMENTAL && AR7
select PHYLIB
select FIXED_PHY
select FIXED_MII_100_FDX
help
TI AR7 CPMAC Ethernet support
config NET_POCKET
bool "Pocket and portable adapters"
depends on PARPORT

View File

@ -159,6 +159,7 @@ obj-$(CONFIG_8139CP) += 8139cp.o
obj-$(CONFIG_8139TOO) += 8139too.o
obj-$(CONFIG_ZNET) += znet.o
obj-$(CONFIG_LAN_SAA9730) += saa9730.o
obj-$(CONFIG_CPMAC) += cpmac.o
obj-$(CONFIG_DEPCA) += depca.o
obj-$(CONFIG_EWRK3) += ewrk3.o
obj-$(CONFIG_ATP) += atp.o

View File

@ -54,13 +54,16 @@
#include <linux/delay.h>
#include <linux/crc32.h>
#include <linux/phy.h>
#include <asm/cpu.h>
#include <asm/mipsregs.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/cpu.h>
#include <au1000.h>
#include <prom.h>
#include "au1000_eth.h"
#ifdef AU1000_ETH_DEBUG
@ -96,11 +99,6 @@ static void mdio_write(struct net_device *, int, int, u16);
static void au1000_adjust_link(struct net_device *);
static void enable_mac(struct net_device *, int);
// externs
extern int get_ethernet_addr(char *ethernet_addr);
extern void str2eaddr(unsigned char *ea, unsigned char *str);
extern char * prom_getcmdline(void);
/*
* Theory of operation
*
@ -619,7 +617,6 @@ static struct net_device * au1000_probe(int port_num)
struct au1000_private *aup = NULL;
struct net_device *dev = NULL;
db_dest_t *pDB, *pDBfree;
char *pmac, *argptr;
char ethaddr[6];
int irq, i, err;
u32 base, macen;
@ -677,21 +674,12 @@ static struct net_device * au1000_probe(int port_num)
au_macs[port_num] = aup;
if (port_num == 0) {
/* Check the environment variables first */
if (get_ethernet_addr(ethaddr) == 0)
if (prom_get_ethernet_addr(ethaddr) == 0)
memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
else {
/* Check command line */
argptr = prom_getcmdline();
if ((pmac = strstr(argptr, "ethaddr=")) == NULL)
printk(KERN_INFO "%s: No MAC address found\n",
dev->name);
printk(KERN_INFO "%s: No MAC address found\n",
dev->name);
/* Use the hard coded MAC addresses */
else {
str2eaddr(ethaddr, pmac + strlen("ethaddr="));
memcpy(au1000_mac_addr, ethaddr,
sizeof(au1000_mac_addr));
}
}
setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);

View File

@ -98,6 +98,7 @@ static char *xmit_hash_policy = NULL;
static int arp_interval = BOND_LINK_ARP_INTERV;
static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
static char *arp_validate = NULL;
static int fail_over_mac = 0;
struct bond_params bonding_defaults;
module_param(max_bonds, int, 0);
@ -131,6 +132,8 @@ module_param_array(arp_ip_target, charp, NULL, 0);
MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
module_param(arp_validate, charp, 0);
MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
module_param(fail_over_mac, int, 0);
MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. 0 of off (default), 1 for on.");
/*----------------------------- Global variables ----------------------------*/
@ -1096,7 +1099,21 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
if (new_active) {
bond_set_slave_active_flags(new_active);
}
bond_send_gratuitous_arp(bond);
/* when bonding does not set the slave MAC address, the bond MAC
* address is the one of the active slave.
*/
if (new_active && bond->params.fail_over_mac)
memcpy(bond->dev->dev_addr, new_active->dev->dev_addr,
new_active->dev->addr_len);
if (bond->curr_active_slave &&
test_bit(__LINK_STATE_LINKWATCH_PENDING,
&bond->curr_active_slave->dev->state)) {
dprintk("delaying gratuitous arp on %s\n",
bond->curr_active_slave->dev->name);
bond->send_grat_arp = 1;
} else
bond_send_gratuitous_arp(bond);
}
}
@ -1217,7 +1234,8 @@ static int bond_compute_features(struct bonding *bond)
struct slave *slave;
struct net_device *bond_dev = bond->dev;
unsigned long features = bond_dev->features;
unsigned short max_hard_header_len = ETH_HLEN;
unsigned short max_hard_header_len = max((u16)ETH_HLEN,
bond_dev->hard_header_len);
int i;
features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
@ -1238,6 +1256,23 @@ static int bond_compute_features(struct bonding *bond)
return 0;
}
static void bond_setup_by_slave(struct net_device *bond_dev,
struct net_device *slave_dev)
{
struct bonding *bond = bond_dev->priv;
bond_dev->neigh_setup = slave_dev->neigh_setup;
bond_dev->type = slave_dev->type;
bond_dev->hard_header_len = slave_dev->hard_header_len;
bond_dev->addr_len = slave_dev->addr_len;
memcpy(bond_dev->broadcast, slave_dev->broadcast,
slave_dev->addr_len);
bond->setup_by_slave = 1;
}
/* enslave device <slave> to bond device <master> */
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
{
@ -1258,8 +1293,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
/* bond must be initialized by bond_open() before enslaving */
if (!(bond_dev->flags & IFF_UP)) {
dprintk("Error, master_dev is not up\n");
return -EPERM;
printk(KERN_WARNING DRV_NAME
" %s: master_dev is not up in bond_enslave\n",
bond_dev->name);
}
/* already enslaved */
@ -1312,14 +1348,42 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
goto err_undo_flags;
}
/* set bonding device ether type by slave - bonding netdevices are
* created with ether_setup, so when the slave type is not ARPHRD_ETHER
* there is a need to override some of the type dependent attribs/funcs.
*
* bond ether type mutual exclusion - don't allow slaves of dissimilar
* ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond
*/
if (bond->slave_cnt == 0) {
if (slave_dev->type != ARPHRD_ETHER)
bond_setup_by_slave(bond_dev, slave_dev);
} else if (bond_dev->type != slave_dev->type) {
printk(KERN_ERR DRV_NAME ": %s ether type (%d) is different "
"from other slaves (%d), can not enslave it.\n",
slave_dev->name,
slave_dev->type, bond_dev->type);
res = -EINVAL;
goto err_undo_flags;
}
if (slave_dev->set_mac_address == NULL) {
printk(KERN_ERR DRV_NAME
": %s: Error: The slave device you specified does "
"not support setting the MAC address. "
"Your kernel likely does not support slave "
"devices.\n", bond_dev->name);
res = -EOPNOTSUPP;
goto err_undo_flags;
if (bond->slave_cnt == 0) {
printk(KERN_WARNING DRV_NAME
": %s: Warning: The first slave device "
"specified does not support setting the MAC "
"address. Enabling the fail_over_mac option.",
bond_dev->name);
bond->params.fail_over_mac = 1;
} else if (!bond->params.fail_over_mac) {
printk(KERN_ERR DRV_NAME
": %s: Error: The slave device specified "
"does not support setting the MAC address, "
"but fail_over_mac is not enabled.\n"
, bond_dev->name);
res = -EOPNOTSUPP;
goto err_undo_flags;
}
}
new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
@ -1340,16 +1404,18 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
*/
memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
/*
* Set slave to master's mac address. The application already
* set the master's mac address to that of the first slave
*/
memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
addr.sa_family = slave_dev->type;
res = dev_set_mac_address(slave_dev, &addr);
if (res) {
dprintk("Error %d calling set_mac_address\n", res);
goto err_free;
if (!bond->params.fail_over_mac) {
/*
* Set slave to master's mac address. The application already
* set the master's mac address to that of the first slave
*/
memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
addr.sa_family = slave_dev->type;
res = dev_set_mac_address(slave_dev, &addr);
if (res) {
dprintk("Error %d calling set_mac_address\n", res);
goto err_free;
}
}
res = netdev_set_master(slave_dev, bond_dev);
@ -1574,9 +1640,11 @@ err_close:
dev_close(slave_dev);
err_restore_mac:
memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
if (!bond->params.fail_over_mac) {
memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
}
err_free:
kfree(new_slave);
@ -1749,10 +1817,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
/* close slave before restoring its mac address */
dev_close(slave_dev);
/* restore original ("permanent") mac address */
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
if (!bond->params.fail_over_mac) {
/* restore original ("permanent") mac address */
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
}
slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
IFF_SLAVE_INACTIVE | IFF_BONDING |
@ -1763,6 +1833,35 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
return 0; /* deletion OK */
}
/*
* Destroy a bonding device.
* Must be under rtnl_lock when this function is called.
*/
void bond_destroy(struct bonding *bond)
{
bond_deinit(bond->dev);
bond_destroy_sysfs_entry(bond);
unregister_netdevice(bond->dev);
}
/*
* First release a slave and than destroy the bond if no more slaves iare left.
* Must be under rtnl_lock when this function is called.
*/
int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev)
{
struct bonding *bond = bond_dev->priv;
int ret;
ret = bond_release(bond_dev, slave_dev);
if ((ret == 0) && (bond->slave_cnt == 0)) {
printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
bond_dev->name, bond_dev->name);
bond_destroy(bond);
}
return ret;
}
/*
* This function releases all slaves.
*/
@ -1839,10 +1938,12 @@ static int bond_release_all(struct net_device *bond_dev)
/* close slave before restoring its mac address */
dev_close(slave_dev);
/* restore original ("permanent") mac address*/
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
if (!bond->params.fail_over_mac) {
/* restore original ("permanent") mac address*/
memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
addr.sa_family = slave_dev->type;
dev_set_mac_address(slave_dev, &addr);
}
slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
IFF_SLAVE_INACTIVE);
@ -2013,6 +2114,17 @@ void bond_mii_monitor(struct net_device *bond_dev)
* program could monitor the link itself if needed.
*/
if (bond->send_grat_arp) {
if (bond->curr_active_slave && test_bit(__LINK_STATE_LINKWATCH_PENDING,
&bond->curr_active_slave->dev->state))
dprintk("Needs to send gratuitous arp but not yet\n");
else {
dprintk("sending delayed gratuitous arp on on %s\n",
bond->curr_active_slave->dev->name);
bond_send_gratuitous_arp(bond);
bond->send_grat_arp = 0;
}
}
read_lock(&bond->curr_slave_lock);
oldcurrent = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
@ -2414,7 +2526,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
if (bond->master_ip) {
bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
bond->master_ip, 0);
bond->master_ip, 0);
}
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
@ -2951,9 +3063,15 @@ static void bond_info_show_master(struct seq_file *seq)
curr = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);
seq_printf(seq, "Bonding Mode: %s\n",
seq_printf(seq, "Bonding Mode: %s",
bond_mode_name(bond->params.mode));
if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
bond->params.fail_over_mac)
seq_printf(seq, " (fail_over_mac)");
seq_printf(seq, "\n");
if (bond->params.mode == BOND_MODE_XOR ||
bond->params.mode == BOND_MODE_8023AD) {
seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
@ -3248,6 +3366,11 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
* ... Or is it this?
*/
break;
case NETDEV_GOING_DOWN:
dprintk("slave %s is going down\n", slave_dev->name);
if (bond->setup_by_slave)
bond_release_and_destroy(bond_dev, slave_dev);
break;
case NETDEV_CHANGEMTU:
/*
* TODO: Should slaves be allowed to
@ -3880,6 +4003,13 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
/*
* If fail_over_mac is enabled, do nothing and return success.
* Returning an error causes ifenslave to fail.
*/
if (bond->params.fail_over_mac)
return 0;
if (!is_valid_ether_addr(sa->sa_data)) {
return -EADDRNOTAVAIL;
}
@ -4217,6 +4347,8 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
bond->current_arp_slave = NULL;
bond->primary_slave = NULL;
bond->dev = bond_dev;
bond->send_grat_arp = 0;
bond->setup_by_slave = 0;
INIT_LIST_HEAD(&bond->vlan_list);
/* Initialize the device entry points */
@ -4265,7 +4397,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
#ifdef CONFIG_PROC_FS
bond_create_proc_entry(bond);
#endif
list_add_tail(&bond->bond_list, &bond_dev_list);
return 0;
@ -4599,6 +4730,11 @@ static int bond_check_params(struct bond_params *params)
primary = NULL;
}
if (fail_over_mac && (bond_mode != BOND_MODE_ACTIVEBACKUP))
printk(KERN_WARNING DRV_NAME
": Warning: fail_over_mac only affects "
"active-backup mode.\n");
/* fill params struct with the proper values */
params->mode = bond_mode;
params->xmit_policy = xmit_hashtype;
@ -4610,6 +4746,7 @@ static int bond_check_params(struct bond_params *params)
params->use_carrier = use_carrier;
params->lacp_fast = lacp_fast;
params->primary[0] = 0;
params->fail_over_mac = fail_over_mac;
if (primary) {
strncpy(params->primary, primary, IFNAMSIZ);

View File

@ -164,9 +164,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
printk(KERN_INFO DRV_NAME
": %s is being deleted...\n",
bond->dev->name);
bond_deinit(bond->dev);
bond_destroy_sysfs_entry(bond);
unregister_netdevice(bond->dev);
bond_destroy(bond);
rtnl_unlock();
goto out;
}
@ -260,17 +258,16 @@ static ssize_t bonding_store_slaves(struct device *d,
char command[IFNAMSIZ + 1] = { 0, };
char *ifname;
int i, res, found, ret = count;
u32 original_mtu;
struct slave *slave;
struct net_device *dev = NULL;
struct bonding *bond = to_bond(d);
/* Quick sanity check -- is the bond interface up? */
if (!(bond->dev->flags & IFF_UP)) {
printk(KERN_ERR DRV_NAME
": %s: Unable to update slaves because interface is down.\n",
printk(KERN_WARNING DRV_NAME
": %s: doing slave updates when interface is down.\n",
bond->dev->name);
ret = -EPERM;
goto out;
}
/* Note: We can't hold bond->lock here, as bond_create grabs it. */
@ -327,6 +324,7 @@ static ssize_t bonding_store_slaves(struct device *d,
}
/* Set the slave's MTU to match the bond */
original_mtu = dev->mtu;
if (dev->mtu != bond->dev->mtu) {
if (dev->change_mtu) {
res = dev->change_mtu(dev,
@ -341,6 +339,9 @@ static ssize_t bonding_store_slaves(struct device *d,
}
rtnl_lock();
res = bond_enslave(bond->dev, dev);
bond_for_each_slave(bond, slave, i)
if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
slave->original_mtu = original_mtu;
rtnl_unlock();
if (res) {
ret = res;
@ -353,13 +354,17 @@ static ssize_t bonding_store_slaves(struct device *d,
bond_for_each_slave(bond, slave, i)
if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
dev = slave->dev;
original_mtu = slave->original_mtu;
break;
}
if (dev) {
printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
bond->dev->name, dev->name);
rtnl_lock();
res = bond_release(bond->dev, dev);
if (bond->setup_by_slave)
res = bond_release_and_destroy(bond->dev, dev);
else
res = bond_release(bond->dev, dev);
rtnl_unlock();
if (res) {
ret = res;
@ -367,9 +372,9 @@ static ssize_t bonding_store_slaves(struct device *d,
}
/* set the slave MTU to the default */
if (dev->change_mtu) {
dev->change_mtu(dev, 1500);
dev->change_mtu(dev, original_mtu);
} else {
dev->mtu = 1500;
dev->mtu = original_mtu;
}
}
else {
@ -562,6 +567,54 @@ static ssize_t bonding_store_arp_validate(struct device *d,
static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
/*
* Show and store fail_over_mac. User only allowed to change the
* value when there are no slaves.
*/
static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attribute *attr, char *buf)
{
struct bonding *bond = to_bond(d);
return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1;
}
static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count)
{
int new_value;
int ret = count;
struct bonding *bond = to_bond(d);
if (bond->slave_cnt != 0) {
printk(KERN_ERR DRV_NAME
": %s: Can't alter fail_over_mac with slaves in bond.\n",
bond->dev->name);
ret = -EPERM;
goto out;
}
if (sscanf(buf, "%d", &new_value) != 1) {
printk(KERN_ERR DRV_NAME
": %s: no fail_over_mac value specified.\n",
bond->dev->name);
ret = -EINVAL;
goto out;
}
if ((new_value == 0) || (new_value == 1)) {
bond->params.fail_over_mac = new_value;
printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n",
bond->dev->name, new_value);
} else {
printk(KERN_INFO DRV_NAME
": %s: Ignoring invalid fail_over_mac value %d.\n",
bond->dev->name, new_value);
}
out:
return ret;
}
static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac);
/*
* Show and set the arp timer interval. There are two tricky bits
* here. First, if ARP monitoring is activated, then we must disable
@ -1383,6 +1436,7 @@ static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
static struct attribute *per_bond_attrs[] = {
&dev_attr_slaves.attr,
&dev_attr_mode.attr,
&dev_attr_fail_over_mac.attr,
&dev_attr_arp_validate.attr,
&dev_attr_arp_interval.attr,
&dev_attr_arp_ip_target.attr,

View File

@ -22,8 +22,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
#define DRV_VERSION "3.1.3"
#define DRV_RELDATE "June 13, 2007"
#define DRV_VERSION "3.2.0"
#define DRV_RELDATE "September 13, 2007"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
@ -128,6 +128,7 @@ struct bond_params {
int arp_interval;
int arp_validate;
int use_carrier;
int fail_over_mac;
int updelay;
int downdelay;
int lacp_fast;
@ -156,6 +157,7 @@ struct slave {
s8 link; /* one of BOND_LINK_XXXX */
s8 state; /* one of BOND_STATE_XXXX */
u32 original_flags;
u32 original_mtu;
u32 link_failure_count;
u16 speed;
u8 duplex;
@ -185,6 +187,8 @@ struct bonding {
struct timer_list mii_timer;
struct timer_list arp_timer;
s8 kill_timers;
s8 send_grat_arp;
s8 setup_by_slave;
struct net_device_stats stats;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry;
@ -292,6 +296,8 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
void bond_destroy(struct bonding *bond);
int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
void bond_deinit(struct net_device *bond_dev);
int bond_create_sysfs(void);
void bond_destroy_sysfs(void);

View File

@ -4443,7 +4443,7 @@ static struct {
{REG_MAC_COLL_EXCESS},
{REG_MAC_COLL_LATE}
};
#define CAS_REG_LEN (sizeof(ethtool_register_table)/sizeof(int))
#define CAS_REG_LEN ARRAY_SIZE(ethtool_register_table)
#define CAS_MAX_REGS (sizeof (u32)*CAS_REG_LEN)
static void cas_read_regs(struct cas *cp, u8 *ptr, int len)

1174
drivers/net/cpmac.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -168,7 +168,6 @@ static int gfar_probe(struct platform_device *pdev)
struct gfar_private *priv = NULL;
struct gianfar_platform_data *einfo;
struct resource *r;
int idx;
int err = 0;
DECLARE_MAC_BUF(mac);
@ -261,7 +260,9 @@ static int gfar_probe(struct platform_device *pdev)
dev->hard_start_xmit = gfar_start_xmit;
dev->tx_timeout = gfar_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
#ifdef CONFIG_GFAR_NAPI
netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT);
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = gfar_netpoll;
#endif
@ -931,9 +932,14 @@ tx_skb_fail:
/* Returns 0 for success. */
static int gfar_enet_open(struct net_device *dev)
{
#ifdef CONFIG_GFAR_NAPI
struct gfar_private *priv = netdev_priv(dev);
#endif
int err;
#ifdef CONFIG_GFAR_NAPI
napi_enable(&priv->napi);
#endif
/* Initialize a bunch of registers */
init_registers(dev);
@ -943,13 +949,17 @@ static int gfar_enet_open(struct net_device *dev)
err = init_phy(dev);
if(err) {
#ifdef CONFIG_GFAR_NAPI
napi_disable(&priv->napi);
#endif
return err;
}
err = startup_gfar(dev);
if (err)
#ifdef CONFIG_GFAR_NAPI
napi_disable(&priv->napi);
#endif
netif_start_queue(dev);
@ -1103,7 +1113,9 @@ static int gfar_close(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
#ifdef CONFIG_GFAR_NAPI
napi_disable(&priv->napi);
#endif
stop_gfar(dev);

View File

@ -413,7 +413,10 @@ static int __init mal_probe(struct ocp_device *ocpdev)
ocpdev->def->index);
return -ENOMEM;
}
mal->dcrbase = maldata->dcr_base;
/* XXX This only works for native dcr for now */
mal->dcrhost = dcr_map(NULL, maldata->dcr_base, 0);
mal->def = ocpdev->def;
INIT_LIST_HEAD(&mal->poll_list);

View File

@ -191,7 +191,6 @@ struct mal_commac {
};
struct ibm_ocp_mal {
int dcrbase;
dcr_host_t dcrhost;
struct list_head poll_list;
@ -209,12 +208,12 @@ struct ibm_ocp_mal {
static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
{
return dcr_read(mal->dcrhost, mal->dcrbase + reg);
return dcr_read(mal->dcrhost, reg);
}
static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
{
dcr_write(mal->dcrhost, mal->dcrbase + reg, val);
dcr_write(mal->dcrhost, reg, val);
}
/* Register MAL devices */

View File

@ -461,6 +461,7 @@ static int __devinit mal_probe(struct of_device *ofdev,
struct mal_instance *mal;
int err = 0, i, bd_size;
int index = mal_count++;
unsigned int dcr_base;
const u32 *prop;
u32 cfg;
@ -497,14 +498,14 @@ static int __devinit mal_probe(struct of_device *ofdev,
}
mal->num_rx_chans = prop[0];
mal->dcr_base = dcr_resource_start(ofdev->node, 0);
if (mal->dcr_base == 0) {
dcr_base = dcr_resource_start(ofdev->node, 0);
if (dcr_base == 0) {
printk(KERN_ERR
"mal%d: can't find DCR resource!\n", index);
err = -ENODEV;
goto fail;
}
mal->dcr_host = dcr_map(ofdev->node, mal->dcr_base, 0x100);
mal->dcr_host = dcr_map(ofdev->node, dcr_base, 0x100);
if (!DCR_MAP_OK(mal->dcr_host)) {
printk(KERN_ERR
"mal%d: failed to map DCRs !\n", index);
@ -626,7 +627,7 @@ static int __devinit mal_probe(struct of_device *ofdev,
fail2:
dma_free_coherent(&ofdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
fail_unmap:
dcr_unmap(mal->dcr_host, mal->dcr_base, 0x100);
dcr_unmap(mal->dcr_host, 0x100);
fail:
kfree(mal);

View File

@ -185,7 +185,6 @@ struct mal_commac {
struct mal_instance {
int version;
int dcr_base;
dcr_host_t dcr_host;
int num_tx_chans; /* Number of TX channels */
@ -213,12 +212,12 @@ struct mal_instance {
static inline u32 get_mal_dcrn(struct mal_instance *mal, int reg)
{
return dcr_read(mal->dcr_host, mal->dcr_base + reg);
return dcr_read(mal->dcr_host, reg);
}
static inline void set_mal_dcrn(struct mal_instance *mal, int reg, u32 val)
{
dcr_write(mal->dcr_host, mal->dcr_base + reg, val);
dcr_write(mal->dcr_host, reg, val);
}
/* Register MAL devices */

View File

@ -840,7 +840,7 @@ toshoboe_probe (struct toshoboe_cb *self)
/* test 1: SIR filter and back to back */
for (j = 0; j < (sizeof (bauds) / sizeof (int)); ++j)
for (j = 0; j < ARRAY_SIZE(bauds); ++j)
{
int fir = (j > 1);
toshoboe_stopchip (self);

View File

@ -208,7 +208,6 @@ static int __init jazz_sonic_probe(struct platform_device *pdev)
struct sonic_local *lp;
struct resource *res;
int err = 0;
int i;
DECLARE_MAC_BUF(mac);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

View File

@ -7,12 +7,12 @@
#define DEBUG
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/mips-boards/simint.h>
#include "mipsnet.h" /* actual device IO mapping */
@ -33,9 +33,8 @@ static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
if (available_len < len)
return -EFAULT;
for (; len > 0; len--, kdata++) {
for (; len > 0; len--, kdata++)
*kdata = inb(mipsnet_reg_address(dev, rxDataBuffer));
}
return inl(mipsnet_reg_address(dev, rxDataCount));
}
@ -47,16 +46,15 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
char *buf_ptr = skb->data;
pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
dev->name, __FUNCTION__, skb->len);
dev->name, __FUNCTION__, skb->len);
outl(skb->len, mipsnet_reg_address(dev, txDataCount));
pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
dev->name, __FUNCTION__, skb->len);
dev->name, __FUNCTION__, skb->len);
for (; count_to_go; buf_ptr++, count_to_go--) {
for (; count_to_go; buf_ptr++, count_to_go--)
outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
}
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
@ -67,7 +65,7 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
{
pr_debug("%s:%s(): transmitting %d bytes\n",
dev->name, __FUNCTION__, skb->len);
dev->name, __FUNCTION__, skb->len);
/* Only one packet at a time. Once TXDONE interrupt is serviced, the
* queue will be restarted.
@ -83,7 +81,8 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
struct sk_buff *skb;
size_t len = count;
if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
skb = alloc_skb(len + 2, GFP_KERNEL);
if (!skb) {
dev->stats.rx_dropped++;
return -ENOMEM;
}
@ -96,7 +95,7 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
skb->ip_summed = CHECKSUM_UNNECESSARY;
pr_debug("%s:%s(): pushing RXed data to kernel\n",
dev->name, __FUNCTION__);
dev->name, __FUNCTION__);
netif_rx(skb);
dev->stats.rx_packets++;
@ -114,42 +113,44 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
if (irq == dev->irq) {
pr_debug("%s:%s(): irq %d for device\n",
dev->name, __FUNCTION__, irq);
dev->name, __FUNCTION__, irq);
retval = IRQ_HANDLED;
interruptFlags =
inl(mipsnet_reg_address(dev, interruptControl));
pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
__FUNCTION__, interruptFlags);
__FUNCTION__, interruptFlags);
if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
pr_debug("%s:%s(): got TXDone\n",
dev->name, __FUNCTION__);
dev->name, __FUNCTION__);
outl(MIPSNET_INTCTL_TXDONE,
mipsnet_reg_address(dev, interruptControl));
// only one packet at a time, we are done.
/* only one packet at a time, we are done. */
netif_wake_queue(dev);
} else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
pr_debug("%s:%s(): got RX data\n",
dev->name, __FUNCTION__);
dev->name, __FUNCTION__);
mipsnet_get_fromdev(dev,
inl(mipsnet_reg_address(dev, rxDataCount)));
inl(mipsnet_reg_address(dev, rxDataCount)));
pr_debug("%s:%s(): clearing RX int\n",
dev->name, __FUNCTION__);
dev->name, __FUNCTION__);
outl(MIPSNET_INTCTL_RXDONE,
mipsnet_reg_address(dev, interruptControl));
} else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
pr_debug("%s:%s(): got test interrupt\n",
dev->name, __FUNCTION__);
// TESTBIT is cleared on read.
// And takes effect after a write with 0
dev->name, __FUNCTION__);
/*
* TESTBIT is cleared on read.
* And takes effect after a write with 0
*/
outl(0, mipsnet_reg_address(dev, interruptControl));
} else {
pr_debug("%s:%s(): no valid fags 0x%016llx\n",
dev->name, __FUNCTION__, interruptFlags);
// Maybe shared IRQ, just ignore, no clearing.
dev->name, __FUNCTION__, interruptFlags);
/* Maybe shared IRQ, just ignore, no clearing. */
retval = IRQ_NONE;
}
@ -159,7 +160,7 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
retval = IRQ_NONE;
}
return retval;
} //mipsnet_interrupt()
}
static int mipsnet_open(struct net_device *dev)
{
@ -171,18 +172,18 @@ static int mipsnet_open(struct net_device *dev)
if (err) {
pr_debug("%s: %s(): can't get irq %d\n",
dev->name, __FUNCTION__, dev->irq);
dev->name, __FUNCTION__, dev->irq);
release_region(dev->base_addr, MIPSNET_IO_EXTENT);
return err;
}
pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
dev->name, __FUNCTION__, dev->base_addr, dev->irq);
dev->name, __FUNCTION__, dev->base_addr, dev->irq);
netif_start_queue(dev);
// test interrupt handler
/* test interrupt handler */
outl(MIPSNET_INTCTL_TESTBIT,
mipsnet_reg_address(dev, interruptControl));
@ -199,8 +200,6 @@ static int mipsnet_close(struct net_device *dev)
static void mipsnet_set_mclist(struct net_device *dev)
{
// we don't do anything
return;
}
static int __init mipsnet_probe(struct device *dev)
@ -226,13 +225,13 @@ static int __init mipsnet_probe(struct device *dev)
*/
netdev->base_addr = 0x4200;
netdev->irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB0 +
inl(mipsnet_reg_address(netdev, interruptInfo));
inl(mipsnet_reg_address(netdev, interruptInfo));
// Get the io region now, get irq on open()
/* Get the io region now, get irq on open() */
if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
"for dev is not availble.\n", netdev->name,
__FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
"for dev is not availble.\n", netdev->name,
__FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
err = -EBUSY;
goto out_free_netdev;
}

View File

@ -9,32 +9,34 @@
/*
* Id of this Net device, as seen by the core.
*/
#define MIPS_NET_DEV_ID ((uint64_t) \
((uint64_t)'M'<< 0)| \
((uint64_t)'I'<< 8)| \
((uint64_t)'P'<<16)| \
((uint64_t)'S'<<24)| \
((uint64_t)'N'<<32)| \
((uint64_t)'E'<<40)| \
((uint64_t)'T'<<48)| \
((uint64_t)'0'<<56))
#define MIPS_NET_DEV_ID ((uint64_t) \
((uint64_t) 'M' << 0)| \
((uint64_t) 'I' << 8)| \
((uint64_t) 'P' << 16)| \
((uint64_t) 'S' << 24)| \
((uint64_t) 'N' << 32)| \
((uint64_t) 'E' << 40)| \
((uint64_t) 'T' << 48)| \
((uint64_t) '0' << 56))
/*
* Net status/control block as seen by sw in the core.
* (Why not use bit fields? can't be bothered with cross-platform struct
* packing.)
*/
typedef struct _net_control_block {
/// dev info for probing
/// reads as MIPSNET%d where %d is some form of version
uint64_t devId; /*0x00 */
struct net_control_block {
/*
* dev info for probing
* reads as MIPSNET%d where %d is some form of version
*/
uint64_t devId; /* 0x00 */
/*
* read only busy flag.
* Set and cleared by the Net Device to indicate that an rx or a tx
* is in progress.
*/
uint32_t busy; /*0x08 */
uint32_t busy; /* 0x08 */
/*
* Set by the Net Device.
@ -43,16 +45,16 @@ typedef struct _net_control_block {
* rxDataBuffer. The value will decrease till 0 until all the data
* from rxDataBuffer has been read.
*/
uint32_t rxDataCount; /*0x0c */
uint32_t rxDataCount; /* 0x0c */
#define MIPSNET_MAX_RXTX_DATACOUNT (1<<16)
/*
* Settable from the MIPS core, cleared by the Net Device.
* The core should set the number of bytes it wants to send,
* then it should write those bytes of data to txDataBuffer.
* The device will clear txDataCount has been processed (not necessarily sent).
* Settable from the MIPS core, cleared by the Net Device. The core
* should set the number of bytes it wants to send, then it should
* write those bytes of data to txDataBuffer. The device will clear
* txDataCount has been processed (not necessarily sent).
*/
uint32_t txDataCount; /*0x10 */
uint32_t txDataCount; /* 0x10 */
/*
* Interrupt control
@ -69,39 +71,42 @@ typedef struct _net_control_block {
* To clear the test interrupt, write 0 to this register.
*/
uint32_t interruptControl; /*0x14 */
#define MIPSNET_INTCTL_TXDONE ((uint32_t)(1<< 0))
#define MIPSNET_INTCTL_RXDONE ((uint32_t)(1<< 1))
#define MIPSNET_INTCTL_TESTBIT ((uint32_t)(1<<31))
#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE|MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TESTBIT)
#define MIPSNET_INTCTL_TXDONE ((uint32_t)(1 << 0))
#define MIPSNET_INTCTL_RXDONE ((uint32_t)(1 << 1))
#define MIPSNET_INTCTL_TESTBIT ((uint32_t)(1 << 31))
#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE | \
MIPSNET_INTCTL_RXDONE | \
MIPSNET_INTCTL_TESTBIT)
/*
* Readonly core-specific interrupt info for the device to signal the core.
* The meaning of the contents of this field might change.
* Readonly core-specific interrupt info for the device to signal the
* core. The meaning of the contents of this field might change.
*
* TODO: the whole memIntf interrupt scheme is messy: the device should
* have no control what so ever of what VPE/register set is being
* used. The MemIntf should only expose interrupt lines, and
* something in the config should be responsible for the
* line<->core/vpe bindings.
*/
/*###\todo: the whole memIntf interrupt scheme is messy: the device should have
* no control what so ever of what VPE/register set is being used.
* The MemIntf should only expose interrupt lines, and something in the
* config should be responsible for the line<->core/vpe bindings.
*/
uint32_t interruptInfo; /*0x18 */
uint32_t interruptInfo; /* 0x18 */
/*
* This is where the received data is read out.
* There is more data to read until rxDataReady is 0.
* Only 1 byte at this regs offset is used.
*/
uint32_t rxDataBuffer; /*0x1c */
uint32_t rxDataBuffer; /* 0x1c */
/*
* This is where the data to transmit is written.
* Data should be written for the amount specified in the txDataCount register.
* Only 1 byte at this regs offset is used.
* This is where the data to transmit is written. Data should be
* written for the amount specified in the txDataCount register. Only
* 1 byte at this regs offset is used.
*/
uint32_t txDataBuffer; /*0x20 */
} MIPS_T_NetControl;
uint32_t txDataBuffer; /* 0x20 */
};
#define MIPSNET_IO_EXTENT 0x40 /* being generous */
#define field_offset(field) ((int)&((MIPS_T_NetControl*)(0))->field)
#define field_offset(field) (offsetof(struct net_control_block, field))
#endif /* __MIPSNET_H */

View File

@ -75,7 +75,7 @@
#include "myri10ge_mcp.h"
#include "myri10ge_mcp_gen_header.h"
#define MYRI10GE_VERSION_STR "1.3.2-1.269"
#define MYRI10GE_VERSION_STR "1.3.2-1.287"
MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
MODULE_AUTHOR("Maintainer: help@myri.com");
@ -214,6 +214,8 @@ struct myri10ge_priv {
unsigned long serial_number;
int vendor_specific_offset;
int fw_multicast_support;
unsigned long features;
u32 max_tso6;
u32 read_dma;
u32 write_dma;
u32 read_write_dma;
@ -311,6 +313,7 @@ MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
#define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
static void myri10ge_set_multicast_list(struct net_device *dev);
static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev);
static inline void put_be32(__be32 val, __be32 __iomem * p)
{
@ -612,6 +615,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
__be32 buf[16];
u32 dma_low, dma_high, size;
int status, i;
struct myri10ge_cmd cmd;
size = 0;
status = myri10ge_load_hotplug_firmware(mgp, &size);
@ -688,6 +692,14 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
dev_info(&mgp->pdev->dev, "handoff confirmed\n");
myri10ge_dummy_rdma(mgp, 1);
/* probe for IPv6 TSO support */
mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
&cmd, 0);
if (status == 0) {
mgp->max_tso6 = cmd.data0;
mgp->features |= NETIF_F_TSO6;
}
return 0;
}
@ -1047,7 +1059,8 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
hlen = MYRI10GE_HLEN > len ? len : MYRI10GE_HLEN;
/* allocate an skb to attach the page(s) to. */
/* allocate an skb to attach the page(s) to. This is done
* after trying LRO, so as to avoid skb allocation overheads */
skb = netdev_alloc_skb(dev, MYRI10GE_HLEN + 16);
if (unlikely(skb == NULL)) {
@ -1217,7 +1230,8 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
static int myri10ge_poll(struct napi_struct *napi, int budget)
{
struct myri10ge_priv *mgp = container_of(napi, struct myri10ge_priv, napi);
struct myri10ge_priv *mgp =
container_of(napi, struct myri10ge_priv, napi);
struct net_device *netdev = mgp->dev;
struct myri10ge_rx_done *rx_done = &mgp->rx_done;
int work_done;
@ -1382,6 +1396,18 @@ static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
return 0;
}
static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled)
{
struct myri10ge_priv *mgp = netdev_priv(netdev);
unsigned long flags = mgp->features & (NETIF_F_TSO6 | NETIF_F_TSO);
if (tso_enabled)
netdev->features |= flags;
else
netdev->features &= ~flags;
return 0;
}
static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
@ -1506,7 +1532,7 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
.set_rx_csum = myri10ge_set_rx_csum,
.set_tx_csum = ethtool_op_set_tx_hw_csum,
.set_sg = ethtool_op_set_sg,
.set_tso = ethtool_op_set_tso,
.set_tso = myri10ge_set_tso,
.get_link = ethtool_op_get_link,
.get_strings = myri10ge_get_strings,
.get_sset_count = myri10ge_get_sset_count,
@ -2164,7 +2190,8 @@ again:
pseudo_hdr_offset = cksum_offset + skb->csum_offset;
/* If the headers are excessively large, then we must
* fall back to a software checksum */
if (unlikely(cksum_offset > 255 || pseudo_hdr_offset > 127)) {
if (unlikely(!mss && (cksum_offset > 255 ||
pseudo_hdr_offset > 127))) {
if (skb_checksum_help(skb))
goto drop;
cksum_offset = 0;
@ -2184,9 +2211,18 @@ again:
/* negative cum_len signifies to the
* send loop that we are still in the
* header portion of the TSO packet.
* TSO header must be at most 134 bytes long */
* TSO header can be at most 1KB long */
cum_len = -(skb_transport_offset(skb) + tcp_hdrlen(skb));
/* for IPv6 TSO, the checksum offset stores the
* TCP header length, to save the firmware from
* the need to parse the headers */
if (skb_is_gso_v6(skb)) {
cksum_offset = tcp_hdrlen(skb);
/* Can only handle headers <= max_tso6 long */
if (unlikely(-cum_len > mgp->max_tso6))
return myri10ge_sw_tso(skb, dev);
}
/* for TSO, pseudo_hdr_offset holds mss.
* The firmware figures out where to put
* the checksum by parsing the header. */
@ -2301,10 +2337,12 @@ again:
req++;
count++;
rdma_count++;
if (unlikely(cksum_offset > seglen))
cksum_offset -= seglen;
else
cksum_offset = 0;
if (cksum_offset != 0 && !(mss && skb_is_gso_v6(skb))) {
if (unlikely(cksum_offset > seglen))
cksum_offset -= seglen;
else
cksum_offset = 0;
}
}
if (frag_idx == frag_cnt)
break;
@ -2387,6 +2425,41 @@ drop:
}
static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev)
{
struct sk_buff *segs, *curr;
struct myri10ge_priv *mgp = dev->priv;
int status;
segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6);
if (unlikely(IS_ERR(segs)))
goto drop;
while (segs) {
curr = segs;
segs = segs->next;
curr->next = NULL;
status = myri10ge_xmit(curr, dev);
if (status != 0) {
dev_kfree_skb_any(curr);
if (segs != NULL) {
curr = segs;
segs = segs->next;
curr->next = NULL;
dev_kfree_skb_any(segs);
}
goto drop;
}
}
dev_kfree_skb_any(skb);
return 0;
drop:
dev_kfree_skb_any(skb);
mgp->stats.tx_dropped += 1;
return 0;
}
static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
{
struct myri10ge_priv *mgp = netdev_priv(dev);
@ -2706,7 +2779,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
}
#ifdef CONFIG_PM
static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct myri10ge_priv *mgp;
@ -2787,7 +2859,6 @@ abort_with_enabled:
return -EIO;
}
#endif /* CONFIG_PM */
static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp)
@ -2954,8 +3025,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
mgp = netdev_priv(netdev);
mgp->dev = netdev;
netif_napi_add(netdev, &mgp->napi,
myri10ge_poll, myri10ge_napi_weight);
netif_napi_add(netdev, &mgp->napi, myri10ge_poll, myri10ge_napi_weight);
mgp->pdev = pdev;
mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
mgp->pause = myri10ge_flow_control;
@ -3077,7 +3147,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->change_mtu = myri10ge_change_mtu;
netdev->set_multicast_list = myri10ge_set_multicast_list;
netdev->set_mac_address = myri10ge_set_mac_address;
netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
netdev->features = mgp->features;
if (dac_enabled)
netdev->features |= NETIF_F_HIGHDMA;

View File

@ -10,7 +10,7 @@ struct mcp_dma_addr {
__be32 low;
};
/* 4 Bytes */
/* 4 Bytes. 8 Bytes for NDIS drivers. */
struct mcp_slot {
__sum16 checksum;
__be16 length;
@ -205,8 +205,87 @@ enum myri10ge_mcp_cmd_type {
/* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned
* chipset */
MXGEFW_CMD_UNALIGNED_STATUS
/* return data = boolean, true if the chipset is known to be unaligned */
MXGEFW_CMD_UNALIGNED_STATUS,
/* return data = boolean, true if the chipset is known to be unaligned */
MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS,
/* data0 = number of big buffers to use. It must be 0 or a power of 2.
* 0 indicates that the NIC consumes as many buffers as they are required
* for packet. This is the default behavior.
* A power of 2 number indicates that the NIC always uses the specified
* number of buffers for each big receive packet.
* It is up to the driver to ensure that this value is big enough for
* the NIC to be able to receive maximum-sized packets.
*/
MXGEFW_CMD_GET_MAX_RSS_QUEUES,
MXGEFW_CMD_ENABLE_RSS_QUEUES,
/* data0 = number of slices n (0, 1, ..., n-1) to enable
* data1 = interrupt mode. 0=share one INTx/MSI, 1=use one MSI-X per queue.
* If all queues share one interrupt, the driver must have set
* RSS_SHARED_INTERRUPT_DMA before enabling queues.
*/
MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET,
MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA,
/* data0, data1 = bus address lsw, msw */
MXGEFW_CMD_GET_RSS_TABLE_OFFSET,
/* get the offset of the indirection table */
MXGEFW_CMD_SET_RSS_TABLE_SIZE,
/* set the size of the indirection table */
MXGEFW_CMD_GET_RSS_KEY_OFFSET,
/* get the offset of the secret key */
MXGEFW_CMD_RSS_KEY_UPDATED,
/* tell nic that the secret key's been updated */
MXGEFW_CMD_SET_RSS_ENABLE,
/* data0 = enable/disable rss
* 0: disable rss. nic does not distribute receive packets.
* 1: enable rss. nic distributes receive packets among queues.
* data1 = hash type
* 1: IPV4
* 2: TCP_IPV4
* 3: IPV4 | TCP_IPV4
*/
MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
/* Return data = the max. size of the entire headers of a IPv6 TSO packet.
* If the header size of a IPv6 TSO packet is larger than the specified
* value, then the driver must not use TSO.
* This size restriction only applies to IPv6 TSO.
* For IPv4 TSO, the maximum size of the headers is fixed, and the NIC
* always has enough header buffer to store maximum-sized headers.
*/
MXGEFW_CMD_SET_TSO_MODE,
/* data0 = TSO mode.
* 0: Linux/FreeBSD style (NIC default)
* 1: NDIS/NetBSD style
*/
MXGEFW_CMD_MDIO_READ,
/* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */
MXGEFW_CMD_MDIO_WRITE,
/* data0 = dev_addr, data1 = register/addr, data2 = value */
MXGEFW_CMD_XFP_I2C_READ,
/* Starts to get a fresh copy of one byte or of the whole xfp i2c table, the
* obtained data is cached inside the xaui-xfi chip :
* data0 : "all" flag : 0 => get one byte, 1=> get 256 bytes,
* data1 : if (data0 == 0): index of byte to refresh [ not used otherwise ]
* The operation might take ~1ms for a single byte or ~65ms when refreshing all 256 bytes
* During the i2c operation, MXGEFW_CMD_XFP_I2C_READ or MXGEFW_CMD_XFP_BYTE attempts
* will return MXGEFW_CMD_ERROR_BUSY
*/
MXGEFW_CMD_XFP_BYTE,
/* Return the last obtained copy of a given byte in the xfp i2c table
* (copy cached during the last relevant MXGEFW_CMD_XFP_I2C_READ)
* data0 : index of the desired table entry
* Return data = the byte stored at the requested index in the table
*/
MXGEFW_CMD_GET_VPUMP_OFFSET,
/* Return data = NIC memory offset of mcp_vpump_public_global */
MXGEFW_CMD_RESET_VPUMP,
/* Resets the VPUMP state */
};
enum myri10ge_mcp_cmd_status {
@ -220,7 +299,10 @@ enum myri10ge_mcp_cmd_status {
MXGEFW_CMD_ERROR_BAD_PORT,
MXGEFW_CMD_ERROR_RESOURCES,
MXGEFW_CMD_ERROR_MULTICAST,
MXGEFW_CMD_ERROR_UNALIGNED
MXGEFW_CMD_ERROR_UNALIGNED,
MXGEFW_CMD_ERROR_NO_MDIO,
MXGEFW_CMD_ERROR_XFP_FAILURE,
MXGEFW_CMD_ERROR_XFP_ABSENT
};
#define MXGEFW_OLD_IRQ_DATA_LEN 40

View File

@ -1576,7 +1576,7 @@ static int netdev_open(struct net_device *dev)
/* Set the timer to check for link beat. */
init_timer(&np->timer);
np->timer.expires = jiffies + NATSEMI_TIMER_FREQ;
np->timer.expires = round_jiffies(jiffies + NATSEMI_TIMER_FREQ);
np->timer.data = (unsigned long)dev;
np->timer.function = &netdev_timer; /* timer handler */
add_timer(&np->timer);
@ -1856,7 +1856,11 @@ static void netdev_timer(unsigned long data)
next_tick = 1;
}
}
mod_timer(&np->timer, jiffies + next_tick);
if (next_tick > 1)
mod_timer(&np->timer, round_jiffies(jiffies + next_tick));
else
mod_timer(&np->timer, jiffies + next_tick);
}
static void dump_ring(struct net_device *dev)
@ -3310,13 +3314,19 @@ static int natsemi_resume (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
struct netdev_private *np = netdev_priv(dev);
int ret = 0;
rtnl_lock();
if (netif_device_present(dev))
goto out;
if (netif_running(dev)) {
BUG_ON(!np->hands_off);
pci_enable_device(pdev);
ret = pci_enable_device(pdev);
if (ret < 0) {
dev_err(&pdev->dev,
"pci_enable_device() failed: %d\n", ret);
goto out;
}
/* pci_power_on(pdev); */
napi_enable(&np->napi);
@ -3331,12 +3341,12 @@ static int natsemi_resume (struct pci_dev *pdev)
spin_unlock_irq(&np->lock);
enable_irq(dev->irq);
mod_timer(&np->timer, jiffies + 1*HZ);
mod_timer(&np->timer, round_jiffies(jiffies + 1*HZ));
}
netif_device_attach(dev);
out:
rtnl_unlock();
return 0;
return ret;
}
#endif /* CONFIG_PM */

View File

@ -93,7 +93,7 @@ static int __init init_reg_offset(struct net_device *dev,unsigned long base_addr
bus_width = *(volatile unsigned char *)ABWCR;
bus_width &= 1 << ((base_addr >> 21) & 7);
for (i = 0; i < sizeof(reg_offset) / sizeof(u32); i++)
for (i = 0; i < ARRAY_SIZE(reg_offset); i++)
if (bus_width == 0)
reg_offset[i] = i * 2 + 1;
else
@ -115,7 +115,7 @@ static int h8300_ne_irq[] = {EXT_IRQ5};
static inline int init_dev(struct net_device *dev)
{
if (h8300_ne_count < (sizeof(h8300_ne_base) / sizeof(unsigned long))) {
if (h8300_ne_count < ARRAY_SIZE(h8300_ne_base)) {
dev->base_addr = h8300_ne_base[h8300_ne_count];
dev->irq = h8300_ne_irq[h8300_ne_count];
h8300_ne_count++;

View File

@ -97,13 +97,16 @@ static void evm_saa9730_unblock_lan_int(struct lan_saa9730_private *lp)
&lp->evm_saa9730_regs->InterruptBlock1);
}
static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
static void __used show_saa9730_regs(struct net_device *dev)
{
struct lan_saa9730_private *lp = netdev_priv(dev);
int i, j;
printk("TxmBufferA = %p\n", lp->TxmBuffer[0][0]);
printk("TxmBufferB = %p\n", lp->TxmBuffer[1][0]);
printk("RcvBufferA = %p\n", lp->RcvBuffer[0][0]);
printk("RcvBufferB = %p\n", lp->RcvBuffer[1][0]);
for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
for (j = 0; j < LAN_SAA9730_TXM_Q_SIZE; j++) {
printk("TxmBuffer[%d][%d] = %x\n", i, j,
@ -146,11 +149,13 @@ static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
readl(&lp->lan_saa9730_regs->RxCtl));
printk("lp->lan_saa9730_regs->RxStatus = %x\n",
readl(&lp->lan_saa9730_regs->RxStatus));
for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
writel(i, &lp->lan_saa9730_regs->CamAddress);
printk("lp->lan_saa9730_regs->CamData = %x\n",
readl(&lp->lan_saa9730_regs->CamData));
}
printk("dev->stats.tx_packets = %lx\n", dev->stats.tx_packets);
printk("dev->stats.tx_errors = %lx\n", dev->stats.tx_errors);
printk("dev->stats.tx_aborted_errors = %lx\n",
@ -855,7 +860,7 @@ static void lan_saa9730_tx_timeout(struct net_device *dev)
/* Transmitter timeout, serious problems */
dev->stats.tx_errors++;
printk("%s: transmit timed out, reset\n", dev->name);
/*show_saa9730_regs(lp); */
/*show_saa9730_regs(dev); */
lan_saa9730_restart(lp);
dev->trans_start = jiffies;

View File

@ -1461,7 +1461,6 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
}
return IRQ_NONE;
#else
struct tc35815_local *lp = dev->priv;
int handled;
u32 status;

View File

@ -1906,7 +1906,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/************** pci *****************/
if ((err = pci_enable_device(pdev))) /* it trigers interrupt, dunno why. */
RET(err); /* it's not a problem though */
goto err_pci; /* it's not a problem though */
if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
!(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
@ -2076,6 +2076,7 @@ err_out_res:
pci_release_regions(pdev);
err_dma:
pci_disable_device(pdev);
err_pci:
vfree(nic);
RET(err);

View File

@ -9034,7 +9034,7 @@ static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len)
int i;
u32 j;
for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) {
for (i = 0; i < ARRAY_SIZE(test_pattern); i++) {
for (j = 0; j < len; j += 4) {
u32 val;

View File

@ -1041,7 +1041,7 @@ static struct InfoLeaf infoleaf_array[] = {
{DC21142, dc21142_infoleaf},
{DC21143, dc21143_infoleaf}
};
#define INFOLEAF_SIZE (sizeof(infoleaf_array)/(sizeof(int)+sizeof(int *)))
#define INFOLEAF_SIZE ARRAY_SIZE(infoleaf_array)
/*
** List the SROM info block functions
@ -1056,7 +1056,7 @@ static int (*dc_infoblock[])(struct net_device *dev, u_char, u_char *) = {
compact_infoblock
};
#define COMPACT (sizeof(dc_infoblock)/sizeof(int *) - 1)
#define COMPACT (ARRAY_SIZE(dc_infoblock) - 1)
/*
** Miscellaneous defines...

View File

@ -63,7 +63,7 @@
#define UGETH_MSG_DEFAULT (NETIF_MSG_IFUP << 1 ) - 1
void uec_set_ethtool_ops(struct net_device *netdev);
static DEFINE_SPINLOCK(ugeth_lock);
static struct {
@ -3454,9 +3454,12 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
u16 length, howmany = 0;
u32 bd_status;
u8 *bdBuffer;
struct net_device * dev;
ugeth_vdbg("%s: IN", __FUNCTION__);
dev = ugeth->dev;
/* collect received buffers */
bd = ugeth->rxBd[rxQ];

View File

@ -1342,11 +1342,11 @@ static int sdla_set_config(struct net_device *dev, struct ifmap *map)
if (flp->initialized)
return(-EINVAL);
for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
for(i=0; i < ARRAY_SIZE(valid_port); i++)
if (valid_port[i] == map->base_addr)
break;
if (i == sizeof(valid_port) / sizeof(int))
if (i == ARRAY_SIZE(valid_port))
return(-EINVAL);
if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
@ -1487,12 +1487,12 @@ got_type:
}
}
for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
for(i=0; i < ARRAY_SIZE(valid_mem); i++)
if (valid_mem[i] == map->mem_start)
break;
err = -EINVAL;
if (i == sizeof(valid_mem) / sizeof(int))
if (i == ARRAY_SIZE(valid_mem))
goto fail2;
if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E)

View File

@ -74,22 +74,12 @@ struct netfront_info {
struct napi_struct napi;
struct xen_netif_tx_front_ring tx;
struct xen_netif_rx_front_ring rx;
unsigned int evtchn;
struct xenbus_device *xbdev;
spinlock_t tx_lock;
spinlock_t rx_lock;
unsigned int evtchn;
/* Receive-ring batched refills. */
#define RX_MIN_TARGET 8
#define RX_DFL_MIN_TARGET 64
#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
unsigned rx_min_target, rx_max_target, rx_target;
struct sk_buff_head rx_batch;
struct timer_list rx_refill_timer;
struct xen_netif_tx_front_ring tx;
int tx_ring_ref;
/*
* {tx,rx}_skbs store outstanding skbuffs. Free tx_skb entries
@ -108,14 +98,23 @@ struct netfront_info {
grant_ref_t grant_tx_ref[NET_TX_RING_SIZE];
unsigned tx_skb_freelist;
spinlock_t rx_lock ____cacheline_aligned_in_smp;
struct xen_netif_rx_front_ring rx;
int rx_ring_ref;
/* Receive-ring batched refills. */
#define RX_MIN_TARGET 8
#define RX_DFL_MIN_TARGET 64
#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
unsigned rx_min_target, rx_max_target, rx_target;
struct sk_buff_head rx_batch;
struct timer_list rx_refill_timer;
struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
grant_ref_t gref_rx_head;
grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
struct xenbus_device *xbdev;
int tx_ring_ref;
int rx_ring_ref;
unsigned long rx_pfn_array[NET_RX_RING_SIZE];
struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1];
struct mmu_update rx_mmu[NET_RX_RING_SIZE];

View File

@ -0,0 +1,13 @@
#ifndef __AU1X00_PROM_H
#define __AU1X00_PROM_H
extern int prom_argc;
extern char **prom_argv;
extern char **prom_envp;
extern void prom_init_cmdline(void);
extern char *prom_getcmdline(void);
extern char *prom_getenv(char *envname);
extern int prom_get_ethernet_addr(char *ethernet_addr);
#endif

View File

@ -33,16 +33,16 @@ typedef struct {
extern dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
unsigned int dcr_c);
extern void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c);
extern void dcr_unmap(dcr_host_t host, unsigned int dcr_c);
static inline u32 dcr_read(dcr_host_t host, unsigned int dcr_n)
{
return in_be32(host.token + dcr_n * host.stride);
return in_be32(host.token + ((host.base + dcr_n) * host.stride));
}
static inline void dcr_write(dcr_host_t host, unsigned int dcr_n, u32 value)
{
out_be32(host.token + dcr_n * host.stride, value);
out_be32(host.token + ((host.base + dcr_n) * host.stride), value);
}
extern u64 of_translate_dcr_address(struct device_node *dev,

View File

@ -29,9 +29,9 @@ typedef struct {
#define DCR_MAP_OK(host) (1)
#define dcr_map(dev, dcr_n, dcr_c) ((dcr_host_t){ .base = (dcr_n) })
#define dcr_unmap(host, dcr_n, dcr_c) do {} while (0)
#define dcr_read(host, dcr_n) mfdcr(dcr_n)
#define dcr_write(host, dcr_n, value) mtdcr(dcr_n, value)
#define dcr_unmap(host, dcr_c) do {} while (0)
#define dcr_read(host, dcr_n) mfdcr(dcr_n + host.base)
#define dcr_write(host, dcr_n, value) mtdcr(dcr_n + host.base, value)
/* Device Control Registers */
void __mtdcr(int reg, unsigned int val);

View File

@ -1781,6 +1781,11 @@ static inline int skb_is_gso(const struct sk_buff *skb)
return skb_shinfo(skb)->gso_size;
}
static inline int skb_is_gso_v6(const struct sk_buff *skb)
{
return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;
}
static inline void skb_forward_csum(struct sk_buff *skb)
{
/* Unfortunately we don't support this one. Any brave souls? */