Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25: (1470 commits)
  [IPV6] ADDRLABEL: Fix double free on label deletion.
  [PPP]: Sparse warning fixes.
  [IPV4] fib_trie: remove unneeded NULL check
  [IPV4] fib_trie: More whitespace cleanup.
  [NET_SCHED]: Use nla_policy for attribute validation in ematches
  [NET_SCHED]: Use nla_policy for attribute validation in actions
  [NET_SCHED]: Use nla_policy for attribute validation in classifiers
  [NET_SCHED]: Use nla_policy for attribute validation in packet schedulers
  [NET_SCHED]: sch_api: introduce constant for rate table size
  [NET_SCHED]: Use typeful attribute parsing helpers
  [NET_SCHED]: Use typeful attribute construction helpers
  [NET_SCHED]: Use NLA_PUT_STRING for string dumping
  [NET_SCHED]: Use nla_nest_start/nla_nest_end
  [NET_SCHED]: Propagate nla_parse return value
  [NET_SCHED]: act_api: use PTR_ERR in tcf_action_init/tcf_action_get
  [NET_SCHED]: act_api: use nlmsg_parse
  [NET_SCHED]: act_api: fix netlink API conversion bug
  [NET_SCHED]: sch_netem: use nla_parse_nested_compat
  [NET_SCHED]: sch_atm: fix format string warning
  [NETNS]: Add namespace for ICMP replying code.
  ...
This commit is contained in:
Linus Torvalds 2008-01-29 22:54:01 +11:00
commit 0ba6c33bcd
1113 changed files with 140020 additions and 55548 deletions

View file

@ -2163,7 +2163,6 @@ static int __devinit amb_init (amb_dev * dev)
static void setup_dev(amb_dev *dev, struct pci_dev *pci_dev)
{
unsigned char pool;
memset (dev, 0, sizeof(amb_dev));
// set up known dev items straight away
dev->pci_dev = pci_dev;
@ -2253,7 +2252,7 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_
goto out_disable;
}
dev = kmalloc (sizeof(amb_dev), GFP_KERNEL);
dev = kzalloc(sizeof(amb_dev), GFP_KERNEL);
if (!dev) {
PRINTK (KERN_ERR, "out of memory!");
err = -ENOMEM;

View file

@ -1,5 +1,3 @@
/* $Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $ */
/*
he.c
@ -99,10 +97,6 @@
#define HPRINTK(fmt,args...) do { } while (0)
#endif /* HE_DEBUG */
/* version definition */
static char *version = "$Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $";
/* declarations */
static int he_open(struct atm_vcc *vcc);
@ -366,7 +360,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
struct he_dev *he_dev = NULL;
int err = 0;
printk(KERN_INFO "he: %s\n", version);
printk(KERN_INFO "ATM he driver\n");
if (pci_enable_device(pci_dev))
return -EIO;
@ -1643,6 +1637,8 @@ he_stop(struct he_dev *he_dev)
if (he_dev->rbpl_base) {
#ifdef USE_RBPL_POOL
int i;
for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
void *cpuaddr = he_dev->rbpl_virt[i].virt;
dma_addr_t dma_handle = he_dev->rbpl_base[i].phys;
@ -1665,6 +1661,8 @@ he_stop(struct he_dev *he_dev)
#ifdef USE_RBPS
if (he_dev->rbps_base) {
#ifdef USE_RBPS_POOL
int i;
for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
void *cpuaddr = he_dev->rbps_virt[i].virt;
dma_addr_t dma_handle = he_dev->rbps_base[i].phys;
@ -2933,7 +2931,7 @@ he_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
left = *pos;
if (!left--)
return sprintf(page, "%s\n", version);
return sprintf(page, "ATM he driver\n");
if (!left--)
return sprintf(page, "%s%s\n\n",

View file

@ -104,7 +104,6 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id
return -EINVAL;
}
cbq->nls = dev->nls;
cbq->seq = 0;
cbq->group = cbq->id.id.idx;
@ -146,7 +145,6 @@ struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls)
spin_lock_init(&dev->queue_lock);
dev->nls = nls;
dev->netlink_groups = 0;
dev->cn_queue = create_workqueue(dev->name);
if (!dev->cn_queue) {

View file

@ -88,6 +88,7 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
found = 1;
group = __cbq->group;
break;
}
}
spin_unlock_bh(&dev->cbdev->queue_lock);
@ -180,34 +181,15 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
return err;
}
/*
* Skb receive helper - checks skb and msg size and calls callback
* helper.
*/
static int __cn_rx_skb(struct sk_buff *skb, struct nlmsghdr *nlh)
{
u32 pid, uid, seq, group;
struct cn_msg *msg;
pid = NETLINK_CREDS(skb)->pid;
uid = NETLINK_CREDS(skb)->uid;
seq = nlh->nlmsg_seq;
group = NETLINK_CB((skb)).dst_group;
msg = NLMSG_DATA(nlh);
return cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
}
/*
* Main netlink receiving function.
*
* It checks skb and netlink header sizes and calls the skb receive
* helper with a shared skb.
* It checks skb, netlink header and msg sizes, and calls callback helper.
*/
static void cn_rx_skb(struct sk_buff *__skb)
{
struct cn_msg *msg;
struct nlmsghdr *nlh;
u32 len;
int err;
struct sk_buff *skb;
@ -223,11 +205,8 @@ static void cn_rx_skb(struct sk_buff *__skb)
return;
}
len = NLMSG_ALIGN(nlh->nlmsg_len);
if (len > skb->len)
len = skb->len;
err = __cn_rx_skb(skb, nlh);
msg = NLMSG_DATA(nlh);
err = cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
if (err < 0)
kfree_skb(skb);
}
@ -441,8 +420,7 @@ static int __devinit cn_init(void)
dev->cbdev = cn_queue_alloc_dev("cqueue", dev->nls);
if (!dev->cbdev) {
if (dev->nls->sk_socket)
sock_release(dev->nls->sk_socket);
netlink_kernel_release(dev->nls);
return -EINVAL;
}
@ -452,8 +430,7 @@ static int __devinit cn_init(void)
if (err) {
cn_already_initialized = 0;
cn_queue_free_dev(dev->cbdev);
if (dev->nls->sk_socket)
sock_release(dev->nls->sk_socket);
netlink_kernel_release(dev->nls);
return -EINVAL;
}
@ -468,8 +445,7 @@ static void __devexit cn_fini(void)
cn_del_callback(&dev->id);
cn_queue_free_dev(dev->cbdev);
if (dev->nls->sk_socket)
sock_release(dev->nls->sk_socket);
netlink_kernel_release(dev->nls);
}
subsys_initcall(cn_init);

View file

@ -110,7 +110,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
__be32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
int ret;
dev = ip_dev_find(ip);
dev = ip_dev_find(&init_net, ip);
if (!dev)
return -EADDRNOTAVAIL;
@ -158,7 +158,7 @@ static void addr_send_arp(struct sockaddr_in *dst_in)
memset(&fl, 0, sizeof fl);
fl.nl_u.ip4_u.daddr = dst_ip;
if (ip_route_output_key(&rt, &fl))
if (ip_route_output_key(&init_net, &rt, &fl))
return;
neigh_event_send(rt->u.dst.neighbour, NULL);
@ -179,7 +179,7 @@ static int addr_resolve_remote(struct sockaddr_in *src_in,
memset(&fl, 0, sizeof fl);
fl.nl_u.ip4_u.daddr = dst_ip;
fl.nl_u.ip4_u.saddr = src_ip;
ret = ip_route_output_key(&rt, &fl);
ret = ip_route_output_key(&init_net, &rt, &fl);
if (ret)
goto out;
@ -261,15 +261,15 @@ static int addr_resolve_local(struct sockaddr_in *src_in,
__be32 dst_ip = dst_in->sin_addr.s_addr;
int ret;
dev = ip_dev_find(dst_ip);
dev = ip_dev_find(&init_net, dst_ip);
if (!dev)
return -EADDRNOTAVAIL;
if (ZERONET(src_ip)) {
if (ipv4_is_zeronet(src_ip)) {
src_in->sin_family = dst_in->sin_family;
src_in->sin_addr.s_addr = dst_ip;
ret = rdma_copy_addr(addr, dev, dev->dev_addr);
} else if (LOOPBACK(src_ip)) {
} else if (ipv4_is_loopback(src_ip)) {
ret = rdma_translate_ip((struct sockaddr *)dst_in, addr);
if (!ret)
memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN);

View file

@ -630,7 +630,8 @@ static inline int cma_zero_addr(struct sockaddr *addr)
struct in6_addr *ip6;
if (addr->sa_family == AF_INET)
return ZERONET(((struct sockaddr_in *) addr)->sin_addr.s_addr);
return ipv4_is_zeronet(
((struct sockaddr_in *)addr)->sin_addr.s_addr);
else {
ip6 = &((struct sockaddr_in6 *) addr)->sin6_addr;
return (ip6->s6_addr32[0] | ip6->s6_addr32[1] |
@ -640,7 +641,7 @@ static inline int cma_zero_addr(struct sockaddr *addr)
static inline int cma_loopback_addr(struct sockaddr *addr)
{
return LOOPBACK(((struct sockaddr_in *) addr)->sin_addr.s_addr);
return ipv4_is_loopback(((struct sockaddr_in *) addr)->sin_addr.s_addr);
}
static inline int cma_any_addr(struct sockaddr *addr)
@ -1288,7 +1289,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
atomic_inc(&conn_id->dev_remove);
conn_id->state = CMA_CONNECT;
dev = ip_dev_find(iw_event->local_addr.sin_addr.s_addr);
dev = ip_dev_find(&init_net, iw_event->local_addr.sin_addr.s_addr);
if (!dev) {
ret = -EADDRNOTAVAIL;
cma_enable_remove(conn_id);

View file

@ -332,7 +332,7 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip,
}
};
if (ip_route_output_flow(&rt, &fl, NULL, 0))
if (ip_route_output_flow(&init_net, &rt, &fl, NULL, 0))
return NULL;
return rt;
}

View file

@ -17,7 +17,7 @@
Annapolis MD 21403
Fixed (again!) the missing interrupt locking on TX/RX shifting.
Alan Cox <Alan.Cox@linux.org>
Alan Cox <Alan.Cox@linux.org>
Removed calls to init_etherdev since they are no longer needed, and
cleaned up modularization just a bit. The driver still allows only
@ -29,16 +29,16 @@
the board. Now getting 150K/second FTP with a 3c501 card. Still playing
with a TX-TX optimisation to see if we can touch 180-200K/second as seems
theoretically maximum.
19950402 Alan Cox <Alan.Cox@linux.org>
19950402 Alan Cox <Alan.Cox@linux.org>
Cleaned up for 2.3.x because we broke SMP now.
20000208 Alan Cox <alan@redhat.com>
20000208 Alan Cox <alan@redhat.com>
Check up pass for 2.5. Nothing significant changed
20021009 Alan Cox <alan@redhat.com>
20021009 Alan Cox <alan@redhat.com>
Fixed zero fill corner case
20030104 Alan Cox <alan@redhat.com>
20030104 Alan Cox <alan@redhat.com>
For the avoidance of doubt the "preferred form" of this code is one which
@ -139,8 +139,8 @@ static const char version[] =
* The boilerplate probe code.
*/
static int io=0x280;
static int irq=5;
static int io = 0x280;
static int irq = 5;
static int mem_start;
/**
@ -229,8 +229,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
* Read the station address PROM data from the special port.
*/
for (i = 0; i < 6; i++)
{
for (i = 0; i < 6; i++) {
outw(i, ioaddr + EL1_DATAPTR);
station_addr[i] = inb(ioaddr + EL1_SAPROM);
}
@ -240,28 +239,24 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
*/
if (station_addr[0] == 0x02 && station_addr[1] == 0x60
&& station_addr[2] == 0x8c)
{
&& station_addr[2] == 0x8c)
mname = "3c501";
} else if (station_addr[0] == 0x00 && station_addr[1] == 0x80
&& station_addr[2] == 0xC8)
{
else if (station_addr[0] == 0x00 && station_addr[1] == 0x80
&& station_addr[2] == 0xC8)
mname = "NP943";
}
else {
else {
release_region(ioaddr, EL1_IO_EXTENT);
return -ENODEV;
}
/*
* We auto-IRQ by shutting off the interrupt line and letting it float
* high.
* We auto-IRQ by shutting off the interrupt line and letting it
* float high.
*/
dev->irq = irq;
if (dev->irq < 2)
{
if (dev->irq < 2) {
unsigned long irq_mask;
irq_mask = probe_irq_on();
@ -274,8 +269,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
mdelay(20);
autoirq = probe_irq_off(irq_mask);
if (autoirq == 0)
{
if (autoirq == 0) {
printk(KERN_WARNING "%s probe at %#x failed to detect IRQ line.\n",
mname, ioaddr);
release_region(ioaddr, EL1_IO_EXTENT);
@ -292,7 +286,8 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
if (autoirq)
dev->irq = autoirq;
printk(KERN_INFO "%s: %s EtherLink at %#lx, using %sIRQ %d.\n", dev->name, mname, dev->base_addr,
printk(KERN_INFO "%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
dev->name, mname, dev->base_addr,
autoirq ? "auto":"assigned ", dev->irq);
#ifdef CONFIG_IP_MULTICAST
@ -343,7 +338,8 @@ static int el_open(struct net_device *dev)
if (el_debug > 2)
printk(KERN_DEBUG "%s: Doing el_open()...", dev->name);
if ((retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev)))
retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev);
if (retval)
return retval;
spin_lock_irqsave(&lp->lock, flags);
@ -371,8 +367,9 @@ static void el_timeout(struct net_device *dev)
int ioaddr = dev->base_addr;
if (el_debug)
printk (KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
dev->name, inb(TX_STATUS), inb(AX_STATUS), inb(RX_STATUS));
printk(KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
dev->name, inb(TX_STATUS),
inb(AX_STATUS), inb(RX_STATUS));
dev->stats.tx_errors++;
outb(TX_NORM, TX_CMD);
outb(RX_NORM, RX_CMD);
@ -425,8 +422,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
do
{
do {
int len = skb->len;
int pad = 0;
int gp_start;
@ -435,10 +431,10 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (len < ETH_ZLEN)
pad = ETH_ZLEN - len;
gp_start = 0x800 - ( len + pad );
gp_start = 0x800 - (len + pad);
lp->tx_pkt_start = gp_start;
lp->collisions = 0;
lp->collisions = 0;
dev->stats.tx_bytes += skb->len;
@ -455,37 +451,42 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
lp->txing = 1;
/*
* Turn interrupts back on while we spend a pleasant afternoon
* loading bytes into the board
* Turn interrupts back on while we spend a pleasant
* afternoon loading bytes into the board
*/
spin_unlock_irqrestore(&lp->lock, flags);
outw(0x00, RX_BUF_CLR); /* Set rx packet area to 0. */
outw(gp_start, GP_LOW); /* aim - packet will be loaded into buffer start */
outsb(DATAPORT,buf,len); /* load buffer (usual thing each byte increments the pointer) */
/* Set rx packet area to 0. */
outw(0x00, RX_BUF_CLR);
/* aim - packet will be loaded into buffer start */
outw(gp_start, GP_LOW);
/* load buffer (usual thing each byte increments the pointer) */
outsb(DATAPORT, buf, len);
if (pad) {
while(pad--) /* Zero fill buffer tail */
while (pad--) /* Zero fill buffer tail */
outb(0, DATAPORT);
}
outw(gp_start, GP_LOW); /* the board reuses the same register */
/* the board reuses the same register */
outw(gp_start, GP_LOW);
if(lp->loading != 2)
{
outb(AX_XMIT, AX_CMD); /* fire ... Trigger xmit. */
lp->loading=0;
if (lp->loading != 2) {
/* fire ... Trigger xmit. */
outb(AX_XMIT, AX_CMD);
lp->loading = 0;
dev->trans_start = jiffies;
if (el_debug > 2)
printk(KERN_DEBUG " queued xmit.\n");
dev_kfree_skb (skb);
dev_kfree_skb(skb);
return 0;
}
/* A receive upset our load, despite our best efforts */
if(el_debug>2)
printk(KERN_DEBUG "%s: burped during tx load.\n", dev->name);
if (el_debug > 2)
printk(KERN_DEBUG "%s: burped during tx load.\n",
dev->name);
spin_lock_irqsave(&lp->lock, flags);
}
while(1);
while (1);
}
@ -534,64 +535,59 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
*/
if (el_debug > 3)
printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x", dev->name, axsr);
printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x",
dev->name, axsr);
if(lp->loading==1 && !lp->txing)
printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n",
dev->name);
if (lp->txing)
{
/*
* Board in transmit mode. May be loading. If we are
* loading we shouldn't have got this.
*/
if (lp->loading == 1 && !lp->txing)
printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n",
dev->name);
if (lp->txing) {
/*
* Board in transmit mode. May be loading. If we are
* loading we shouldn't have got this.
*/
int txsr = inb(TX_STATUS);
if(lp->loading==1)
{
if(el_debug > 2)
{
printk(KERN_DEBUG "%s: Interrupt while loading [", dev->name);
printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x]\n", txsr, inw(GP_LOW),inw(RX_LOW));
if (lp->loading == 1) {
if (el_debug > 2) {
printk(KERN_DEBUG "%s: Interrupt while loading [",
dev->name);
printk(" txsr=%02x gp=%04x rp=%04x]\n",
txsr, inw(GP_LOW), inw(RX_LOW));
}
lp->loading=2; /* Force a reload */
/* Force a reload */
lp->loading = 2;
spin_unlock(&lp->lock);
goto out;
}
if (el_debug > 6)
printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x", txsr, inw(GP_LOW),inw(RX_LOW));
printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x",
txsr, inw(GP_LOW), inw(RX_LOW));
if ((axsr & 0x80) && (txsr & TX_READY) == 0)
{
if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
/*
* FIXME: is there a logic to whether to keep on trying or
* reset immediately ?
* FIXME: is there a logic to whether to keep
* on trying or reset immediately ?
*/
if(el_debug>1)
printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x"
" gp=%03x rp=%03x.\n", dev->name, txsr, axsr,
inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR));
if (el_debug > 1)
printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
dev->name, txsr, axsr,
inw(ioaddr + EL1_DATAPTR),
inw(ioaddr + EL1_RXPTR));
lp->txing = 0;
netif_wake_queue(dev);
}
else if (txsr & TX_16COLLISIONS)
{
} else if (txsr & TX_16COLLISIONS) {
/*
* Timed out
*/
if (el_debug)
printk (KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n",dev->name);
printk(KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
outb(AX_SYS, AX_CMD);
lp->txing = 0;
dev->stats.tx_aborted_errors++;
netif_wake_queue(dev);
}
else if (txsr & TX_COLLISION)
{
} else if (txsr & TX_COLLISION) {
/*
* Retrigger xmit.
*/
@ -599,7 +595,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
if (el_debug > 6)
printk(KERN_DEBUG " retransmitting after a collision.\n");
/*
* Poor little chip can't reset its own start pointer
* Poor little chip can't reset its own start
* pointer
*/
outb(AX_SYS, AX_CMD);
@ -608,53 +605,45 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
dev->stats.collisions++;
spin_unlock(&lp->lock);
goto out;
}
else
{
} else {
/*
* It worked.. we will now fall through and receive
*/
dev->stats.tx_packets++;
if (el_debug > 6)
printk(KERN_DEBUG " Tx succeeded %s\n",
(txsr & TX_RDY) ? "." : "but tx is busy!");
(txsr & TX_RDY) ? "." : "but tx is busy!");
/*
* This is safe the interrupt is atomic WRT itself.
*/
lp->txing = 0;
netif_wake_queue(dev); /* In case more to transmit */
/* In case more to transmit */
netif_wake_queue(dev);
}
}
else
{
/*
* In receive mode.
*/
} else {
/*
* In receive mode.
*/
int rxsr = inb(RX_STATUS);
if (el_debug > 5)
printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS),inw(RX_LOW));
printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS), inw(RX_LOW));
/*
* Just reading rx_status fixes most errors.
*/
if (rxsr & RX_MISSED)
dev->stats.rx_missed_errors++;
else if (rxsr & RX_RUNT)
{ /* Handled to avoid board lock-up. */
else if (rxsr & RX_RUNT) {
/* Handled to avoid board lock-up. */
dev->stats.rx_length_errors++;
if (el_debug > 5)
printk(KERN_DEBUG " runt.\n");
}
else if (rxsr & RX_GOOD)
{
} else if (rxsr & RX_GOOD) {
/*
* Receive worked.
*/
el_receive(dev);
}
else
{
} else {
/*
* Nothing? Something is broken!
*/
@ -702,8 +691,7 @@ static void el_receive(struct net_device *dev)
if (el_debug > 4)
printk(KERN_DEBUG " el_receive %d.\n", pkt_len);
if ((pkt_len < 60) || (pkt_len > 1536))
{
if (pkt_len < 60 || pkt_len > 1536) {
if (el_debug)
printk(KERN_DEBUG "%s: bogus packet, length=%d\n", dev->name, pkt_len);
dev->stats.rx_over_errors++;
@ -722,26 +710,23 @@ static void el_receive(struct net_device *dev)
*/
outw(0x00, GP_LOW);
if (skb == NULL)
{
if (skb == NULL) {
printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", dev->name);
dev->stats.rx_dropped++;
return;
}
else
{
skb_reserve(skb,2); /* Force 16 byte alignment */
} else {
skb_reserve(skb, 2); /* Force 16 byte alignment */
/*
* The read increments through the bytes. The interrupt
* handler will fix the pointer when it returns to
* receive mode.
*/
insb(DATAPORT, skb_put(skb,pkt_len), pkt_len);
skb->protocol=eth_type_trans(skb,dev);
insb(DATAPORT, skb_put(skb, pkt_len), pkt_len);
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->last_rx = jiffies;
dev->stats.rx_packets++;
dev->stats.rx_bytes+=pkt_len;
dev->stats.rx_bytes += pkt_len;
}
return;
}
@ -760,7 +745,7 @@ static void el_reset(struct net_device *dev)
struct net_local *lp = netdev_priv(dev);
int ioaddr = dev->base_addr;
if (el_debug> 2)
if (el_debug > 2)
printk(KERN_INFO "3c501 reset...");
outb(AX_RESET, AX_CMD); /* Reset the chip */
outb(AX_LOOP, AX_CMD); /* Aux control, irq and loopback enabled */
@ -794,7 +779,8 @@ static int el1_close(struct net_device *dev)
int ioaddr = dev->base_addr;
if (el_debug > 2)
printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n", dev->name, ioaddr);
printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n",
dev->name, ioaddr);
netif_stop_queue(dev);
@ -822,18 +808,14 @@ static void set_multicast_list(struct net_device *dev)
{
int ioaddr = dev->base_addr;
if(dev->flags&IFF_PROMISC)
{
if (dev->flags & IFF_PROMISC) {
outb(RX_PROM, RX_CMD);
inb(RX_STATUS);
}
else if (dev->mc_list || dev->flags&IFF_ALLMULTI)
{
outb(RX_MULT, RX_CMD); /* Multicast or all multicast is the same */
} else if (dev->mc_list || dev->flags & IFF_ALLMULTI) {
/* Multicast or all multicast is the same */
outb(RX_MULT, RX_CMD);
inb(RX_STATUS); /* Clear status. */
}
else
{
} else {
outb(RX_NORM, RX_CMD);
inb(RX_STATUS);
}

View file

@ -747,7 +747,7 @@ static void init_82586_mem(struct net_device *dev)
int boguscnt = 50;
while (readw(shmem+iSCB_STATUS) == 0)
if (--boguscnt == 0) {
printk("%s: i82586 initialization timed out with status %04x,"
printk("%s: i82586 initialization timed out with status %04x, "
"cmd %04x.\n", dev->name,
readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
break;
@ -832,10 +832,11 @@ static void el16_rx(struct net_device *dev)
if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
|| (pkt_len & 0xC000) != 0xC000) {
printk("%s: Rx frame at %#x corrupted, status %04x cmd %04x"
"next %04x data-buf @%04x %04x.\n", dev->name, rx_head,
frame_status, rfd_cmd, next_rx_frame, data_buffer_addr,
pkt_len);
printk(KERN_ERR "%s: Rx frame at %#x corrupted, "
"status %04x cmd %04x next %04x "
"data-buf @%04x %04x.\n",
dev->name, rx_head, frame_status, rfd_cmd,
next_rx_frame, data_buffer_addr, pkt_len);
} else if ((frame_status & 0x2000) == 0) {
/* Frame Rxed, but with error. */
dev->stats.rx_errors++;
@ -851,7 +852,9 @@ static void el16_rx(struct net_device *dev)
pkt_len &= 0x3fff;
skb = dev_alloc_skb(pkt_len+2);
if (skb == NULL) {
printk("%s: Memory squeeze, dropping packet.\n", dev->name);
printk(KERN_ERR "%s: Memory squeeze, "
"dropping packet.\n",
dev->name);
dev->stats.rx_dropped++;
break;
}

View file

@ -1361,7 +1361,7 @@ static int boomerang_rx(struct net_device *dev)
/* Check if the packet is long enough to just accept without
copying to a properly sized skbuff. */
if (pkt_len < rx_copybreak
&& (skb = dev_alloc_skb(pkt_len + 4)) != 0) {
&& (skb = dev_alloc_skb(pkt_len + 4)) != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
/* 'skb_put()' points to the start of sk_buff data area. */
memcpy(skb_put(skb, pkt_len),

View file

@ -277,8 +277,6 @@ static int lance_rx (struct net_device *dev)
volatile struct lance_init_block *ib = lp->init_block;
volatile struct lance_rx_desc *rd;
unsigned char bits;
int len = 0; /* XXX shut up gcc warnings */
struct sk_buff *skb = 0; /* XXX shut up gcc warnings */
#ifdef TEST_HITS
int i;
#endif
@ -318,10 +316,10 @@ static int lance_rx (struct net_device *dev)
if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++;
if (bits & LE_R1_EOP) dev->stats.rx_errors++;
} else {
len = (rd->mblength & 0xfff) - 4;
skb = dev_alloc_skb (len+2);
int len = (rd->mblength & 0xfff) - 4;
struct sk_buff *skb = dev_alloc_skb (len+2);
if (skb == 0) {
if (!skb) {
printk ("%s: Memory squeeze, deferring packet.\n",
dev->name);
dev->stats.rx_dropped++;

View file

@ -912,6 +912,24 @@ config DM9000
To compile this driver as a module, choose M here. The module
will be called dm9000.
config ENC28J60
tristate "ENC28J60 support"
depends on EXPERIMENTAL && SPI && NET_ETHERNET
select CRC32
---help---
Support for the Microchip EN28J60 ethernet chip.
To compile this driver as a module, choose M here and read
<file:Documentation/networking/net-modules.txt>. The module will be
called enc28j60.
config ENC28J60_WRITEVERIFY
bool "Enable write verify"
depends on ENC28J60
---help---
Enable the verify after the buffer write useful for debugging purpose.
If unsure, say N.
config SMC911X
tristate "SMSC LAN911[5678] support"
select CRC32
@ -1584,6 +1602,18 @@ config 8139_OLD_RX_RESET
experience problems, you can enable this option to restore the
old RX-reset behavior. If unsure, say N.
config R6040
tristate "RDC R6040 Fast Ethernet Adapter support (EXPERIMENTAL)"
depends on NET_PCI && PCI
select CRC32
select MII
help
This is a driver for the R6040 Fast Ethernet MACs found in the
the RDC R-321x System-on-chips.
To compile this driver as a module, choose M here: the module
will be called r6040. This is recommended.
config SIS900
tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
depends on NET_PCI && PCI
@ -1785,7 +1815,7 @@ config DE620
config SGISEEQ
tristate "SGI Seeq ethernet controller support"
depends on SGI_IP22
depends on SGI_HAS_SEEQ
help
Say Y here if you have an Seeq based Ethernet network card. This is
used in many Silicon Graphics machines.
@ -1989,6 +2019,28 @@ config IP1000
To compile this driver as a module, choose M here: the module
will be called ipg. This is recommended.
config IGB
tristate "Intel(R) 82575 PCI-Express Gigabit Ethernet support"
depends on PCI
---help---
This driver supports Intel(R) 82575 gigabit ethernet family of
adapters. For more information on how to identify your adapter, go
to the Adapter & Driver ID Guide at:
<http://support.intel.com/support/network/adapter/pro100/21397.htm>
For general information and support, go to the Intel support
website at:
<http://support.intel.com>
More specific information on configuring the driver is in
<file:Documentation/networking/e1000.txt>.
To compile this driver as a module, choose M here and read
<file:Documentation/networking/net-modules.txt>. The module
will be called igb.
source "drivers/net/ixp2000/Kconfig"
config MYRI_SBUS
@ -2560,6 +2612,7 @@ config PASEMI_MAC
tristate "PA Semi 1/10Gbit MAC"
depends on PPC64 && PCI
select PHYLIB
select INET_LRO
help
This driver supports the on-chip 1/10Gbit Ethernet controller on
PA Semi's PWRficient line of chips.
@ -2585,6 +2638,16 @@ config TEHUTI
help
Tehuti Networks 10G Ethernet NIC
config BNX2X
tristate "Broadcom NetXtremeII 10Gb support"
depends on PCI
select ZLIB_INFLATE
help
This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
To compile this driver as a module, choose M here: the module
will be called bnx2x. This is recommended.
endif # NETDEV_10000
source "drivers/net/tokenring/Kconfig"
@ -3015,23 +3078,6 @@ config NET_FC
adaptor below. You also should have said Y to "SCSI support" and
"SCSI generic support".
config SHAPER
tristate "Traffic Shaper (OBSOLETE)"
depends on EXPERIMENTAL
---help---
The traffic shaper is a virtual network device that allows you to
limit the rate of outgoing data flow over some other network device.
The traffic that you want to slow down can then be routed through
these virtual devices. See
<file:Documentation/networking/shaper.txt> for more information.
An alternative to this traffic shaper are traffic schedulers which
you'll get if you say Y to "QoS and/or fair queuing" in
"Networking options".
To compile this driver as a module, choose M here: the module
will be called shaper. If unsure, say N.
config NETCONSOLE
tristate "Network console logging support (EXPERIMENTAL)"
depends on EXPERIMENTAL

View file

@ -6,12 +6,14 @@ obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_E1000E) += e1000e/
obj-$(CONFIG_IBM_EMAC) += ibm_emac/
obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
obj-$(CONFIG_IGB) += igb/
obj-$(CONFIG_IXGBE) += ixgbe/
obj-$(CONFIG_IXGB) += ixgb/
obj-$(CONFIG_IP1000) += ipg.o
obj-$(CONFIG_CHELSIO_T1) += chelsio/
obj-$(CONFIG_CHELSIO_T3) += cxgb3/
obj-$(CONFIG_EHEA) += ehea/
obj-$(CONFIG_CAN) += can/
obj-$(CONFIG_BONDING) += bonding/
obj-$(CONFIG_ATL1) += atl1/
obj-$(CONFIG_GIANFAR) += gianfar_driver.o
@ -54,6 +56,7 @@ obj-$(CONFIG_TLAN) += tlan.o
obj-$(CONFIG_EPIC100) += epic100.o
obj-$(CONFIG_SIS190) += sis190.o
obj-$(CONFIG_SIS900) += sis900.o
obj-$(CONFIG_R6040) += r6040.o
obj-$(CONFIG_YELLOWFIN) += yellowfin.o
obj-$(CONFIG_ACENIC) += acenic.o
obj-$(CONFIG_ISERIES_VETH) += iseries_veth.o
@ -63,6 +66,7 @@ obj-$(CONFIG_STNIC) += stnic.o 8390.o
obj-$(CONFIG_FEALNX) += fealnx.o
obj-$(CONFIG_TIGON3) += tg3.o
obj-$(CONFIG_BNX2) += bnx2.o
obj-$(CONFIG_BNX2X) += bnx2x.o
spidernet-y += spider_net.o spider_net_ethtool.o
obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
@ -92,7 +96,6 @@ obj-$(CONFIG_NET_SB1000) += sb1000.o
obj-$(CONFIG_MAC8390) += mac8390.o
obj-$(CONFIG_APNE) += apne.o 8390.o
obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
obj-$(CONFIG_SHAPER) += shaper.o
obj-$(CONFIG_HP100) += hp100.o
obj-$(CONFIG_SMC9194) += smc9194.o
obj-$(CONFIG_FEC) += fec.o
@ -216,6 +219,7 @@ obj-$(CONFIG_DM9000) += dm9000.o
obj-$(CONFIG_FEC_8XX) += fec_8xx/
obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
obj-$(CONFIG_MLX4_CORE) += mlx4/
obj-$(CONFIG_ENC28J60) += enc28j60.o
obj-$(CONFIG_MACB) += macb.o

View file

@ -269,8 +269,6 @@ static int lance_rx (struct net_device *dev)
volatile struct lance_regs *ll = lp->ll;
volatile struct lance_rx_desc *rd;
unsigned char bits;
int len = 0; /* XXX shut up gcc warnings */
struct sk_buff *skb = 0; /* XXX shut up gcc warnings */
#ifdef TEST_HITS
int i;
@ -306,10 +304,10 @@ static int lance_rx (struct net_device *dev)
if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++;
if (bits & LE_R1_EOP) dev->stats.rx_errors++;
} else {
len = (rd->mblength & 0xfff) - 4;
skb = dev_alloc_skb (len+2);
int len = (rd->mblength & 0xfff) - 4;
struct sk_buff *skb = dev_alloc_skb (len+2);
if (skb == 0) {
if (!skb) {
printk(KERN_WARNING "%s: Memory squeeze, "
"deferring packet.\n", dev->name);
dev->stats.rx_dropped++;
@ -477,7 +475,7 @@ static irqreturn_t lance_interrupt (int irq, void *dev_id)
return IRQ_HANDLED;
}
struct net_device *last_dev = 0;
struct net_device *last_dev;
static int lance_open (struct net_device *dev)
{

View file

@ -1945,13 +1945,13 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
err = pci_enable_device(pdev);
if(err){
printk(KERN_ERR "amd8111e: Cannot enable new PCI device,"
printk(KERN_ERR "amd8111e: Cannot enable new PCI device, "
"exiting.\n");
return err;
}
if(!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)){
printk(KERN_ERR "amd8111e: Cannot find PCI base address"
printk(KERN_ERR "amd8111e: Cannot find PCI base address, "
"exiting.\n");
err = -ENODEV;
goto err_disable_pdev;

View file

@ -465,8 +465,9 @@ found:
/* Snarf the interrupt vector now. */
ret = request_irq(irq, &net_interrupt, 0, DRV_NAME, dev);
if (ret) {
printk (" AT1700 at %#3x is unusable due to a conflict on"
"IRQ %d.\n", ioaddr, irq);
printk(KERN_ERR "AT1700 at %#3x is unusable due to a "
"conflict on IRQ %d.\n",
ioaddr, irq);
goto err_mca;
}

View file

@ -128,6 +128,8 @@ static void b44_init_rings(struct b44 *);
#define B44_FULL_RESET 1
#define B44_FULL_RESET_SKIP_PHY 2
#define B44_PARTIAL_RESET 3
#define B44_CHIP_RESET_FULL 4
#define B44_CHIP_RESET_PARTIAL 5
static void b44_init_hw(struct b44 *, int);
@ -1259,7 +1261,7 @@ static void b44_clear_stats(struct b44 *bp)
}
/* bp->lock is held. */
static void b44_chip_reset(struct b44 *bp)
static void b44_chip_reset(struct b44 *bp, int reset_kind)
{
struct ssb_device *sdev = bp->sdev;
@ -1281,6 +1283,13 @@ static void b44_chip_reset(struct b44 *bp)
ssb_device_enable(bp->sdev, 0);
b44_clear_stats(bp);
/*
* Don't enable PHY if we are doing a partial reset
* we are probably going to power down
*/
if (reset_kind == B44_CHIP_RESET_PARTIAL)
return;
switch (sdev->bus->bustype) {
case SSB_BUSTYPE_SSB:
bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
@ -1316,7 +1325,14 @@ static void b44_chip_reset(struct b44 *bp)
static void b44_halt(struct b44 *bp)
{
b44_disable_ints(bp);
b44_chip_reset(bp);
/* reset PHY */
b44_phy_reset(bp);
/* power down PHY */
printk(KERN_INFO PFX "%s: powering down PHY\n", bp->dev->name);
bw32(bp, B44_MAC_CTRL, MAC_CTRL_PHY_PDOWN);
/* now reset the chip, but without enabling the MAC&PHY
* part of it. This has to be done _after_ we shut down the PHY */
b44_chip_reset(bp, B44_CHIP_RESET_PARTIAL);
}
/* bp->lock is held. */
@ -1365,7 +1381,7 @@ static void b44_init_hw(struct b44 *bp, int reset_kind)
{
u32 val;
b44_chip_reset(bp);
b44_chip_reset(bp, B44_CHIP_RESET_FULL);
if (reset_kind == B44_FULL_RESET) {
b44_phy_reset(bp);
b44_setup_phy(bp);
@ -1422,7 +1438,7 @@ static int b44_open(struct net_device *dev)
err = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev);
if (unlikely(err < 0)) {
napi_disable(&bp->napi);
b44_chip_reset(bp);
b44_chip_reset(bp, B44_CHIP_RESET_PARTIAL);
b44_free_rings(bp);
b44_free_consistent(bp);
goto out;
@ -2060,11 +2076,11 @@ static int __devinit b44_get_invariants(struct b44 *bp)
if (sdev->bus->bustype == SSB_BUSTYPE_SSB &&
instance > 1) {
addr = sdev->bus->sprom.r1.et1mac;
bp->phy_addr = sdev->bus->sprom.r1.et1phyaddr;
addr = sdev->bus->sprom.et1mac;
bp->phy_addr = sdev->bus->sprom.et1phyaddr;
} else {
addr = sdev->bus->sprom.r1.et0mac;
bp->phy_addr = sdev->bus->sprom.r1.et0phyaddr;
addr = sdev->bus->sprom.et0mac;
bp->phy_addr = sdev->bus->sprom.et0phyaddr;
}
memcpy(bp->dev->dev_addr, addr, 6);
@ -2188,7 +2204,7 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
/* Chip reset provides power to the b44 MAC & PCI cores, which
* is necessary for MAC register access.
*/
b44_chip_reset(bp);
b44_chip_reset(bp, B44_CHIP_RESET_FULL);
printk(KERN_INFO "%s: Broadcom 44xx/47xx 10/100BaseT Ethernet %s\n",
dev->name, print_mac(mac, dev->dev_addr));
@ -2212,6 +2228,7 @@ static void __devexit b44_remove_one(struct ssb_device *sdev)
unregister_netdev(dev);
ssb_bus_may_powerdown(sdev->bus);
free_netdev(dev);
ssb_pcihost_set_power_state(sdev, PCI_D3hot);
ssb_set_drvdata(sdev, NULL);
}
@ -2240,6 +2257,7 @@ static int b44_suspend(struct ssb_device *sdev, pm_message_t state)
b44_setup_wol(bp);
}
ssb_pcihost_set_power_state(sdev, PCI_D3hot);
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -154,6 +154,33 @@ struct status_block {
#endif
};
/*
* status_block definition
*/
struct status_block_msix {
#if defined(__BIG_ENDIAN)
u16 status_tx_quick_consumer_index;
u16 status_rx_quick_consumer_index;
u16 status_completion_producer_index;
u16 status_cmd_consumer_index;
u32 status_unused;
u16 status_idx;
u8 status_unused2;
u8 status_blk_num;
#elif defined(__LITTLE_ENDIAN)
u16 status_rx_quick_consumer_index;
u16 status_tx_quick_consumer_index;
u16 status_cmd_consumer_index;
u16 status_completion_producer_index;
u32 status_unused;
u8 status_blk_num;
u8 status_unused2;
u16 status_idx;
#endif
};
#define BNX2_SBLK_MSIX_ALIGN_SIZE 128
/*
* statistics_block definition
@ -259,6 +286,7 @@ struct l2_fhdr {
#define L2_FHDR_STATUS_TCP_SEGMENT (1<<14)
#define L2_FHDR_STATUS_UDP_DATAGRAM (1<<15)
#define L2_FHDR_STATUS_SPLIT (1<<16)
#define L2_FHDR_ERRORS_BAD_CRC (1<<17)
#define L2_FHDR_ERRORS_PHY_DECODE (1<<18)
#define L2_FHDR_ERRORS_ALIGNMENT (1<<19)
@ -332,6 +360,12 @@ struct l2_fhdr {
#define BNX2_L2CTX_NX_BDHADDR_LO 0x00000014
#define BNX2_L2CTX_NX_BDIDX 0x00000018
#define BNX2_L2CTX_HOST_PG_BDIDX 0x00000044
#define BNX2_L2CTX_PG_BUF_SIZE 0x00000048
#define BNX2_L2CTX_RBDC_KEY 0x0000004c
#define BNX2_L2CTX_RBDC_JUMBO_KEY 0x3ffe
#define BNX2_L2CTX_NX_PG_BDHADDR_HI 0x00000050
#define BNX2_L2CTX_NX_PG_BDHADDR_LO 0x00000054
/*
* pci_config_l definition
@ -406,6 +440,7 @@ struct l2_fhdr {
#define BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM (1L<<17)
#define BNX2_PCICFG_INT_ACK_CMD_MASK_INT (1L<<18)
#define BNX2_PCICFG_INT_ACK_CMD_INTERRUPT_NUM (0xfL<<24)
#define BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT 24
#define BNX2_PCICFG_STATUS_BIT_SET_CMD 0x00000088
#define BNX2_PCICFG_STATUS_BIT_CLEAR_CMD 0x0000008c
@ -421,6 +456,9 @@ struct l2_fhdr {
#define BNX2_PCI_GRC_WINDOW_ADDR_VALUE (0x1ffL<<13)
#define BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN (1L<<31)
#define BNX2_PCI_GRC_WINDOW2_BASE 0xc000
#define BNX2_PCI_GRC_WINDOW3_BASE 0xe000
#define BNX2_PCI_CONFIG_1 0x00000404
#define BNX2_PCI_CONFIG_1_RESERVED0 (0xffL<<0)
#define BNX2_PCI_CONFIG_1_READ_BOUNDARY (0x7L<<8)
@ -693,6 +731,8 @@ struct l2_fhdr {
#define BNX2_PCI_GRC_WINDOW3_ADDR 0x00000618
#define BNX2_PCI_GRC_WINDOW3_ADDR_VALUE (0x1ffL<<13)
#define BNX2_MSIX_TABLE_ADDR 0x318000
#define BNX2_MSIX_PBA_ADDR 0x31c000
/*
* misc_reg definition
@ -4445,6 +4485,14 @@ struct l2_fhdr {
#define BNX2_MQ_MEM_RD_DATA2_VALUE (0x3fffffffL<<0)
#define BNX2_MQ_MEM_RD_DATA2_VALUE_XI (0x7fffffffL<<0)
#define BNX2_MQ_MAP_L2_3 0x00003d2c
#define BNX2_MQ_MAP_L2_3_MQ_OFFSET (0xffL<<0)
#define BNX2_MQ_MAP_L2_3_SZ (0x3L<<8)
#define BNX2_MQ_MAP_L2_3_CTX_OFFSET (0x2ffL<<10)
#define BNX2_MQ_MAP_L2_3_BIN_OFFSET (0x7L<<23)
#define BNX2_MQ_MAP_L2_3_ARM (0x3L<<26)
#define BNX2_MQ_MAP_L2_3_ENA (0x1L<<31)
#define BNX2_MQ_MAP_L2_3_DEFAULT 0x82004646
/*
* tsch_reg definition
@ -6296,6 +6344,15 @@ struct l2_fhdr {
#define MII_BNX2_DSP_RW_PORT 0x15
#define MII_BNX2_DSP_ADDRESS 0x17
#define MII_BNX2_DSP_EXPAND_REG 0x0f00
#define MII_EXPAND_REG1 (MII_BNX2_DSP_EXPAND_REG | 1)
#define MII_EXPAND_REG1_RUDI_C 0x20
#define MII_EXPAND_SERDES_CTL (MII_BNX2_DSP_EXPAND_REG | 2)
#define MII_BNX2_MISC_SHADOW 0x1c
#define MISC_SHDW_AN_DBG 0x6800
#define MISC_SHDW_AN_DBG_NOSYNC 0x0002
#define MISC_SHDW_MODE_CTL 0x7c00
#define MISC_SHDW_MODE_CTL_SIG_DET 0x0010
#define MII_BNX2_BLK_ADDR 0x1f
#define MII_BNX2_BLK_ADDR_IEEE0 0x0000
@ -6336,7 +6393,7 @@ struct l2_fhdr {
#define MAX_ETHERNET_PACKET_SIZE 1514
#define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014
#define RX_COPY_THRESH 92
#define RX_COPY_THRESH 128
#define BNX2_MISC_ENABLE_DEFAULT 0x7ffffff
@ -6355,9 +6412,11 @@ struct l2_fhdr {
#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
#define MAX_RX_RINGS 4
#define MAX_RX_PG_RINGS 16
#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd))
#define MAX_RX_DESC_CNT (RX_DESC_CNT - 1)
#define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS)
#define MAX_TOTAL_RX_PG_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_PG_RINGS)
#define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \
(MAX_TX_DESC_CNT - 1)) ? \
@ -6370,6 +6429,7 @@ struct l2_fhdr {
(x) + 2 : (x) + 1
#define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx)
#define RX_PG_RING_IDX(x) ((x) & bp->rx_max_pg_ring_idx)
#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> (BCM_PAGE_BITS - 4))
#define RX_IDX(x) ((x) & MAX_RX_DESC_CNT)
@ -6408,6 +6468,17 @@ struct sw_bd {
DECLARE_PCI_UNMAP_ADDR(mapping)
};
struct sw_pg {
struct page *page;
DECLARE_PCI_UNMAP_ADDR(mapping)
};
#define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
#define SW_RXPG_RING_SIZE (sizeof(struct sw_pg) * RX_DESC_CNT)
#define RXBD_RING_SIZE (sizeof(struct rx_bd) * RX_DESC_CNT)
#define SW_TXBD_RING_SIZE (sizeof(struct sw_bd) * TX_DESC_CNT)
#define TXBD_RING_SIZE (sizeof(struct tx_bd) * TX_DESC_CNT)
/* Buffered flash (Atmel: AT45DB011B) specific information */
#define SEEPROM_PAGE_BITS 2
#define SEEPROM_PHY_PAGE_SIZE (1 << SEEPROM_PAGE_BITS)
@ -6465,6 +6536,39 @@ struct flash_spec {
u8 *name;
};
#define BNX2_MAX_MSIX_HW_VEC 9
#define BNX2_MAX_MSIX_VEC 2
#define BNX2_BASE_VEC 0
#define BNX2_TX_VEC 1
#define BNX2_TX_INT_NUM (BNX2_TX_VEC << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT)
struct bnx2_irq {
irq_handler_t handler;
u16 vector;
u8 requested;
char name[16];
};
struct bnx2_napi {
struct napi_struct napi ____cacheline_aligned;
struct bnx2 *bp;
struct status_block *status_blk;
struct status_block_msix *status_blk_msix;
u32 last_status_idx;
u32 int_num;
u16 tx_cons;
u16 hw_tx_cons;
u32 rx_prod_bseq;
u16 rx_prod;
u16 rx_cons;
u16 rx_pg_prod;
u16 rx_pg_cons;
};
struct bnx2 {
/* Fields used in the tx and intr/napi performance paths are grouped */
/* together in the beginning of the structure. */
@ -6473,33 +6577,32 @@ struct bnx2 {
struct net_device *dev;
struct pci_dev *pdev;
struct napi_struct napi;
atomic_t intr_sem;
struct status_block *status_blk;
u32 last_status_idx;
u32 flags;
#define PCIX_FLAG 0x00000001
#define PCI_32BIT_FLAG 0x00000002
#define ONE_TDMA_FLAG 0x00000004 /* no longer used */
#define NO_WOL_FLAG 0x00000008
#define USING_MSI_FLAG 0x00000020
#define ASF_ENABLE_FLAG 0x00000040
#define MSI_CAP_FLAG 0x00000080
#define ONE_SHOT_MSI_FLAG 0x00000100
#define PCIE_FLAG 0x00000200
#define BNX2_FLAG_PCIX 0x00000001
#define BNX2_FLAG_PCI_32BIT 0x00000002
#define BNX2_FLAG_MSIX_CAP 0x00000004
#define BNX2_FLAG_NO_WOL 0x00000008
#define BNX2_FLAG_USING_MSI 0x00000020
#define BNX2_FLAG_ASF_ENABLE 0x00000040
#define BNX2_FLAG_MSI_CAP 0x00000080
#define BNX2_FLAG_ONE_SHOT_MSI 0x00000100
#define BNX2_FLAG_PCIE 0x00000200
#define BNX2_FLAG_USING_MSIX 0x00000400
#define BNX2_FLAG_USING_MSI_OR_MSIX (BNX2_FLAG_USING_MSI | \
BNX2_FLAG_USING_MSIX)
#define BNX2_FLAG_JUMBO_BROKEN 0x00000800
/* Put tx producer and consumer fields in separate cache lines. */
u32 tx_prod_bseq __attribute__((aligned(L1_CACHE_BYTES)));
u16 tx_prod;
u8 tx_vec;
u32 tx_bidx_addr;
u32 tx_bseq_addr;
u16 tx_cons __attribute__((aligned(L1_CACHE_BYTES)));
u16 hw_tx_cons;
struct bnx2_napi bnx2_napi[BNX2_MAX_MSIX_VEC];
#ifdef BCM_VLAN
struct vlan_group *vlgrp;
@ -6508,16 +6611,17 @@ struct bnx2 {
u32 rx_offset;
u32 rx_buf_use_size; /* useable size */
u32 rx_buf_size; /* with alignment */
u32 rx_copy_thresh;
u32 rx_jumbo_thresh;
u32 rx_max_ring_idx;
u32 rx_prod_bseq;
u16 rx_prod;
u16 rx_cons;
u32 rx_max_pg_ring_idx;
u32 rx_csum;
struct sw_bd *rx_buf_ring;
struct rx_bd *rx_desc_ring[MAX_RX_RINGS];
struct sw_pg *rx_pg_ring;
struct rx_bd *rx_pg_desc_ring[MAX_RX_PG_RINGS];
/* TX constants */
struct tx_bd *tx_desc_ring;
@ -6540,15 +6644,16 @@ struct bnx2 {
spinlock_t indirect_lock;
u32 phy_flags;
#define PHY_SERDES_FLAG 1
#define PHY_CRC_FIX_FLAG 2
#define PHY_PARALLEL_DETECT_FLAG 4
#define PHY_2_5G_CAPABLE_FLAG 8
#define PHY_INT_MODE_MASK_FLAG 0x300
#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100
#define PHY_INT_MODE_LINK_READY_FLAG 0x200
#define PHY_DIS_EARLY_DAC_FLAG 0x400
#define REMOTE_PHY_CAP_FLAG 0x800
#define BNX2_PHY_FLAG_SERDES 0x00000001
#define BNX2_PHY_FLAG_CRC_FIX 0x00000002
#define BNX2_PHY_FLAG_PARALLEL_DETECT 0x00000004
#define BNX2_PHY_FLAG_2_5G_CAPABLE 0x00000008
#define BNX2_PHY_FLAG_INT_MODE_MASK 0x00000300
#define BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING 0x00000100
#define BNX2_PHY_FLAG_INT_MODE_LINK_READY 0x00000200
#define BNX2_PHY_FLAG_DIS_EARLY_DAC 0x00000400
#define BNX2_PHY_FLAG_REMOTE_PHY_CAP 0x00000800
#define BNX2_PHY_FLAG_FORCED_DOWN 0x00001000
u32 mii_bmcr;
u32 mii_bmsr;
@ -6605,6 +6710,10 @@ struct bnx2 {
int rx_ring_size;
dma_addr_t rx_desc_mapping[MAX_RX_RINGS];
int rx_max_pg_ring;
int rx_pg_ring_size;
dma_addr_t rx_pg_desc_mapping[MAX_RX_PG_RINGS];
u16 tx_quick_cons_trip;
u16 tx_quick_cons_trip_int;
u16 rx_quick_cons_trip;
@ -6622,6 +6731,7 @@ struct bnx2 {
u32 stats_ticks;
struct status_block *status_blk;
dma_addr_t status_blk_mapping;
struct statistics_block *stats_blk;
@ -6680,6 +6790,9 @@ struct bnx2 {
u32 flash_size;
int status_stats_size;
struct bnx2_irq irq_tbl[BNX2_MAX_MSIX_VEC];
int irq_nvecs;
};
static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset);
@ -6737,7 +6850,7 @@ struct fw_info {
const u32 text_addr;
const u32 text_len;
const u32 text_index;
u32 *text;
__le32 *text;
u8 *gz_text;
const u32 gz_text_len;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

9064
drivers/net/bnx2x.c Normal file

File diff suppressed because it is too large Load diff

1071
drivers/net/bnx2x.h Normal file

File diff suppressed because it is too large Load diff

198
drivers/net/bnx2x_fw_defs.h Normal file
View file

@ -0,0 +1,198 @@
/* bnx2x_fw_defs.h: Broadcom Everest network driver.
*
* Copyright (c) 2007 Broadcom Corporation
*
* 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.
*/
#define CSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
(0x1922 + (port * 0x40) + (index * 0x4))
#define CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
(0x1900 + (port * 0x40))
#define CSTORM_HC_BTR_OFFSET(port)\
(0x1984 + (port * 0xc0))
#define CSTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index)\
(0x141a + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
#define CSTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index)\
(0x1418 + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
#define CSTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id)\
(0x1400 + (port * 0x280) + (cpu_id * 0x28))
#define CSTORM_STATS_FLAGS_OFFSET(port) (0x5108 + (port * 0x8))
#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id)\
(0x1510 + (port * 0x240) + (client_id * 0x20))
#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
(0x138a + (port * 0x28) + (index * 0x4))
#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
(0x1370 + (port * 0x28))
#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port)\
(0x4b70 + (port * 0x8))
#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function)\
(0x1418 + (function * 0x30))
#define TSTORM_HC_BTR_OFFSET(port)\
(0x13c4 + (port * 0x18))
#define TSTORM_INDIRECTION_TABLE_OFFSET(port)\
(0x22c8 + (port * 0x80))
#define TSTORM_INDIRECTION_TABLE_SIZE 0x80
#define TSTORM_MAC_FILTER_CONFIG_OFFSET(port)\
(0x1420 + (port * 0x30))
#define TSTORM_RCQ_PROD_OFFSET(port, client_id)\
(0x1508 + (port * 0x240) + (client_id * 0x20))
#define TSTORM_STATS_FLAGS_OFFSET(port) (0x4b90 + (port * 0x8))
#define USTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
(0x191a + (port * 0x28) + (index * 0x4))
#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
(0x1900 + (port * 0x28))
#define USTORM_HC_BTR_OFFSET(port)\
(0x1954 + (port * 0xb8))
#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port)\
(0x5408 + (port * 0x8))
#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index)\
(0x141a + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
#define USTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index)\
(0x1418 + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
#define USTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id)\
(0x1400 + (port * 0x280) + (cpu_id * 0x28))
#define XSTORM_ASSERT_LIST_INDEX_OFFSET 0x1000
#define XSTORM_ASSERT_LIST_OFFSET(idx) (0x1020 + (idx * 0x10))
#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
(0x141a + (port * 0x28) + (index * 0x4))
#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
(0x1400 + (port * 0x28))
#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port)\
(0x5408 + (port * 0x8))
#define XSTORM_HC_BTR_OFFSET(port)\
(0x1454 + (port * 0x18))
#define XSTORM_SPQ_PAGE_BASE_OFFSET(port)\
(0x5328 + (port * 0x18))
#define XSTORM_SPQ_PROD_OFFSET(port)\
(0x5330 + (port * 0x18))
#define XSTORM_STATS_FLAGS_OFFSET(port) (0x53f8 + (port * 0x8))
#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
/**
* This file defines HSI constatnts for the ETH flow
*/
/* hash types */
#define DEFAULT_HASH_TYPE 0
#define IPV4_HASH_TYPE 1
#define TCP_IPV4_HASH_TYPE 2
#define IPV6_HASH_TYPE 3
#define TCP_IPV6_HASH_TYPE 4
/* values of command IDs in the ramrod message */
#define RAMROD_CMD_ID_ETH_PORT_SETUP (80)
#define RAMROD_CMD_ID_ETH_CLIENT_SETUP (85)
#define RAMROD_CMD_ID_ETH_STAT_QUERY (90)
#define RAMROD_CMD_ID_ETH_UPDATE (100)
#define RAMROD_CMD_ID_ETH_HALT (105)
#define RAMROD_CMD_ID_ETH_SET_MAC (110)
#define RAMROD_CMD_ID_ETH_CFC_DEL (115)
#define RAMROD_CMD_ID_ETH_PORT_DEL (120)
#define RAMROD_CMD_ID_ETH_FORWARD_SETUP (125)
/* command values for set mac command */
#define T_ETH_MAC_COMMAND_SET 0
#define T_ETH_MAC_COMMAND_INVALIDATE 1
#define T_ETH_INDIRECTION_TABLE_SIZE 128
/* Maximal L2 clients supported */
#define ETH_MAX_RX_CLIENTS (18)
/**
* This file defines HSI constatnts common to all microcode flows
*/
/* Connection types */
#define ETH_CONNECTION_TYPE 0
#define PROTOCOL_STATE_BIT_OFFSET 6
#define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
/* microcode fixed page page size 4K (chains and ring segments) */
#define MC_PAGE_SIZE (4096)
/* Host coalescing constants */
/* IGU constants */
#define IGU_PORT_BASE 0x0400
#define IGU_ADDR_MSIX 0x0000
#define IGU_ADDR_INT_ACK 0x0200
#define IGU_ADDR_PROD_UPD 0x0201
#define IGU_ADDR_ATTN_BITS_UPD 0x0202
#define IGU_ADDR_ATTN_BITS_SET 0x0203
#define IGU_ADDR_ATTN_BITS_CLR 0x0204
#define IGU_ADDR_COALESCE_NOW 0x0205
#define IGU_ADDR_SIMD_MASK 0x0206
#define IGU_ADDR_SIMD_NOMASK 0x0207
#define IGU_ADDR_MSI_CTL 0x0210
#define IGU_ADDR_MSI_ADDR_LO 0x0211
#define IGU_ADDR_MSI_ADDR_HI 0x0212
#define IGU_ADDR_MSI_DATA 0x0213
#define IGU_INT_ENABLE 0
#define IGU_INT_DISABLE 1
#define IGU_INT_NOP 2
#define IGU_INT_NOP2 3
/* index numbers */
#define HC_USTORM_DEF_SB_NUM_INDICES 4
#define HC_CSTORM_DEF_SB_NUM_INDICES 8
#define HC_XSTORM_DEF_SB_NUM_INDICES 4
#define HC_TSTORM_DEF_SB_NUM_INDICES 4
#define HC_USTORM_SB_NUM_INDICES 4
#define HC_CSTORM_SB_NUM_INDICES 4
/* index values - which counterto update */
#define HC_INDEX_U_ETH_RX_CQ_CONS 1
#define HC_INDEX_C_ETH_TX_CQ_CONS 1
#define HC_INDEX_DEF_X_SPQ_CONS 0
#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS 2
#define HC_INDEX_DEF_C_ETH_SLOW_PATH 3
/* used by the driver to get the SB offset */
#define USTORM_ID 0
#define CSTORM_ID 1
#define XSTORM_ID 2
#define TSTORM_ID 3
#define ATTENTION_ID 4
/* max number of slow path commands per port */
#define MAX_RAMRODS_PER_PORT (8)
/* values for RX ETH CQE type field */
#define RX_ETH_CQE_TYPE_ETH_FASTPATH (0)
#define RX_ETH_CQE_TYPE_ETH_RAMROD (1)
/* MAC address list size */
#define T_MAC_ADDRESS_LIST_SIZE (96)
#define XSTORM_IP_ID_ROLL_HALF 0x8000
#define XSTORM_IP_ID_ROLL_ALL 0
#define FW_LOG_LIST_SIZE (50)
#define NUM_OF_PROTOCOLS 4
#define MAX_COS_NUMBER 16
#define MAX_T_STAT_COUNTER_ID 18
#define T_FAIR 1
#define FAIR_MEM 2
#define RS_PERIODIC_TIMEOUT_IN_SDM_TICS 25
#define UNKNOWN_ADDRESS 0
#define UNICAST_ADDRESS 1
#define MULTICAST_ADDRESS 2
#define BROADCAST_ADDRESS 3

2176
drivers/net/bnx2x_hsi.h Normal file

File diff suppressed because it is too large Load diff

564
drivers/net/bnx2x_init.h Normal file
View file

@ -0,0 +1,564 @@
/* bnx2x_init.h: Broadcom Everest network driver.
*
* Copyright (c) 2007 Broadcom Corporation
*
* 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.
*
* Written by: Eliezer Tamir <eliezert@broadcom.com>
*/
#ifndef BNX2X_INIT_H
#define BNX2X_INIT_H
#define COMMON 0x1
#define PORT0 0x2
#define PORT1 0x4
#define INIT_EMULATION 0x1
#define INIT_FPGA 0x2
#define INIT_ASIC 0x4
#define INIT_HARDWARE 0x7
#define STORM_INTMEM_SIZE (0x5800 / 4)
#define TSTORM_INTMEM_ADDR 0x1a0000
#define CSTORM_INTMEM_ADDR 0x220000
#define XSTORM_INTMEM_ADDR 0x2a0000
#define USTORM_INTMEM_ADDR 0x320000
/* Init operation types and structures */
#define OP_RD 0x1 /* read single register */
#define OP_WR 0x2 /* write single register */
#define OP_IW 0x3 /* write single register using mailbox */
#define OP_SW 0x4 /* copy a string to the device */
#define OP_SI 0x5 /* copy a string using mailbox */
#define OP_ZR 0x6 /* clear memory */
#define OP_ZP 0x7 /* unzip then copy with DMAE */
#define OP_WB 0x8 /* copy a string using DMAE */
struct raw_op {
u32 op :8;
u32 offset :24;
u32 raw_data;
};
struct op_read {
u32 op :8;
u32 offset :24;
u32 pad;
};
struct op_write {
u32 op :8;
u32 offset :24;
u32 val;
};
struct op_string_write {
u32 op :8;
u32 offset :24;
#ifdef __LITTLE_ENDIAN
u16 data_off;
u16 data_len;
#else /* __BIG_ENDIAN */
u16 data_len;
u16 data_off;
#endif
};
struct op_zero {
u32 op :8;
u32 offset :24;
u32 len;
};
union init_op {
struct op_read read;
struct op_write write;
struct op_string_write str_wr;
struct op_zero zero;
struct raw_op raw;
};
#include "bnx2x_init_values.h"
static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
u32 dst_addr, u32 len32);
static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len);
static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
u32 len)
{
int i;
for (i = 0; i < len; i++) {
REG_WR(bp, addr + i*4, data[i]);
if (!(i % 10000)) {
touch_softlockup_watchdog();
cpu_relax();
}
}
}
#define INIT_MEM_WR(reg, data, reg_off, len) \
bnx2x_init_str_wr(bp, reg + reg_off*4, data, len)
static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
u16 len)
{
int i;
for (i = 0; i < len; i++) {
REG_WR_IND(bp, addr + i*4, data[i]);
if (!(i % 10000)) {
touch_softlockup_watchdog();
cpu_relax();
}
}
}
static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
u32 len, int gunzip)
{
int offset = 0;
if (gunzip) {
int rc;
#ifdef __BIG_ENDIAN
int i, size;
u32 *temp;
temp = kmalloc(len, GFP_KERNEL);
size = (len / 4) + ((len % 4) ? 1 : 0);
for (i = 0; i < size; i++)
temp[i] = swab32(data[i]);
data = temp;
#endif
rc = bnx2x_gunzip(bp, (u8 *)data, len);
if (rc) {
DP(NETIF_MSG_HW, "gunzip failed ! rc %d\n", rc);
return;
}
len = bp->gunzip_outlen;
#ifdef __BIG_ENDIAN
kfree(temp);
for (i = 0; i < len; i++)
((u32 *)bp->gunzip_buf)[i] =
swab32(((u32 *)bp->gunzip_buf)[i]);
#endif
} else {
if ((len * 4) > FW_BUF_SIZE) {
BNX2X_ERR("LARGE DMAE OPERATION ! len 0x%x\n", len*4);
return;
}
memcpy(bp->gunzip_buf, data, len * 4);
}
while (len > DMAE_LEN32_MAX) {
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
addr + offset, DMAE_LEN32_MAX);
offset += DMAE_LEN32_MAX * 4;
len -= DMAE_LEN32_MAX;
}
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len);
}
#define INIT_MEM_WB(reg, data, reg_off, len) \
bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 0)
#define INIT_GUNZIP_DMAE(reg, data, reg_off, len) \
bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 1)
static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
{
int offset = 0;
if ((len * 4) > FW_BUF_SIZE) {
BNX2X_ERR("LARGE DMAE OPERATION ! len 0x%x\n", len * 4);
return;
}
memset(bp->gunzip_buf, fill, len * 4);
while (len > DMAE_LEN32_MAX) {
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
addr + offset, DMAE_LEN32_MAX);
offset += DMAE_LEN32_MAX * 4;
len -= DMAE_LEN32_MAX;
}
bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len);
}
static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
{
int i;
union init_op *op;
u32 op_type, addr, len;
const u32 *data;
for (i = op_start; i < op_end; i++) {
op = (union init_op *)&(init_ops[i]);
op_type = op->str_wr.op;
addr = op->str_wr.offset;
len = op->str_wr.data_len;
data = init_data + op->str_wr.data_off;
switch (op_type) {
case OP_RD:
REG_RD(bp, addr);
break;
case OP_WR:
REG_WR(bp, addr, op->write.val);
break;
case OP_SW:
bnx2x_init_str_wr(bp, addr, data, len);
break;
case OP_WB:
bnx2x_init_wr_wb(bp, addr, data, len, 0);
break;
case OP_SI:
bnx2x_init_ind_wr(bp, addr, data, len);
break;
case OP_ZR:
bnx2x_init_fill(bp, addr, 0, op->zero.len);
break;
case OP_ZP:
bnx2x_init_wr_wb(bp, addr, data, len, 1);
break;
default:
BNX2X_ERR("BAD init operation!\n");
}
}
}
/****************************************************************************
* PXP
****************************************************************************/
/*
* This code configures the PCI read/write arbiter
* which implements a wighted round robin
* between the virtual queues in the chip.
*
* The values were derived for each PCI max payload and max request size.
* since max payload and max request size are only known at run time,
* this is done as a separate init stage.
*/
#define NUM_WR_Q 13
#define NUM_RD_Q 29
#define MAX_RD_ORD 3
#define MAX_WR_ORD 2
/* configuration for one arbiter queue */
struct arb_line {
int l;
int add;
int ubound;
};
/* derived configuration for each read queue for each max request size */
static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
{{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
{{4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4} },
{{4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3} },
{{8 , 3 , 6}, {16 , 3 , 11}, {16 , 3 , 11}, {16 , 3 , 11} },
{{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
{{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81}, {64 , 64 , 120} }
};
/* derived configuration for each write queue for each max request size */
static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
{{4 , 6 , 3}, {4 , 6 , 3}, {4 , 6 , 3} },
{{4 , 2 , 3}, {4 , 2 , 3}, {4 , 2 , 3} },
{{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
{{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
{{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
{{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
{{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25} },
{{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
{{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
{{8 , 9 , 6}, {16 , 9 , 11}, {32 , 9 , 21} },
{{8 , 47 , 19}, {16 , 47 , 19}, {32 , 47 , 21} },
{{8 , 9 , 6}, {16 , 9 , 11}, {16 , 9 , 11} },
{{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} }
};
/* register adresses for read queues */
static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
{PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
PXP2_REG_RQ_BW_RD_UBOUND0},
{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
PXP2_REG_PSWRQ_BW_UB1},
{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
PXP2_REG_PSWRQ_BW_UB2},
{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
PXP2_REG_PSWRQ_BW_UB3},
{PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
PXP2_REG_RQ_BW_RD_UBOUND4},
{PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
PXP2_REG_RQ_BW_RD_UBOUND5},
{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
PXP2_REG_PSWRQ_BW_UB6},
{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
PXP2_REG_PSWRQ_BW_UB7},
{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
PXP2_REG_PSWRQ_BW_UB8},
{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
PXP2_REG_PSWRQ_BW_UB9},
{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
PXP2_REG_PSWRQ_BW_UB10},
{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
PXP2_REG_PSWRQ_BW_UB11},
{PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
PXP2_REG_RQ_BW_RD_UBOUND12},
{PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
PXP2_REG_RQ_BW_RD_UBOUND13},
{PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
PXP2_REG_RQ_BW_RD_UBOUND14},
{PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
PXP2_REG_RQ_BW_RD_UBOUND15},
{PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
PXP2_REG_RQ_BW_RD_UBOUND16},
{PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
PXP2_REG_RQ_BW_RD_UBOUND17},
{PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
PXP2_REG_RQ_BW_RD_UBOUND18},
{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
PXP2_REG_RQ_BW_RD_UBOUND19},
{PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
PXP2_REG_RQ_BW_RD_UBOUND20},
{PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
PXP2_REG_RQ_BW_RD_UBOUND22},
{PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
PXP2_REG_RQ_BW_RD_UBOUND23},
{PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
PXP2_REG_RQ_BW_RD_UBOUND24},
{PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
PXP2_REG_RQ_BW_RD_UBOUND25},
{PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
PXP2_REG_RQ_BW_RD_UBOUND26},
{PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
PXP2_REG_RQ_BW_RD_UBOUND27},
{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
PXP2_REG_PSWRQ_BW_UB28}
};
/* register adresses for wrtie queues */
static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
PXP2_REG_PSWRQ_BW_UB1},
{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
PXP2_REG_PSWRQ_BW_UB2},
{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
PXP2_REG_PSWRQ_BW_UB3},
{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
PXP2_REG_PSWRQ_BW_UB6},
{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
PXP2_REG_PSWRQ_BW_UB7},
{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
PXP2_REG_PSWRQ_BW_UB8},
{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
PXP2_REG_PSWRQ_BW_UB9},
{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
PXP2_REG_PSWRQ_BW_UB10},
{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
PXP2_REG_PSWRQ_BW_UB11},
{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
PXP2_REG_PSWRQ_BW_UB28},
{PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
PXP2_REG_RQ_BW_WR_UBOUND29},
{PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
PXP2_REG_RQ_BW_WR_UBOUND30}
};
static void bnx2x_init_pxp(struct bnx2x *bp)
{
int r_order, w_order;
u32 val, i;
pci_read_config_word(bp->pdev,
bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val);
DP(NETIF_MSG_HW, "read 0x%x from devctl\n", val);
w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12);
if (r_order > MAX_RD_ORD) {
DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
r_order, MAX_RD_ORD);
r_order = MAX_RD_ORD;
}
if (w_order > MAX_WR_ORD) {
DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
w_order, MAX_WR_ORD);
w_order = MAX_WR_ORD;
}
DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
for (i = 0; i < NUM_RD_Q-1; i++) {
REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
REG_WR(bp, read_arb_addr[i].add,
read_arb_data[i][r_order].add);
REG_WR(bp, read_arb_addr[i].ubound,
read_arb_data[i][r_order].ubound);
}
for (i = 0; i < NUM_WR_Q-1; i++) {
if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
(write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
REG_WR(bp, write_arb_addr[i].l,
write_arb_data[i][w_order].l);
REG_WR(bp, write_arb_addr[i].add,
write_arb_data[i][w_order].add);
REG_WR(bp, write_arb_addr[i].ubound,
write_arb_data[i][w_order].ubound);
} else {
val = REG_RD(bp, write_arb_addr[i].l);
REG_WR(bp, write_arb_addr[i].l,
val | (write_arb_data[i][w_order].l << 10));
val = REG_RD(bp, write_arb_addr[i].add);
REG_WR(bp, write_arb_addr[i].add,
val | (write_arb_data[i][w_order].add << 10));
val = REG_RD(bp, write_arb_addr[i].ubound);
REG_WR(bp, write_arb_addr[i].ubound,
val | (write_arb_data[i][w_order].ubound << 7));
}
}
val = write_arb_data[NUM_WR_Q-1][w_order].add;
val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
val = read_arb_data[NUM_RD_Q-1][r_order].add;
val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
REG_WR(bp, PXP2_REG_RQ_WR_MBS0 + 8, w_order);
REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
REG_WR(bp, PXP2_REG_RQ_RD_MBS0 + 8, r_order);
REG_WR(bp, PXP2_REG_WR_DMAE_TH, (128 << w_order)/16);
}
/****************************************************************************
* CDU
****************************************************************************/
#define CDU_REGION_NUMBER_XCM_AG 2
#define CDU_REGION_NUMBER_UCM_AG 4
/**
* String-to-compress [31:8] = CID (all 24 bits)
* String-to-compress [7:4] = Region
* String-to-compress [3:0] = Type
*/
#define CDU_VALID_DATA(_cid, _region, _type) \
(((_cid) << 8) | (((_region) & 0xf) << 4) | (((_type) & 0xf)))
#define CDU_CRC8(_cid, _region, _type) \
calc_crc8(CDU_VALID_DATA(_cid, _region, _type), 0xff)
#define CDU_RSRVD_VALUE_TYPE_A(_cid, _region, _type) \
(0x80 | (CDU_CRC8(_cid, _region, _type) & 0x7f))
#define CDU_RSRVD_VALUE_TYPE_B(_crc, _type) \
(0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7))
#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
/*****************************************************************************
* Description:
* Calculates crc 8 on a word value: polynomial 0-1-2-8
* Code was translated from Verilog.
****************************************************************************/
static u8 calc_crc8(u32 data, u8 crc)
{
u8 D[32];
u8 NewCRC[8];
u8 C[8];
u8 crc_res;
u8 i;
/* split the data into 31 bits */
for (i = 0; i < 32; i++) {
D[i] = data & 1;
data = data >> 1;
}
/* split the crc into 8 bits */
for (i = 0; i < 8; i++) {
C[i] = crc & 1;
crc = crc >> 1;
}
NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
C[6] ^ C[7];
NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
C[0] ^ C[1] ^ C[4] ^ C[5];
NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
C[1] ^ C[2] ^ C[5] ^ C[6];
NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
C[3] ^ C[4] ^ C[7];
NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
C[5];
NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
C[6];
crc_res = 0;
for (i = 0; i < 8; i++)
crc_res |= (NewCRC[i] << i);
return crc_res;
}
#endif /* BNX2X_INIT_H */

File diff suppressed because it is too large Load diff

4394
drivers/net/bnx2x_reg.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -2517,7 +2517,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
fl.fl4_dst = targets[i];
fl.fl4_tos = RTO_ONLINK;
rv = ip_route_output_key(&rt, &fl);
rv = ip_route_output_key(&init_net, &rt, &fl);
if (rv) {
if (net_ratelimit()) {
printk(KERN_WARNING DRV_NAME

25
drivers/net/can/Kconfig Normal file
View file

@ -0,0 +1,25 @@
menu "CAN Device Drivers"
depends on CAN
config CAN_VCAN
tristate "Virtual Local CAN Interface (vcan)"
depends on CAN
default N
---help---
Similar to the network loopback devices, vcan offers a
virtual local CAN interface.
This driver can also be built as a module. If so, the module
will be called vcan.
config CAN_DEBUG_DEVICES
bool "CAN devices debugging messages"
depends on CAN
default N
---help---
Say Y here if you want the CAN device drivers to produce a bunch of
debug messages to the system log. Select this if you are having
a problem with CAN support and want to see more of what is going
on.
endmenu

5
drivers/net/can/Makefile Normal file
View file

@ -0,0 +1,5 @@
#
# Makefile for the Linux Controller Area Network drivers.
#
obj-$(CONFIG_CAN_VCAN) += vcan.o

169
drivers/net/can/vcan.c Normal file
View file

@ -0,0 +1,169 @@
/*
* vcan.c - Virtual CAN interface
*
* Copyright (c) 2002-2007 Volkswagen Group Electronic Research
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Volkswagen nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* Alternatively, provided that this notice is retained in full, this
* software may be distributed under the terms of the GNU General
* Public License ("GPL") version 2, in which case the provisions of the
* GPL apply INSTEAD OF those given above.
*
* The provided data structures and external interfaces from this code
* are not restricted to be used by modules with a GPL compatible license.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* Send feedback to <socketcan-users@lists.berlios.de>
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/can.h>
#include <net/rtnetlink.h>
static __initdata const char banner[] =
KERN_INFO "vcan: Virtual CAN interface driver\n";
MODULE_DESCRIPTION("virtual CAN interface");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Urs Thuermann <[email protected]>");
/*
* CAN test feature:
* Enable the echo on driver level for testing the CAN core echo modes.
* See Documentation/networking/can.txt for details.
*/
static int echo; /* echo testing. Default: 0 (Off) */
module_param(echo, bool, S_IRUGO);
MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)");
static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
{
struct net_device_stats *stats = &dev->stats;
stats->rx_packets++;
stats->rx_bytes += skb->len;
skb->protocol = htons(ETH_P_CAN);
skb->pkt_type = PACKET_BROADCAST;
skb->dev = dev;
skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_rx(skb);
}
static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
{
struct net_device_stats *stats = &dev->stats;
int loop;
stats->tx_packets++;
stats->tx_bytes += skb->len;
/* set flag whether this packet has to be looped back */
loop = skb->pkt_type == PACKET_LOOPBACK;
if (!echo) {
/* no echo handling available inside this driver */
if (loop) {
/*
* only count the packets here, because the
* CAN core already did the echo for us
*/
stats->rx_packets++;
stats->rx_bytes += skb->len;
}
kfree_skb(skb);
return NETDEV_TX_OK;
}
/* perform standard echo handling for CAN network interfaces */
if (loop) {
struct sock *srcsk = skb->sk;
skb = skb_share_check(skb, GFP_ATOMIC);
if (!skb)
return NETDEV_TX_OK;
/* receive with packet counting */
skb->sk = srcsk;
vcan_rx(skb, dev);
} else {
/* no looped packets => no counting */
kfree_skb(skb);
}
return NETDEV_TX_OK;
}
static void vcan_setup(struct net_device *dev)
{
dev->type = ARPHRD_CAN;
dev->mtu = sizeof(struct can_frame);
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->tx_queue_len = 0;
dev->flags = IFF_NOARP;
/* set flags according to driver capabilities */
if (echo)
dev->flags |= IFF_ECHO;
dev->hard_start_xmit = vcan_tx;
dev->destructor = free_netdev;
}
static struct rtnl_link_ops vcan_link_ops __read_mostly = {
.kind = "vcan",
.setup = vcan_setup,
};
static __init int vcan_init_module(void)
{
printk(banner);
if (echo)
printk(KERN_INFO "vcan: enabled echo on driver level.\n");
return rtnl_link_register(&vcan_link_ops);
}
static __exit void vcan_cleanup_module(void)
{
rtnl_link_unregister(&vcan_link_ops);
}
module_init(vcan_init_module);
module_exit(vcan_cleanup_module);

View file

@ -4394,7 +4394,7 @@ static struct {
{"tx_fifo_errors"},
{"tx_packets"}
};
#define CAS_NUM_STAT_KEYS (sizeof(ethtool_cassini_statnames)/ETH_GSTRING_LEN)
#define CAS_NUM_STAT_KEYS ARRAY_SIZE(ethtool_cassini_statnames)
static struct {
const int offsets; /* neg. values for 2nd arg to cas_read_phy */
@ -5085,7 +5085,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
/* give us access to cassini registers */
cp->regs = pci_iomap(pdev, 0, casreg_len);
if (cp->regs == 0UL) {
if (!cp->regs) {
dev_err(&pdev->dev, "Cannot map device registers, aborting.\n");
goto err_out_free_res;
}

View file

@ -379,7 +379,7 @@ extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config
extern const struct board_info *t1_get_board_info(unsigned int board_id);
extern const struct board_info *t1_get_board_info_from_ids(unsigned int devid,
unsigned short ssid);
extern int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data);
extern int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data);
extern int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
struct adapter_params *p);
extern int t1_init_hw_modules(adapter_t *adapter);

View file

@ -814,7 +814,7 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
e->magic = EEPROM_MAGIC(adapter);
for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32))
t1_seeprom_read(adapter, i, (u32 *)&buf[i]);
t1_seeprom_read(adapter, i, (__le32 *)&buf[i]);
memcpy(data, buf + e->offset, e->len);
return 0;
}
@ -1042,7 +1042,7 @@ static int __devinit init_one(struct pci_dev *pdev,
pci_using_dac = 1;
if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
CH_ERR("%s: unable to obtain 64-bit DMA for"
CH_ERR("%s: unable to obtain 64-bit DMA for "
"consistent allocations\n", pci_name(pdev));
err = -ENODEV;
goto out_disable_pdev;

View file

@ -297,6 +297,7 @@ struct peespi *t1_espi_create(adapter_t *adapter)
return espi;
}
#if 0
void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val)
{
struct peespi *espi = adapter->espi;
@ -309,6 +310,7 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val)
writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
spin_unlock(&espi->lock);
}
#endif /* 0 */
u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait)
{

View file

@ -62,7 +62,6 @@ void t1_espi_intr_disable(struct peespi *);
int t1_espi_intr_handler(struct peespi *);
const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi);
void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val);
u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait);
int t1_espi_get_mon_t204(adapter_t *, u32 *, u8);

View file

@ -330,6 +330,8 @@ unsigned int t1_sched_update_parms(struct sge *sge, unsigned int port,
return max_avail_segs * (p->mtu - 40);
}
#if 0
/*
* t1_sched_max_avail_bytes() tells the scheduler the maximum amount of
* data that can be pushed per port.
@ -357,6 +359,8 @@ void t1_sched_set_drain_bits_per_us(struct sge *sge, unsigned int port,
t1_sched_update_parms(sge, port, 0, 0);
}
#endif /* 0 */
/*
* get_clock() implements a ns clock (see ktime_get)

View file

@ -88,8 +88,6 @@ void t1_sge_intr_disable(struct sge *);
void t1_sge_intr_clear(struct sge *);
const struct sge_intr_counts *t1_sge_get_intr_counts(const struct sge *sge);
void t1_sge_get_port_stats(const struct sge *sge, int port, struct sge_port_stats *);
void t1_sched_set_max_avail_bytes(struct sge *, unsigned int);
void t1_sched_set_drain_bits_per_us(struct sge *, unsigned int, unsigned int);
unsigned int t1_sched_update_parms(struct sge *, unsigned int, unsigned int,
unsigned int);

View file

@ -563,10 +563,11 @@ struct chelsio_vpd_t {
* written to the Control register. The hardware device will set the flag to a
* one when 4B have been transferred to the Data register.
*/
int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data)
int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data)
{
int i = EEPROM_MAX_POLL;
u16 val;
u32 v;
if (addr >= EEPROMSIZE || (addr & 3))
return -EINVAL;
@ -582,8 +583,8 @@ int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data)
adapter->name, addr);
return -EIO;
}
pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, data);
*data = le32_to_cpu(*data);
pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, &v);
*data = cpu_to_le32(v);
return 0;
}
@ -593,7 +594,7 @@ static int t1_eeprom_vpd_get(adapter_t *adapter, struct chelsio_vpd_t *vpd)
for (addr = 0; !ret && addr < sizeof(*vpd); addr += sizeof(u32))
ret = t1_seeprom_read(adapter, addr,
(u32 *)((u8 *)vpd + addr));
(__le32 *)((u8 *)vpd + addr));
return ret;
}

View file

@ -661,9 +661,6 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
int queue;
u32 status;
if (!dev)
return IRQ_NONE;
priv = netdev_priv(dev);
status = cpmac_read(priv->regs, CPMAC_MAC_INT_VECTOR);

View file

@ -71,6 +71,7 @@ enum { /* adapter flags */
USING_MSI = (1 << 1),
USING_MSIX = (1 << 2),
QUEUES_BOUND = (1 << 3),
TP_PARITY_INIT = (1 << 4),
};
struct fl_pg_chunk {

View file

@ -681,8 +681,8 @@ int t3_phy_intr_handler(struct adapter *adapter);
void t3_link_changed(struct adapter *adapter, int port_id);
int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data);
int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data);
int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data);
int t3_seeprom_write(struct adapter *adapter, u32 addr, __le32 data);
int t3_seeprom_wp(struct adapter *adapter, int enable);
int t3_get_tp_version(struct adapter *adapter, u32 *vers);
int t3_check_tpsram_version(struct adapter *adapter, int *must_load);

View file

@ -76,20 +76,20 @@ enum {
#define EEPROM_MAGIC 0x38E2F10C
#define CH_DEVICE(devid, ssid, idx) \
{ PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx }
#define CH_DEVICE(devid, idx) \
{ PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, PCI_ANY_ID, 0, 0, idx }
static const struct pci_device_id cxgb3_pci_tbl[] = {
CH_DEVICE(0x20, 1, 0), /* PE9000 */
CH_DEVICE(0x21, 1, 1), /* T302E */
CH_DEVICE(0x22, 1, 2), /* T310E */
CH_DEVICE(0x23, 1, 3), /* T320X */
CH_DEVICE(0x24, 1, 1), /* T302X */
CH_DEVICE(0x25, 1, 3), /* T320E */
CH_DEVICE(0x26, 1, 2), /* T310X */
CH_DEVICE(0x30, 1, 2), /* T3B10 */
CH_DEVICE(0x31, 1, 3), /* T3B20 */
CH_DEVICE(0x32, 1, 1), /* T3B02 */
CH_DEVICE(0x20, 0), /* PE9000 */
CH_DEVICE(0x21, 1), /* T302E */
CH_DEVICE(0x22, 2), /* T310E */
CH_DEVICE(0x23, 3), /* T320X */
CH_DEVICE(0x24, 1), /* T302X */
CH_DEVICE(0x25, 3), /* T320E */
CH_DEVICE(0x26, 2), /* T310X */
CH_DEVICE(0x30, 2), /* T3B10 */
CH_DEVICE(0x31, 3), /* T3B20 */
CH_DEVICE(0x32, 1), /* T3B02 */
{0,}
};
@ -306,6 +306,77 @@ static int request_msix_data_irqs(struct adapter *adap)
return 0;
}
static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt,
unsigned long n)
{
int attempts = 5;
while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) {
if (!--attempts)
return -ETIMEDOUT;
msleep(10);
}
return 0;
}
static int init_tp_parity(struct adapter *adap)
{
int i;
struct sk_buff *skb;
struct cpl_set_tcb_field *greq;
unsigned long cnt = adap->sge.qs[0].rspq.offload_pkts;
t3_tp_set_offload_mode(adap, 1);
for (i = 0; i < 16; i++) {
struct cpl_smt_write_req *req;
skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i));
req->iff = i;
t3_mgmt_tx(adap, skb);
}
for (i = 0; i < 2048; i++) {
struct cpl_l2t_write_req *req;
skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i));
req->params = htonl(V_L2T_W_IDX(i));
t3_mgmt_tx(adap, skb);
}
for (i = 0; i < 2048; i++) {
struct cpl_rte_write_req *req;
skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i));
req->l2t_idx = htonl(V_L2T_W_IDX(i));
t3_mgmt_tx(adap, skb);
}
skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL);
greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq));
memset(greq, 0, sizeof(*greq));
greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(greq) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, 0));
greq->mask = cpu_to_be64(1);
t3_mgmt_tx(adap, skb);
i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
t3_tp_set_offload_mode(adap, 0);
return i;
}
/**
* setup_rss - configure RSS
* @adap: the adapter
@ -336,7 +407,7 @@ static void setup_rss(struct adapter *adap)
t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN |
F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN |
V_RRCPLCPUSIZE(6), cpus, rspq_map);
V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map);
}
static void init_napi(struct adapter *adap)
@ -410,8 +481,7 @@ static int setup_sge_qsets(struct adapter *adap)
return 0;
}
static ssize_t attr_show(struct device *d, struct device_attribute *attr,
char *buf,
static ssize_t attr_show(struct device *d, char *buf,
ssize_t(*format) (struct net_device *, char *))
{
ssize_t len;
@ -423,7 +493,7 @@ static ssize_t attr_show(struct device *d, struct device_attribute *attr,
return len;
}
static ssize_t attr_store(struct device *d, struct device_attribute *attr,
static ssize_t attr_store(struct device *d,
const char *buf, size_t len,
ssize_t(*set) (struct net_device *, unsigned int),
unsigned int min_val, unsigned int max_val)
@ -457,7 +527,7 @@ static ssize_t format_##name(struct net_device *dev, char *buf) \
static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
char *buf) \
{ \
return attr_show(d, attr, buf, format_##name); \
return attr_show(d, buf, format_##name); \
}
static ssize_t set_nfilters(struct net_device *dev, unsigned int val)
@ -480,7 +550,7 @@ static ssize_t set_nfilters(struct net_device *dev, unsigned int val)
static ssize_t store_nfilters(struct device *d, struct device_attribute *attr,
const char *buf, size_t len)
{
return attr_store(d, attr, buf, len, set_nfilters, 0, ~0);
return attr_store(d, buf, len, set_nfilters, 0, ~0);
}
static ssize_t set_nservers(struct net_device *dev, unsigned int val)
@ -500,7 +570,7 @@ static ssize_t set_nservers(struct net_device *dev, unsigned int val)
static ssize_t store_nservers(struct device *d, struct device_attribute *attr,
const char *buf, size_t len)
{
return attr_store(d, attr, buf, len, set_nservers, 0, ~0);
return attr_store(d, buf, len, set_nservers, 0, ~0);
}
#define CXGB3_ATTR_R(name, val_expr) \
@ -524,7 +594,7 @@ static struct attribute *cxgb3_attrs[] = {
static struct attribute_group cxgb3_attr_group = {.attrs = cxgb3_attrs };
static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr,
static ssize_t tm_attr_show(struct device *d,
char *buf, int sched)
{
struct port_info *pi = netdev_priv(to_net_dev(d));
@ -550,7 +620,7 @@ static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr,
return len;
}
static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr,
static ssize_t tm_attr_store(struct device *d,
const char *buf, size_t len, int sched)
{
struct port_info *pi = netdev_priv(to_net_dev(d));
@ -578,12 +648,12 @@ static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr,
static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
char *buf) \
{ \
return tm_attr_show(d, attr, buf, sched); \
return tm_attr_show(d, buf, sched); \
} \
static ssize_t store_##name(struct device *d, struct device_attribute *attr, \
const char *buf, size_t len) \
{ \
return tm_attr_store(d, attr, buf, len, sched); \
return tm_attr_store(d, buf, len, sched); \
} \
static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
@ -720,7 +790,7 @@ static int upgrade_fw(struct adapter *adap)
else
dev_err(dev, "failed to upgrade to firmware %d.%d.%d\n",
FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
return ret;
}
@ -747,7 +817,7 @@ static int update_tpsram(struct adapter *adap)
struct device *dev = &adap->pdev->dev;
int ret;
char rev;
rev = t3rev2char(adap);
if (!rev)
return 0;
@ -761,10 +831,10 @@ static int update_tpsram(struct adapter *adap)
buf);
return ret;
}
ret = t3_check_tpsram(adap, tpsram->data, tpsram->size);
if (ret)
goto release_tpsram;
goto release_tpsram;
ret = t3_set_proto_sram(adap, tpsram->data);
if (ret == 0)
@ -780,7 +850,7 @@ static int update_tpsram(struct adapter *adap)
release_tpsram:
release_firmware(tpsram);
return ret;
}
@ -818,6 +888,7 @@ static int cxgb_up(struct adapter *adap)
if (err)
goto out;
t3_set_reg_field(adap, A_TP_PARA_REG5, 0, F_RXDDPOFFINIT);
t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
err = setup_sge_qsets(adap);
@ -839,7 +910,8 @@ static int cxgb_up(struct adapter *adap)
if (err)
goto irq_err;
if (request_msix_data_irqs(adap)) {
err = request_msix_data_irqs(adap);
if (err) {
free_irq(adap->msix_info[0].vec, adap);
goto irq_err;
}
@ -856,6 +928,16 @@ static int cxgb_up(struct adapter *adap)
t3_sge_start(adap);
t3_intr_enable(adap);
if (adap->params.rev >= T3_REV_C && !(adap->flags & TP_PARITY_INIT) &&
is_offload(adap) && init_tp_parity(adap) == 0)
adap->flags |= TP_PARITY_INIT;
if (adap->flags & TP_PARITY_INIT) {
t3_write_reg(adap, A_TP_INT_CAUSE,
F_CMCACHEPERR | F_ARPLUTPERR);
t3_write_reg(adap, A_TP_INT_ENABLE, 0x7fbfffff);
}
if ((adap->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX)
bind_qsets(adap);
adap->flags |= QUEUES_BOUND;
@ -1560,7 +1642,7 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
e->magic = EEPROM_MAGIC;
for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4)
err = t3_seeprom_read(adapter, i, (u32 *) & buf[i]);
err = t3_seeprom_read(adapter, i, (__le32 *) & buf[i]);
if (!err)
memcpy(data, buf + e->offset, e->len);
@ -1573,7 +1655,8 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
u32 aligned_offset, aligned_len, *p;
u32 aligned_offset, aligned_len;
__le32 *p;
u8 *buf;
int err;
@ -1587,11 +1670,11 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
buf = kmalloc(aligned_len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
err = t3_seeprom_read(adapter, aligned_offset, (u32 *) buf);
err = t3_seeprom_read(adapter, aligned_offset, (__le32 *) buf);
if (!err && aligned_len > 4)
err = t3_seeprom_read(adapter,
aligned_offset + aligned_len - 4,
(u32 *) & buf[aligned_len - 4]);
(__le32 *) & buf[aligned_len - 4]);
if (err)
goto out;
memcpy(buf + (eeprom->offset & 3), data, eeprom->len);
@ -1602,7 +1685,7 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
if (err)
goto out;
for (p = (u32 *) buf; !err && aligned_len; aligned_len -= 4, p++) {
for (p = (__le32 *) buf; !err && aligned_len; aligned_len -= 4, p++) {
err = t3_seeprom_write(adapter, aligned_offset, *p);
aligned_offset += 4;
}
@ -2144,7 +2227,7 @@ static void cxgb_netpoll(struct net_device *dev)
for (qidx = pi->first_qset; qidx < pi->first_qset + pi->nqsets; qidx++) {
struct sge_qset *qs = &adapter->sge.qs[qidx];
void *source;
if (adapter->flags & USING_MSIX)
source = qs;
else
@ -2315,6 +2398,106 @@ void t3_fatal_err(struct adapter *adapter)
}
/**
* t3_io_error_detected - called when PCI error is detected
* @pdev: Pointer to PCI device
* @state: The current pci connection state
*
* This function is called after a PCI bus error affecting
* this device has been detected.
*/
static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
struct adapter *adapter = pci_get_drvdata(pdev);
int i;
/* Stop all ports */
for_each_port(adapter, i) {
struct net_device *netdev = adapter->port[i];
if (netif_running(netdev))
cxgb_close(netdev);
}
if (is_offload(adapter) &&
test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
offload_close(&adapter->tdev);
/* Free sge resources */
t3_free_sge_resources(adapter);
adapter->flags &= ~FULL_INIT_DONE;
pci_disable_device(pdev);
/* Request a slot slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
}
/**
* t3_io_slot_reset - called after the pci bus has been reset.
* @pdev: Pointer to PCI device
*
* Restart the card from scratch, as if from a cold-boot.
*/
static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev)
{
struct adapter *adapter = pci_get_drvdata(pdev);
if (pci_enable_device(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
}
pci_set_master(pdev);
t3_prep_adapter(adapter, adapter->params.info, 1);
return PCI_ERS_RESULT_RECOVERED;
}
/**
* t3_io_resume - called when traffic can start flowing again.
* @pdev: Pointer to PCI device
*
* This callback is called when the error recovery driver tells us that
* its OK to resume normal operation.
*/
static void t3_io_resume(struct pci_dev *pdev)
{
struct adapter *adapter = pci_get_drvdata(pdev);
int i;
/* Restart the ports */
for_each_port(adapter, i) {
struct net_device *netdev = adapter->port[i];
if (netif_running(netdev)) {
if (cxgb_open(netdev)) {
dev_err(&pdev->dev,
"can't bring device back up"
" after reset\n");
continue;
}
netif_device_attach(netdev);
}
}
if (is_offload(adapter)) {
__set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map);
if (offload_open(adapter->port[0]))
printk(KERN_WARNING
"Could not bring back offload capabilities\n");
}
}
static struct pci_error_handlers t3_err_handler = {
.error_detected = t3_io_error_detected,
.slot_reset = t3_io_slot_reset,
.resume = t3_io_resume,
};
static int __devinit cxgb_enable_msix(struct adapter *adap)
{
struct msix_entry entries[SGE_QSETS + 1];
@ -2507,7 +2690,7 @@ static int __devinit init_one(struct pci_dev *pdev,
err = -ENODEV;
goto out_free_dev;
}
/*
* The card is now ready to go. If any errors occur during device
* registration we do not fail the whole card but rather proceed only
@ -2584,10 +2767,6 @@ static void __devexit remove_one(struct pci_dev *pdev)
sysfs_remove_group(&adapter->port[0]->dev.kobj,
&cxgb3_attr_group);
for_each_port(adapter, i)
if (test_bit(i, &adapter->registered_device_map))
unregister_netdev(adapter->port[i]);
if (is_offload(adapter)) {
cxgb3_adapter_unofld(adapter);
if (test_bit(OFFLOAD_DEVMAP_BIT,
@ -2595,6 +2774,10 @@ static void __devexit remove_one(struct pci_dev *pdev)
offload_close(&adapter->tdev);
}
for_each_port(adapter, i)
if (test_bit(i, &adapter->registered_device_map))
unregister_netdev(adapter->port[i]);
t3_free_sge_resources(adapter);
cxgb_disable_msi(adapter);
@ -2615,6 +2798,7 @@ static struct pci_driver driver = {
.id_table = cxgb3_pci_tbl,
.probe = init_one,
.remove = __devexit_p(remove_one),
.err_handler = &t3_err_handler,
};
static int __init cxgb3_init_module(void)

View file

@ -403,8 +403,6 @@ static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data)
static int rx_offload_blackhole(struct t3cdev *dev, struct sk_buff **skbs,
int n)
{
CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data %u\n",
n, ntohl(*(__be32 *)skbs[0]->data));
while (n--)
dev_kfree_skb_any(skbs[n]);
return 0;
@ -488,7 +486,7 @@ static void t3_process_tid_release_list(struct work_struct *work)
tid_release_task);
struct sk_buff *skb;
struct t3cdev *tdev = td->dev;
spin_lock_bh(&td->tid_release_lock);
while (td->tid_release_list) {
@ -634,6 +632,18 @@ static int do_l2t_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
return CPL_RET_BUF_DONE;
}
static int do_rte_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
{
struct cpl_rte_write_rpl *rpl = cplhdr(skb);
if (rpl->status != CPL_ERR_NONE)
printk(KERN_ERR
"Unexpected RTE_WRITE_RPL status %u for entry %u\n",
rpl->status, GET_TID(rpl));
return CPL_RET_BUF_DONE;
}
static int do_act_open_rpl(struct t3cdev *dev, struct sk_buff *skb)
{
struct cpl_act_open_rpl *rpl = cplhdr(skb);
@ -1004,7 +1014,7 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
if (!is_offloading(olddev))
return;
if (!is_offloading(newdev)) {
printk(KERN_WARNING "%s: Redirect to non-offload"
printk(KERN_WARNING "%s: Redirect to non-offload "
"device ignored.\n", __FUNCTION__);
return;
}
@ -1257,6 +1267,7 @@ void __init cxgb3_offload_init(void)
t3_register_cpl_handler(CPL_SMT_WRITE_RPL, do_smt_write_rpl);
t3_register_cpl_handler(CPL_L2T_WRITE_RPL, do_l2t_write_rpl);
t3_register_cpl_handler(CPL_RTE_WRITE_RPL, do_rte_write_rpl);
t3_register_cpl_handler(CPL_PASS_OPEN_RPL, do_stid_rpl);
t3_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, do_stid_rpl);
t3_register_cpl_handler(CPL_PASS_ACCEPT_REQ, do_cr);

View file

@ -76,14 +76,14 @@
#define FW_WROPCODE_MNGT 0x1D
#define FW_MNGTOPCODE_PKTSCHED_SET 0x00
/* Maximum size of a WR sent from the host, limited by the SGE.
/* Maximum size of a WR sent from the host, limited by the SGE.
*
* Note: WR coming from ULP or TP are only limited by CIM.
* Note: WR coming from ULP or TP are only limited by CIM.
*/
#define FW_WR_SIZE 128
/* Maximum number of outstanding WRs sent from the host. Value must be
* programmed in the CTRL/TUNNEL/QP SGE Egress Context and used by
* programmed in the CTRL/TUNNEL/QP SGE Egress Context and used by
* offload modules to limit the number of WRs per connection.
*/
#define FW_T3_WR_NUM 16
@ -99,7 +99,7 @@
* queues must start at SGE Egress Context FW_TUNNEL_SGEEC_START and must
* start at 'TID' (or 'uP Token') FW_TUNNEL_TID_START.
*
* Ingress Traffic (e.g. DMA completion credit) for TUNNEL Queue[i] is sent
* Ingress Traffic (e.g. DMA completion credit) for TUNNEL Queue[i] is sent
* to RESP Queue[i].
*/
#define FW_TUNNEL_NUM 8
@ -116,10 +116,10 @@
#define FW_CTRL_SGEEC_START 65528
#define FW_CTRL_TID_START 65536
/* FW_OFLD_NUM corresponds to the number of supported OFFLOAD Queues. These
* queues must start at SGE Egress Context FW_OFLD_SGEEC_START.
*
* Note: the 'uP Token' in the SGE Egress Context fields is irrelevant for
/* FW_OFLD_NUM corresponds to the number of supported OFFLOAD Queues. These
* queues must start at SGE Egress Context FW_OFLD_SGEEC_START.
*
* Note: the 'uP Token' in the SGE Egress Context fields is irrelevant for
* OFFLOAD Queues, as the host is responsible for providing the correct TID in
* every WR.
*
@ -129,14 +129,14 @@
#define FW_OFLD_SGEEC_START 0
/*
*
*
*/
#define FW_RI_NUM 1
#define FW_RI_SGEEC_START 65527
#define FW_RI_TID_START 65552
/*
* The RX_PKT_TID
* The RX_PKT_TID
*/
#define FW_RX_PKT_NUM 1
#define FW_RX_PKT_TID_START 65553

View file

@ -337,7 +337,7 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
atomic_set(&e->refcnt, 1);
neigh_replace(e, neigh);
if (neigh->dev->priv_flags & IFF_802_1Q_VLAN)
e->vlan = VLAN_DEV_INFO(neigh->dev)->vlan_id;
e->vlan = vlan_dev_info(neigh->dev)->vlan_id;
else
e->vlan = VLAN_NONE;
spin_unlock(&e->lock);

View file

@ -1,5 +1,17 @@
#define A_SG_CONTROL 0x0
#define S_CONGMODE 29
#define V_CONGMODE(x) ((x) << S_CONGMODE)
#define F_CONGMODE V_CONGMODE(1U)
#define S_TNLFLMODE 28
#define V_TNLFLMODE(x) ((x) << S_TNLFLMODE)
#define F_TNLFLMODE V_TNLFLMODE(1U)
#define S_FATLPERREN 27
#define V_FATLPERREN(x) ((x) << S_FATLPERREN)
#define F_FATLPERREN V_FATLPERREN(1U)
#define S_DROPPKT 20
#define V_DROPPKT(x) ((x) << S_DROPPKT)
#define F_DROPPKT V_DROPPKT(1U)
@ -172,6 +184,64 @@
#define A_SG_INT_CAUSE 0x5c
#define S_HIRCQPARITYERROR 31
#define V_HIRCQPARITYERROR(x) ((x) << S_HIRCQPARITYERROR)
#define F_HIRCQPARITYERROR V_HIRCQPARITYERROR(1U)
#define S_LORCQPARITYERROR 30
#define V_LORCQPARITYERROR(x) ((x) << S_LORCQPARITYERROR)
#define F_LORCQPARITYERROR V_LORCQPARITYERROR(1U)
#define S_HIDRBPARITYERROR 29
#define V_HIDRBPARITYERROR(x) ((x) << S_HIDRBPARITYERROR)
#define F_HIDRBPARITYERROR V_HIDRBPARITYERROR(1U)
#define S_LODRBPARITYERROR 28
#define V_LODRBPARITYERROR(x) ((x) << S_LODRBPARITYERROR)
#define F_LODRBPARITYERROR V_LODRBPARITYERROR(1U)
#define S_FLPARITYERROR 22
#define M_FLPARITYERROR 0x3f
#define V_FLPARITYERROR(x) ((x) << S_FLPARITYERROR)
#define G_FLPARITYERROR(x) (((x) >> S_FLPARITYERROR) & M_FLPARITYERROR)
#define S_ITPARITYERROR 20
#define M_ITPARITYERROR 0x3
#define V_ITPARITYERROR(x) ((x) << S_ITPARITYERROR)
#define G_ITPARITYERROR(x) (((x) >> S_ITPARITYERROR) & M_ITPARITYERROR)
#define S_IRPARITYERROR 19
#define V_IRPARITYERROR(x) ((x) << S_IRPARITYERROR)
#define F_IRPARITYERROR V_IRPARITYERROR(1U)
#define S_RCPARITYERROR 18
#define V_RCPARITYERROR(x) ((x) << S_RCPARITYERROR)
#define F_RCPARITYERROR V_RCPARITYERROR(1U)
#define S_OCPARITYERROR 17
#define V_OCPARITYERROR(x) ((x) << S_OCPARITYERROR)
#define F_OCPARITYERROR V_OCPARITYERROR(1U)
#define S_CPPARITYERROR 16
#define V_CPPARITYERROR(x) ((x) << S_CPPARITYERROR)
#define F_CPPARITYERROR V_CPPARITYERROR(1U)
#define S_R_REQ_FRAMINGERROR 15
#define V_R_REQ_FRAMINGERROR(x) ((x) << S_R_REQ_FRAMINGERROR)
#define F_R_REQ_FRAMINGERROR V_R_REQ_FRAMINGERROR(1U)
#define S_UC_REQ_FRAMINGERROR 14
#define V_UC_REQ_FRAMINGERROR(x) ((x) << S_UC_REQ_FRAMINGERROR)
#define F_UC_REQ_FRAMINGERROR V_UC_REQ_FRAMINGERROR(1U)
#define S_HICTLDRBDROPERR 13
#define V_HICTLDRBDROPERR(x) ((x) << S_HICTLDRBDROPERR)
#define F_HICTLDRBDROPERR V_HICTLDRBDROPERR(1U)
#define S_LOCTLDRBDROPERR 12
#define V_LOCTLDRBDROPERR(x) ((x) << S_LOCTLDRBDROPERR)
#define F_LOCTLDRBDROPERR V_LOCTLDRBDROPERR(1U)
#define S_HIPIODRBDROPERR 11
#define V_HIPIODRBDROPERR(x) ((x) << S_HIPIODRBDROPERR)
#define F_HIPIODRBDROPERR V_HIPIODRBDROPERR(1U)
@ -286,6 +356,10 @@
#define A_PCIX_CFG 0x88
#define S_DMASTOPEN 19
#define V_DMASTOPEN(x) ((x) << S_DMASTOPEN)
#define F_DMASTOPEN V_DMASTOPEN(1U)
#define S_CLIDECEN 18
#define V_CLIDECEN(x) ((x) << S_CLIDECEN)
#define F_CLIDECEN V_CLIDECEN(1U)
@ -313,6 +387,22 @@
#define V_BISTERR(x) ((x) << S_BISTERR)
#define S_TXPARERR 18
#define V_TXPARERR(x) ((x) << S_TXPARERR)
#define F_TXPARERR V_TXPARERR(1U)
#define S_RXPARERR 17
#define V_RXPARERR(x) ((x) << S_RXPARERR)
#define F_RXPARERR V_RXPARERR(1U)
#define S_RETRYLUTPARERR 16
#define V_RETRYLUTPARERR(x) ((x) << S_RETRYLUTPARERR)
#define F_RETRYLUTPARERR V_RETRYLUTPARERR(1U)
#define S_RETRYBUFPARERR 15
#define V_RETRYBUFPARERR(x) ((x) << S_RETRYBUFPARERR)
#define F_RETRYBUFPARERR V_RETRYBUFPARERR(1U)
#define S_PCIE_MSIXPARERR 12
#define M_PCIE_MSIXPARERR 0x7
@ -348,6 +438,10 @@
#define A_PCIE_INT_CAUSE 0x84
#define S_PCIE_DMASTOPEN 24
#define V_PCIE_DMASTOPEN(x) ((x) << S_PCIE_DMASTOPEN)
#define F_PCIE_DMASTOPEN V_PCIE_DMASTOPEN(1U)
#define A_PCIE_CFG 0x88
#define S_PCIE_CLIDECEN 16
@ -741,6 +835,54 @@
#define A_CIM_HOST_INT_ENABLE 0x298
#define S_DTAGPARERR 28
#define V_DTAGPARERR(x) ((x) << S_DTAGPARERR)
#define F_DTAGPARERR V_DTAGPARERR(1U)
#define S_ITAGPARERR 27
#define V_ITAGPARERR(x) ((x) << S_ITAGPARERR)
#define F_ITAGPARERR V_ITAGPARERR(1U)
#define S_IBQTPPARERR 26
#define V_IBQTPPARERR(x) ((x) << S_IBQTPPARERR)
#define F_IBQTPPARERR V_IBQTPPARERR(1U)
#define S_IBQULPPARERR 25
#define V_IBQULPPARERR(x) ((x) << S_IBQULPPARERR)
#define F_IBQULPPARERR V_IBQULPPARERR(1U)
#define S_IBQSGEHIPARERR 24
#define V_IBQSGEHIPARERR(x) ((x) << S_IBQSGEHIPARERR)
#define F_IBQSGEHIPARERR V_IBQSGEHIPARERR(1U)
#define S_IBQSGELOPARERR 23
#define V_IBQSGELOPARERR(x) ((x) << S_IBQSGELOPARERR)
#define F_IBQSGELOPARERR V_IBQSGELOPARERR(1U)
#define S_OBQULPLOPARERR 22
#define V_OBQULPLOPARERR(x) ((x) << S_OBQULPLOPARERR)
#define F_OBQULPLOPARERR V_OBQULPLOPARERR(1U)
#define S_OBQULPHIPARERR 21
#define V_OBQULPHIPARERR(x) ((x) << S_OBQULPHIPARERR)
#define F_OBQULPHIPARERR V_OBQULPHIPARERR(1U)
#define S_OBQSGEPARERR 20
#define V_OBQSGEPARERR(x) ((x) << S_OBQSGEPARERR)
#define F_OBQSGEPARERR V_OBQSGEPARERR(1U)
#define S_DCACHEPARERR 19
#define V_DCACHEPARERR(x) ((x) << S_DCACHEPARERR)
#define F_DCACHEPARERR V_DCACHEPARERR(1U)
#define S_ICACHEPARERR 18
#define V_ICACHEPARERR(x) ((x) << S_ICACHEPARERR)
#define F_ICACHEPARERR V_ICACHEPARERR(1U)
#define S_DRAMPARERR 17
#define V_DRAMPARERR(x) ((x) << S_DRAMPARERR)
#define F_DRAMPARERR V_DRAMPARERR(1U)
#define A_CIM_HOST_INT_CAUSE 0x29c
#define S_BLKWRPLINT 12
@ -799,8 +941,42 @@
#define A_CIM_HOST_ACC_DATA 0x2b4
#define A_CIM_IBQ_DBG_CFG 0x2c0
#define S_IBQDBGADDR 16
#define M_IBQDBGADDR 0x1ff
#define V_IBQDBGADDR(x) ((x) << S_IBQDBGADDR)
#define G_IBQDBGADDR(x) (((x) >> S_IBQDBGADDR) & M_IBQDBGADDR)
#define S_IBQDBGQID 3
#define M_IBQDBGQID 0x3
#define V_IBQDBGQID(x) ((x) << S_IBQDBGQID)
#define G_IBQDBGQID(x) (((x) >> S_IBQDBGQID) & M_IBQDBGQID)
#define S_IBQDBGWR 2
#define V_IBQDBGWR(x) ((x) << S_IBQDBGWR)
#define F_IBQDBGWR V_IBQDBGWR(1U)
#define S_IBQDBGBUSY 1
#define V_IBQDBGBUSY(x) ((x) << S_IBQDBGBUSY)
#define F_IBQDBGBUSY V_IBQDBGBUSY(1U)
#define S_IBQDBGEN 0
#define V_IBQDBGEN(x) ((x) << S_IBQDBGEN)
#define F_IBQDBGEN V_IBQDBGEN(1U)
#define A_CIM_IBQ_DBG_DATA 0x2c8
#define A_TP_IN_CONFIG 0x300
#define S_RXFBARBPRIO 25
#define V_RXFBARBPRIO(x) ((x) << S_RXFBARBPRIO)
#define F_RXFBARBPRIO V_RXFBARBPRIO(1U)
#define S_TXFBARBPRIO 24
#define V_TXFBARBPRIO(x) ((x) << S_TXFBARBPRIO)
#define F_TXFBARBPRIO V_TXFBARBPRIO(1U)
#define S_NICMODE 14
#define V_NICMODE(x) ((x) << S_NICMODE)
#define F_NICMODE V_NICMODE(1U)
@ -965,8 +1141,30 @@
#define V_LOCKTID(x) ((x) << S_LOCKTID)
#define F_LOCKTID V_LOCKTID(1U)
#define S_TABLELATENCYDELTA 0
#define M_TABLELATENCYDELTA 0xf
#define V_TABLELATENCYDELTA(x) ((x) << S_TABLELATENCYDELTA)
#define G_TABLELATENCYDELTA(x) \
(((x) >> S_TABLELATENCYDELTA) & M_TABLELATENCYDELTA)
#define A_TP_PC_CONFIG2 0x34c
#define S_DISBLEDAPARBIT0 15
#define V_DISBLEDAPARBIT0(x) ((x) << S_DISBLEDAPARBIT0)
#define F_DISBLEDAPARBIT0 V_DISBLEDAPARBIT0(1U)
#define S_ENABLEARPMISS 13
#define V_ENABLEARPMISS(x) ((x) << S_ENABLEARPMISS)
#define F_ENABLEARPMISS V_ENABLEARPMISS(1U)
#define S_ENABLENONOFDTNLSYN 12
#define V_ENABLENONOFDTNLSYN(x) ((x) << S_ENABLENONOFDTNLSYN)
#define F_ENABLENONOFDTNLSYN V_ENABLENONOFDTNLSYN(1U)
#define S_ENABLEIPV6RSS 11
#define V_ENABLEIPV6RSS(x) ((x) << S_ENABLEIPV6RSS)
#define F_ENABLEIPV6RSS V_ENABLEIPV6RSS(1U)
#define S_CHDRAFULL 4
#define V_CHDRAFULL(x) ((x) << S_CHDRAFULL)
#define F_CHDRAFULL V_CHDRAFULL(1U)
@ -1018,6 +1216,12 @@
#define A_TP_PARA_REG4 0x370
#define A_TP_PARA_REG5 0x374
#define S_RXDDPOFFINIT 3
#define V_RXDDPOFFINIT(x) ((x) << S_RXDDPOFFINIT)
#define F_RXDDPOFFINIT V_RXDDPOFFINIT(1U)
#define A_TP_PARA_REG6 0x378
#define S_T3A_ENABLEESND 13
@ -1138,6 +1342,10 @@
#define V_TNLLKPEN(x) ((x) << S_TNLLKPEN)
#define F_TNLLKPEN V_TNLLKPEN(1U)
#define S_RRCPLMAPEN 7
#define V_RRCPLMAPEN(x) ((x) << S_RRCPLMAPEN)
#define F_RRCPLMAPEN V_RRCPLMAPEN(1U)
#define S_RRCPLCPUSIZE 4
#define M_RRCPLCPUSIZE 0x7
#define V_RRCPLCPUSIZE(x) ((x) << S_RRCPLCPUSIZE)
@ -1146,6 +1354,10 @@
#define V_RQFEEDBACKENABLE(x) ((x) << S_RQFEEDBACKENABLE)
#define F_RQFEEDBACKENABLE V_RQFEEDBACKENABLE(1U)
#define S_HASHTOEPLITZ 2
#define V_HASHTOEPLITZ(x) ((x) << S_HASHTOEPLITZ)
#define F_HASHTOEPLITZ V_HASHTOEPLITZ(1U)
#define S_DISABLE 0
#define A_TP_TM_PIO_ADDR 0x418
@ -1198,6 +1410,22 @@
#define A_TP_INT_ENABLE 0x470
#define S_FLMTXFLSTEMPTY 30
#define V_FLMTXFLSTEMPTY(x) ((x) << S_FLMTXFLSTEMPTY)
#define F_FLMTXFLSTEMPTY V_FLMTXFLSTEMPTY(1U)
#define S_FLMRXFLSTEMPTY 29
#define V_FLMRXFLSTEMPTY(x) ((x) << S_FLMRXFLSTEMPTY)
#define F_FLMRXFLSTEMPTY V_FLMRXFLSTEMPTY(1U)
#define S_ARPLUTPERR 26
#define V_ARPLUTPERR(x) ((x) << S_ARPLUTPERR)
#define F_ARPLUTPERR V_ARPLUTPERR(1U)
#define S_CMCACHEPERR 24
#define V_CMCACHEPERR(x) ((x) << S_CMCACHEPERR)
#define F_CMCACHEPERR V_CMCACHEPERR(1U)
#define A_TP_INT_CAUSE 0x474
#define A_TP_TX_MOD_Q1_Q0_RATE_LIMIT 0x8
@ -1241,9 +1469,37 @@
#define A_ULPRX_INT_ENABLE 0x504
#define S_PARERR 0
#define V_PARERR(x) ((x) << S_PARERR)
#define F_PARERR V_PARERR(1U)
#define S_DATASELFRAMEERR0 7
#define V_DATASELFRAMEERR0(x) ((x) << S_DATASELFRAMEERR0)
#define F_DATASELFRAMEERR0 V_DATASELFRAMEERR0(1U)
#define S_DATASELFRAMEERR1 6
#define V_DATASELFRAMEERR1(x) ((x) << S_DATASELFRAMEERR1)
#define F_DATASELFRAMEERR1 V_DATASELFRAMEERR1(1U)
#define S_PCMDMUXPERR 5
#define V_PCMDMUXPERR(x) ((x) << S_PCMDMUXPERR)
#define F_PCMDMUXPERR V_PCMDMUXPERR(1U)
#define S_ARBFPERR 4
#define V_ARBFPERR(x) ((x) << S_ARBFPERR)
#define F_ARBFPERR V_ARBFPERR(1U)
#define S_ARBPF0PERR 3
#define V_ARBPF0PERR(x) ((x) << S_ARBPF0PERR)
#define F_ARBPF0PERR V_ARBPF0PERR(1U)
#define S_ARBPF1PERR 2
#define V_ARBPF1PERR(x) ((x) << S_ARBPF1PERR)
#define F_ARBPF1PERR V_ARBPF1PERR(1U)
#define S_PARERRPCMD 1
#define V_PARERRPCMD(x) ((x) << S_PARERRPCMD)
#define F_PARERRPCMD V_PARERRPCMD(1U)
#define S_PARERRDATA 0
#define V_PARERRDATA(x) ((x) << S_PARERRDATA)
#define F_PARERRDATA V_PARERRDATA(1U)
#define A_ULPRX_INT_CAUSE 0x508
@ -1291,6 +1547,10 @@
#define A_ULPTX_CONFIG 0x580
#define S_CFG_CQE_SOP_MASK 1
#define V_CFG_CQE_SOP_MASK(x) ((x) << S_CFG_CQE_SOP_MASK)
#define F_CFG_CQE_SOP_MASK V_CFG_CQE_SOP_MASK(1U)
#define S_CFG_RR_ARB 0
#define V_CFG_RR_ARB(x) ((x) << S_CFG_RR_ARB)
#define F_CFG_RR_ARB V_CFG_RR_ARB(1U)
@ -1537,6 +1797,10 @@
#define A_CPL_INTR_ENABLE 0x650
#define S_CIM_OP_MAP_PERR 5
#define V_CIM_OP_MAP_PERR(x) ((x) << S_CIM_OP_MAP_PERR)
#define F_CIM_OP_MAP_PERR V_CIM_OP_MAP_PERR(1U)
#define S_CIM_OVFL_ERROR 4
#define V_CIM_OVFL_ERROR(x) ((x) << S_CIM_OVFL_ERROR)
#define F_CIM_OVFL_ERROR V_CIM_OVFL_ERROR(1U)

View file

@ -91,6 +91,10 @@ struct rx_desc {
struct tx_sw_desc { /* SW state per Tx descriptor */
struct sk_buff *skb;
u8 eop; /* set if last descriptor for packet */
u8 addr_idx; /* buffer index of first SGL entry in descriptor */
u8 fragidx; /* first page fragment associated with descriptor */
s8 sflit; /* start flit of first SGL entry in descriptor */
};
struct rx_sw_desc { /* SW state per Rx descriptor */
@ -109,13 +113,6 @@ struct rsp_desc { /* response queue descriptor */
u8 intr_gen;
};
struct unmap_info { /* packet unmapping info, overlays skb->cb */
int sflit; /* start flit of first SGL entry in Tx descriptor */
u16 fragidx; /* first page fragment in current Tx descriptor */
u16 addr_idx; /* buffer index of first SGL entry in descriptor */
u32 len; /* mapped length of skb main body */
};
/*
* Holds unmapping information for Tx packets that need deferred unmapping.
* This structure lives at skb->head and must be allocated by callers.
@ -177,6 +174,7 @@ static inline struct sge_qset *txq_to_qset(const struct sge_txq *q, int qidx)
static inline void refill_rspq(struct adapter *adapter,
const struct sge_rspq *q, unsigned int credits)
{
rmb();
t3_write_reg(adapter, A_SG_RSPQ_CREDIT_RETURN,
V_RSPQ(q->cntxt_id) | V_CREDITS(credits));
}
@ -209,32 +207,36 @@ static inline int need_skb_unmap(void)
*
* Unmap the main body of an sk_buff and its page fragments, if any.
* Because of the fairly complicated structure of our SGLs and the desire
* to conserve space for metadata, we keep the information necessary to
* unmap an sk_buff partly in the sk_buff itself (in its cb), and partly
* in the Tx descriptors (the physical addresses of the various data
* buffers). The send functions initialize the state in skb->cb so we
* can unmap the buffers held in the first Tx descriptor here, and we
* have enough information at this point to update the state for the next
* Tx descriptor.
* to conserve space for metadata, the information necessary to unmap an
* sk_buff is spread across the sk_buff itself (buffer lengths), the HW Tx
* descriptors (the physical addresses of the various data buffers), and
* the SW descriptor state (assorted indices). The send functions
* initialize the indices for the first packet descriptor so we can unmap
* the buffers held in the first Tx descriptor here, and we have enough
* information at this point to set the state for the next Tx descriptor.
*
* Note that it is possible to clean up the first descriptor of a packet
* before the send routines have written the next descriptors, but this
* race does not cause any problem. We just end up writing the unmapping
* info for the descriptor first.
*/
static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q,
unsigned int cidx, struct pci_dev *pdev)
{
const struct sg_ent *sgp;
struct unmap_info *ui = (struct unmap_info *)skb->cb;
int nfrags, frag_idx, curflit, j = ui->addr_idx;
struct tx_sw_desc *d = &q->sdesc[cidx];
int nfrags, frag_idx, curflit, j = d->addr_idx;
sgp = (struct sg_ent *)&q->desc[cidx].flit[ui->sflit];
sgp = (struct sg_ent *)&q->desc[cidx].flit[d->sflit];
frag_idx = d->fragidx;
if (ui->len) {
pci_unmap_single(pdev, be64_to_cpu(sgp->addr[0]), ui->len,
PCI_DMA_TODEVICE);
ui->len = 0; /* so we know for next descriptor for this skb */
if (frag_idx == 0 && skb_headlen(skb)) {
pci_unmap_single(pdev, be64_to_cpu(sgp->addr[0]),
skb_headlen(skb), PCI_DMA_TODEVICE);
j = 1;
}
frag_idx = ui->fragidx;
curflit = ui->sflit + 1 + j;
curflit = d->sflit + 1 + j;
nfrags = skb_shinfo(skb)->nr_frags;
while (frag_idx < nfrags && curflit < WR_FLITS) {
@ -250,10 +252,11 @@ static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q,
frag_idx++;
}
if (frag_idx < nfrags) { /* SGL continues into next Tx descriptor */
ui->fragidx = frag_idx;
ui->addr_idx = j;
ui->sflit = curflit - WR_FLITS - j; /* sflit can be -1 */
if (frag_idx < nfrags) { /* SGL continues into next Tx descriptor */
d = cidx + 1 == q->size ? q->sdesc : d + 1;
d->fragidx = frag_idx;
d->addr_idx = j;
d->sflit = curflit - WR_FLITS - j; /* sflit can be -1 */
}
}
@ -281,7 +284,7 @@ static void free_tx_desc(struct adapter *adapter, struct sge_txq *q,
if (d->skb) { /* an SGL is present */
if (need_unmap)
unmap_skb(d->skb, q, cidx, pdev);
if (d->skb->priority == cidx)
if (d->eop)
kfree_skb(d->skb);
}
++d;
@ -456,7 +459,7 @@ nomem: q->alloc_failed++;
}
q->credits++;
}
wmb();
t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
}
@ -912,15 +915,13 @@ static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb,
sd->skb = skb;
if (need_skb_unmap()) {
struct unmap_info *ui = (struct unmap_info *)skb->cb;
ui->fragidx = 0;
ui->addr_idx = 0;
ui->sflit = flits;
sd->fragidx = 0;
sd->addr_idx = 0;
sd->sflit = flits;
}
if (likely(ndesc == 1)) {
skb->priority = pidx;
sd->eop = 1;
wrp->wr_hi = htonl(F_WR_SOP | F_WR_EOP | V_WR_DATATYPE(1) |
V_WR_SGLSFLT(flits)) | wr_hi;
wmb();
@ -948,6 +949,7 @@ static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb,
fp += avail;
d++;
sd->eop = 0;
sd++;
if (++pidx == q->size) {
pidx = 0;
@ -966,7 +968,7 @@ static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb,
wr_gen2(d, gen);
flits = 1;
}
skb->priority = pidx;
sd->eop = 1;
wrp->wr_hi |= htonl(F_WR_EOP);
wmb();
wp->wr_lo = htonl(V_WR_LEN(WR_FLITS) | V_WR_GEN(ogen)) | wr_lo;
@ -1051,8 +1053,6 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl;
sgl_flits = make_sgl(skb, sgp, skb->data, skb_headlen(skb), adap->pdev);
if (need_skb_unmap())
((struct unmap_info *)skb->cb)->len = skb_headlen(skb);
write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits, gen,
htonl(V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) | compl),
@ -1354,6 +1354,7 @@ static void restart_ctrlq(unsigned long data)
}
spin_unlock(&q->lock);
wmb();
t3_write_reg(qs->adap, A_SG_KDOORBELL,
F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
}
@ -1363,7 +1364,12 @@ static void restart_ctrlq(unsigned long data)
*/
int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
{
return ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb);
int ret;
local_bh_disable();
ret = ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb);
local_bh_enable();
return ret;
}
/**
@ -1380,13 +1386,14 @@ static void deferred_unmap_destructor(struct sk_buff *skb)
const dma_addr_t *p;
const struct skb_shared_info *si;
const struct deferred_unmap_info *dui;
const struct unmap_info *ui = (struct unmap_info *)skb->cb;
dui = (struct deferred_unmap_info *)skb->head;
p = dui->addr;
if (ui->len)
pci_unmap_single(dui->pdev, *p++, ui->len, PCI_DMA_TODEVICE);
if (skb->tail - skb->transport_header)
pci_unmap_single(dui->pdev, *p++,
skb->tail - skb->transport_header,
PCI_DMA_TODEVICE);
si = skb_shinfo(skb);
for (i = 0; i < si->nr_frags; i++)
@ -1451,8 +1458,6 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb,
if (need_skb_unmap()) {
setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits);
skb->destructor = deferred_unmap_destructor;
((struct unmap_info *)skb->cb)->len = (skb->tail -
skb->transport_header);
}
write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits,
@ -1574,6 +1579,7 @@ static void restart_offloadq(unsigned long data)
set_bit(TXQ_RUNNING, &q->flags);
set_bit(TXQ_LAST_PKT_DB, &q->flags);
#endif
wmb();
t3_write_reg(adap, A_SG_KDOORBELL,
F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
}
@ -1739,7 +1745,6 @@ static inline int rx_offload(struct t3cdev *tdev, struct sge_rspq *rq,
struct sk_buff *skb, struct sk_buff *rx_gather[],
unsigned int gather_idx)
{
rq->offload_pkts++;
skb_reset_mac_header(skb);
skb_reset_network_header(skb);
skb_reset_transport_header(skb);
@ -1809,7 +1814,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
skb->dev->last_rx = jiffies;
pi = netdev_priv(skb->dev);
if (pi->rx_csum_offload && p->csum_valid && p->csum == 0xffff &&
if (pi->rx_csum_offload && p->csum_valid && p->csum == htons(0xffff) &&
!p->fragment) {
rspq_to_qset(rq)->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
@ -1956,7 +1961,7 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs,
int eth, ethpad = 2;
struct sk_buff *skb = NULL;
u32 len, flags = ntohl(r->flags);
u32 rss_hi = *(const u32 *)r, rss_lo = r->rss_hdr.rss_hash_val;
__be32 rss_hi = *(const __be32 *)r, rss_lo = r->rss_hdr.rss_hash_val;
eth = r->rss_hdr.opcode == CPL_RX_PKT;
@ -2033,6 +2038,7 @@ no_mem:
if (eth)
rx_eth(adap, q, skb, ethpad);
else {
q->offload_pkts++;
/* Preserve the RSS info in csum & priority */
skb->csum = rss_hi;
skb->priority = rss_lo;
@ -2442,6 +2448,15 @@ irq_handler_t t3_intr_handler(struct adapter *adap, int polling)
return t3_intr;
}
#define SGE_PARERR (F_CPPARITYERROR | F_OCPARITYERROR | F_RCPARITYERROR | \
F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \
V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \
F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \
F_HIRCQPARITYERROR)
#define SGE_FRAMINGERR (F_UC_REQ_FRAMINGERROR | F_R_REQ_FRAMINGERROR)
#define SGE_FATALERR (SGE_PARERR | SGE_FRAMINGERR | F_RSPQCREDITOVERFOW | \
F_RSPQDISABLED)
/**
* t3_sge_err_intr_handler - SGE async event interrupt handler
* @adapter: the adapter
@ -2452,6 +2467,13 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
{
unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE);
if (status & SGE_PARERR)
CH_ALERT(adapter, "SGE parity error (0x%x)\n",
status & SGE_PARERR);
if (status & SGE_FRAMINGERR)
CH_ALERT(adapter, "SGE framing error (0x%x)\n",
status & SGE_FRAMINGERR);
if (status & F_RSPQCREDITOVERFOW)
CH_ALERT(adapter, "SGE response queue credit overflow\n");
@ -2468,7 +2490,7 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
status & F_HIPIODRBDROPERR ? "high" : "lo");
t3_write_reg(adapter, A_SG_INT_CAUSE, status);
if (status & (F_RSPQCREDITOVERFOW | F_RSPQDISABLED))
if (status & SGE_FATALERR)
t3_fatal_err(adapter);
}
@ -2780,7 +2802,7 @@ void t3_sge_init(struct adapter *adap, struct sge_params *p)
unsigned int ctrl, ups = ffs(pci_resource_len(adap->pdev, 2) >> 12);
ctrl = F_DROPPKT | V_PKTSHIFT(2) | F_FLMODE | F_AVOIDCQOVFL |
F_CQCRDTCTRL |
F_CQCRDTCTRL | F_CONGMODE | F_TNLFLMODE | F_FATLPERREN |
V_HOSTPAGESIZE(PAGE_SHIFT - 11) | F_BIGENDIANINGRESS |
V_USERSPACESIZE(ups ? ups - 1 : 0) | F_ISCSICOALESCING;
#if SGE_NUM_GENBITS == 1
@ -2789,7 +2811,6 @@ void t3_sge_init(struct adapter *adap, struct sge_params *p)
if (adap->params.rev > 0) {
if (!(adap->flags & (USING_MSIX | USING_MSI)))
ctrl |= F_ONEINTMULTQ | F_OPTONEINTMULTQ;
ctrl |= F_CQCRDTCTRL | F_AVOIDCQOVFL;
}
t3_write_reg(adap, A_SG_CONTROL, ctrl);
t3_write_reg(adap, A_SG_EGR_RCQ_DRB_THRSH, V_HIRCQDRBTHRSH(512) |
@ -2797,7 +2818,8 @@ void t3_sge_init(struct adapter *adap, struct sge_params *p)
t3_write_reg(adap, A_SG_TIMER_TICK, core_ticks_per_usec(adap) / 10);
t3_write_reg(adap, A_SG_CMDQ_CREDIT_TH, V_THRESHOLD(32) |
V_TIMEOUT(200 * core_ticks_per_usec(adap)));
t3_write_reg(adap, A_SG_HI_DRB_HI_THRSH, 1000);
t3_write_reg(adap, A_SG_HI_DRB_HI_THRSH,
adap->params.rev < T3_REV_C ? 1000 : 500);
t3_write_reg(adap, A_SG_HI_DRB_LO_THRSH, 256);
t3_write_reg(adap, A_SG_LO_DRB_HI_THRSH, 1000);
t3_write_reg(adap, A_SG_LO_DRB_LO_THRSH, 256);

View file

@ -62,7 +62,7 @@ int t3_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
return 0;
}
if (--attempts == 0)
return -EAGAIN;
return -EAGAIN;
if (delay)
udelay(delay);
}
@ -537,10 +537,11 @@ struct t3_vpd {
* addres is written to the control register. The hardware device will
* set the flag to 1 when 4 bytes have been read into the data register.
*/
int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data)
int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data)
{
u16 val;
int attempts = EEPROM_MAX_POLL;
u32 v;
unsigned int base = adapter->params.pci.vpd_cap_addr;
if ((addr >= EEPROMSIZE && addr != EEPROM_STAT_ADDR) || (addr & 3))
@ -556,8 +557,8 @@ int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data)
CH_ERR(adapter, "reading EEPROM address 0x%x failed\n", addr);
return -EIO;
}
pci_read_config_dword(adapter->pdev, base + PCI_VPD_DATA, data);
*data = le32_to_cpu(*data);
pci_read_config_dword(adapter->pdev, base + PCI_VPD_DATA, &v);
*data = cpu_to_le32(v);
return 0;
}
@ -570,7 +571,7 @@ int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data)
* Write a 32-bit word to a location in VPD EEPROM using the card's PCI
* VPD ROM capability.
*/
int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data)
int t3_seeprom_write(struct adapter *adapter, u32 addr, __le32 data)
{
u16 val;
int attempts = EEPROM_MAX_POLL;
@ -580,7 +581,7 @@ int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data)
return -EINVAL;
pci_write_config_dword(adapter->pdev, base + PCI_VPD_DATA,
cpu_to_le32(data));
le32_to_cpu(data));
pci_write_config_word(adapter->pdev,base + PCI_VPD_ADDR,
addr | PCI_VPD_ADDR_F);
do {
@ -631,14 +632,14 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
* Card information is normally at VPD_BASE but some early cards had
* it at 0.
*/
ret = t3_seeprom_read(adapter, VPD_BASE, (u32 *)&vpd);
ret = t3_seeprom_read(adapter, VPD_BASE, (__le32 *)&vpd);
if (ret)
return ret;
addr = vpd.id_tag == 0x82 ? VPD_BASE : 0;
for (i = 0; i < sizeof(vpd); i += 4) {
ret = t3_seeprom_read(adapter, addr + i,
(u32 *)((u8 *)&vpd + i));
(__le32 *)((u8 *)&vpd + i));
if (ret)
return ret;
}
@ -865,7 +866,7 @@ int t3_get_tp_version(struct adapter *adapter, u32 *vers)
1, 1, 5, 1);
if (ret)
return ret;
*vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
return 0;
@ -896,7 +897,7 @@ int t3_check_tpsram_version(struct adapter *adapter, int *must_load)
major = G_TP_VERSION_MAJOR(vers);
minor = G_TP_VERSION_MINOR(vers);
if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
return 0;
if (major != TP_VERSION_MAJOR)
@ -913,7 +914,7 @@ int t3_check_tpsram_version(struct adapter *adapter, int *must_load)
}
/**
* t3_check_tpsram - check if provided protocol SRAM
* t3_check_tpsram - check if provided protocol SRAM
* is compatible with this driver
* @adapter: the adapter
* @tp_sram: the firmware image to write
@ -926,7 +927,7 @@ int t3_check_tpsram(struct adapter *adapter, u8 *tp_sram, unsigned int size)
{
u32 csum;
unsigned int i;
const u32 *p = (const u32 *)tp_sram;
const __be32 *p = (const __be32 *)tp_sram;
/* Verify checksum */
for (csum = 0, i = 0; i < size / sizeof(csum); i++)
@ -988,13 +989,17 @@ int t3_check_fw_version(struct adapter *adapter, int *must_load)
CH_ERR(adapter, "found wrong FW version(%u.%u), "
"driver needs version %u.%u\n", major, minor,
FW_VERSION_MAJOR, FW_VERSION_MINOR);
else {
else if (minor < FW_VERSION_MINOR) {
*must_load = 0;
CH_WARN(adapter, "found wrong FW minor version(%u.%u), "
CH_WARN(adapter, "found old FW minor version(%u.%u), "
"driver compiled for version %u.%u\n", major, minor,
FW_VERSION_MAJOR, FW_VERSION_MINOR);
} else {
CH_WARN(adapter, "found newer FW version(%u.%u), "
"driver compiled for version %u.%u\n", major, minor,
FW_VERSION_MAJOR, FW_VERSION_MINOR);
return 0;
}
return -EINVAL;
}
@ -1036,7 +1041,7 @@ int t3_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size)
{
u32 csum;
unsigned int i;
const u32 *p = (const u32 *)fw_data;
const __be32 *p = (const __be32 *)fw_data;
int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
if ((size & 3) || size < FW_MIN_SIZE)
@ -1259,7 +1264,13 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
return fatal;
}
#define SGE_INTR_MASK (F_RSPQDISABLED)
#define SGE_INTR_MASK (F_RSPQDISABLED | \
F_UC_REQ_FRAMINGERROR | F_R_REQ_FRAMINGERROR | \
F_CPPARITYERROR | F_OCPARITYERROR | F_RCPARITYERROR | \
F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \
V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \
F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \
F_HIRCQPARITYERROR)
#define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \
F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \
F_NFASRCHFAIL)
@ -1276,16 +1287,23 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
#define PCIE_INTR_MASK (F_UNXSPLCPLERRR | F_UNXSPLCPLERRC | F_PCIE_PIOPARERR |\
F_PCIE_WFPARERR | F_PCIE_RFPARERR | F_PCIE_CFPARERR | \
/* V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR) | */ \
V_BISTERR(M_BISTERR) | F_PEXERR)
#define ULPRX_INTR_MASK F_PARERR
#define ULPTX_INTR_MASK 0
#define CPLSW_INTR_MASK (F_TP_FRAMING_ERROR | \
F_RETRYBUFPARERR | F_RETRYLUTPARERR | F_RXPARERR | \
F_TXPARERR | V_BISTERR(M_BISTERR))
#define ULPRX_INTR_MASK (F_PARERRDATA | F_PARERRPCMD | F_ARBPF1PERR | \
F_ARBPF0PERR | F_ARBFPERR | F_PCMDMUXPERR | \
F_DATASELFRAMEERR1 | F_DATASELFRAMEERR0)
#define ULPTX_INTR_MASK 0xfc
#define CPLSW_INTR_MASK (F_CIM_OP_MAP_PERR | F_TP_FRAMING_ERROR | \
F_SGE_FRAMING_ERROR | F_CIM_FRAMING_ERROR | \
F_ZERO_SWITCH_ERROR)
#define CIM_INTR_MASK (F_BLKWRPLINT | F_BLKRDPLINT | F_BLKWRCTLINT | \
F_BLKRDCTLINT | F_BLKWRFLASHINT | F_BLKRDFLASHINT | \
F_SGLWRFLASHINT | F_WRBLKFLASHINT | F_BLKWRBOOTINT | \
F_FLASHRANGEINT | F_SDRAMRANGEINT | F_RSVDSPACEINT)
F_FLASHRANGEINT | F_SDRAMRANGEINT | F_RSVDSPACEINT | \
F_DRAMPARERR | F_ICACHEPARERR | F_DCACHEPARERR | \
F_OBQSGEPARERR | F_OBQULPHIPARERR | F_OBQULPLOPARERR | \
F_IBQSGELOPARERR | F_IBQSGEHIPARERR | F_IBQULPPARERR | \
F_IBQTPPARERR | F_ITAGPARERR | F_DTAGPARERR)
#define PMTX_INTR_MASK (F_ZERO_C_CMD_ERROR | ICSPI_FRM_ERR | OESPI_FRM_ERR | \
V_ICSPI_PAR_ERROR(M_ICSPI_PAR_ERROR) | \
V_OESPI_PAR_ERROR(M_OESPI_PAR_ERROR))
@ -1354,6 +1372,10 @@ static void pcie_intr_handler(struct adapter *adapter)
{F_PCIE_CFPARERR, "PCI command FIFO parity error", -1, 1},
{V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR),
"PCI MSI-X table/PBA parity error", -1, 1},
{F_RETRYBUFPARERR, "PCI retry buffer parity error", -1, 1},
{F_RETRYLUTPARERR, "PCI retry LUT parity error", -1, 1},
{F_RXPARERR, "PCI Rx parity error", -1, 1},
{F_TXPARERR, "PCI Tx parity error", -1, 1},
{V_BISTERR(M_BISTERR), "PCI BIST error", -1, 1},
{0}
};
@ -1379,8 +1401,16 @@ static void tp_intr_handler(struct adapter *adapter)
{0}
};
static struct intr_info tp_intr_info_t3c[] = {
{0x1fffffff, "TP parity error", -1, 1},
{F_FLMRXFLSTEMPTY, "TP out of Rx pages", -1, 1},
{F_FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1},
{0}
};
if (t3_handle_intr_status(adapter, A_TP_INT_CAUSE, 0xffffffff,
tp_intr_info, NULL))
adapter->params.rev < T3_REV_C ?
tp_intr_info : tp_intr_info_t3c, NULL))
t3_fatal_err(adapter);
}
@ -1402,6 +1432,18 @@ static void cim_intr_handler(struct adapter *adapter)
{F_BLKWRCTLINT, "CIM block write to CTL space", -1, 1},
{F_BLKRDPLINT, "CIM block read from PL space", -1, 1},
{F_BLKWRPLINT, "CIM block write to PL space", -1, 1},
{F_DRAMPARERR, "CIM DRAM parity error", -1, 1},
{F_ICACHEPARERR, "CIM icache parity error", -1, 1},
{F_DCACHEPARERR, "CIM dcache parity error", -1, 1},
{F_OBQSGEPARERR, "CIM OBQ SGE parity error", -1, 1},
{F_OBQULPHIPARERR, "CIM OBQ ULPHI parity error", -1, 1},
{F_OBQULPLOPARERR, "CIM OBQ ULPLO parity error", -1, 1},
{F_IBQSGELOPARERR, "CIM IBQ SGELO parity error", -1, 1},
{F_IBQSGEHIPARERR, "CIM IBQ SGEHI parity error", -1, 1},
{F_IBQULPPARERR, "CIM IBQ ULP parity error", -1, 1},
{F_IBQTPPARERR, "CIM IBQ TP parity error", -1, 1},
{F_ITAGPARERR, "CIM itag parity error", -1, 1},
{F_DTAGPARERR, "CIM dtag parity error", -1, 1},
{0}
};
@ -1416,7 +1458,14 @@ static void cim_intr_handler(struct adapter *adapter)
static void ulprx_intr_handler(struct adapter *adapter)
{
static const struct intr_info ulprx_intr_info[] = {
{F_PARERR, "ULP RX parity error", -1, 1},
{F_PARERRDATA, "ULP RX data parity error", -1, 1},
{F_PARERRPCMD, "ULP RX command parity error", -1, 1},
{F_ARBPF1PERR, "ULP RX ArbPF1 parity error", -1, 1},
{F_ARBPF0PERR, "ULP RX ArbPF0 parity error", -1, 1},
{F_ARBFPERR, "ULP RX ArbF parity error", -1, 1},
{F_PCMDMUXPERR, "ULP RX PCMDMUX parity error", -1, 1},
{F_DATASELFRAMEERR1, "ULP RX frame error", -1, 1},
{F_DATASELFRAMEERR0, "ULP RX frame error", -1, 1},
{0}
};
@ -1435,6 +1484,7 @@ static void ulptx_intr_handler(struct adapter *adapter)
STAT_ULP_CH0_PBL_OOB, 0},
{F_PBL_BOUND_ERR_CH1, "ULP TX channel 1 PBL out of bounds",
STAT_ULP_CH1_PBL_OOB, 0},
{0xfc, "ULP TX parity error", -1, 1},
{0}
};
@ -1509,7 +1559,8 @@ static void pmrx_intr_handler(struct adapter *adapter)
static void cplsw_intr_handler(struct adapter *adapter)
{
static const struct intr_info cplsw_intr_info[] = {
/* { F_CIM_OVFL_ERROR, "CPL switch CIM overflow", -1, 1 }, */
{F_CIM_OP_MAP_PERR, "CPL switch CIM parity error", -1, 1},
{F_CIM_OVFL_ERROR, "CPL switch CIM overflow", -1, 1},
{F_TP_FRAMING_ERROR, "CPL switch TP framing error", -1, 1},
{F_SGE_FRAMING_ERROR, "CPL switch SGE framing error", -1, 1},
{F_CIM_FRAMING_ERROR, "CPL switch CIM framing error", -1, 1},
@ -1730,7 +1781,6 @@ void t3_intr_enable(struct adapter *adapter)
MC7_INTR_MASK},
{A_MC5_DB_INT_ENABLE, MC5_INTR_MASK},
{A_ULPRX_INT_ENABLE, ULPRX_INTR_MASK},
{A_TP_INT_ENABLE, 0x3bfffff},
{A_PM1_TX_INT_ENABLE, PMTX_INTR_MASK},
{A_PM1_RX_INT_ENABLE, PMRX_INTR_MASK},
{A_CIM_HOST_INT_ENABLE, CIM_INTR_MASK},
@ -1740,6 +1790,8 @@ void t3_intr_enable(struct adapter *adapter)
adapter->slow_intr_mask = PL_INTR_MASK;
t3_write_regs(adapter, intr_en_avp, ARRAY_SIZE(intr_en_avp), 0);
t3_write_reg(adapter, A_TP_INT_ENABLE,
adapter->params.rev >= T3_REV_C ? 0x2bfffff : 0x3bfffff);
if (adapter->params.rev > 0) {
t3_write_reg(adapter, A_CPL_INTR_ENABLE,
@ -1894,6 +1946,16 @@ static int t3_sge_write_context(struct adapter *adapter, unsigned int id,
0, SG_CONTEXT_CMD_ATTEMPTS, 1);
}
static int clear_sge_ctxt(struct adapter *adap, unsigned int id,
unsigned int type)
{
t3_write_reg(adap, A_SG_CONTEXT_DATA0, 0);
t3_write_reg(adap, A_SG_CONTEXT_DATA1, 0);
t3_write_reg(adap, A_SG_CONTEXT_DATA2, 0);
t3_write_reg(adap, A_SG_CONTEXT_DATA3, 0);
return t3_sge_write_context(adap, id, type);
}
/**
* t3_sge_init_ecntxt - initialize an SGE egress context
* @adapter: the adapter to configure
@ -2395,7 +2457,7 @@ static inline unsigned int pm_num_pages(unsigned int mem_size,
t3_write_reg((adap), A_ ## reg, (start)); \
start += size
/*
/**
* partition_mem - partition memory and configure TP memory settings
* @adap: the adapter
* @p: the TP parameters
@ -2480,7 +2542,7 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
V_AUTOSTATE2(1) | V_AUTOSTATE1(0) |
V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) |
F_AUTOCAREFUL | F_AUTOENABLE | V_DACK_MODE(1));
t3_set_reg_field(adap, A_TP_IN_CONFIG, F_IPV6ENABLE | F_NICMODE,
t3_set_reg_field(adap, A_TP_IN_CONFIG, F_RXFBARBPRIO | F_TXFBARBPRIO,
F_IPV6ENABLE | F_NICMODE);
t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814);
t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105);
@ -2492,10 +2554,12 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
F_ENABLEEPCMDAFULL,
F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK |
F_TXCONGESTIONMODE | F_RXCONGESTIONMODE);
t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0);
t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL,
F_ENABLEIPV6RSS | F_ENABLENONOFDTNLSYN |
F_ENABLEARPMISS | F_DISBLEDAPARBIT0);
t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080);
t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000);
if (adap->params.rev > 0) {
tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE);
t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO,
@ -2505,6 +2569,11 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
} else
t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED);
if (adap->params.rev == T3_REV_C)
t3_set_reg_field(adap, A_TP_PC_CONFIG,
V_TABLELATENCYDELTA(M_TABLELATENCYDELTA),
V_TABLELATENCYDELTA(4));
t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0);
t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0);
t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0);
@ -2809,15 +2878,15 @@ static void ulp_config(struct adapter *adap, const struct tp_params *p)
int t3_set_proto_sram(struct adapter *adap, u8 *data)
{
int i;
u32 *buf = (u32 *)data;
__be32 *buf = (__be32 *)data;
for (i = 0; i < PROTO_SRAM_LINES; i++) {
t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, be32_to_cpu(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, be32_to_cpu(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, be32_to_cpu(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, be32_to_cpu(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, be32_to_cpu(*buf++));
t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31);
if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1))
return -EIO;
@ -3194,7 +3263,8 @@ static void config_pcie(struct adapter *adap)
V_REPLAYLMT(rpllmt));
t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff);
t3_set_reg_field(adap, A_PCIE_CFG, F_PCIE_CLIDECEN, F_PCIE_CLIDECEN);
t3_set_reg_field(adap, A_PCIE_CFG, 0,
F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN);
}
/*
@ -3207,7 +3277,7 @@ static void config_pcie(struct adapter *adap)
*/
int t3_init_hw(struct adapter *adapter, u32 fw_params)
{
int err = -EIO, attempts = 100;
int err = -EIO, attempts, i;
const struct vpd_params *vpd = &adapter->params.vpd;
if (adapter->params.rev > 0)
@ -3225,6 +3295,10 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
adapter->params.mc5.nfilters,
adapter->params.mc5.nroutes))
goto out_err;
for (i = 0; i < 32; i++)
if (clear_sge_ctxt(adapter, i, F_CQ))
goto out_err;
}
if (tp_init(adapter, &adapter->params.tp))
@ -3240,7 +3314,12 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
if (is_pcie(adapter))
config_pcie(adapter);
else
t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN);
t3_set_reg_field(adapter, A_PCIX_CFG, 0,
F_DMASTOPEN | F_CLIDECEN);
if (adapter->params.rev == T3_REV_C)
t3_set_reg_field(adapter, A_ULPTX_CONFIG, 0,
F_CFG_CQE_SOP_MASK);
t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff);
t3_write_reg(adapter, A_PM1_RX_MODE, 0);
@ -3253,6 +3332,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
V_BOOTADDR(FW_FLASH_BOOT_ADDR >> 2));
t3_read_reg(adapter, A_CIM_BOOT_CFG); /* flush */
attempts = 100;
do { /* wait for uP to initialize */
msleep(20);
} while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
@ -3387,6 +3467,7 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
t3_write_reg(adapter, A_T3DBG_GPIO_EN,
ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL);
t3_write_reg(adapter, A_MC5_DB_SERVER_INDEX, 0);
t3_write_reg(adapter, A_SG_OCO_BASE, V_BASE1(0xfff));
if (adapter->params.rev == 0 || !uses_xaui(adapter))
val |= F_ENRGMII;
@ -3403,13 +3484,13 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
}
/*
* Reset the adapter.
* Reset the adapter.
* Older PCIe cards lose their config space during reset, PCI-X
* ones don't.
*/
static int t3_reset_adapter(struct adapter *adapter)
{
int i, save_and_restore_pcie =
int i, save_and_restore_pcie =
adapter->params.rev < T3_REV_B2 && is_pcie(adapter);
uint16_t devid = 0;
@ -3436,6 +3517,36 @@ static int t3_reset_adapter(struct adapter *adapter)
return 0;
}
static int __devinit init_parity(struct adapter *adap)
{
int i, err, addr;
if (t3_read_reg(adap, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
return -EBUSY;
for (err = i = 0; !err && i < 16; i++)
err = clear_sge_ctxt(adap, i, F_EGRESS);
for (i = 0xfff0; !err && i <= 0xffff; i++)
err = clear_sge_ctxt(adap, i, F_EGRESS);
for (i = 0; !err && i < SGE_QSETS; i++)
err = clear_sge_ctxt(adap, i, F_RESPONSEQ);
if (err)
return err;
t3_write_reg(adap, A_CIM_IBQ_DBG_DATA, 0);
for (i = 0; i < 4; i++)
for (addr = 0; addr <= M_IBQDBGADDR; addr++) {
t3_write_reg(adap, A_CIM_IBQ_DBG_CFG, F_IBQDBGEN |
F_IBQDBGWR | V_IBQDBGQID(i) |
V_IBQDBGADDR(addr));
err = t3_wait_op_done(adap, A_CIM_IBQ_DBG_CFG,
F_IBQDBGBUSY, 0, 2, 1);
if (err)
return err;
}
return 0;
}
/*
* Initialize adapter SW state for the various HW modules, set initial values
* for some adapter tunables, take PHYs out of reset, and initialize the MDIO
@ -3503,6 +3614,9 @@ int __devinit t3_prep_adapter(struct adapter *adapter,
}
early_hw_init(adapter, ai);
ret = init_parity(adapter);
if (ret)
return ret;
for_each_port(adapter, i) {
u8 hw_addr[6];

View file

@ -38,7 +38,7 @@
#define DRV_VERSION "1.0-ko"
/* Firmware version */
#define FW_VERSION_MAJOR 4
#define FW_VERSION_MINOR 6
#define FW_VERSION_MAJOR 5
#define FW_VERSION_MINOR 0
#define FW_VERSION_MICRO 0
#endif /* __CHELSIO_VERSION_H */

View file

@ -153,7 +153,7 @@ static int t3b2_mac_reset(struct cmac *mac)
unsigned int oft = mac->offset;
u32 val;
if (!macidx(mac))
if (!macidx(mac))
t3_set_reg_field(adap, A_MPS_CFG, F_PORT0ACTIVE, 0);
else
t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0);
@ -187,11 +187,11 @@ static int t3b2_mac_reset(struct cmac *mac)
msleep(1);
t3b_pcs_reset(mac);
}
t3_write_reg(adap, A_XGM_RX_CFG + oft,
t3_write_reg(adap, A_XGM_RX_CFG + oft,
F_DISPAUSEFRAMES | F_EN1536BFRAMES |
F_RMFCS | F_ENJUMBO | F_ENHASHMCAST);
if (!macidx(mac))
if (!macidx(mac))
t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE);
else
t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE);
@ -336,7 +336,7 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
* Adjust the PAUSE frame watermarks. We always set the LWM, and the
* HWM only if flow-control is enabled.
*/
hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu,
hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu,
MAC_RXFIFO_SIZE * 38 / 100);
hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4);
@ -449,7 +449,7 @@ int t3_mac_enable(struct cmac *mac, int which)
struct adapter *adap = mac->adapter;
unsigned int oft = mac->offset;
struct mac_stats *s = &mac->stats;
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);

View file

@ -719,15 +719,15 @@ out:
spin_unlock(&lp->lock);
}
static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id)
static irqreturn_t lance_dma_merr_int(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
printk("%s: DMA error\n", dev->name);
printk(KERN_ERR "%s: DMA error\n", dev->name);
return IRQ_HANDLED;
}
static irqreturn_t lance_interrupt(const int irq, void *dev_id)
static irqreturn_t lance_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct lance_private *lp = netdev_priv(dev);

View file

@ -106,6 +106,13 @@
* the RFD, the RFD must be dma_sync'ed to maintain a consistent
* view from software and hardware.
*
* In order to keep updates to the RFD link field from colliding with
* hardware writes to mark packets complete, we use the feature that
* hardware will not write to a size 0 descriptor and mark the previous
* packet as end-of-list (EL). After updating the link, we remove EL
* and only then restore the size such that hardware may use the
* previous-to-end RFD.
*
* Under typical operation, the receive unit (RU) is start once,
* and the controller happily fills RFDs as frames arrive. If
* replacement RFDs cannot be allocated, or the RU goes non-active,
@ -281,6 +288,7 @@ struct csr {
};
enum scb_status {
rus_no_res = 0x08,
rus_ready = 0x10,
rus_mask = 0x3C,
};
@ -393,12 +401,12 @@ enum cb_command {
};
struct rfd {
u16 status;
u16 command;
u32 link;
u32 rbd;
u16 actual_size;
u16 size;
__le16 status;
__le16 command;
__le32 link;
__le32 rbd;
__le16 actual_size;
__le16 size;
};
struct rx {
@ -453,19 +461,19 @@ struct config {
#define E100_MAX_MULTICAST_ADDRS 64
struct multi {
u16 count;
__le16 count;
u8 addr[E100_MAX_MULTICAST_ADDRS * ETH_ALEN + 2/*pad*/];
};
/* Important: keep total struct u32-aligned */
#define UCODE_SIZE 134
struct cb {
u16 status;
u16 command;
u32 link;
__le16 status;
__le16 command;
__le32 link;
union {
u8 iaaddr[ETH_ALEN];
u32 ucode[UCODE_SIZE];
__le32 ucode[UCODE_SIZE];
struct config config;
struct multi multi;
struct {
@ -474,12 +482,12 @@ struct cb {
u8 threshold;
u8 tbd_count;
struct {
u32 buf_addr;
u16 size;
__le32 buf_addr;
__le16 size;
u16 eol;
} tbd;
} tcb;
u32 dump_buffer_addr;
__le32 dump_buffer_addr;
} u;
struct cb *next, *prev;
dma_addr_t dma_addr;
@ -491,15 +499,15 @@ enum loopback {
};
struct stats {
u32 tx_good_frames, tx_max_collisions, tx_late_collisions,
__le32 tx_good_frames, tx_max_collisions, tx_late_collisions,
tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions,
tx_multiple_collisions, tx_total_collisions;
u32 rx_good_frames, rx_crc_errors, rx_alignment_errors,
__le32 rx_good_frames, rx_crc_errors, rx_alignment_errors,
rx_resource_errors, rx_overrun_errors, rx_cdt_errors,
rx_short_frame_errors;
u32 fc_xmt_pause, fc_rcv_pause, fc_rcv_unsupported;
u16 xmt_tco_frames, rcv_tco_frames;
u32 complete;
__le32 fc_xmt_pause, fc_rcv_pause, fc_rcv_unsupported;
__le16 xmt_tco_frames, rcv_tco_frames;
__le32 complete;
};
struct mem {
@ -544,7 +552,7 @@ struct nic {
struct cb *cb_to_use;
struct cb *cb_to_send;
struct cb *cb_to_clean;
u16 tx_command;
__le16 tx_command;
/* End: frequently used values: keep adjacent for cache effect */
enum {
@ -585,7 +593,7 @@ struct nic {
u16 leds;
u16 eeprom_wc;
u16 eeprom[256];
__le16 eeprom[256];
spinlock_t mdio_lock;
};
@ -663,7 +671,7 @@ static int e100_self_test(struct nic *nic)
return 0;
}
static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, __le16 data)
{
u32 cmd_addr_data[3];
u8 ctrl;
@ -672,7 +680,7 @@ static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
/* Three cmds: write/erase enable, write data, write/erase disable */
cmd_addr_data[0] = op_ewen << (addr_len - 2);
cmd_addr_data[1] = (((op_write << addr_len) | addr) << 16) |
cpu_to_le16(data);
le16_to_cpu(data);
cmd_addr_data[2] = op_ewds << (addr_len - 2);
/* Bit-bang cmds to write word to eeprom */
@ -701,7 +709,7 @@ static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
};
/* General technique stolen from the eepro100 driver - very clever */
static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
static __le16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
{
u32 cmd_addr_data;
u16 data = 0;
@ -738,7 +746,7 @@ static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
iowrite8(0, &nic->csr->eeprom_ctrl_lo);
e100_write_flush(nic); udelay(4);
return le16_to_cpu(data);
return cpu_to_le16(data);
};
/* Load entire EEPROM image into driver cache and validate checksum */
@ -753,13 +761,12 @@ static int e100_eeprom_load(struct nic *nic)
for(addr = 0; addr < nic->eeprom_wc; addr++) {
nic->eeprom[addr] = e100_eeprom_read(nic, &addr_len, addr);
if(addr < nic->eeprom_wc - 1)
checksum += cpu_to_le16(nic->eeprom[addr]);
checksum += le16_to_cpu(nic->eeprom[addr]);
}
/* The checksum, stored in the last word, is calculated such that
* the sum of words should be 0xBABA */
checksum = le16_to_cpu(0xBABA - checksum);
if(checksum != nic->eeprom[nic->eeprom_wc - 1]) {
if (cpu_to_le16(0xBABA - checksum) != nic->eeprom[nic->eeprom_wc - 1]) {
DPRINTK(PROBE, ERR, "EEPROM corrupted\n");
if (!eeprom_bad_csum_allow)
return -EAGAIN;
@ -786,8 +793,8 @@ static int e100_eeprom_save(struct nic *nic, u16 start, u16 count)
/* The checksum, stored in the last word, is calculated such that
* the sum of words should be 0xBABA */
for(addr = 0; addr < nic->eeprom_wc - 1; addr++)
checksum += cpu_to_le16(nic->eeprom[addr]);
nic->eeprom[nic->eeprom_wc - 1] = le16_to_cpu(0xBABA - checksum);
checksum += le16_to_cpu(nic->eeprom[addr]);
nic->eeprom[nic->eeprom_wc - 1] = cpu_to_le16(0xBABA - checksum);
e100_eeprom_write(nic, addr_len, nic->eeprom_wc - 1,
nic->eeprom[nic->eeprom_wc - 1]);
@ -952,7 +959,7 @@ static void e100_get_defaults(struct nic *nic)
((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
/* Template for a freshly allocated RFD */
nic->blank_rfd.command = cpu_to_le16(cb_el);
nic->blank_rfd.command = 0;
nic->blank_rfd.rbd = 0xFFFFFFFF;
nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
@ -1485,15 +1492,15 @@ static void e100_update_stats(struct nic *nic)
struct net_device *dev = nic->netdev;
struct net_device_stats *ns = &dev->stats;
struct stats *s = &nic->mem->stats;
u32 *complete = (nic->mac < mac_82558_D101_A4) ? &s->fc_xmt_pause :
(nic->mac < mac_82559_D101M) ? (u32 *)&s->xmt_tco_frames :
__le32 *complete = (nic->mac < mac_82558_D101_A4) ? &s->fc_xmt_pause :
(nic->mac < mac_82559_D101M) ? (__le32 *)&s->xmt_tco_frames :
&s->complete;
/* Device's stats reporting may take several microseconds to
* complete, so where always waiting for results of the
* previous command. */
if(*complete == le32_to_cpu(cuc_dump_reset_complete)) {
if(*complete == cpu_to_le32(cuc_dump_reset_complete)) {
*complete = 0;
nic->tx_frames = le32_to_cpu(s->tx_good_frames);
nic->tx_collisions = le32_to_cpu(s->tx_total_collisions);
@ -1783,7 +1790,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
if(pci_dma_mapping_error(rx->dma_addr)) {
if (pci_dma_mapping_error(rx->dma_addr)) {
dev_kfree_skb_any(rx->skb);
rx->skb = NULL;
rx->dma_addr = 0;
@ -1791,15 +1798,11 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
}
/* Link the RFD to end of RFA by linking previous RFD to
* this one, and clearing EL bit of previous. */
if(rx->prev->skb) {
* this one. We are safe to touch the previous RFD because
* it is protected by the before last buffer's el bit being set */
if (rx->prev->skb) {
struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data;
put_unaligned(cpu_to_le32(rx->dma_addr),
(u32 *)&prev_rfd->link);
wmb();
prev_rfd->command &= ~cpu_to_le16(cb_el);
pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
sizeof(struct rfd), PCI_DMA_TODEVICE);
put_unaligned(cpu_to_le32(rx->dma_addr), &prev_rfd->link);
}
return 0;
@ -1824,8 +1827,19 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status);
/* If data isn't ready, nothing to indicate */
if(unlikely(!(rfd_status & cb_complete)))
if (unlikely(!(rfd_status & cb_complete))) {
/* If the next buffer has the el bit, but we think the receiver
* is still running, check to see if it really stopped while
* we had interrupts off.
* This allows for a fast restart without re-enabling
* interrupts */
if ((le16_to_cpu(rfd->command) & cb_el) &&
(RU_RUNNING == nic->ru_running))
if (readb(&nic->csr->scb.status) & rus_no_res)
nic->ru_running = RU_SUSPENDED;
return -ENODATA;
}
/* Get actual data size */
actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF;
@ -1836,9 +1850,18 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
pci_unmap_single(nic->pdev, rx->dma_addr,
RFD_BUF_LEN, PCI_DMA_FROMDEVICE);
/* this allows for a fast restart without re-enabling interrupts */
if(le16_to_cpu(rfd->command) & cb_el)
/* If this buffer has the el bit, but we think the receiver
* is still running, check to see if it really stopped while
* we had interrupts off.
* This allows for a fast restart without re-enabling interrupts.
* This can happen when the RU sees the size change but also sees
* the el bit set. */
if ((le16_to_cpu(rfd->command) & cb_el) &&
(RU_RUNNING == nic->ru_running)) {
if (readb(&nic->csr->scb.status) & rus_no_res)
nic->ru_running = RU_SUSPENDED;
}
/* Pull off the RFD and put the actual data (minus eth hdr) */
skb_reserve(skb, sizeof(struct rfd));
@ -1870,31 +1893,30 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
unsigned int work_to_do)
{
struct rx *rx;
int restart_required = 0;
struct rx *rx_to_start = NULL;
/* are we already rnr? then pay attention!!! this ensures that
* the state machine progression never allows a start with a
* partially cleaned list, avoiding a race between hardware
* and rx_to_clean when in NAPI mode */
if(RU_SUSPENDED == nic->ru_running)
restart_required = 1;
int restart_required = 0, err = 0;
struct rx *old_before_last_rx, *new_before_last_rx;
struct rfd *old_before_last_rfd, *new_before_last_rfd;
/* Indicate newly arrived packets */
for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) {
int err = e100_rx_indicate(nic, rx, work_done, work_to_do);
if(-EAGAIN == err) {
/* hit quota so have more work to do, restart once
* cleanup is complete */
restart_required = 0;
err = e100_rx_indicate(nic, rx, work_done, work_to_do);
/* Hit quota or no more to clean */
if (-EAGAIN == err || -ENODATA == err)
break;
} else if(-ENODATA == err)
break; /* No more to clean */
}
/* save our starting point as the place we'll restart the receiver */
if(restart_required)
rx_to_start = nic->rx_to_clean;
/* On EAGAIN, hit quota so have more work to do, restart once
* cleanup is complete.
* Else, are we already rnr? then pay attention!!! this ensures that
* the state machine progression never allows a start with a
* partially cleaned list, avoiding a race between hardware
* and rx_to_clean when in NAPI mode */
if (-EAGAIN != err && RU_SUSPENDED == nic->ru_running)
restart_required = 1;
old_before_last_rx = nic->rx_to_use->prev->prev;
old_before_last_rfd = (struct rfd *)old_before_last_rx->skb->data;
/* Alloc new skbs to refill list */
for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) {
@ -1902,10 +1924,42 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
break; /* Better luck next time (see watchdog) */
}
new_before_last_rx = nic->rx_to_use->prev->prev;
if (new_before_last_rx != old_before_last_rx) {
/* Set the el-bit on the buffer that is before the last buffer.
* This lets us update the next pointer on the last buffer
* without worrying about hardware touching it.
* We set the size to 0 to prevent hardware from touching this
* buffer.
* When the hardware hits the before last buffer with el-bit
* and size of 0, it will RNR interrupt, the RUS will go into
* the No Resources state. It will not complete nor write to
* this buffer. */
new_before_last_rfd =
(struct rfd *)new_before_last_rx->skb->data;
new_before_last_rfd->size = 0;
new_before_last_rfd->command |= cpu_to_le16(cb_el);
pci_dma_sync_single_for_device(nic->pdev,
new_before_last_rx->dma_addr, sizeof(struct rfd),
PCI_DMA_TODEVICE);
/* Now that we have a new stopping point, we can clear the old
* stopping point. We must sync twice to get the proper
* ordering on the hardware side of things. */
old_before_last_rfd->command &= ~cpu_to_le16(cb_el);
pci_dma_sync_single_for_device(nic->pdev,
old_before_last_rx->dma_addr, sizeof(struct rfd),
PCI_DMA_TODEVICE);
old_before_last_rfd->size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
pci_dma_sync_single_for_device(nic->pdev,
old_before_last_rx->dma_addr, sizeof(struct rfd),
PCI_DMA_TODEVICE);
}
if(restart_required) {
// ack the rnr?
writeb(stat_ack_rnr, &nic->csr->scb.stat_ack);
e100_start_receiver(nic, rx_to_start);
e100_start_receiver(nic, nic->rx_to_clean);
if(work_done)
(*work_done)++;
}
@ -1937,6 +1991,7 @@ static int e100_rx_alloc_list(struct nic *nic)
{
struct rx *rx;
unsigned int i, count = nic->params.rfds.count;
struct rfd *before_last;
nic->rx_to_use = nic->rx_to_clean = NULL;
nic->ru_running = RU_UNINITIALIZED;
@ -1952,6 +2007,19 @@ static int e100_rx_alloc_list(struct nic *nic)
return -ENOMEM;
}
}
/* Set the el-bit on the buffer that is before the last buffer.
* This lets us update the next pointer on the last buffer without
* worrying about hardware touching it.
* We set the size to 0 to prevent hardware from touching this buffer.
* When the hardware hits the before last buffer with el-bit and size
* of 0, it will RNR interrupt, the RU will go into the No Resources
* state. It will not complete nor write to this buffer. */
rx = nic->rxs->prev->prev;
before_last = (struct rfd *)rx->skb->data;
before_last->command |= cpu_to_le16(cb_el);
before_last->size = 0;
pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
sizeof(struct rfd), PCI_DMA_TODEVICE);
nic->rx_to_use = nic->rx_to_clean = nic->rxs;
nic->ru_running = RU_SUSPENDED;
@ -2369,7 +2437,7 @@ static const char e100_gstrings_test[][ETH_GSTRING_LEN] = {
"Mac loopback (offline)",
"Phy loopback (offline)",
};
#define E100_TEST_LEN sizeof(e100_gstrings_test) / ETH_GSTRING_LEN
#define E100_TEST_LEN ARRAY_SIZE(e100_gstrings_test)
static void e100_diag_test(struct net_device *netdev,
struct ethtool_test *test, u64 *data)
@ -2431,7 +2499,7 @@ static const char e100_gstrings_stats[][ETH_GSTRING_LEN] = {
"rx_flow_control_unsupported", "tx_tco_packets", "rx_tco_packets",
};
#define E100_NET_STATS_LEN 21
#define E100_STATS_LEN sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN
#define E100_STATS_LEN ARRAY_SIZE(e100_gstrings_stats)
static int e100_get_sset_count(struct net_device *netdev, int sset)
{

View file

@ -110,7 +110,7 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
"Interrupt test (offline)", "Loopback test (offline)",
"Link test (on/offline)"
};
#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
static int
e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
@ -728,39 +728,65 @@ err_setup:
return err;
}
#define REG_PATTERN_TEST(R, M, W) \
{ \
uint32_t pat, val; \
const uint32_t test[] = \
{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
for (pat = 0; pat < ARRAY_SIZE(test); pat++) { \
E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \
val = E1000_READ_REG(&adapter->hw, R); \
if (val != (test[pat] & W & M)) { \
DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
"0x%08X expected 0x%08X\n", \
E1000_##R, val, (test[pat] & W & M)); \
*data = (adapter->hw.mac_type < e1000_82543) ? \
E1000_82542_##R : E1000_##R; \
return 1; \
} \
} \
static bool reg_pattern_test(struct e1000_adapter *adapter, uint64_t *data,
int reg, uint32_t mask, uint32_t write)
{
static const uint32_t test[] =
{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
uint8_t __iomem *address = adapter->hw.hw_addr + reg;
uint32_t read;
int i;
for (i = 0; i < ARRAY_SIZE(test); i++) {
writel(write & test[i], address);
read = readl(address);
if (read != (write & test[i] & mask)) {
DPRINTK(DRV, ERR, "pattern test reg %04X failed: "
"got 0x%08X expected 0x%08X\n",
reg, read, (write & test[i] & mask));
*data = reg;
return true;
}
}
return false;
}
#define REG_SET_AND_CHECK(R, M, W) \
{ \
uint32_t val; \
E1000_WRITE_REG(&adapter->hw, R, W & M); \
val = E1000_READ_REG(&adapter->hw, R); \
if ((W & M) != (val & M)) { \
DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
"expected 0x%08X\n", E1000_##R, (val & M), (W & M)); \
*data = (adapter->hw.mac_type < e1000_82543) ? \
E1000_82542_##R : E1000_##R; \
return 1; \
} \
static bool reg_set_and_check(struct e1000_adapter *adapter, uint64_t *data,
int reg, uint32_t mask, uint32_t write)
{
uint8_t __iomem *address = adapter->hw.hw_addr + reg;
uint32_t read;
writel(write & mask, address);
read = readl(address);
if ((read & mask) != (write & mask)) {
DPRINTK(DRV, ERR, "set/check reg %04X test failed: "
"got 0x%08X expected 0x%08X\n",
reg, (read & mask), (write & mask));
*data = reg;
return true;
}
return false;
}
#define REG_PATTERN_TEST(reg, mask, write) \
do { \
if (reg_pattern_test(adapter, data, \
(adapter->hw.mac_type >= e1000_82543) \
? E1000_##reg : E1000_82542_##reg, \
mask, write)) \
return 1; \
} while (0)
#define REG_SET_AND_CHECK(reg, mask, write) \
do { \
if (reg_set_and_check(adapter, data, \
(adapter->hw.mac_type >= e1000_82543) \
? E1000_##reg : E1000_82542_##reg, \
mask, write)) \
return 1; \
} while (0)
static int
e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
{

View file

@ -421,8 +421,6 @@ void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, u
void e1000_get_bus_info(struct e1000_hw *hw);
void e1000_pci_set_mwi(struct e1000_hw *hw);
void e1000_pci_clear_mwi(struct e1000_hw *hw);
void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
int32_t e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value);
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc);
int e1000_pcix_get_mmrbc(struct e1000_hw *hw);
@ -595,35 +593,35 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
/* Receive Descriptor */
struct e1000_rx_desc {
uint64_t buffer_addr; /* Address of the descriptor's data buffer */
uint16_t length; /* Length of data DMAed into data buffer */
uint16_t csum; /* Packet checksum */
__le64 buffer_addr; /* Address of the descriptor's data buffer */
__le16 length; /* Length of data DMAed into data buffer */
__le16 csum; /* Packet checksum */
uint8_t status; /* Descriptor status */
uint8_t errors; /* Descriptor Errors */
uint16_t special;
__le16 special;
};
/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
struct {
uint64_t buffer_addr;
uint64_t reserved;
__le64 buffer_addr;
__le64 reserved;
} read;
struct {
struct {
uint32_t mrq; /* Multiple Rx Queues */
__le32 mrq; /* Multiple Rx Queues */
union {
uint32_t rss; /* RSS Hash */
__le32 rss; /* RSS Hash */
struct {
uint16_t ip_id; /* IP id */
uint16_t csum; /* Packet Checksum */
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
uint32_t status_error; /* ext status/error */
uint16_t length;
uint16_t vlan; /* VLAN tag */
__le32 status_error; /* ext status/error */
__le16 length;
__le16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
@ -633,29 +631,29 @@ union e1000_rx_desc_extended {
union e1000_rx_desc_packet_split {
struct {
/* one buffer for protocol header(s), three data buffers */
uint64_t buffer_addr[MAX_PS_BUFFERS];
__le64 buffer_addr[MAX_PS_BUFFERS];
} read;
struct {
struct {
uint32_t mrq; /* Multiple Rx Queues */
__le32 mrq; /* Multiple Rx Queues */
union {
uint32_t rss; /* RSS Hash */
__le32 rss; /* RSS Hash */
struct {
uint16_t ip_id; /* IP id */
uint16_t csum; /* Packet Checksum */
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
uint32_t status_error; /* ext status/error */
uint16_t length0; /* length of buffer 0 */
uint16_t vlan; /* VLAN tag */
__le32 status_error; /* ext status/error */
__le16 length0; /* length of buffer 0 */
__le16 vlan; /* VLAN tag */
} middle;
struct {
uint16_t header_status;
uint16_t length[3]; /* length of buffers 1-3 */
__le16 header_status;
__le16 length[3]; /* length of buffers 1-3 */
} upper;
uint64_t reserved;
__le64 reserved;
} wb; /* writeback */
};
@ -715,21 +713,21 @@ union e1000_rx_desc_packet_split {
/* Transmit Descriptor */
struct e1000_tx_desc {
uint64_t buffer_addr; /* Address of the descriptor's data buffer */
__le64 buffer_addr; /* Address of the descriptor's data buffer */
union {
uint32_t data;
__le32 data;
struct {
uint16_t length; /* Data buffer length */
__le16 length; /* Data buffer length */
uint8_t cso; /* Checksum offset */
uint8_t cmd; /* Descriptor control */
} flags;
} lower;
union {
uint32_t data;
__le32 data;
struct {
uint8_t status; /* Descriptor status */
uint8_t css; /* Checksum start */
uint16_t special;
__le16 special;
} fields;
} upper;
};
@ -759,49 +757,49 @@ struct e1000_tx_desc {
/* Offload Context Descriptor */
struct e1000_context_desc {
union {
uint32_t ip_config;
__le32 ip_config;
struct {
uint8_t ipcss; /* IP checksum start */
uint8_t ipcso; /* IP checksum offset */
uint16_t ipcse; /* IP checksum end */
__le16 ipcse; /* IP checksum end */
} ip_fields;
} lower_setup;
union {
uint32_t tcp_config;
__le32 tcp_config;
struct {
uint8_t tucss; /* TCP checksum start */
uint8_t tucso; /* TCP checksum offset */
uint16_t tucse; /* TCP checksum end */
__le16 tucse; /* TCP checksum end */
} tcp_fields;
} upper_setup;
uint32_t cmd_and_length; /* */
__le32 cmd_and_length; /* */
union {
uint32_t data;
__le32 data;
struct {
uint8_t status; /* Descriptor status */
uint8_t hdr_len; /* Header length */
uint16_t mss; /* Maximum segment size */
__le16 mss; /* Maximum segment size */
} fields;
} tcp_seg_setup;
};
/* Offload data descriptor */
struct e1000_data_desc {
uint64_t buffer_addr; /* Address of the descriptor's buffer address */
__le64 buffer_addr; /* Address of the descriptor's buffer address */
union {
uint32_t data;
__le32 data;
struct {
uint16_t length; /* Data buffer length */
__le16 length; /* Data buffer length */
uint8_t typ_len_ext; /* */
uint8_t cmd; /* */
} flags;
} lower;
union {
uint32_t data;
__le32 data;
struct {
uint8_t status; /* Descriptor status */
uint8_t popts; /* Packet Options */
uint16_t special; /* */
__le16 special; /* */
} fields;
} upper;
};
@ -817,8 +815,8 @@ struct e1000_data_desc {
/* Receive Address Register */
struct e1000_rar {
volatile uint32_t low; /* receive address low */
volatile uint32_t high; /* receive address high */
volatile __le32 low; /* receive address low */
volatile __le32 high; /* receive address high */
};
/* Number of entries in the Multicast Table Array (MTA). */

View file

@ -73,14 +73,6 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x1026),
INTEL_E1000_ETHERNET_DEVICE(0x1027),
INTEL_E1000_ETHERNET_DEVICE(0x1028),
INTEL_E1000_ETHERNET_DEVICE(0x1049),
INTEL_E1000_ETHERNET_DEVICE(0x104A),
INTEL_E1000_ETHERNET_DEVICE(0x104B),
INTEL_E1000_ETHERNET_DEVICE(0x104C),
INTEL_E1000_ETHERNET_DEVICE(0x104D),
INTEL_E1000_ETHERNET_DEVICE(0x105E),
INTEL_E1000_ETHERNET_DEVICE(0x105F),
INTEL_E1000_ETHERNET_DEVICE(0x1060),
INTEL_E1000_ETHERNET_DEVICE(0x1075),
INTEL_E1000_ETHERNET_DEVICE(0x1076),
INTEL_E1000_ETHERNET_DEVICE(0x1077),
@ -89,28 +81,9 @@ static struct pci_device_id e1000_pci_tbl[] = {
INTEL_E1000_ETHERNET_DEVICE(0x107A),
INTEL_E1000_ETHERNET_DEVICE(0x107B),
INTEL_E1000_ETHERNET_DEVICE(0x107C),
INTEL_E1000_ETHERNET_DEVICE(0x107D),
INTEL_E1000_ETHERNET_DEVICE(0x107E),
INTEL_E1000_ETHERNET_DEVICE(0x107F),
INTEL_E1000_ETHERNET_DEVICE(0x108A),
INTEL_E1000_ETHERNET_DEVICE(0x108B),
INTEL_E1000_ETHERNET_DEVICE(0x108C),
INTEL_E1000_ETHERNET_DEVICE(0x1096),
INTEL_E1000_ETHERNET_DEVICE(0x1098),
INTEL_E1000_ETHERNET_DEVICE(0x1099),
INTEL_E1000_ETHERNET_DEVICE(0x109A),
INTEL_E1000_ETHERNET_DEVICE(0x10A4),
INTEL_E1000_ETHERNET_DEVICE(0x10A5),
INTEL_E1000_ETHERNET_DEVICE(0x10B5),
INTEL_E1000_ETHERNET_DEVICE(0x10B9),
INTEL_E1000_ETHERNET_DEVICE(0x10BA),
INTEL_E1000_ETHERNET_DEVICE(0x10BB),
INTEL_E1000_ETHERNET_DEVICE(0x10BC),
INTEL_E1000_ETHERNET_DEVICE(0x10C4),
INTEL_E1000_ETHERNET_DEVICE(0x10C5),
INTEL_E1000_ETHERNET_DEVICE(0x10D5),
INTEL_E1000_ETHERNET_DEVICE(0x10D9),
INTEL_E1000_ETHERNET_DEVICE(0x10DA),
/* required last entry */
{0,}
};
@ -153,7 +126,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
struct e1000_tx_ring *tx_ring);
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring);
static void e1000_set_multi(struct net_device *netdev);
static void e1000_set_rx_mode(struct net_device *netdev);
static void e1000_update_phy_info(unsigned long data);
static void e1000_watchdog(unsigned long data);
static void e1000_82547_tx_fifo_stall(unsigned long data);
@ -299,14 +272,14 @@ module_exit(e1000_exit_module);
static int e1000_request_irq(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
void (*handler) = &e1000_intr;
irq_handler_t handler = e1000_intr;
int irq_flags = IRQF_SHARED;
int err;
if (adapter->hw.mac_type >= e1000_82571) {
adapter->have_msi = !pci_enable_msi(adapter->pdev);
if (adapter->have_msi) {
handler = &e1000_intr_msi;
handler = e1000_intr_msi;
irq_flags = 0;
}
}
@ -514,7 +487,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
struct net_device *netdev = adapter->netdev;
int i;
e1000_set_multi(netdev);
e1000_set_rx_mode(netdev);
e1000_restore_vlan(adapter);
e1000_init_manageability(adapter);
@ -844,6 +817,64 @@ e1000_reset(struct e1000_adapter *adapter)
e1000_release_manageability(adapter);
}
/**
* Dump the eeprom for users having checksum issues
**/
void e1000_dump_eeprom(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct ethtool_eeprom eeprom;
const struct ethtool_ops *ops = netdev->ethtool_ops;
u8 *data;
int i;
u16 csum_old, csum_new = 0;
eeprom.len = ops->get_eeprom_len(netdev);
eeprom.offset = 0;
data = kmalloc(eeprom.len, GFP_KERNEL);
if (!data) {
printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
" data\n");
return;
}
ops->get_eeprom(netdev, &eeprom, data);
csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
(data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
csum_new += data[i] + (data[i + 1] << 8);
csum_new = EEPROM_SUM - csum_new;
printk(KERN_ERR "/*********************/\n");
printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
printk(KERN_ERR "Calculated : 0x%04x\n", csum_new);
printk(KERN_ERR "Offset Values\n");
printk(KERN_ERR "======== ======\n");
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
printk(KERN_ERR "Include this output when contacting your support "
"provider.\n");
printk(KERN_ERR "This is not a software error! Something bad "
"happened to your hardware or\n");
printk(KERN_ERR "EEPROM image. Ignoring this "
"problem could result in further problems,\n");
printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
"which is invalid\n");
printk(KERN_ERR "and requires you to set the proper MAC "
"address manually before continuing\n");
printk(KERN_ERR "to enable this network device.\n");
printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
"to your hardware vendor\n");
printk(KERN_ERR "or Intel Customer Support: [email protected]\n");
printk(KERN_ERR "/*********************/\n");
kfree(data);
}
/**
* e1000_probe - Device Initialization Routine
* @pdev: PCI device information struct
@ -927,7 +958,7 @@ e1000_probe(struct pci_dev *pdev,
netdev->stop = &e1000_close;
netdev->hard_start_xmit = &e1000_xmit_frame;
netdev->get_stats = &e1000_get_stats;
netdev->set_multicast_list = &e1000_set_multi;
netdev->set_rx_mode = &e1000_set_rx_mode;
netdev->set_mac_address = &e1000_set_mac;
netdev->change_mtu = &e1000_change_mtu;
netdev->do_ioctl = &e1000_ioctl;
@ -995,7 +1026,6 @@ e1000_probe(struct pci_dev *pdev,
adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
/* initialize eeprom parameters */
if (e1000_init_eeprom_params(&adapter->hw)) {
E1000_ERR("EEPROM initialization failed\n");
goto err_eeprom;
@ -1007,23 +1037,29 @@ e1000_probe(struct pci_dev *pdev,
e1000_reset_hw(&adapter->hw);
/* make sure the EEPROM is good */
if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
goto err_eeprom;
e1000_dump_eeprom(adapter);
/*
* set MAC address to all zeroes to invalidate and temporary
* disable this device for the user. This blocks regular
* traffic while still permitting ethtool ioctls from reaching
* the hardware as well as allowing the user to run the
* interface after manually setting a hw addr using
* `ip set address`
*/
memset(adapter->hw.mac_addr, 0, netdev->addr_len);
} else {
/* copy the MAC address out of the EEPROM */
if (e1000_read_mac_addr(&adapter->hw))
DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
}
/* copy the MAC address out of the EEPROM */
if (e1000_read_mac_addr(&adapter->hw))
DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
/* don't block initalization here due to bad MAC address */
memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
if (!is_valid_ether_addr(netdev->perm_addr)) {
if (!is_valid_ether_addr(netdev->perm_addr))
DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
goto err_eeprom;
}
e1000_get_bus_info(&adapter->hw);
@ -2410,21 +2446,22 @@ e1000_set_mac(struct net_device *netdev, void *p)
}
/**
* e1000_set_multi - Multicast and Promiscuous mode set
* e1000_set_rx_mode - Secondary Unicast, 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,
* The set_rx_mode entry point is called whenever the unicast or multicast
* address lists or the network interface flags are updated. This routine is
* responsible for configuring the hardware for proper unicast, multicast,
* promiscuous mode, and all-multi behavior.
**/
static void
e1000_set_multi(struct net_device *netdev)
e1000_set_rx_mode(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
struct dev_mc_list *mc_ptr;
struct dev_addr_list *uc_ptr;
struct dev_addr_list *mc_ptr;
uint32_t rctl;
uint32_t hash_value;
int i, rar_entries = E1000_RAR_ENTRIES;
@ -2447,9 +2484,16 @@ e1000_set_multi(struct net_device *netdev)
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
} else if (netdev->flags & IFF_ALLMULTI) {
rctl |= E1000_RCTL_MPE;
rctl &= ~E1000_RCTL_UPE;
} else {
rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
rctl &= ~E1000_RCTL_MPE;
}
uc_ptr = NULL;
if (netdev->uc_count > rar_entries - 1) {
rctl |= E1000_RCTL_UPE;
} else if (!(netdev->flags & IFF_PROMISC)) {
rctl &= ~E1000_RCTL_UPE;
uc_ptr = netdev->uc_list;
}
E1000_WRITE_REG(hw, RCTL, rctl);
@ -2459,7 +2503,10 @@ e1000_set_multi(struct net_device *netdev)
if (hw->mac_type == e1000_82542_rev2_0)
e1000_enter_82542_rst(adapter);
/* load the first 14 multicast address into the exact filters 1-14
/* load the first 14 addresses into the exact filters 1-14. Unicast
* addresses take precedence to avoid disabling unicast filtering
* when possible.
*
* RAR 0 is used for the station MAC adddress
* if there are not 14 addresses, go ahead and clear the filters
* -- with 82571 controllers only 0-13 entries are filled here
@ -2467,8 +2514,11 @@ e1000_set_multi(struct net_device *netdev)
mc_ptr = netdev->mc_list;
for (i = 1; i < rar_entries; i++) {
if (mc_ptr) {
e1000_rar_set(hw, mc_ptr->dmi_addr, i);
if (uc_ptr) {
e1000_rar_set(hw, uc_ptr->da_addr, i);
uc_ptr = uc_ptr->next;
} else if (mc_ptr) {
e1000_rar_set(hw, mc_ptr->da_addr, i);
mc_ptr = mc_ptr->next;
} else {
E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
@ -2477,6 +2527,7 @@ e1000_set_multi(struct net_device *netdev)
E1000_WRITE_FLUSH(hw);
}
}
WARN_ON(uc_ptr != NULL);
/* clear the old settings from the multicast hash table */
@ -2488,7 +2539,7 @@ e1000_set_multi(struct net_device *netdev)
/* load any remaining addresses into the hash table */
for (; mc_ptr; mc_ptr = mc_ptr->next) {
hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
e1000_mta_set(hw, hash_value);
}
@ -3680,10 +3731,6 @@ e1000_update_stats(struct e1000_adapter *adapter)
}
/* Fill out the OS statistics structure */
adapter->net_stats.rx_packets = adapter->stats.gprc;
adapter->net_stats.tx_packets = adapter->stats.gptc;
adapter->net_stats.rx_bytes = adapter->stats.gorcl;
adapter->net_stats.tx_bytes = adapter->stats.gotcl;
adapter->net_stats.multicast = adapter->stats.mprc;
adapter->net_stats.collisions = adapter->stats.colc;
@ -4059,6 +4106,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
}
adapter->total_tx_bytes += total_tx_bytes;
adapter->total_tx_packets += total_tx_packets;
adapter->net_stats.tx_bytes += total_tx_bytes;
adapter->net_stats.tx_packets += total_tx_packets;
return cleaned;
}
@ -4106,8 +4155,8 @@ e1000_rx_checksum(struct e1000_adapter *adapter,
/* Hardware complements the payload checksum, so we undo it
* and then put the value in host order for further stack use.
*/
csum = ntohl(csum ^ 0xFFFF);
skb->csum = csum;
__sum16 sum = (__force __sum16)htons(csum);
skb->csum = csum_unfold(~sum);
skb->ip_summed = CHECKSUM_COMPLETE;
}
adapter->hw_csum_good++;
@ -4281,6 +4330,8 @@ next_desc:
adapter->total_rx_packets += total_rx_packets;
adapter->total_rx_bytes += total_rx_bytes;
adapter->net_stats.rx_bytes += total_rx_bytes;
adapter->net_stats.rx_packets += total_rx_packets;
return cleaned;
}
@ -4468,6 +4519,8 @@ next_desc:
adapter->total_rx_packets += total_rx_packets;
adapter->total_rx_bytes += total_rx_bytes;
adapter->net_stats.rx_bytes += total_rx_bytes;
adapter->net_stats.rx_packets += total_rx_packets;
return cleaned;
}
@ -4631,7 +4684,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
rx_desc->read.buffer_addr[j+1] =
cpu_to_le64(ps_page_dma->ps_page_dma[j]);
} else
rx_desc->read.buffer_addr[j+1] = ~0;
rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
}
skb = netdev_alloc_skb(netdev,
@ -4874,22 +4927,6 @@ e1000_pci_clear_mwi(struct e1000_hw *hw)
pci_clear_mwi(adapter->pdev);
}
void
e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
{
struct e1000_adapter *adapter = hw->back;
pci_read_config_word(adapter->pdev, reg, value);
}
void
e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
{
struct e1000_adapter *adapter = hw->back;
pci_write_config_word(adapter->pdev, reg, *value);
}
int
e1000_pcix_get_mmrbc(struct e1000_hw *hw)
{
@ -5095,7 +5132,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
if (wufc) {
e1000_setup_rctl(adapter);
e1000_set_multi(netdev);
e1000_set_rx_mode(netdev);
/* turn on all-multi mode if wake on multicast is enabled */
if (wufc & E1000_WUFC_MC) {

View file

@ -194,6 +194,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
break;
case E1000_DEV_ID_82571EB_SERDES:
case E1000_DEV_ID_82572EI_SERDES:
case E1000_DEV_ID_82571EB_SERDES_DUAL:
case E1000_DEV_ID_82571EB_SERDES_QUAD:
hw->media_type = e1000_media_type_internal_serdes;
break;
default:
@ -260,6 +262,7 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
case E1000_DEV_ID_82571EB_QUAD_COPPER:
case E1000_DEV_ID_82571EB_QUAD_FIBER:
case E1000_DEV_ID_82571EB_QUAD_COPPER_LP:
case E1000_DEV_ID_82571PT_QUAD_COPPER:
adapter->flags |= FLAG_IS_QUAD_PORT;
/* mark the first port */
if (global_quad_port_a == 0)
@ -285,6 +288,9 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
if (adapter->flags & FLAG_IS_QUAD_PORT &&
(!(adapter->flags & FLAG_IS_QUAD_PORT_A)))
adapter->flags &= ~FLAG_HAS_WOL;
/* Does not support WoL on any port */
if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)
adapter->flags &= ~FLAG_HAS_WOL;
break;
case e1000_82573:
@ -752,6 +758,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
ew32(IMC, 0xffffffff);
icr = er32(ICR);
if (hw->mac.type == e1000_82571 &&
hw->dev_spec.e82571.alt_mac_addr_is_present)
e1000e_set_laa_state_82571(hw, true);
return 0;
}
@ -1339,7 +1349,6 @@ struct e1000_info e1000_82573_info = {
| FLAG_HAS_STATS_ICR_ICT
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_ASPM
| FLAG_HAS_ERT
| FLAG_HAS_SWSM_ON_LOAD,
.pba = 20,

View file

@ -557,6 +557,7 @@
#define NVM_INIT_3GIO_3 0x001A
#define NVM_INIT_CONTROL3_PORT_A 0x0024
#define NVM_CFG 0x0012
#define NVM_ALT_MAC_ADDR_PTR 0x0037
#define NVM_CHECKSUM_REG 0x003F
#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */

View file

@ -288,7 +288,6 @@ struct e1000_info {
#define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5)
#define FLAG_HAS_SWSM_ON_LOAD (1 << 6)
#define FLAG_HAS_JUMBO_FRAMES (1 << 7)
#define FLAG_HAS_ASPM (1 << 8)
#define FLAG_HAS_STATS_ICR_ICT (1 << 9)
#define FLAG_HAS_STATS_PTC_PRC (1 << 10)
#define FLAG_HAS_SMART_POWER_DOWN (1 << 11)

View file

@ -95,15 +95,14 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
{ "tx_dma_failed", E1000_STAT(tx_dma_failed) },
};
#define E1000_GLOBAL_STATS_LEN \
sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats)
#define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN)
static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
"Register test (offline)", "Eeprom test (offline)",
"Interrupt test (offline)", "Loopback test (offline)",
"Link test (on/offline)"
};
#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
static int e1000_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
@ -691,41 +690,63 @@ err_setup:
return err;
}
#define REG_PATTERN_TEST(R, M, W) REG_PATTERN_TEST_ARRAY(R, 0, M, W)
#define REG_PATTERN_TEST_ARRAY(reg, offset, mask, writeable) \
{ \
u32 _pat; \
u32 _value; \
u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
for (_pat = 0; _pat < ARRAY_SIZE(_test); _pat++) { \
E1000_WRITE_REG_ARRAY(hw, reg, offset, \
(_test[_pat] & writeable)); \
_value = E1000_READ_REG_ARRAY(hw, reg, offset); \
if (_value != (_test[_pat] & writeable & mask)) { \
ndev_err(netdev, "pattern test reg %04X " \
"failed: got 0x%08X expected 0x%08X\n", \
reg + offset, \
value, (_test[_pat] & writeable & mask)); \
*data = reg; \
return 1; \
} \
} \
bool reg_pattern_test_array(struct e1000_adapter *adapter, u64 *data,
int reg, int offset, u32 mask, u32 write)
{
int i;
u32 read;
static const u32 test[] =
{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
for (i = 0; i < ARRAY_SIZE(test); i++) {
E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset,
(test[i] & write));
read = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset);
if (read != (test[i] & write & mask)) {
ndev_err(adapter->netdev, "pattern test reg %04X "
"failed: got 0x%08X expected 0x%08X\n",
reg + offset,
read, (test[i] & write & mask));
*data = reg;
return true;
}
}
return false;
}
#define REG_SET_AND_CHECK(R, M, W) \
{ \
u32 _value; \
__ew32(hw, R, W & M); \
_value = __er32(hw, R); \
if ((W & M) != (_value & M)) { \
ndev_err(netdev, "set/check reg %04X test failed: " \
"got 0x%08X expected 0x%08X\n", R, (_value & M), \
(W & M)); \
*data = R; \
return 1; \
} \
static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
int reg, u32 mask, u32 write)
{
u32 read;
__ew32(&adapter->hw, reg, write & mask);
read = __er32(&adapter->hw, reg);
if ((write & mask) != (read & mask)) {
ndev_err(adapter->netdev, "set/check reg %04X test failed: "
"got 0x%08X expected 0x%08X\n", reg, (read & mask),
(write & mask));
*data = reg;
return true;
}
return false;
}
#define REG_PATTERN_TEST(R, M, W) \
do { \
if (reg_pattern_test_array(adapter, data, R, 0, M, W)) \
return 1; \
} while (0)
#define REG_PATTERN_TEST_ARRAY(R, offset, M, W) \
do { \
if (reg_pattern_test_array(adapter, data, R, offset, M, W)) \
return 1; \
} while (0)
#define REG_SET_AND_CHECK(R, M, W) \
do { \
if (reg_set_and_check(adapter, data, R, M, W)) \
return 1; \
} while (0)
static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
{
struct e1000_hw *hw = &adapter->hw;

View file

@ -303,8 +303,11 @@ enum e1e_registers {
#define E1000_DEV_ID_82571EB_FIBER 0x105F
#define E1000_DEV_ID_82571EB_SERDES 0x1060
#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC
#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
#define E1000_DEV_ID_82572EI_COPPER 0x107D
#define E1000_DEV_ID_82572EI_FIBER 0x107E
#define E1000_DEV_ID_82572EI_SERDES 0x107F
@ -420,35 +423,35 @@ enum e1000_smart_speed {
/* Receive Descriptor */
struct e1000_rx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
u16 length; /* Length of data DMAed into data buffer */
u16 csum; /* Packet checksum */
__le64 buffer_addr; /* Address of the descriptor's data buffer */
__le16 length; /* Length of data DMAed into data buffer */
__le16 csum; /* Packet checksum */
u8 status; /* Descriptor status */
u8 errors; /* Descriptor Errors */
u16 special;
__le16 special;
};
/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
struct {
u64 buffer_addr;
u64 reserved;
__le64 buffer_addr;
__le64 reserved;
} read;
struct {
struct {
u32 mrq; /* Multiple Rx Queues */
__le32 mrq; /* Multiple Rx Queues */
union {
u32 rss; /* RSS Hash */
__le32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length;
u16 vlan; /* VLAN tag */
__le32 status_error; /* ext status/error */
__le16 length;
__le16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
@ -458,49 +461,49 @@ union e1000_rx_desc_extended {
union e1000_rx_desc_packet_split {
struct {
/* one buffer for protocol header(s), three data buffers */
u64 buffer_addr[MAX_PS_BUFFERS];
__le64 buffer_addr[MAX_PS_BUFFERS];
} read;
struct {
struct {
u32 mrq; /* Multiple Rx Queues */
__le32 mrq; /* Multiple Rx Queues */
union {
u32 rss; /* RSS Hash */
__le32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
__le16 ip_id; /* IP id */
__le16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length0; /* length of buffer 0 */
u16 vlan; /* VLAN tag */
__le32 status_error; /* ext status/error */
__le16 length0; /* length of buffer 0 */
__le16 vlan; /* VLAN tag */
} middle;
struct {
u16 header_status;
u16 length[3]; /* length of buffers 1-3 */
__le16 header_status;
__le16 length[3]; /* length of buffers 1-3 */
} upper;
u64 reserved;
__le64 reserved;
} wb; /* writeback */
};
/* Transmit Descriptor */
struct e1000_tx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
__le64 buffer_addr; /* Address of the descriptor's data buffer */
union {
u32 data;
__le32 data;
struct {
u16 length; /* Data buffer length */
__le16 length; /* Data buffer length */
u8 cso; /* Checksum offset */
u8 cmd; /* Descriptor control */
} flags;
} lower;
union {
u32 data;
__le32 data;
struct {
u8 status; /* Descriptor status */
u8 css; /* Checksum start */
u16 special;
__le16 special;
} fields;
} upper;
};
@ -508,49 +511,49 @@ struct e1000_tx_desc {
/* Offload Context Descriptor */
struct e1000_context_desc {
union {
u32 ip_config;
__le32 ip_config;
struct {
u8 ipcss; /* IP checksum start */
u8 ipcso; /* IP checksum offset */
u16 ipcse; /* IP checksum end */
__le16 ipcse; /* IP checksum end */
} ip_fields;
} lower_setup;
union {
u32 tcp_config;
__le32 tcp_config;
struct {
u8 tucss; /* TCP checksum start */
u8 tucso; /* TCP checksum offset */
u16 tucse; /* TCP checksum end */
__le16 tucse; /* TCP checksum end */
} tcp_fields;
} upper_setup;
u32 cmd_and_length;
__le32 cmd_and_length;
union {
u32 data;
__le32 data;
struct {
u8 status; /* Descriptor status */
u8 hdr_len; /* Header length */
u16 mss; /* Maximum segment size */
__le16 mss; /* Maximum segment size */
} fields;
} tcp_seg_setup;
};
/* Offload data descriptor */
struct e1000_data_desc {
u64 buffer_addr; /* Address of the descriptor's buffer address */
__le64 buffer_addr; /* Address of the descriptor's buffer address */
union {
u32 data;
__le32 data;
struct {
u16 length; /* Data buffer length */
__le16 length; /* Data buffer length */
u8 typ_len_ext;
u8 cmd;
} flags;
} lower;
union {
u32 data;
__le32 data;
struct {
u8 status; /* Descriptor status */
u8 popts; /* Packet Options */
u16 special; /* */
__le16 special; /* */
} fields;
} upper;
};
@ -816,6 +819,7 @@ struct e1000_bus_info {
struct e1000_dev_spec_82571 {
bool laa_is_present;
bool alt_mac_addr_is_present;
};
struct e1000_shadow_ram {

View file

@ -2059,9 +2059,44 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
{
s32 ret_val;
u16 offset, nvm_data, i;
u16 mac_addr_offset = 0;
if (hw->mac.type == e1000_82571) {
/* Check for an alternate MAC address. An alternate MAC
* address can be setup by pre-boot software and must be
* treated like a permanent address and must override the
* actual permanent MAC address. */
ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
&mac_addr_offset);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
return ret_val;
}
if (mac_addr_offset == 0xFFFF)
mac_addr_offset = 0;
if (mac_addr_offset) {
if (hw->bus.func == E1000_FUNC_1)
mac_addr_offset += ETH_ALEN/sizeof(u16);
/* make sure we have a valid mac address here
* before using it */
ret_val = e1000_read_nvm(hw, mac_addr_offset, 1,
&nvm_data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
return ret_val;
}
if (nvm_data & 0x0001)
mac_addr_offset = 0;
}
if (mac_addr_offset)
hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
}
for (i = 0; i < ETH_ALEN; i += 2) {
offset = i >> 1;
offset = mac_addr_offset + (i >> 1);
ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
@ -2072,7 +2107,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
}
/* Flip last bit of mac address if we're on second port */
if (hw->bus.func == E1000_FUNC_1)
if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1)
hw->mac.perm_addr[5] ^= 1;
for (i = 0; i < ETH_ALEN; i++)

View file

@ -91,7 +91,7 @@ static int e1000_desc_unused(struct e1000_ring *ring)
static void e1000_receive_skb(struct e1000_adapter *adapter,
struct net_device *netdev,
struct sk_buff *skb,
u8 status, u16 vlan)
u8 status, __le16 vlan)
{
skb->protocol = eth_type_trans(skb, netdev);
@ -142,8 +142,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
/* Hardware complements the payload checksum, so we undo it
* and then put the value in host order for further stack use.
*/
csum = ntohl(csum ^ 0xFFFF);
skb->csum = csum;
__sum16 sum = (__force __sum16)htons(csum);
skb->csum = csum_unfold(~sum);
skb->ip_summed = CHECKSUM_COMPLETE;
}
adapter->hw_csum_good++;
@ -248,7 +248,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
ps_page = &buffer_info->ps_pages[j];
if (j >= adapter->rx_ps_pages) {
/* all unused desc entries get hw null ptr */
rx_desc->read.buffer_addr[j+1] = ~0;
rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
continue;
}
if (!ps_page->page) {
@ -458,6 +458,8 @@ next_desc:
adapter->total_rx_packets += total_rx_packets;
adapter->total_rx_bytes += total_rx_bytes;
adapter->net_stats.rx_packets += total_rx_packets;
adapter->net_stats.rx_bytes += total_rx_bytes;
return cleaned;
}
@ -593,6 +595,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
}
adapter->total_tx_bytes += total_tx_bytes;
adapter->total_tx_packets += total_tx_packets;
adapter->net_stats.tx_packets += total_tx_packets;
adapter->net_stats.tx_bytes += total_tx_bytes;
return cleaned;
}
@ -755,6 +759,8 @@ next_desc:
adapter->total_rx_packets += total_rx_packets;
adapter->total_rx_bytes += total_rx_bytes;
adapter->net_stats.rx_packets += total_rx_packets;
adapter->net_stats.rx_bytes += total_rx_bytes;
return cleaned;
}
@ -935,7 +941,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
static int e1000_request_irq(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
void (*handler) = &e1000_intr;
irq_handler_t handler = e1000_intr;
int irq_flags = IRQF_SHARED;
int err;
@ -945,7 +951,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter)
"Unable to allocate MSI interrupt Error: %d\n", err);
} else {
adapter->flags |= FLAG_MSI_ENABLED;
handler = &e1000_intr_msi;
handler = e1000_intr_msi;
irq_flags = 0;
}
@ -2535,10 +2541,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
}
/* Fill out the OS statistics structure */
adapter->net_stats.rx_packets = adapter->stats.gprc;
adapter->net_stats.tx_packets = adapter->stats.gptc;
adapter->net_stats.rx_bytes = adapter->stats.gorcl;
adapter->net_stats.tx_bytes = adapter->stats.gotcl;
adapter->net_stats.multicast = adapter->stats.mprc;
adapter->net_stats.collisions = adapter->stats.colc;
@ -3509,6 +3511,33 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
return 0;
}
static void e1000e_disable_l1aspm(struct pci_dev *pdev)
{
int pos;
u32 cap;
u16 val;
/*
* 82573 workaround - disable L1 ASPM on mobile chipsets
*
* L1 ASPM on various mobile (ich7) chipsets do not behave properly
* resulting in lost data or garbage information on the pci-e link
* level. This could result in (false) bad EEPROM checksum errors,
* long ping times (up to 2s) or even a system freeze/hang.
*
* Unfortunately this feature saves about 1W power consumption when
* active.
*/
pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &cap);
pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
if (val & 0x2) {
dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
val &= ~0x2;
pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
}
}
#ifdef CONFIG_PM
static int e1000_resume(struct pci_dev *pdev)
{
@ -3519,6 +3548,7 @@ static int e1000_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
e1000e_disable_l1aspm(pdev);
err = pci_enable_device(pdev);
if (err) {
dev_err(&pdev->dev,
@ -3619,6 +3649,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
e1000e_disable_l1aspm(pdev);
if (pci_enable_device(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
@ -3720,6 +3751,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
e1000e_disable_l1aspm(pdev);
err = pci_enable_device(pdev);
if (err)
return err;
@ -4056,16 +4088,15 @@ static struct pci_error_handlers e1000_err_handler = {
};
static struct pci_device_id e1000_pci_tbl[] = {
/*
* Support for 82571/2/3, es2lan and ich8 will be phased in
* stepwise.
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
@ -4088,8 +4119,6 @@ static struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
*/
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },

View file

@ -262,13 +262,6 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
.max = MAX_RXDELAY } }
};
/* modify min and default if 82573 for slow ping w/a,
* a value greater than 8 needs to be set for RDTR */
if (adapter->flags & FLAG_HAS_ASPM) {
opt.def = 32;
opt.arg.r.min = 8;
}
if (num_RxIntDelay > bd) {
adapter->rx_int_delay = RxIntDelay[bd];
e1000_validate_option(&adapter->rx_int_delay, &opt,

View file

@ -49,8 +49,7 @@ static const u16 e1000_igp_2_cable_length_table[] =
100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
124};
#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
(sizeof(e1000_igp_2_cable_length_table) / \
sizeof(e1000_igp_2_cable_length_table[0]))
ARRAY_SIZE(e1000_igp_2_cable_length_table)
/**
* e1000e_check_reset_block_generic - Check if PHY reset is blocked

View file

@ -304,13 +304,7 @@ enum commands {
#if defined(__alpha__)
# define clear_suspend(cmd) clear_bit(30, &(cmd)->cmd_status);
#else
# if defined(__LITTLE_ENDIAN)
# define clear_suspend(cmd) ((__u16 *)&(cmd)->cmd_status)[1] &= ~0x4000
# elif defined(__BIG_ENDIAN)
# define clear_suspend(cmd) ((__u16 *)&(cmd)->cmd_status)[1] &= ~0x0040
# else
# error Unsupported byteorder
# endif
# define clear_suspend(cmd) ((__le16 *)&(cmd)->cmd_status)[1] &= ~cpu_to_le16(1<<14)
#endif
enum SCBCmdBits {
@ -331,17 +325,17 @@ enum SCBPort_cmds {
/* The Speedo3 Rx and Tx frame/buffer descriptors. */
struct descriptor { /* A generic descriptor. */
volatile s32 cmd_status; /* All command and status fields. */
u32 link; /* struct descriptor * */
volatile __le32 cmd_status; /* All command and status fields. */
__le32 link; /* struct descriptor * */
unsigned char params[0];
};
/* The Speedo3 Rx and Tx buffer descriptors. */
struct RxFD { /* Receive frame descriptor. */
volatile s32 status;
u32 link; /* struct RxFD * */
u32 rx_buf_addr; /* void * */
u32 count;
volatile __le32 status;
__le32 link; /* struct RxFD * */
__le32 rx_buf_addr; /* void * */
__le32 count;
} RxFD_ALIGNMENT;
/* Selected elements of the Tx/RxFD.status word. */
@ -354,16 +348,16 @@ enum RxFD_bits {
#define CONFIG_DATA_SIZE 22
struct TxFD { /* Transmit frame descriptor set. */
s32 status;
u32 link; /* void * */
u32 tx_desc_addr; /* Always points to the tx_buf_addr element. */
s32 count; /* # of TBD (=1), Tx start thresh., etc. */
__le32 status;
__le32 link; /* void * */
__le32 tx_desc_addr; /* Always points to the tx_buf_addr element. */
__le32 count; /* # of TBD (=1), Tx start thresh., etc. */
/* This constitutes two "TBD" entries -- we only use one. */
#define TX_DESCR_BUF_OFFSET 16
u32 tx_buf_addr0; /* void *, frame to be transmitted. */
s32 tx_buf_size0; /* Length of Tx frame. */
u32 tx_buf_addr1; /* void *, frame to be transmitted. */
s32 tx_buf_size1; /* Length of Tx frame. */
__le32 tx_buf_addr0; /* void *, frame to be transmitted. */
__le32 tx_buf_size0; /* Length of Tx frame. */
__le32 tx_buf_addr1; /* void *, frame to be transmitted. */
__le32 tx_buf_size1; /* Length of Tx frame. */
/* the structure must have space for at least CONFIG_DATA_SIZE starting
* from tx_desc_addr field */
};
@ -379,23 +373,23 @@ struct speedo_mc_block {
/* Elements of the dump_statistics block. This block must be lword aligned. */
struct speedo_stats {
u32 tx_good_frames;
u32 tx_coll16_errs;
u32 tx_late_colls;
u32 tx_underruns;
u32 tx_lost_carrier;
u32 tx_deferred;
u32 tx_one_colls;
u32 tx_multi_colls;
u32 tx_total_colls;
u32 rx_good_frames;
u32 rx_crc_errs;
u32 rx_align_errs;
u32 rx_resource_errs;
u32 rx_overrun_errs;
u32 rx_colls_errs;
u32 rx_runt_errs;
u32 done_marker;
__le32 tx_good_frames;
__le32 tx_coll16_errs;
__le32 tx_late_colls;
__le32 tx_underruns;
__le32 tx_lost_carrier;
__le32 tx_deferred;
__le32 tx_one_colls;
__le32 tx_multi_colls;
__le32 tx_total_colls;
__le32 rx_good_frames;
__le32 rx_crc_errs;
__le32 rx_align_errs;
__le32 rx_resource_errs;
__le32 rx_overrun_errs;
__le32 rx_colls_errs;
__le32 rx_runt_errs;
__le32 done_marker;
};
enum Rx_ring_state_bits {
@ -1139,7 +1133,7 @@ speedo_rx_soft_reset(struct net_device *dev)
rfd = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE];
rfd->rx_buf_addr = 0xffffffff;
rfd->rx_buf_addr = cpu_to_le32(0xffffffff);
if (wait_for_cmd_done(dev, sp) != 0) {
printk("%s: RxAbort command stalled\n", dev->name);
@ -1275,7 +1269,7 @@ speedo_init_rx_ring(struct net_device *dev)
rxf->status = cpu_to_le32(0x00000001); /* '1' is flag value only. */
rxf->link = 0; /* None yet. */
/* This field unused by i82557. */
rxf->rx_buf_addr = 0xffffffff;
rxf->rx_buf_addr = cpu_to_le32(0xffffffff);
rxf->count = cpu_to_le32(PKT_BUF_SZ << 16);
pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[i],
sizeof(struct RxFD), PCI_DMA_TODEVICE);
@ -1657,7 +1651,7 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
skb->dev = dev;
skb_reserve(skb, sizeof(struct RxFD));
rxf->rx_buf_addr = 0xffffffff;
rxf->rx_buf_addr = cpu_to_le32(0xffffffff);
pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
sizeof(struct RxFD), PCI_DMA_TODEVICE);
return rxf;
@ -1788,7 +1782,7 @@ speedo_rx(struct net_device *dev)
/* Check if the packet is long enough to just accept without
copying to a properly sized skbuff. */
if (pkt_len < rx_copybreak
&& (skb = dev_alloc_skb(pkt_len + 2)) != 0) {
&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
/* 'skb_put()' points to the start of sk_buff data area. */
pci_dma_sync_single_for_cpu(sp->pdev, sp->rx_ring_dma[entry],
@ -1933,7 +1927,7 @@ speedo_get_stats(struct net_device *dev)
void __iomem *ioaddr = sp->regs;
/* Update only if the previous dump finished. */
if (sp->lstats->done_marker == le32_to_cpu(0xA007)) {
if (sp->lstats->done_marker == cpu_to_le32(0xA007)) {
sp->stats.tx_aborted_errors += le32_to_cpu(sp->lstats->tx_coll16_errs);
sp->stats.tx_window_errors += le32_to_cpu(sp->lstats->tx_late_colls);
sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats->tx_underruns);
@ -2142,7 +2136,7 @@ static void set_rx_mode(struct net_device *dev)
/* The simple case of 0-3 multicast list entries occurs often, and
fits within one tx_ring[] entry. */
struct dev_mc_list *mclist;
u16 *setup_params, *eaddrs;
__le16 *setup_params, *eaddrs;
spin_lock_irqsave(&sp->lock, flags);
entry = sp->cur_tx++ % TX_RING_SIZE;
@ -2154,12 +2148,12 @@ static void set_rx_mode(struct net_device *dev)
sp->tx_ring[entry].link =
cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
sp->tx_ring[entry].tx_desc_addr = 0; /* Really MC list count. */
setup_params = (u16 *)&sp->tx_ring[entry].tx_desc_addr;
setup_params = (__le16 *)&sp->tx_ring[entry].tx_desc_addr;
*setup_params++ = cpu_to_le16(dev->mc_count*6);
/* Fill in the multicast addresses. */
for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
i++, mclist = mclist->next) {
eaddrs = (u16 *)mclist->dmi_addr;
eaddrs = (__le16 *)mclist->dmi_addr;
*setup_params++ = *eaddrs++;
*setup_params++ = *eaddrs++;
*setup_params++ = *eaddrs++;
@ -2177,7 +2171,7 @@ static void set_rx_mode(struct net_device *dev)
spin_unlock_irqrestore(&sp->lock, flags);
} else if (new_rx_mode == 0) {
struct dev_mc_list *mclist;
u16 *setup_params, *eaddrs;
__le16 *setup_params, *eaddrs;
struct speedo_mc_block *mc_blk;
struct descriptor *mc_setup_frm;
int i;
@ -2204,12 +2198,12 @@ static void set_rx_mode(struct net_device *dev)
mc_setup_frm->cmd_status =
cpu_to_le32(CmdSuspend | CmdIntr | CmdMulticastList);
/* Link set below. */
setup_params = (u16 *)&mc_setup_frm->params;
setup_params = (__le16 *)&mc_setup_frm->params;
*setup_params++ = cpu_to_le16(dev->mc_count*6);
/* Fill in the multicast addresses. */
for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
i++, mclist = mclist->next) {
eaddrs = (u16 *)mclist->dmi_addr;
eaddrs = (__le16 *)mclist->dmi_addr;
*setup_params++ = *eaddrs++;
*setup_params++ = *eaddrs++;
*setup_params++ = *eaddrs++;

View file

@ -456,8 +456,9 @@ static int eexp_open(struct net_device *dev)
if (!dev->irq || !irqrmap[dev->irq])
return -ENXIO;
ret = request_irq(dev->irq,&eexp_irq,0,dev->name,dev);
if (ret) return ret;
ret = request_irq(dev->irq, &eexp_irq, 0, dev->name, dev);
if (ret)
return ret;
if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress")) {
printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
@ -768,7 +769,7 @@ static void eexp_cmd_clear(struct net_device *dev)
}
}
static irqreturn_t eexp_irq(int irq, void *dev_info)
static irqreturn_t eexp_irq(int dummy, void *dev_info)
{
struct net_device *dev = dev_info;
struct net_local *lp;
@ -783,8 +784,7 @@ static irqreturn_t eexp_irq(int irq, void *dev_info)
old_read_ptr = inw(ioaddr+READ_PTR);
old_write_ptr = inw(ioaddr+WRITE_PTR);
outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
outb(SIRQ_dis|irqrmap[dev->irq], ioaddr+SET_IRQ);
status = scb_status(dev);
@ -851,7 +851,7 @@ static irqreturn_t eexp_irq(int irq, void *dev_info)
eexp_cmd_clear(dev);
outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ);
outb(SIRQ_en|irqrmap[dev->irq], ioaddr+SET_IRQ);
#if NET_DEBUG > 6
printk("%s: leaving eexp_irq()\n", dev->name);

1600
drivers/net/enc28j60.c Normal file

File diff suppressed because it is too large Load diff

309
drivers/net/enc28j60_hw.h Normal file
View file

@ -0,0 +1,309 @@
/*
* enc28j60_hw.h: EDTP FrameThrower style enc28j60 registers
*
* $Id: enc28j60_hw.h,v 1.9 2007/12/14 11:59:16 claudio Exp $
*/
#ifndef _ENC28J60_HW_H
#define _ENC28J60_HW_H
/*
* ENC28J60 Control Registers
* Control register definitions are a combination of address,
* bank number, and Ethernet/MAC/PHY indicator bits.
* - Register address (bits 0-4)
* - Bank number (bits 5-6)
* - MAC/MII indicator (bit 7)
*/
#define ADDR_MASK 0x1F
#define BANK_MASK 0x60
#define SPRD_MASK 0x80
/* All-bank registers */
#define EIE 0x1B
#define EIR 0x1C
#define ESTAT 0x1D
#define ECON2 0x1E
#define ECON1 0x1F
/* Bank 0 registers */
#define ERDPTL (0x00|0x00)
#define ERDPTH (0x01|0x00)
#define EWRPTL (0x02|0x00)
#define EWRPTH (0x03|0x00)
#define ETXSTL (0x04|0x00)
#define ETXSTH (0x05|0x00)
#define ETXNDL (0x06|0x00)
#define ETXNDH (0x07|0x00)
#define ERXSTL (0x08|0x00)
#define ERXSTH (0x09|0x00)
#define ERXNDL (0x0A|0x00)
#define ERXNDH (0x0B|0x00)
#define ERXRDPTL (0x0C|0x00)
#define ERXRDPTH (0x0D|0x00)
#define ERXWRPTL (0x0E|0x00)
#define ERXWRPTH (0x0F|0x00)
#define EDMASTL (0x10|0x00)
#define EDMASTH (0x11|0x00)
#define EDMANDL (0x12|0x00)
#define EDMANDH (0x13|0x00)
#define EDMADSTL (0x14|0x00)
#define EDMADSTH (0x15|0x00)
#define EDMACSL (0x16|0x00)
#define EDMACSH (0x17|0x00)
/* Bank 1 registers */
#define EHT0 (0x00|0x20)
#define EHT1 (0x01|0x20)
#define EHT2 (0x02|0x20)
#define EHT3 (0x03|0x20)
#define EHT4 (0x04|0x20)
#define EHT5 (0x05|0x20)
#define EHT6 (0x06|0x20)
#define EHT7 (0x07|0x20)
#define EPMM0 (0x08|0x20)
#define EPMM1 (0x09|0x20)
#define EPMM2 (0x0A|0x20)
#define EPMM3 (0x0B|0x20)
#define EPMM4 (0x0C|0x20)
#define EPMM5 (0x0D|0x20)
#define EPMM6 (0x0E|0x20)
#define EPMM7 (0x0F|0x20)
#define EPMCSL (0x10|0x20)
#define EPMCSH (0x11|0x20)
#define EPMOL (0x14|0x20)
#define EPMOH (0x15|0x20)
#define EWOLIE (0x16|0x20)
#define EWOLIR (0x17|0x20)
#define ERXFCON (0x18|0x20)
#define EPKTCNT (0x19|0x20)
/* Bank 2 registers */
#define MACON1 (0x00|0x40|SPRD_MASK)
/* #define MACON2 (0x01|0x40|SPRD_MASK) */
#define MACON3 (0x02|0x40|SPRD_MASK)
#define MACON4 (0x03|0x40|SPRD_MASK)
#define MABBIPG (0x04|0x40|SPRD_MASK)
#define MAIPGL (0x06|0x40|SPRD_MASK)
#define MAIPGH (0x07|0x40|SPRD_MASK)
#define MACLCON1 (0x08|0x40|SPRD_MASK)
#define MACLCON2 (0x09|0x40|SPRD_MASK)
#define MAMXFLL (0x0A|0x40|SPRD_MASK)
#define MAMXFLH (0x0B|0x40|SPRD_MASK)
#define MAPHSUP (0x0D|0x40|SPRD_MASK)
#define MICON (0x11|0x40|SPRD_MASK)
#define MICMD (0x12|0x40|SPRD_MASK)
#define MIREGADR (0x14|0x40|SPRD_MASK)
#define MIWRL (0x16|0x40|SPRD_MASK)
#define MIWRH (0x17|0x40|SPRD_MASK)
#define MIRDL (0x18|0x40|SPRD_MASK)
#define MIRDH (0x19|0x40|SPRD_MASK)
/* Bank 3 registers */
#define MAADR1 (0x00|0x60|SPRD_MASK)
#define MAADR0 (0x01|0x60|SPRD_MASK)
#define MAADR3 (0x02|0x60|SPRD_MASK)
#define MAADR2 (0x03|0x60|SPRD_MASK)
#define MAADR5 (0x04|0x60|SPRD_MASK)
#define MAADR4 (0x05|0x60|SPRD_MASK)
#define EBSTSD (0x06|0x60)
#define EBSTCON (0x07|0x60)
#define EBSTCSL (0x08|0x60)
#define EBSTCSH (0x09|0x60)
#define MISTAT (0x0A|0x60|SPRD_MASK)
#define EREVID (0x12|0x60)
#define ECOCON (0x15|0x60)
#define EFLOCON (0x17|0x60)
#define EPAUSL (0x18|0x60)
#define EPAUSH (0x19|0x60)
/* PHY registers */
#define PHCON1 0x00
#define PHSTAT1 0x01
#define PHHID1 0x02
#define PHHID2 0x03
#define PHCON2 0x10
#define PHSTAT2 0x11
#define PHIE 0x12
#define PHIR 0x13
#define PHLCON 0x14
/* ENC28J60 EIE Register Bit Definitions */
#define EIE_INTIE 0x80
#define EIE_PKTIE 0x40
#define EIE_DMAIE 0x20
#define EIE_LINKIE 0x10
#define EIE_TXIE 0x08
/* #define EIE_WOLIE 0x04 (reserved) */
#define EIE_TXERIE 0x02
#define EIE_RXERIE 0x01
/* ENC28J60 EIR Register Bit Definitions */
#define EIR_PKTIF 0x40
#define EIR_DMAIF 0x20
#define EIR_LINKIF 0x10
#define EIR_TXIF 0x08
/* #define EIR_WOLIF 0x04 (reserved) */
#define EIR_TXERIF 0x02
#define EIR_RXERIF 0x01
/* ENC28J60 ESTAT Register Bit Definitions */
#define ESTAT_INT 0x80
#define ESTAT_LATECOL 0x10
#define ESTAT_RXBUSY 0x04
#define ESTAT_TXABRT 0x02
#define ESTAT_CLKRDY 0x01
/* ENC28J60 ECON2 Register Bit Definitions */
#define ECON2_AUTOINC 0x80
#define ECON2_PKTDEC 0x40
#define ECON2_PWRSV 0x20
#define ECON2_VRPS 0x08
/* ENC28J60 ECON1 Register Bit Definitions */
#define ECON1_TXRST 0x80
#define ECON1_RXRST 0x40
#define ECON1_DMAST 0x20
#define ECON1_CSUMEN 0x10
#define ECON1_TXRTS 0x08
#define ECON1_RXEN 0x04
#define ECON1_BSEL1 0x02
#define ECON1_BSEL0 0x01
/* ENC28J60 MACON1 Register Bit Definitions */
#define MACON1_LOOPBK 0x10
#define MACON1_TXPAUS 0x08
#define MACON1_RXPAUS 0x04
#define MACON1_PASSALL 0x02
#define MACON1_MARXEN 0x01
/* ENC28J60 MACON2 Register Bit Definitions */
#define MACON2_MARST 0x80
#define MACON2_RNDRST 0x40
#define MACON2_MARXRST 0x08
#define MACON2_RFUNRST 0x04
#define MACON2_MATXRST 0x02
#define MACON2_TFUNRST 0x01
/* ENC28J60 MACON3 Register Bit Definitions */
#define MACON3_PADCFG2 0x80
#define MACON3_PADCFG1 0x40
#define MACON3_PADCFG0 0x20
#define MACON3_TXCRCEN 0x10
#define MACON3_PHDRLEN 0x08
#define MACON3_HFRMLEN 0x04
#define MACON3_FRMLNEN 0x02
#define MACON3_FULDPX 0x01
/* ENC28J60 MICMD Register Bit Definitions */
#define MICMD_MIISCAN 0x02
#define MICMD_MIIRD 0x01
/* ENC28J60 MISTAT Register Bit Definitions */
#define MISTAT_NVALID 0x04
#define MISTAT_SCAN 0x02
#define MISTAT_BUSY 0x01
/* ENC28J60 ERXFCON Register Bit Definitions */
#define ERXFCON_UCEN 0x80
#define ERXFCON_ANDOR 0x40
#define ERXFCON_CRCEN 0x20
#define ERXFCON_PMEN 0x10
#define ERXFCON_MPEN 0x08
#define ERXFCON_HTEN 0x04
#define ERXFCON_MCEN 0x02
#define ERXFCON_BCEN 0x01
/* ENC28J60 PHY PHCON1 Register Bit Definitions */
#define PHCON1_PRST 0x8000
#define PHCON1_PLOOPBK 0x4000
#define PHCON1_PPWRSV 0x0800
#define PHCON1_PDPXMD 0x0100
/* ENC28J60 PHY PHSTAT1 Register Bit Definitions */
#define PHSTAT1_PFDPX 0x1000
#define PHSTAT1_PHDPX 0x0800
#define PHSTAT1_LLSTAT 0x0004
#define PHSTAT1_JBSTAT 0x0002
/* ENC28J60 PHY PHSTAT2 Register Bit Definitions */
#define PHSTAT2_TXSTAT (1 << 13)
#define PHSTAT2_RXSTAT (1 << 12)
#define PHSTAT2_COLSTAT (1 << 11)
#define PHSTAT2_LSTAT (1 << 10)
#define PHSTAT2_DPXSTAT (1 << 9)
#define PHSTAT2_PLRITY (1 << 5)
/* ENC28J60 PHY PHCON2 Register Bit Definitions */
#define PHCON2_FRCLINK 0x4000
#define PHCON2_TXDIS 0x2000
#define PHCON2_JABBER 0x0400
#define PHCON2_HDLDIS 0x0100
/* ENC28J60 PHY PHIE Register Bit Definitions */
#define PHIE_PLNKIE (1 << 4)
#define PHIE_PGEIE (1 << 1)
/* ENC28J60 PHY PHIR Register Bit Definitions */
#define PHIR_PLNKIF (1 << 4)
#define PHIR_PGEIF (1 << 1)
/* ENC28J60 Packet Control Byte Bit Definitions */
#define PKTCTRL_PHUGEEN 0x08
#define PKTCTRL_PPADEN 0x04
#define PKTCTRL_PCRCEN 0x02
#define PKTCTRL_POVERRIDE 0x01
/* ENC28J60 Transmit Status Vector */
#define TSV_TXBYTECNT 0
#define TSV_TXCOLLISIONCNT 16
#define TSV_TXCRCERROR 20
#define TSV_TXLENCHKERROR 21
#define TSV_TXLENOUTOFRANGE 22
#define TSV_TXDONE 23
#define TSV_TXMULTICAST 24
#define TSV_TXBROADCAST 25
#define TSV_TXPACKETDEFER 26
#define TSV_TXEXDEFER 27
#define TSV_TXEXCOLLISION 28
#define TSV_TXLATECOLLISION 29
#define TSV_TXGIANT 30
#define TSV_TXUNDERRUN 31
#define TSV_TOTBYTETXONWIRE 32
#define TSV_TXCONTROLFRAME 48
#define TSV_TXPAUSEFRAME 49
#define TSV_BACKPRESSUREAPP 50
#define TSV_TXVLANTAGFRAME 51
#define TSV_SIZE 7
#define TSV_BYTEOF(x) ((x) / 8)
#define TSV_BITMASK(x) (1 << ((x) % 8))
#define TSV_GETBIT(x, y) (((x)[TSV_BYTEOF(y)] & TSV_BITMASK(y)) ? 1 : 0)
/* ENC28J60 Receive Status Vector */
#define RSV_RXLONGEVDROPEV 16
#define RSV_CARRIEREV 18
#define RSV_CRCERROR 20
#define RSV_LENCHECKERR 21
#define RSV_LENOUTOFRANGE 22
#define RSV_RXOK 23
#define RSV_RXMULTICAST 24
#define RSV_RXBROADCAST 25
#define RSV_DRIBBLENIBBLE 26
#define RSV_RXCONTROLFRAME 27
#define RSV_RXPAUSEFRAME 28
#define RSV_RXUNKNOWNOPCODE 29
#define RSV_RXTYPEVLAN 30
#define RSV_SIZE 6
#define RSV_BITMASK(x) (1 << ((x) - 16))
#define RSV_GETBIT(x, y) (((x) & RSV_BITMASK(y)) ? 1 : 0)
/* SPI operation codes */
#define ENC28J60_READ_CTRL_REG 0x00
#define ENC28J60_READ_BUF_MEM 0x3A
#define ENC28J60_WRITE_CTRL_REG 0x40
#define ENC28J60_WRITE_BUF_MEM 0x7A
#define ENC28J60_BIT_FIELD_SET 0x80
#define ENC28J60_BIT_FIELD_CLR 0xA0
#define ENC28J60_SOFT_RESET 0xFF
/* buffer boundaries applied to internal 8K ram
* entire available packet buffer space is allocated.
* Give TX buffer space for one full ethernet frame (~1500 bytes)
* receive buffer gets the rest */
#define TXSTART_INIT 0x1A00
#define TXEND_INIT 0x1FFF
/* Put RX buffer at 0 as suggested by the Errata datasheet */
#define RXSTART_INIT 0x0000
#define RXEND_INIT 0x19FF
/* maximum ethernet frame length */
#define MAX_FRAMELEN 1518
/* Prefered half duplex: LEDA: Link status LEDB: Rx/Tx activity */
#define ENC28J60_LAMPS_MODE 0x3476
#endif

View file

@ -712,8 +712,8 @@ static const struct nv_ethtool_str nv_etests_str[] = {
};
struct register_test {
__le32 reg;
__le32 mask;
__u32 reg;
__u32 mask;
};
static const struct register_test nv_registers_test[] = {
@ -929,6 +929,16 @@ static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target,
#define NV_SETUP_RX_RING 0x01
#define NV_SETUP_TX_RING 0x02
static inline u32 dma_low(dma_addr_t addr)
{
return addr;
}
static inline u32 dma_high(dma_addr_t addr)
{
return addr>>31>>1; /* 0 if 32bit, shift down by 32 if 64bit */
}
static void setup_hw_rings(struct net_device *dev, int rxtx_flags)
{
struct fe_priv *np = get_nvpriv(dev);
@ -936,19 +946,19 @@ static void setup_hw_rings(struct net_device *dev, int rxtx_flags)
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
if (rxtx_flags & NV_SETUP_RX_RING) {
writel((u32) cpu_to_le64(np->ring_addr), base + NvRegRxRingPhysAddr);
writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr);
}
if (rxtx_flags & NV_SETUP_TX_RING) {
writel((u32) cpu_to_le64(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
writel(dma_low(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
}
} else {
if (rxtx_flags & NV_SETUP_RX_RING) {
writel((u32) cpu_to_le64(np->ring_addr), base + NvRegRxRingPhysAddr);
writel((u32) (cpu_to_le64(np->ring_addr) >> 32), base + NvRegRxRingPhysAddrHigh);
writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr);
writel(dma_high(np->ring_addr), base + NvRegRxRingPhysAddrHigh);
}
if (rxtx_flags & NV_SETUP_TX_RING) {
writel((u32) cpu_to_le64(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr);
writel((u32) (cpu_to_le64(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)) >> 32), base + NvRegTxRingPhysAddrHigh);
writel(dma_low(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr);
writel(dma_high(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddrHigh);
}
}
}
@ -1571,8 +1581,8 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
skb_tailroom(skb),
PCI_DMA_FROMDEVICE);
np->put_rx_ctx->dma_len = skb_tailroom(skb);
np->put_rx.ex->bufhigh = cpu_to_le64(np->put_rx_ctx->dma) >> 32;
np->put_rx.ex->buflow = cpu_to_le64(np->put_rx_ctx->dma) & 0x0FFFFFFFF;
np->put_rx.ex->bufhigh = cpu_to_le32(dma_high(np->put_rx_ctx->dma));
np->put_rx.ex->buflow = cpu_to_le32(dma_low(np->put_rx_ctx->dma));
wmb();
np->put_rx.ex->flaglen = cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL);
if (unlikely(np->put_rx.ex++ == np->last_rx.ex))
@ -1937,8 +1947,8 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
PCI_DMA_TODEVICE);
np->put_tx_ctx->dma_len = bcnt;
put_tx->bufhigh = cpu_to_le64(np->put_tx_ctx->dma) >> 32;
put_tx->buflow = cpu_to_le64(np->put_tx_ctx->dma) & 0x0FFFFFFFF;
put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma));
put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma));
put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
tx_flags = NV_TX2_VALID;
@ -1963,8 +1973,8 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt,
PCI_DMA_TODEVICE);
np->put_tx_ctx->dma_len = bcnt;
put_tx->bufhigh = cpu_to_le64(np->put_tx_ctx->dma) >> 32;
put_tx->buflow = cpu_to_le64(np->put_tx_ctx->dma) & 0x0FFFFFFFF;
put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma));
put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma));
put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
offset += bcnt;
@ -2680,8 +2690,8 @@ static void nv_set_multicast(struct net_device *dev)
walk = dev->mc_list;
while (walk != NULL) {
u32 a, b;
a = le32_to_cpu(*(u32 *) walk->dmi_addr);
b = le16_to_cpu(*(u16 *) (&walk->dmi_addr[4]));
a = le32_to_cpu(*(__le32 *) walk->dmi_addr);
b = le16_to_cpu(*(__le16 *) (&walk->dmi_addr[4]));
alwaysOn[0] &= a;
alwaysOff[0] &= ~a;
alwaysOn[1] &= b;
@ -4539,8 +4549,8 @@ static int nv_loopback_test(struct net_device *dev)
np->tx_ring.orig[0].buf = cpu_to_le32(test_dma_addr);
np->tx_ring.orig[0].flaglen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra);
} else {
np->tx_ring.ex[0].bufhigh = cpu_to_le64(test_dma_addr) >> 32;
np->tx_ring.ex[0].buflow = cpu_to_le64(test_dma_addr) & 0x0FFFFFFFF;
np->tx_ring.ex[0].bufhigh = cpu_to_le32(dma_high(test_dma_addr));
np->tx_ring.ex[0].buflow = cpu_to_le32(dma_low(test_dma_addr));
np->tx_ring.ex[0].flaglen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra);
}
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);

View file

@ -37,24 +37,6 @@
#include "gianfar.h"
#define GFAR_ATTR(_name) \
static ssize_t gfar_show_##_name(struct device *dev, \
struct device_attribute *attr, char *buf); \
static ssize_t gfar_set_##_name(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count); \
static DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
#define GFAR_CREATE_FILE(_dev, _name) \
device_create_file(&_dev->dev, &dev_attr_##_name)
GFAR_ATTR(bd_stash);
GFAR_ATTR(rx_stash_size);
GFAR_ATTR(rx_stash_index);
GFAR_ATTR(fifo_threshold);
GFAR_ATTR(fifo_starve);
GFAR_ATTR(fifo_starve_off);
static ssize_t gfar_show_bd_stash(struct device *dev,
struct device_attribute *attr, char *buf)
{
@ -100,6 +82,8 @@ static ssize_t gfar_set_bd_stash(struct device *dev,
return count;
}
DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
static ssize_t gfar_show_rx_stash_size(struct device *dev,
struct device_attribute *attr, char *buf)
{
@ -146,6 +130,9 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev,
return count;
}
DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
gfar_set_rx_stash_size);
/* Stashing will only be enabled when rx_stash_size != 0 */
static ssize_t gfar_show_rx_stash_index(struct device *dev,
struct device_attribute *attr,
@ -184,6 +171,9 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev,
return count;
}
DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
gfar_set_rx_stash_index);
static ssize_t gfar_show_fifo_threshold(struct device *dev,
struct device_attribute *attr,
char *buf)
@ -219,6 +209,9 @@ static ssize_t gfar_set_fifo_threshold(struct device *dev,
return count;
}
DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
gfar_set_fifo_threshold);
static ssize_t gfar_show_fifo_starve(struct device *dev,
struct device_attribute *attr, char *buf)
{
@ -253,6 +246,8 @@ static ssize_t gfar_set_fifo_starve(struct device *dev,
return count;
}
DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve, gfar_set_fifo_starve);
static ssize_t gfar_show_fifo_starve_off(struct device *dev,
struct device_attribute *attr,
char *buf)
@ -288,9 +283,13 @@ static ssize_t gfar_set_fifo_starve_off(struct device *dev,
return count;
}
DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
gfar_set_fifo_starve_off);
void gfar_init_sysfs(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
int rc;
/* Initialize the default values */
priv->rx_stash_size = DEFAULT_STASH_LENGTH;
@ -301,11 +300,12 @@ void gfar_init_sysfs(struct net_device *dev)
priv->bd_stash_en = DEFAULT_BD_STASH;
/* Create our sysfs files */
GFAR_CREATE_FILE(dev, bd_stash);
GFAR_CREATE_FILE(dev, rx_stash_size);
GFAR_CREATE_FILE(dev, rx_stash_index);
GFAR_CREATE_FILE(dev, fifo_threshold);
GFAR_CREATE_FILE(dev, fifo_starve);
GFAR_CREATE_FILE(dev, fifo_starve_off);
rc = device_create_file(&dev->dev, &dev_attr_bd_stash);
rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_size);
rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_index);
rc |= device_create_file(&dev->dev, &dev_attr_fifo_threshold);
rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve);
rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve_off);
if (rc)
dev_err(&dev->dev, "Error creating gianfar sysfs files.\n");
}

View file

@ -701,7 +701,7 @@ static void sixpack_close(struct tty_struct *tty)
sp = tty->disc_data;
tty->disc_data = NULL;
write_unlock(&disc_data_lock);
if (sp == 0)
if (!sp)
return;
/*

View file

@ -821,7 +821,7 @@ static void mkiss_close(struct tty_struct *tty)
tty->disc_data = NULL;
write_unlock(&disc_data_lock);
if (ax == 0)
if (!ax)
return;
/*

View file

@ -201,7 +201,6 @@ static void z8530_init(void);
static void init_channel(struct scc_channel *scc);
static void scc_key_trx (struct scc_channel *scc, char tx);
static irqreturn_t scc_isr(int irq, void *dev_id);
static void scc_init_timer(struct scc_channel *scc);
static int scc_net_alloc(const char *name, struct scc_channel *scc);
@ -629,6 +628,7 @@ static void scc_isr_dispatch(struct scc_channel *scc, int vector)
static irqreturn_t scc_isr(int irq, void *dev_id)
{
int chip_irq = (long) dev_id;
unsigned char vector;
struct scc_channel *scc;
struct scc_ctrl *ctrl;
@ -665,7 +665,7 @@ static irqreturn_t scc_isr(int irq, void *dev_id)
ctrl = SCC_ctrl;
while (ctrl->chan_A)
{
if (ctrl->irq != irq)
if (ctrl->irq != chip_irq)
{
ctrl++;
continue;
@ -1732,7 +1732,9 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (!Ivec[hwcfg.irq].used && hwcfg.irq)
{
if (request_irq(hwcfg.irq, scc_isr, IRQF_DISABLED, "AX.25 SCC", NULL))
if (request_irq(hwcfg.irq, scc_isr,
IRQF_DISABLED, "AX.25 SCC",
(void *)(long) hwcfg.irq))
printk(KERN_WARNING "z8530drv: warning, cannot get IRQ %d\n", hwcfg.irq);
else
Ivec[hwcfg.irq].used = 1;

View file

@ -1153,7 +1153,7 @@ static void hp100_init_pdls(struct net_device *dev)
printk("hp100: %s: init pdls\n", dev->name);
#endif
if (0 == lp->page_vaddr_algn)
if (!lp->page_vaddr_algn)
printk("hp100: %s: Warning: lp->page_vaddr_algn not initialised!\n", dev->name);
else {
/* pageptr shall point into the DMA accessible memory region */

View file

@ -1297,7 +1297,6 @@ static int emac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
return emac_xmit_finish(dev, len);
}
#ifdef CONFIG_IBM_NEW_EMAC_TAH
static inline int emac_xmit_split(struct emac_instance *dev, int slot,
u32 pd, int len, int last, u16 base_ctrl)
{
@ -1410,9 +1409,6 @@ static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
DBG2(dev, "stopped TX queue" NL);
return 1;
}
#else
# define emac_start_xmit_sg emac_start_xmit
#endif /* !defined(CONFIG_IBM_NEW_EMAC_TAH) */
/* Tx lock BHs */
static void emac_parse_tx_error(struct emac_instance *dev, u16 ctrl)
@ -2683,13 +2679,8 @@ static int __devinit emac_probe(struct of_device *ofdev,
/* Fill in the driver function table */
ndev->open = &emac_open;
#ifdef CONFIG_IBM_NEW_EMAC_TAH
if (dev->tah_dev) {
ndev->hard_start_xmit = &emac_start_xmit_sg;
if (dev->tah_dev)
ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
} else
#endif
ndev->hard_start_xmit = &emac_start_xmit;
ndev->tx_timeout = &emac_tx_timeout;
ndev->watchdog_timeo = 5 * HZ;
ndev->stop = &emac_close;
@ -2697,8 +2688,11 @@ static int __devinit emac_probe(struct of_device *ofdev,
ndev->set_multicast_list = &emac_set_multicast_list;
ndev->do_ioctl = &emac_ioctl;
if (emac_phy_supports_gige(dev->phy_mode)) {
ndev->hard_start_xmit = &emac_start_xmit_sg;
ndev->change_mtu = &emac_change_mtu;
dev->commac.ops = &emac_commac_sg_ops;
} else {
ndev->hard_start_xmit = &emac_start_xmit;
}
SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);

View file

@ -83,7 +83,7 @@ History:
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/mca-legacy.h>
#include <linux/mca.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@ -161,13 +161,13 @@ static void PrTime(void)
/* deduce resources out of POS registers */
static void getaddrs(int slot, int *base, int *memlen, int *iobase,
int *irq, ibmlana_medium * medium)
static void getaddrs(struct mca_device *mdev, int *base, int *memlen,
int *iobase, int *irq, ibmlana_medium *medium)
{
u_char pos0, pos1;
pos0 = mca_read_stored_pos(slot, 2);
pos1 = mca_read_stored_pos(slot, 3);
pos0 = mca_device_read_stored_pos(mdev, 2);
pos1 = mca_device_read_stored_pos(mdev, 3);
*base = 0xc0000 + ((pos1 & 0xf0) << 9);
*memlen = (pos1 & 0x01) ? 0x8000 : 0x4000;
@ -704,9 +704,9 @@ static void irqtxerr_handler(struct net_device *dev)
/* general interrupt entry */
static irqreturn_t irq_handler(int irq, void *device)
static irqreturn_t irq_handler(int dummy, void *device)
{
struct net_device *dev = (struct net_device *) device;
struct net_device *dev = device;
u16 ival;
/* in case we're not meant... */
@ -744,6 +744,7 @@ static irqreturn_t irq_handler(int irq, void *device)
/* MCA info */
#if 0 /* info available elsewhere, but this is kept for reference */
static int ibmlana_getinfo(char *buf, int slot, void *d)
{
int len = 0, i;
@ -771,6 +772,7 @@ static int ibmlana_getinfo(char *buf, int slot, void *d)
return len;
}
#endif
/* open driver. Means also initialization and start of LANCE */
@ -890,42 +892,52 @@ static void ibmlana_set_multicast_list(struct net_device *dev)
* hardware check
* ------------------------------------------------------------------------ */
static int ibmlana_irq;
static int ibmlana_io;
static int startslot; /* counts through slots when probing multiple devices */
static int ibmlana_probe(struct net_device *dev)
static short ibmlana_adapter_ids[] __initdata = {
IBM_LANA_ID,
0x0000
};
static char *ibmlana_adapter_names[] __initdata = {
"IBM LAN Adapter/A",
NULL
};
static int ibmlana_init_one(struct device *kdev)
{
int slot, z;
struct mca_device *mdev = to_mca_device(kdev);
struct net_device *dev;
int slot = mdev->slot, z, rc;
int base = 0, irq = 0, iobase = 0, memlen = 0;
ibmlana_priv *priv;
ibmlana_medium medium;
DECLARE_MAC_BUF(mac);
/* can't work without an MCA bus ;-) */
if (MCA_bus == 0)
return -ENODEV;
dev = alloc_etherdev(sizeof(ibmlana_priv));
if (!dev)
return -ENOMEM;
dev->irq = ibmlana_irq;
dev->base_addr = ibmlana_io;
base = dev->mem_start;
irq = dev->irq;
for (slot = startslot; (slot = mca_find_adapter(IBM_LANA_ID, slot)) != -1; slot++) {
/* deduce card addresses */
getaddrs(slot, &base, &memlen, &iobase, &irq, &medium);
/* deduce card addresses */
getaddrs(mdev, &base, &memlen, &iobase, &irq, &medium);
/* slot already in use ? */
if (mca_is_adapter_used(slot))
continue;
/* were we looking for something different ? */
if (dev->irq && dev->irq != irq)
continue;
if (dev->mem_start && dev->mem_start != base)
continue;
/* found something that matches */
break;
/* were we looking for something different ? */
if (dev->irq && dev->irq != irq) {
rc = -ENODEV;
goto err_out;
}
if (dev->mem_start && dev->mem_start != base) {
rc = -ENODEV;
goto err_out;
}
/* nothing found ? */
if (slot == -1)
return (base != 0 || irq != 0) ? -ENXIO : -ENODEV;
/* announce success */
printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1);
@ -934,16 +946,16 @@ static int ibmlana_probe(struct net_device *dev)
if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) {
printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase);
startslot = slot + 1;
return -EBUSY;
rc = -EBUSY;
goto err_out;
}
priv = netdev_priv(dev);
priv->slot = slot;
priv->realirq = irq;
priv->realirq = mca_device_transform_irq(mdev, irq);
priv->medium = medium;
spin_lock_init(&priv->lock);
/* set base + irq for this device (irq not allocated so far) */
dev->irq = 0;
@ -955,22 +967,18 @@ static int ibmlana_probe(struct net_device *dev)
if (!priv->base) {
printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME);
startslot = slot + 1;
release_region(iobase, IBM_LANA_IORANGE);
return -EBUSY;
rc = -EBUSY;
goto err_out_reg;
}
/* make procfs entries */
mca_set_adapter_name(slot, "IBM LAN Adapter/A");
mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmlana_getinfo, dev);
mca_mark_as_used(slot);
mca_device_set_name(mdev, ibmlana_adapter_names[mdev->index]);
mca_device_set_claim(mdev, 1);
/* set methods */
dev->open = ibmlana_open;
dev->stop = ibmlana_close;
dev->hard_start_xmit = ibmlana_tx;
dev->do_ioctl = NULL;
dev->set_multicast_list = ibmlana_set_multicast_list;
dev->flags |= IFF_MULTICAST;
@ -996,6 +1004,35 @@ static int ibmlana_probe(struct net_device *dev)
startslot = slot + 1;
rc = register_netdev(dev);
if (rc)
goto err_out_claimed;
dev_set_drvdata(kdev, dev);
return 0;
err_out_claimed:
mca_device_set_claim(mdev, 0);
iounmap(priv->base);
err_out_reg:
release_region(iobase, IBM_LANA_IORANGE);
err_out:
free_netdev(dev);
return rc;
}
static int ibmlana_remove_one(struct device *kdev)
{
struct mca_device *mdev = to_mca_device(kdev);
struct net_device *dev = dev_get_drvdata(kdev);
ibmlana_priv *priv = netdev_priv(dev);
unregister_netdev(dev);
/*DeinitBoard(dev); */
release_region(dev->base_addr, IBM_LANA_IORANGE);
mca_device_set_claim(mdev, 0);
iounmap(priv->base);
free_netdev(dev);
return 0;
}
@ -1003,66 +1040,31 @@ static int ibmlana_probe(struct net_device *dev)
* modularization support
* ------------------------------------------------------------------------ */
#ifdef MODULE
#define DEVMAX 5
static struct net_device *moddevs[DEVMAX];
static int irq;
static int io;
module_param(irq, int, 0);
module_param(io, int, 0);
module_param_named(irq, ibmlana_irq, int, 0);
module_param_named(io, ibmlana_io, int, 0);
MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
MODULE_LICENSE("GPL");
int init_module(void)
{
int z;
static struct mca_driver ibmlana_driver = {
.id_table = ibmlana_adapter_ids,
.driver = {
.name = "ibmlana",
.bus = &mca_bus_type,
.probe = ibmlana_init_one,
.remove = ibmlana_remove_one,
},
};
startslot = 0;
for (z = 0; z < DEVMAX; z++) {
struct net_device *dev = alloc_etherdev(sizeof(ibmlana_priv));
if (!dev)
break;
dev->irq = irq;
dev->base_addr = io;
if (ibmlana_probe(dev)) {
free_netdev(dev);
break;
}
if (register_netdev(dev)) {
ibmlana_priv *priv = netdev_priv(dev);
release_region(dev->base_addr, IBM_LANA_IORANGE);
mca_mark_as_unused(priv->slot);
mca_set_adapter_name(priv->slot, "");
mca_set_adapter_procfn(priv->slot, NULL, NULL);
iounmap(priv->base);
free_netdev(dev);
break;
}
moddevs[z] = dev;
}
return (z > 0) ? 0 : -EIO;
static int __init ibmlana_init_module(void)
{
return mca_register_driver(&ibmlana_driver);
}
void cleanup_module(void)
static void __exit ibmlana_cleanup_module(void)
{
int z;
for (z = 0; z < DEVMAX; z++) {
struct net_device *dev = moddevs[z];
if (dev) {
ibmlana_priv *priv = netdev_priv(dev);
unregister_netdev(dev);
/*DeinitBoard(dev); */
release_region(dev->base_addr, IBM_LANA_IORANGE);
mca_mark_as_unused(priv->slot);
mca_set_adapter_name(priv->slot, "");
mca_set_adapter_procfn(priv->slot, NULL, NULL);
iounmap(priv->base);
free_netdev(dev);
}
}
mca_unregister_driver(&ibmlana_driver);
}
#endif /* MODULE */
module_init(ibmlana_init_module);
module_exit(ibmlana_cleanup_module);

37
drivers/net/igb/Makefile Normal file
View file

@ -0,0 +1,37 @@
################################################################################
#
# Intel 82575 PCI-Express Ethernet Linux driver
# Copyright(c) 1999 - 2007 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope 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.,
# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
#
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
#
# Contact Information:
# Linux NICS <[email protected]>
# e1000-devel Mailing List <[email protected]>
# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
#
################################################################################
#
# Makefile for the Intel(R) 82575 PCI-Express ethernet driver
#
obj-$(CONFIG_IGB) += igb.o
igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \
e1000_mac.o e1000_nvm.o e1000_phy.o

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,150 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _E1000_82575_H_
#define _E1000_82575_H_
#define E1000_RAR_ENTRIES_82575 16
/* SRRCTL bit definitions */
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002
#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
#define E1000_EICR_TX_QUEUE ( \
E1000_EICR_TX_QUEUE0 | \
E1000_EICR_TX_QUEUE1 | \
E1000_EICR_TX_QUEUE2 | \
E1000_EICR_TX_QUEUE3)
#define E1000_EICR_RX_QUEUE ( \
E1000_EICR_RX_QUEUE0 | \
E1000_EICR_RX_QUEUE1 | \
E1000_EICR_RX_QUEUE2 | \
E1000_EICR_RX_QUEUE3)
#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE
#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE
/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */
/* Receive Descriptor - Advanced */
union e1000_adv_rx_desc {
struct {
u64 pkt_addr; /* Packet buffer address */
u64 hdr_addr; /* Header buffer address */
} read;
struct {
struct {
struct {
u16 pkt_info; /* RSS type, Packet type */
u16 hdr_info; /* Split Header,
* header buffer length */
} lo_dword;
union {
u32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length; /* Packet length */
u16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
/* RSS Hash results */
/* RSS Packet Types as indicated in the receive descriptor */
/* Transmit Descriptor - Advanced */
union e1000_adv_tx_desc {
struct {
u64 buffer_addr; /* Address of descriptor's data buf */
u32 cmd_type_len;
u32 olinfo_status;
} read;
struct {
u64 rsvd; /* Reserved */
u32 nxtseq_seed;
u32 status;
} wb;
};
/* Adv Transmit Descriptor Config Masks */
#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
/* Context descriptors */
struct e1000_adv_tx_context_desc {
u32 vlan_macip_lens;
u32 seqnum_seed;
u32 type_tucmd_mlhl;
u32 mss_l4len_idx;
};
#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
/* IPSec Encrypt Enable for ESP */
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
/* Adv ctxt IPSec SA IDX mask */
/* Adv ctxt IPSec ESP len mask */
/* Additional Transmit Descriptor Control definitions */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
/* Tx Queue Arbitration Priority 0=low, 1=high */
/* Additional Receive Descriptor Control definitions */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
/* Direct Cache Access (DCA) definitions */
#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* TX Desc writeback RO bit */
#endif

View file

@ -0,0 +1,772 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _E1000_DEFINES_H_
#define _E1000_DEFINES_H_
/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
#define REQ_TX_DESCRIPTOR_MULTIPLE 8
#define REQ_RX_DESCRIPTOR_MULTIPLE 8
/* Definitions for power management and wakeup registers */
/* Wake Up Control */
#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
/* Wake Up Status */
/* Wake Up Packet Length */
/* Four Flexible Filters are supported */
#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
/* Each Flexible Filter is at most 128 (0x80) bytes in length */
#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128
/* Extended Device Control */
#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
#define E1000_CTRL_EXT_EIAME 0x01000000
#define E1000_CTRL_EXT_IRCA 0x00000001
/* Interrupt delay cancellation */
/* Driver loaded bit for FW */
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000
/* Interrupt acknowledge Auto-mask */
/* Clear Interrupt timers after IMS clear */
/* packet buffer parity error detection enabled */
/* descriptor FIFO parity error detection enable */
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
#define E1000_I2CCMD_REG_ADDR_SHIFT 16
#define E1000_I2CCMD_PHY_ADDR_SHIFT 24
#define E1000_I2CCMD_OPCODE_READ 0x08000000
#define E1000_I2CCMD_OPCODE_WRITE 0x00000000
#define E1000_I2CCMD_READY 0x20000000
#define E1000_I2CCMD_ERROR 0x80000000
#define E1000_MAX_SGMII_PHY_REG_ADDR 255
#define E1000_I2CCMD_PHY_TIMEOUT 200
/* Receive Decriptor bit definitions */
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
#define E1000_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
#define E1000_RXDEXT_STATERR_CE 0x01000000
#define E1000_RXDEXT_STATERR_SE 0x02000000
#define E1000_RXDEXT_STATERR_SEQ 0x04000000
#define E1000_RXDEXT_STATERR_CXE 0x10000000
#define E1000_RXDEXT_STATERR_TCPE 0x20000000
#define E1000_RXDEXT_STATERR_IPE 0x40000000
#define E1000_RXDEXT_STATERR_RXE 0x80000000
/* mask to determine if packets should be dropped due to frame errors */
#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
E1000_RXD_ERR_CE | \
E1000_RXD_ERR_SE | \
E1000_RXD_ERR_SEQ | \
E1000_RXD_ERR_CXE | \
E1000_RXD_ERR_RXE)
/* Same mask, but for extended and packet split descriptors */
#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
E1000_RXDEXT_STATERR_CE | \
E1000_RXDEXT_STATERR_SE | \
E1000_RXDEXT_STATERR_SEQ | \
E1000_RXDEXT_STATERR_CXE | \
E1000_RXDEXT_STATERR_RXE)
#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000
/* Management Control */
#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
/* Enable Neighbor Discovery Filtering */
#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
/* Enable MAC address filtering */
#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000
/* Enable MNG packets to host memory */
#define E1000_MANC_EN_MNG2HOST 0x00200000
/* Enable IP address filtering */
/* Receive Control */
#define E1000_RCTL_EN 0x00000002 /* enable */
#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
/*
* Use byte values for the following shift parameters
* Usage:
* psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
* E1000_PSRCTL_BSIZE0_MASK) |
* ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
* E1000_PSRCTL_BSIZE1_MASK) |
* ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
* E1000_PSRCTL_BSIZE2_MASK) |
* ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
* E1000_PSRCTL_BSIZE3_MASK))
* where value0 = [128..16256], default=256
* value1 = [1024..64512], default=4096
* value2 = [0..64512], default=4096
* value3 = [0..64512], default=0
*/
#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F
#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00
#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000
#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000
#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */
#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */
#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */
#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */
/* SWFW_SYNC Definitions */
#define E1000_SWFW_EEP_SM 0x1
#define E1000_SWFW_PHY0_SM 0x2
#define E1000_SWFW_PHY1_SM 0x4
/* FACTPS Definitions */
/* Device Control */
#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
/* Defined polarity of Dock/Undock indication in SDP[0] */
/* Reset both PHY ports, through PHYRST_N pin */
/* enable link status from external LINK_0 and LINK_1 pins */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
#define E1000_CTRL_RST 0x04000000 /* Global reset */
#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
/* Initiate an interrupt to manageability engine */
#define E1000_CTRL_I2C_ENA 0x02000000 /* I2C enable */
/* Bit definitions for the Management Data IO (MDIO) and Management Data
* Clock (MDC) pins in the Device Control Register.
*/
#define E1000_CONNSW_ENRGSRC 0x4
#define E1000_PCS_LCTL_FLV_LINK_UP 1
#define E1000_PCS_LCTL_FSV_100 2
#define E1000_PCS_LCTL_FSV_1000 4
#define E1000_PCS_LCTL_FDV_FULL 8
#define E1000_PCS_LCTL_FSD 0x10
#define E1000_PCS_LCTL_FORCE_LINK 0x20
#define E1000_PCS_LCTL_AN_ENABLE 0x10000
#define E1000_PCS_LCTL_AN_RESTART 0x20000
#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000
#define E1000_PCS_LSTS_LINK_OK 1
#define E1000_PCS_LSTS_SPEED_100 2
#define E1000_PCS_LSTS_SPEED_1000 4
#define E1000_PCS_LSTS_DUPLEX_FULL 8
#define E1000_PCS_LSTS_SYNK_OK 0x10
/* Device Status */
#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
#define E1000_STATUS_FUNC_SHIFT 2
#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
/* Change in Dock/Undock state. Clear on write '0'. */
/* Status of Master requests. */
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000
/* BMC external code execution disabled */
/* Constants used to intrepret the masked PCI-X bus speed. */
#define SPEED_10 10
#define SPEED_100 100
#define SPEED_1000 1000
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
#define ADVERTISE_10_HALF 0x0001
#define ADVERTISE_10_FULL 0x0002
#define ADVERTISE_100_HALF 0x0004
#define ADVERTISE_100_FULL 0x0008
#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */
#define ADVERTISE_1000_FULL 0x0020
/* 1000/H is not supported, nor spec-compliant. */
#define E1000_ALL_SPEED_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
ADVERTISE_1000_FULL)
#define E1000_ALL_NOT_GIG (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
ADVERTISE_100_HALF | ADVERTISE_100_FULL)
#define E1000_ALL_100_SPEED (ADVERTISE_100_HALF | ADVERTISE_100_FULL)
#define E1000_ALL_10_SPEED (ADVERTISE_10_HALF | ADVERTISE_10_FULL)
#define E1000_ALL_FULL_DUPLEX (ADVERTISE_10_FULL | ADVERTISE_100_FULL | \
ADVERTISE_1000_FULL)
#define E1000_ALL_HALF_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_100_HALF)
#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
/* LED Control */
#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
#define E1000_LEDCTL_LED0_MODE_SHIFT 0
#define E1000_LEDCTL_LED0_IVRT 0x00000040
#define E1000_LEDCTL_LED0_BLINK 0x00000080
#define E1000_LEDCTL_MODE_LED_ON 0xE
#define E1000_LEDCTL_MODE_LED_OFF 0xF
/* Transmit Descriptor bit definitions */
#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
/* Extended desc bits for Linksec and timesync */
/* Transmit Control */
#define E1000_TCTL_EN 0x00000002 /* enable tx */
#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
/* Transmit Arbitration Count */
/* SerDes Control */
#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
/* Receive Checksum Control */
#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* Header split receive */
/* Collision related configuration parameters */
#define E1000_COLLISION_THRESHOLD 15
#define E1000_CT_SHIFT 4
#define E1000_COLLISION_DISTANCE 63
#define E1000_COLD_SHIFT 12
/* Ethertype field values */
#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */
#define MAX_JUMBO_FRAME_SIZE 0x3F00
/* Extended Configuration Control and Size */
#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040
/* PBA constants */
#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
#define E1000_PBA_24K 0x0018
#define E1000_PBA_34K 0x0022
#define IFS_MAX 80
#define IFS_MIN 40
#define IFS_RATIO 4
#define IFS_STEP 10
#define MIN_NUM_XMITS 1000
/* SW Semaphore Register */
#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
/* Interrupt Cause Read */
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
#define E1000_ICR_RXO 0x00000040 /* rx overrun */
#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
#define E1000_ICR_TXD_LOW 0x00008000
#define E1000_ICR_SRPD 0x00010000
#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
#define E1000_ICR_MNG 0x00040000 /* Manageability event */
#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_INT_ASSERTED 0x80000000
/* queue 0 Rx descriptor FIFO parity error */
#define E1000_ICR_RXD_FIFO_PAR0 0x00100000
/* queue 0 Tx descriptor FIFO parity error */
#define E1000_ICR_TXD_FIFO_PAR0 0x00200000
/* host arb read buffer parity error */
#define E1000_ICR_HOST_ARB_PAR 0x00400000
#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
/* queue 1 Rx descriptor FIFO parity error */
#define E1000_ICR_RXD_FIFO_PAR1 0x01000000
/* queue 1 Tx descriptor FIFO parity error */
#define E1000_ICR_TXD_FIFO_PAR1 0x02000000
/* FW changed the status of DISSW bit in the FWSM */
#define E1000_ICR_DSW 0x00000020
/* LAN connected device generates an interrupt */
#define E1000_ICR_PHYINT 0x00001000
#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
/* Extended Interrupt Cause Read */
#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */
#define E1000_EICR_RX_QUEUE1 0x00000002 /* Rx Queue 1 Interrupt */
#define E1000_EICR_RX_QUEUE2 0x00000004 /* Rx Queue 2 Interrupt */
#define E1000_EICR_RX_QUEUE3 0x00000008 /* Rx Queue 3 Interrupt */
#define E1000_EICR_TX_QUEUE0 0x00000100 /* Tx Queue 0 Interrupt */
#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */
#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */
#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */
#define E1000_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */
/* TCP Timer */
/*
* This defines the bits that are set in the Interrupt Mask
* Set/Read Register. Each bit is documented below:
* o RXT0 = Receiver Timer Interrupt (ring 0)
* o TXDW = Transmit Descriptor Written Back
* o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
* o RXSEQ = Receive Sequence Error
* o LSC = Link Status Change
*/
#define IMS_ENABLE_MASK ( \
E1000_IMS_RXT0 | \
E1000_IMS_TXDW | \
E1000_IMS_RXDMT0 | \
E1000_IMS_RXSEQ | \
E1000_IMS_LSC)
/* Interrupt Mask Set */
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
/* queue 0 Rx descriptor FIFO parity error */
/* queue 0 Tx descriptor FIFO parity error */
/* host arb read buffer parity error */
/* packet buffer parity error */
/* queue 1 Rx descriptor FIFO parity error */
/* queue 1 Tx descriptor FIFO parity error */
/* Extended Interrupt Mask Set */
#define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */
#define E1000_EIMS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */
/* Interrupt Cause Set */
#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
/* queue 0 Rx descriptor FIFO parity error */
/* queue 0 Tx descriptor FIFO parity error */
/* host arb read buffer parity error */
/* packet buffer parity error */
/* queue 1 Rx descriptor FIFO parity error */
/* queue 1 Tx descriptor FIFO parity error */
/* Extended Interrupt Cause Set */
/* Transmit Descriptor Control */
/* Enable the counting of descriptors still to be processed. */
/* Flow Control Constants */
#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
#define FLOW_CONTROL_TYPE 0x8808
/* 802.1q VLAN Packet Size */
#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMA'd) */
#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
/* Receive Address */
/*
* Number of high/low register pairs in the RAR. The RAR (Receive Address
* Registers) holds the directed and multicast addresses that we monitor.
* Technically, we have 16 spots. However, we reserve one of these spots
* (RAR[15]) for our directed address used by controllers with
* manageability enabled, allowing us room for 15 multicast addresses.
*/
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
/* Error Codes */
#define E1000_ERR_NVM 1
#define E1000_ERR_PHY 2
#define E1000_ERR_CONFIG 3
#define E1000_ERR_PARAM 4
#define E1000_ERR_MAC_INIT 5
#define E1000_ERR_RESET 9
#define E1000_ERR_MASTER_REQUESTS_PENDING 10
#define E1000_ERR_HOST_INTERFACE_COMMAND 11
#define E1000_BLK_PHY_RESET 12
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14
/* Loop limit on how long we wait for auto-negotiation to complete */
#define COPPER_LINK_UP_LIMIT 10
#define PHY_AUTO_NEG_LIMIT 45
#define PHY_FORCE_LIMIT 20
/* Number of 100 microseconds we wait for PCI Express master disable */
#define MASTER_DISABLE_TIMEOUT 800
/* Number of milliseconds we wait for PHY configuration done after MAC reset */
#define PHY_CFG_TIMEOUT 100
/* Number of 2 milliseconds we wait for acquiring MDIO ownership. */
/* Number of milliseconds for NVM auto read done after MAC reset. */
#define AUTO_READ_DONE_TIMEOUT 10
/* Flow Control */
#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
/* Transmit Configuration Word */
#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
/* Receive Configuration Word */
/* PCI Express Control */
#define E1000_GCR_RXD_NO_SNOOP 0x00000001
#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002
#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004
#define E1000_GCR_TXD_NO_SNOOP 0x00000008
#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010
#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020
#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \
E1000_GCR_RXDSCW_NO_SNOOP | \
E1000_GCR_RXDSCR_NO_SNOOP | \
E1000_GCR_TXD_NO_SNOOP | \
E1000_GCR_TXDSCW_NO_SNOOP | \
E1000_GCR_TXDSCR_NO_SNOOP)
/* PHY Control Register */
#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
#define MII_CR_SPEED_1000 0x0040
#define MII_CR_SPEED_100 0x2000
#define MII_CR_SPEED_10 0x0000
/* PHY Status Register */
#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
/* Autoneg Advertisement Register */
#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */
#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */
/* Link Partner Ability Register (Base Page) */
#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */
#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */
/* Autoneg Expansion Register */
/* 1000BASE-T Control Register */
#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
/* 0=DTE device */
#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */
/* 0=Configure PHY as Slave */
#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
/* 0=Automatic Master/Slave config */
/* 1000BASE-T Status Register */
#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
/* PHY 1000 MII Register/Bit Definitions */
/* PHY Registers defined by IEEE */
#define PHY_CONTROL 0x00 /* Control Register */
#define PHY_STATUS 0x01 /* Status Regiser */
#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */
#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
/* NVM Control */
#define E1000_EECD_SK 0x00000001 /* NVM Clock */
#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */
#define E1000_EECD_DI 0x00000004 /* NVM Data In */
#define E1000_EECD_DO 0x00000008 /* NVM Data Out */
#define E1000_EECD_REQ 0x00000040 /* NVM Access Request */
#define E1000_EECD_GNT 0x00000080 /* NVM Access Grant */
#define E1000_EECD_PRES 0x00000100 /* NVM Present */
/* NVM Addressing bits based on type 0=small, 1=large */
#define E1000_EECD_ADDR_BITS 0x00000400
#define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */
#define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */
#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */
#define E1000_EECD_SIZE_EX_SHIFT 11
/* Offset to data in NVM read/write registers */
#define E1000_NVM_RW_REG_DATA 16
#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
#define E1000_NVM_RW_REG_START 1 /* Start operation */
#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
#define E1000_NVM_POLL_READ 0 /* Flag for polling for read complete */
/* NVM Word Offsets */
#define NVM_ID_LED_SETTINGS 0x0004
/* For SERDES output amplitude adjustment. */
#define NVM_INIT_CONTROL2_REG 0x000F
#define NVM_INIT_CONTROL3_PORT_A 0x0024
#define NVM_ALT_MAC_ADDR_PTR 0x0037
#define NVM_CHECKSUM_REG 0x003F
#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */
#define E1000_NVM_CFG_DONE_PORT_1 0x80000 /* ...for second port */
/* Mask bits for fields in Word 0x0f of the NVM */
#define NVM_WORD0F_PAUSE_MASK 0x3000
#define NVM_WORD0F_ASM_DIR 0x2000
/* Mask bits for fields in Word 0x1a of the NVM */
/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
#define NVM_SUM 0xBABA
#define NVM_PBA_OFFSET_0 8
#define NVM_PBA_OFFSET_1 9
#define NVM_WORD_SIZE_BASE_SHIFT 6
/* NVM Commands - Microwire */
/* NVM Commands - SPI */
#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
#define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */
#define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */
#define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */
#define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */
/* SPI NVM Status Register */
#define NVM_STATUS_RDY_SPI 0x01
/* Word definitions for ID LED Settings */
#define ID_LED_RESERVED_0000 0x0000
#define ID_LED_RESERVED_FFFF 0xFFFF
#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \
(ID_LED_OFF1_OFF2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2))
#define ID_LED_DEF1_DEF2 0x1
#define ID_LED_DEF1_ON2 0x2
#define ID_LED_DEF1_OFF2 0x3
#define ID_LED_ON1_DEF2 0x4
#define ID_LED_ON1_ON2 0x5
#define ID_LED_ON1_OFF2 0x6
#define ID_LED_OFF1_DEF2 0x7
#define ID_LED_OFF1_ON2 0x8
#define ID_LED_OFF1_OFF2 0x9
#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
#define IGP_ACTIVITY_LED_ENABLE 0x0300
#define IGP_LED3_MODE 0x07000000
/* PCI/PCI-X/PCI-EX Config space */
#define PCI_HEADER_TYPE_REGISTER 0x0E
#define PCIE_LINK_STATUS 0x12
#define PCI_HEADER_TYPE_MULTIFUNC 0x80
#define PCIE_LINK_WIDTH_MASK 0x3F0
#define PCIE_LINK_WIDTH_SHIFT 4
#define PHY_REVISION_MASK 0xFFFFFFF0
#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
#define MAX_PHY_MULTI_PAGE_REG 0xF
/* Bit definitions for valid PHY IDs. */
/*
* I = Integrated
* E = External
*/
#define M88E1111_I_PHY_ID 0x01410CC0
#define IGP03E1000_E_PHY_ID 0x02A80390
#define M88_VENDOR 0x0141
/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */
#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */
/* M88E1000 PHY Specific Control Register */
#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
/* 1=CLK125 low, 0=CLK125 toggling */
#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
/* Manual MDI configuration */
#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
#define M88E1000_PSCR_AUTO_X_1000T 0x0040
/* Auto crossover enabled all speeds */
#define M88E1000_PSCR_AUTO_X_MODE 0x0060
/*
* 1=Enable Extended 10BASE-T distance (Lower 10BASE-T RX Threshold
* 0=Normal 10BASE-T RX Threshold
*/
/* 1=5-bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */
#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
/* M88E1000 PHY Specific Status Register */
#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */
#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
/*
* 0 = <50M
* 1 = 50-80M
* 2 = 80-110M
* 3 = 110-140M
* 4 = >140M
*/
#define M88E1000_PSSR_CABLE_LENGTH 0x0380
#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
/* M88E1000 Extended PHY Specific Control Register */
/*
* 1 = Lost lock detect enabled.
* Will assert lost lock and bring
* link down if idle not seen
* within 1ms in 1000BASE-T
*/
/*
* Number of times we will attempt to autonegotiate before downshifting if we
* are the master
*/
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000
/*
* Number of times we will attempt to autonegotiate before downshifting if we
* are the slave
*/
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300
#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100
#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
/* M88EC018 Rev 2 specific DownShift settings */
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
/* MDI Control */
#define E1000_MDIC_REG_SHIFT 16
#define E1000_MDIC_PHY_SHIFT 21
#define E1000_MDIC_OP_WRITE 0x04000000
#define E1000_MDIC_OP_READ 0x08000000
#define E1000_MDIC_READY 0x10000000
#define E1000_MDIC_ERROR 0x40000000
/* SerDes Control */
#define E1000_GEN_CTL_READY 0x80000000
#define E1000_GEN_CTL_ADDRESS_SHIFT 8
#define E1000_GEN_POLL_TIMEOUT 640
#endif

599
drivers/net/igb/e1000_hw.h Normal file
View file

@ -0,0 +1,599 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _E1000_HW_H_
#define _E1000_HW_H_
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/io.h>
#include "e1000_mac.h"
#include "e1000_regs.h"
#include "e1000_defines.h"
struct e1000_hw;
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
#define E1000_REVISION_2 2
#define E1000_REVISION_4 4
#define E1000_FUNC_1 1
enum e1000_mac_type {
e1000_undefined = 0,
e1000_82575,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
};
enum e1000_media_type {
e1000_media_type_unknown = 0,
e1000_media_type_copper = 1,
e1000_media_type_fiber = 2,
e1000_media_type_internal_serdes = 3,
e1000_num_media_types
};
enum e1000_nvm_type {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
e1000_nvm_eeprom_microwire,
e1000_nvm_flash_hw,
e1000_nvm_flash_sw
};
enum e1000_nvm_override {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large,
e1000_nvm_override_microwire_small,
e1000_nvm_override_microwire_large
};
enum e1000_phy_type {
e1000_phy_unknown = 0,
e1000_phy_none,
e1000_phy_m88,
e1000_phy_igp,
e1000_phy_igp_2,
e1000_phy_gg82563,
e1000_phy_igp_3,
e1000_phy_ife,
};
enum e1000_bus_type {
e1000_bus_type_unknown = 0,
e1000_bus_type_pci,
e1000_bus_type_pcix,
e1000_bus_type_pci_express,
e1000_bus_type_reserved
};
enum e1000_bus_speed {
e1000_bus_speed_unknown = 0,
e1000_bus_speed_33,
e1000_bus_speed_66,
e1000_bus_speed_100,
e1000_bus_speed_120,
e1000_bus_speed_133,
e1000_bus_speed_2500,
e1000_bus_speed_5000,
e1000_bus_speed_reserved
};
enum e1000_bus_width {
e1000_bus_width_unknown = 0,
e1000_bus_width_pcie_x1,
e1000_bus_width_pcie_x2,
e1000_bus_width_pcie_x4 = 4,
e1000_bus_width_pcie_x8 = 8,
e1000_bus_width_32,
e1000_bus_width_64,
e1000_bus_width_reserved
};
enum e1000_1000t_rx_status {
e1000_1000t_rx_status_not_ok = 0,
e1000_1000t_rx_status_ok,
e1000_1000t_rx_status_undefined = 0xFF
};
enum e1000_rev_polarity {
e1000_rev_polarity_normal = 0,
e1000_rev_polarity_reversed,
e1000_rev_polarity_undefined = 0xFF
};
enum e1000_fc_type {
e1000_fc_none = 0,
e1000_fc_rx_pause,
e1000_fc_tx_pause,
e1000_fc_full,
e1000_fc_default = 0xFF
};
/* Receive Descriptor */
struct e1000_rx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
u16 length; /* Length of data DMAed into data buffer */
u16 csum; /* Packet checksum */
u8 status; /* Descriptor status */
u8 errors; /* Descriptor Errors */
u16 special;
};
/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
struct {
u64 buffer_addr;
u64 reserved;
} read;
struct {
struct {
u32 mrq; /* Multiple Rx Queues */
union {
u32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length;
u16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define MAX_PS_BUFFERS 4
/* Receive Descriptor - Packet Split */
union e1000_rx_desc_packet_split {
struct {
/* one buffer for protocol header(s), three data buffers */
u64 buffer_addr[MAX_PS_BUFFERS];
} read;
struct {
struct {
u32 mrq; /* Multiple Rx Queues */
union {
u32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length0; /* length of buffer 0 */
u16 vlan; /* VLAN tag */
} middle;
struct {
u16 header_status;
u16 length[3]; /* length of buffers 1-3 */
} upper;
u64 reserved;
} wb; /* writeback */
};
/* Transmit Descriptor */
struct e1000_tx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
union {
u32 data;
struct {
u16 length; /* Data buffer length */
u8 cso; /* Checksum offset */
u8 cmd; /* Descriptor control */
} flags;
} lower;
union {
u32 data;
struct {
u8 status; /* Descriptor status */
u8 css; /* Checksum start */
u16 special;
} fields;
} upper;
};
/* Offload Context Descriptor */
struct e1000_context_desc {
union {
u32 ip_config;
struct {
u8 ipcss; /* IP checksum start */
u8 ipcso; /* IP checksum offset */
u16 ipcse; /* IP checksum end */
} ip_fields;
} lower_setup;
union {
u32 tcp_config;
struct {
u8 tucss; /* TCP checksum start */
u8 tucso; /* TCP checksum offset */
u16 tucse; /* TCP checksum end */
} tcp_fields;
} upper_setup;
u32 cmd_and_length;
union {
u32 data;
struct {
u8 status; /* Descriptor status */
u8 hdr_len; /* Header length */
u16 mss; /* Maximum segment size */
} fields;
} tcp_seg_setup;
};
/* Offload data descriptor */
struct e1000_data_desc {
u64 buffer_addr; /* Address of the descriptor's buffer address */
union {
u32 data;
struct {
u16 length; /* Data buffer length */
u8 typ_len_ext;
u8 cmd;
} flags;
} lower;
union {
u32 data;
struct {
u8 status; /* Descriptor status */
u8 popts; /* Packet Options */
u16 special;
} fields;
} upper;
};
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
u64 crcerrs;
u64 algnerrc;
u64 symerrs;
u64 rxerrc;
u64 mpc;
u64 scc;
u64 ecol;
u64 mcc;
u64 latecol;
u64 colc;
u64 dc;
u64 tncrs;
u64 sec;
u64 cexterr;
u64 rlec;
u64 xonrxc;
u64 xontxc;
u64 xoffrxc;
u64 xofftxc;
u64 fcruc;
u64 prc64;
u64 prc127;
u64 prc255;
u64 prc511;
u64 prc1023;
u64 prc1522;
u64 gprc;
u64 bprc;
u64 mprc;
u64 gptc;
u64 gorc;
u64 gotc;
u64 rnbc;
u64 ruc;
u64 rfc;
u64 roc;
u64 rjc;
u64 mgprc;
u64 mgpdc;
u64 mgptc;
u64 tor;
u64 tot;
u64 tpr;
u64 tpt;
u64 ptc64;
u64 ptc127;
u64 ptc255;
u64 ptc511;
u64 ptc1023;
u64 ptc1522;
u64 mptc;
u64 bptc;
u64 tsctc;
u64 tsctfc;
u64 iac;
u64 icrxptc;
u64 icrxatc;
u64 ictxptc;
u64 ictxatc;
u64 ictxqec;
u64 ictxqmtc;
u64 icrxdmtc;
u64 icrxoc;
u64 cbtmpc;
u64 htdpmc;
u64 cbrdpc;
u64 cbrmpc;
u64 rpthc;
u64 hgptc;
u64 htcbdpc;
u64 hgorc;
u64 hgotc;
u64 lenerrs;
u64 scvpc;
u64 hrmpc;
};
struct e1000_phy_stats {
u32 idle_errors;
u32 receive_errors;
};
struct e1000_host_mng_dhcp_cookie {
u32 signature;
u8 status;
u8 reserved0;
u16 vlan_id;
u32 reserved1;
u16 reserved2;
u8 reserved3;
u8 checksum;
};
/* Host Interface "Rev 1" */
struct e1000_host_command_header {
u8 command_id;
u8 command_length;
u8 command_options;
u8 checksum;
};
#define E1000_HI_MAX_DATA_LENGTH 252
struct e1000_host_command_info {
struct e1000_host_command_header command_header;
u8 command_data[E1000_HI_MAX_DATA_LENGTH];
};
/* Host Interface "Rev 2" */
struct e1000_host_mng_command_header {
u8 command_id;
u8 checksum;
u16 reserved1;
u16 reserved2;
u16 command_length;
};
#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
struct e1000_host_mng_command_info {
struct e1000_host_mng_command_header command_header;
u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
};
#include "e1000_mac.h"
#include "e1000_phy.h"
#include "e1000_nvm.h"
struct e1000_mac_operations {
s32 (*check_for_link)(struct e1000_hw *);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
void (*rar_set)(struct e1000_hw *, u8 *, u32);
s32 (*read_mac_addr)(struct e1000_hw *);
s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
};
struct e1000_phy_operations {
s32 (*acquire_phy)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_phy_info)(struct e1000_hw *);
s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
void (*release_phy)(struct e1000_hw *);
s32 (*reset_phy)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
s32 (*write_phy_reg)(struct e1000_hw *, u32, u16);
};
struct e1000_nvm_operations {
s32 (*acquire_nvm)(struct e1000_hw *);
s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *);
void (*release_nvm)(struct e1000_hw *);
s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
};
struct e1000_info {
s32 (*get_invariants)(struct e1000_hw *);
struct e1000_mac_operations *mac_ops;
struct e1000_phy_operations *phy_ops;
struct e1000_nvm_operations *nvm_ops;
};
extern const struct e1000_info e1000_82575_info;
struct e1000_mac_info {
struct e1000_mac_operations ops;
u8 addr[6];
u8 perm_addr[6];
enum e1000_mac_type type;
u32 collision_delta;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 mc_filter_type;
u32 tx_packet_delta;
u32 txcw;
u16 current_ifs_val;
u16 ifs_max_val;
u16 ifs_min_val;
u16 ifs_ratio;
u16 ifs_step_size;
u16 mta_reg_count;
u16 rar_entry_count;
u8 forced_speed_duplex;
bool adaptive_ifs;
bool arc_subsystem_valid;
bool asf_firmware_present;
bool autoneg;
bool autoneg_failed;
bool disable_av;
bool disable_hw_init_bits;
bool get_link_status;
bool ifs_params_forced;
bool in_ifs_mode;
bool report_tx_early;
bool serdes_has_link;
bool tx_pkt_filtering;
};
struct e1000_phy_info {
struct e1000_phy_operations ops;
enum e1000_phy_type type;
enum e1000_1000t_rx_status local_rx;
enum e1000_1000t_rx_status remote_rx;
enum e1000_ms_type ms_type;
enum e1000_ms_type original_ms_type;
enum e1000_rev_polarity cable_polarity;
enum e1000_smart_speed smart_speed;
u32 addr;
u32 id;
u32 reset_delay_us; /* in usec */
u32 revision;
enum e1000_media_type media_type;
u16 autoneg_advertised;
u16 autoneg_mask;
u16 cable_length;
u16 max_cable_length;
u16 min_cable_length;
u8 mdix;
bool disable_polarity_correction;
bool is_mdix;
bool polarity_correction;
bool reset_disable;
bool speed_downgraded;
bool autoneg_wait_to_complete;
};
struct e1000_nvm_info {
struct e1000_nvm_operations ops;
enum e1000_nvm_type type;
enum e1000_nvm_override override;
u32 flash_bank_size;
u32 flash_base_addr;
u16 word_size;
u16 delay_usec;
u16 address_bits;
u16 opcode_bits;
u16 page_size;
};
struct e1000_bus_info {
enum e1000_bus_type type;
enum e1000_bus_speed speed;
enum e1000_bus_width width;
u32 snoop;
u16 func;
u16 pci_cmd_word;
};
struct e1000_fc_info {
u32 high_water; /* Flow control high-water mark */
u32 low_water; /* Flow control low-water mark */
u16 pause_time; /* Flow control pause timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
enum e1000_fc_type type; /* Type of flow control */
enum e1000_fc_type original_type;
};
struct e1000_hw {
void *back;
void *dev_spec;
u8 __iomem *hw_addr;
u8 __iomem *flash_address;
unsigned long io_base;
struct e1000_mac_info mac;
struct e1000_fc_info fc;
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
struct e1000_host_mng_dhcp_cookie mng_cookie;
u32 dev_spec_size;
u16 device_id;
u16 subsystem_vendor_id;
u16 subsystem_device_id;
u16 vendor_id;
u8 revision_id;
};
#ifdef DEBUG
extern char *igb_get_hw_dev_name(struct e1000_hw *hw);
#define hw_dbg(hw, format, arg...) \
printk(KERN_DEBUG "%s: " format, igb_get_hw_dev_name(hw), ##arg)
#else
static inline int __attribute__ ((format (printf, 2, 3)))
hw_dbg(struct e1000_hw *hw, const char *format, ...)
{
return 0;
}
#endif
#endif

1505
drivers/net/igb/e1000_mac.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,98 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _E1000_MAC_H_
#define _E1000_MAC_H_
#include "e1000_hw.h"
#include "e1000_phy.h"
#include "e1000_nvm.h"
#include "e1000_defines.h"
/*
* Functions that should not be called directly from drivers but can be used
* by other files in this 'shared code'
*/
s32 igb_blink_led(struct e1000_hw *hw);
s32 igb_check_for_copper_link(struct e1000_hw *hw);
s32 igb_cleanup_led(struct e1000_hw *hw);
s32 igb_config_fc_after_link_up(struct e1000_hw *hw);
s32 igb_disable_pcie_master(struct e1000_hw *hw);
s32 igb_force_mac_fc(struct e1000_hw *hw);
s32 igb_get_auto_rd_done(struct e1000_hw *hw);
s32 igb_get_bus_info_pcie(struct e1000_hw *hw);
s32 igb_get_hw_semaphore(struct e1000_hw *hw);
s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 igb_id_led_init(struct e1000_hw *hw);
s32 igb_led_off(struct e1000_hw *hw);
void igb_update_mc_addr_list(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count);
s32 igb_setup_link(struct e1000_hw *hw);
s32 igb_validate_mdi_setting(struct e1000_hw *hw);
s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
void igb_clear_vfta(struct e1000_hw *hw);
void igb_config_collision_dist(struct e1000_hw *hw);
void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
void igb_put_hw_semaphore(struct e1000_hw *hw);
void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
s32 igb_check_alt_mac_addr(struct e1000_hw *hw);
void igb_remove_device(struct e1000_hw *hw);
void igb_reset_adaptive(struct e1000_hw *hw);
void igb_update_adaptive(struct e1000_hw *hw);
void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
bool igb_enable_mng_pass_thru(struct e1000_hw *hw);
enum e1000_mng_mode {
e1000_mng_mode_none = 0,
e1000_mng_mode_asf,
e1000_mng_mode_pt,
e1000_mng_mode_ipmi,
e1000_mng_mode_host_if_only
};
#define E1000_FACTPS_MNGCG 0x20000000
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
/* Driver sets this bit when done to put command in RAM */
#define E1000_HICR_C 0x02
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
#endif

605
drivers/net/igb/e1000_nvm.c Normal file
View file

@ -0,0 +1,605 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#include <linux/if_ether.h>
#include <linux/delay.h>
#include "e1000_mac.h"
#include "e1000_nvm.h"
/**
* e1000_raise_eec_clk - Raise EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Enable/Raise the EEPROM clock bit.
**/
static void igb_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd | E1000_EECD_SK;
wr32(E1000_EECD, *eecd);
wrfl();
udelay(hw->nvm.delay_usec);
}
/**
* e1000_lower_eec_clk - Lower EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Clear/Lower the EEPROM clock bit.
**/
static void igb_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd & ~E1000_EECD_SK;
wr32(E1000_EECD, *eecd);
wrfl();
udelay(hw->nvm.delay_usec);
}
/**
* e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
* @hw: pointer to the HW structure
* @data: data to send to the EEPROM
* @count: number of bits to shift out
*
* We need to shift 'count' bits out to the EEPROM. So, the value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
**/
static void igb_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
u32 mask;
mask = 0x01 << (count - 1);
if (nvm->type == e1000_nvm_eeprom_microwire)
eecd &= ~E1000_EECD_DO;
else if (nvm->type == e1000_nvm_eeprom_spi)
eecd |= E1000_EECD_DO;
do {
eecd &= ~E1000_EECD_DI;
if (data & mask)
eecd |= E1000_EECD_DI;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
igb_raise_eec_clk(hw, &eecd);
igb_lower_eec_clk(hw, &eecd);
mask >>= 1;
} while (mask);
eecd &= ~E1000_EECD_DI;
wr32(E1000_EECD, eecd);
}
/**
* e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
* @hw: pointer to the HW structure
* @count: number of bits to shift in
*
* In order to read a register from the EEPROM, we need to shift 'count' bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the data out
* "DO" bit. During this "shifting in" process the data in "DI" bit should
* always be clear.
**/
static u16 igb_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
{
u32 eecd;
u32 i;
u16 data;
eecd = rd32(E1000_EECD);
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
data = 0;
for (i = 0; i < count; i++) {
data <<= 1;
igb_raise_eec_clk(hw, &eecd);
eecd = rd32(E1000_EECD);
eecd &= ~E1000_EECD_DI;
if (eecd & E1000_EECD_DO)
data |= 1;
igb_lower_eec_clk(hw, &eecd);
}
return data;
}
/**
* e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion
* @hw: pointer to the HW structure
* @ee_reg: EEPROM flag for polling
*
* Polls the EEPROM status bit for either read or write completion based
* upon the value of 'ee_reg'.
**/
static s32 igb_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
{
u32 attempts = 100000;
u32 i, reg = 0;
s32 ret_val = -E1000_ERR_NVM;
for (i = 0; i < attempts; i++) {
if (ee_reg == E1000_NVM_POLL_READ)
reg = rd32(E1000_EERD);
else
reg = rd32(E1000_EEWR);
if (reg & E1000_NVM_RW_REG_DONE) {
ret_val = 0;
break;
}
udelay(5);
}
return ret_val;
}
/**
* e1000_acquire_nvm - Generic request for access to EEPROM
* @hw: pointer to the HW structure
*
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
s32 igb_acquire_nvm(struct e1000_hw *hw)
{
u32 eecd = rd32(E1000_EECD);
s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
s32 ret_val = 0;
wr32(E1000_EECD, eecd | E1000_EECD_REQ);
eecd = rd32(E1000_EECD);
while (timeout) {
if (eecd & E1000_EECD_GNT)
break;
udelay(5);
eecd = rd32(E1000_EECD);
timeout--;
}
if (!timeout) {
eecd &= ~E1000_EECD_REQ;
wr32(E1000_EECD, eecd);
hw_dbg(hw, "Could not acquire NVM grant\n");
ret_val = -E1000_ERR_NVM;
}
return ret_val;
}
/**
* e1000_standby_nvm - Return EEPROM to standby state
* @hw: pointer to the HW structure
*
* Return the EEPROM to a standby state.
**/
static void igb_standby_nvm(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
if (nvm->type == e1000_nvm_eeprom_microwire) {
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
igb_raise_eec_clk(hw, &eecd);
/* Select EEPROM */
eecd |= E1000_EECD_CS;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
igb_lower_eec_clk(hw, &eecd);
} else if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
eecd &= ~E1000_EECD_CS;
wr32(E1000_EECD, eecd);
wrfl();
udelay(nvm->delay_usec);
}
}
/**
* e1000_stop_nvm - Terminate EEPROM command
* @hw: pointer to the HW structure
*
* Terminates the current command by inverting the EEPROM's chip select pin.
**/
static void e1000_stop_nvm(struct e1000_hw *hw)
{
u32 eecd;
eecd = rd32(E1000_EECD);
if (hw->nvm.type == e1000_nvm_eeprom_spi) {
/* Pull CS high */
eecd |= E1000_EECD_CS;
igb_lower_eec_clk(hw, &eecd);
} else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
/* CS on Microcwire is active-high */
eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
wr32(E1000_EECD, eecd);
igb_raise_eec_clk(hw, &eecd);
igb_lower_eec_clk(hw, &eecd);
}
}
/**
* e1000_release_nvm - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
**/
void igb_release_nvm(struct e1000_hw *hw)
{
u32 eecd;
e1000_stop_nvm(hw);
eecd = rd32(E1000_EECD);
eecd &= ~E1000_EECD_REQ;
wr32(E1000_EECD, eecd);
}
/**
* e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
* @hw: pointer to the HW structure
*
* Setups the EEPROM for reading and writing.
**/
static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = rd32(E1000_EECD);
s32 ret_val = 0;
u16 timeout = 0;
u8 spi_stat_reg;
if (nvm->type == e1000_nvm_eeprom_microwire) {
/* Clear SK and DI */
eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
wr32(E1000_EECD, eecd);
/* Set CS */
eecd |= E1000_EECD_CS;
wr32(E1000_EECD, eecd);
} else if (nvm->type == e1000_nvm_eeprom_spi) {
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
wr32(E1000_EECD, eecd);
udelay(1);
timeout = NVM_MAX_RETRY_SPI;
/*
* Read "Status Register" repeatedly until the LSB is cleared.
* The EEPROM will signal that the command has been completed
* by clearing bit 0 of the internal status register. If it's
* not cleared within 'timeout', then error out.
*/
while (timeout) {
igb_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
hw->nvm.opcode_bits);
spi_stat_reg = (u8)igb_shift_in_eec_bits(hw, 8);
if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
break;
udelay(5);
igb_standby_nvm(hw);
timeout--;
}
if (!timeout) {
hw_dbg(hw, "SPI NVM Status error\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
}
out:
return ret_val;
}
/**
* e1000_read_nvm_eerd - Reads EEPROM using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM using the EERD register.
**/
s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, eerd = 0;
s32 ret_val = 0;
/*
* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg(hw, "nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
for (i = 0; i < words; i++) {
eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
E1000_NVM_RW_REG_START;
wr32(E1000_EERD, eerd);
ret_val = igb_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
if (ret_val)
break;
data[i] = (rd32(E1000_EERD) >>
E1000_NVM_RW_REG_DATA);
}
out:
return ret_val;
}
/**
* e1000_write_nvm_spi - Write to EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the EEPROM
*
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
* EEPROM will most likley contain an invalid checksum.
**/
s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val;
u16 widx = 0;
/*
* A check for invalid values: offset too large, too many words,
* and not enough words.
*/
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
hw_dbg(hw, "nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = hw->nvm.ops.acquire_nvm(hw);
if (ret_val)
goto out;
msleep(10);
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
ret_val = igb_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
igb_standby_nvm(hw);
/* Send the WRITE ENABLE command (8 bit opcode) */
igb_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
nvm->opcode_bits);
igb_standby_nvm(hw);
/*
* Some SPI eeproms use the 8th address bit embedded in the
* opcode
*/
if ((nvm->address_bits == 8) && (offset >= 128))
write_opcode |= NVM_A8_OPCODE_SPI;
/* Send the Write command (8-bit opcode + addr) */
igb_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
igb_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
nvm->address_bits);
/* Loop to allow for up to whole page write of eeprom */
while (widx < words) {
u16 word_out = data[widx];
word_out = (word_out >> 8) | (word_out << 8);
igb_shift_out_eec_bits(hw, word_out, 16);
widx++;
if ((((offset + widx) * 2) % nvm->page_size) == 0) {
igb_standby_nvm(hw);
break;
}
}
}
msleep(10);
release:
hw->nvm.ops.release_nvm(hw);
out:
return ret_val;
}
/**
* e1000_read_part_num - Read device part number
* @hw: pointer to the HW structure
* @part_num: pointer to device part number
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in part_num.
**/
s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num)
{
s32 ret_val;
u16 nvm_data;
ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
goto out;
}
*part_num = (u32)(nvm_data << 16);
ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
goto out;
}
*part_num |= nvm_data;
out:
return ret_val;
}
/**
* e1000_read_mac_addr - Read device MAC address
* @hw: pointer to the HW structure
*
* Reads the device MAC address from the EEPROM and stores the value.
* Since devices with two ports use the same EEPROM, we increment the
* last bit in the MAC address for the second port.
**/
s32 igb_read_mac_addr(struct e1000_hw *hw)
{
s32 ret_val = 0;
u16 offset, nvm_data, i;
for (i = 0; i < ETH_ALEN; i += 2) {
offset = i >> 1;
ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
goto out;
}
hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
}
/* Flip last bit of mac address if we're on second port */
if (hw->bus.func == E1000_FUNC_1)
hw->mac.perm_addr[5] ^= 1;
for (i = 0; i < ETH_ALEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
out:
return ret_val;
}
/**
* e1000_validate_nvm_checksum - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
s32 igb_validate_nvm_checksum(struct e1000_hw *hw)
{
s32 ret_val = 0;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error\n");
goto out;
}
checksum += nvm_data;
}
if (checksum != (u16) NVM_SUM) {
hw_dbg(hw, "NVM Checksum Invalid\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
out:
return ret_val;
}
/**
* e1000_update_nvm_checksum - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM.
**/
s32 igb_update_nvm_checksum(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg(hw, "NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = hw->nvm.ops.write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val)
hw_dbg(hw, "NVM Write Error while updating checksum.\n");
out:
return ret_val;
}

View file

@ -0,0 +1,40 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _E1000_NVM_H_
#define _E1000_NVM_H_
s32 igb_acquire_nvm(struct e1000_hw *hw);
void igb_release_nvm(struct e1000_hw *hw);
s32 igb_read_mac_addr(struct e1000_hw *hw);
s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num);
s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_validate_nvm_checksum(struct e1000_hw *hw);
s32 igb_update_nvm_checksum(struct e1000_hw *hw);
#endif

1807
drivers/net/igb/e1000_phy.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,98 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _E1000_PHY_H_
#define _E1000_PHY_H_
enum e1000_ms_type {
e1000_ms_hw_default = 0,
e1000_ms_force_master,
e1000_ms_force_slave,
e1000_ms_auto
};
enum e1000_smart_speed {
e1000_smart_speed_default = 0,
e1000_smart_speed_on,
e1000_smart_speed_off
};
s32 igb_check_downshift(struct e1000_hw *hw);
s32 igb_check_reset_block(struct e1000_hw *hw);
s32 igb_copper_link_autoneg(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex(struct e1000_hw *hw);
s32 igb_copper_link_setup_igp(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw);
s32 igb_get_cable_length_m88(struct e1000_hw *hw);
s32 igb_get_cable_length_igp_2(struct e1000_hw *hw);
s32 igb_get_phy_id(struct e1000_hw *hw);
s32 igb_get_phy_info_igp(struct e1000_hw *hw);
s32 igb_get_phy_info_m88(struct e1000_hw *hw);
s32 igb_phy_sw_reset(struct e1000_hw *hw);
s32 igb_phy_hw_reset(struct e1000_hw *hw);
s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
/* Enable flexible speed on link-up */
#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
#define IGP01E1000_PSSR_MDIX 0x0008
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP02E1000_PHY_CHANNEL_NUM 4
#define IGP02E1000_PHY_AGC_A 0x11B1
#define IGP02E1000_PHY_AGC_B 0x12B1
#define IGP02E1000_PHY_AGC_C 0x14B1
#define IGP02E1000_PHY_AGC_D 0x18B1
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */
#define IGP02E1000_AGC_LENGTH_MASK 0x7F
#define IGP02E1000_AGC_RANGE 15
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
#endif

View file

@ -0,0 +1,270 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
#ifndef _E1000_REGS_H_
#define _E1000_REGS_H_
#define E1000_CTRL 0x00000 /* Device Control - RW */
#define E1000_STATUS 0x00008 /* Device Status - RO */
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_RCTL 0x00100 /* RX Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
#define E1000_EITR(_n) (0x01680 + (0x4 * (_n)))
#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
#define E1000_TCTL 0x00400 /* TX Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n)))
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
/* Split and Replication RX Control - RW */
/*
* Convenience macros
*
* Note: "_n" is the queue number of the register to be written to.
*
* Example usage:
* E1000_RDBAL_REG(current_rx_queue)
*/
#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) \
: (0x0C000 + ((_n) * 0x40)))
#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) \
: (0x0C004 + ((_n) * 0x40)))
#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) \
: (0x0C008 + ((_n) * 0x40)))
#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) \
: (0x0C00C + ((_n) * 0x40)))
#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) \
: (0x0C010 + ((_n) * 0x40)))
#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) \
: (0x0C018 + ((_n) * 0x40)))
#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) \
: (0x0C028 + ((_n) * 0x40)))
#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) \
: (0x0E000 + ((_n) * 0x40)))
#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) \
: (0x0E004 + ((_n) * 0x40)))
#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) \
: (0x0E008 + ((_n) * 0x40)))
#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) \
: (0x0E010 + ((_n) * 0x40)))
#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) \
: (0x0E018 + ((_n) * 0x40)))
#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \
: (0x0E028 + ((_n) * 0x40)))
#define E1000_TARC(_n) (0x03840 + (_n << 8))
#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \
: (0x0E038 + ((_n) * 0x40)))
#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \
: (0x0E03C + ((_n) * 0x40)))
#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
#define E1000_DTXCTL 0x03590 /* DMA TX Control - RW */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
#define E1000_DC 0x04030 /* Defer Count - R/clr */
#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
/* Interrupt Cause Rx Packet Timer Expire Count */
#define E1000_ICRXPTC 0x04104
/* Interrupt Cause Rx Absolute Timer Expire Count */
#define E1000_ICRXATC 0x04108
/* Interrupt Cause Tx Packet Timer Expire Count */
#define E1000_ICTXPTC 0x0410C
/* Interrupt Cause Tx Absolute Timer Expire Count */
#define E1000_ICTXATC 0x04110
/* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQEC 0x04118
/* Interrupt Cause Tx Queue Minimum Threshold Count */
#define E1000_ICTXQMTC 0x0411C
/* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXDMTC 0x04120
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
#define E1000_CBTMPC 0x0402C /* Circuit Breaker TX Packet Count */
#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */
#define E1000_CBRMPC 0x040FC /* Circuit Breaker RX Packet Count */
#define E1000_RPTHC 0x04104 /* Rx Packets To Host */
#define E1000_HGPTC 0x04118 /* Host Good Packets TX Count */
#define E1000_HTCBDPC 0x04124 /* Host TX Circuit Breaker Dropped Count */
#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */
#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */
#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
#define E1000_LENERRS 0x04138 /* Length Errors Count */
#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
#define E1000_RLPML 0x05004 /* RX Long Packet Max Length */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
#define E1000_WUS 0x05810 /* Wakeup Status - RO */
#define E1000_MANC 0x05820 /* Management Control - RW */
#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
#define E1000_HOST_IF 0x08800 /* Host Interface */
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_HICR 0x08F00 /* Host Inteface Control */
/* RSS registers */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */
/* MSI-X Allocation Register (_i) - RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4))
/* MSI-X Table entry addr low reg 0 - RW */
#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10))
/* MSI-X Table entry addr upper reg 0 - RW */
#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10))
/* MSI-X Table entry message reg 0 - RW */
#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10))
/* MSI-X Table entry vector ctrl reg 0 - RW */
#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10))
/* Redirection Table - RW Array */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
#define E1000_REGISTER(a, reg) reg
#define wr32(reg, value) (writel(value, hw->hw_addr + reg))
#define rd32(reg) (readl(hw->hw_addr + reg))
#define wrfl() ((void)rd32(E1000_STATUS))
#define array_wr32(reg, offset, value) \
(writel(value, hw->hw_addr + reg + ((offset) << 2)))
#define array_rd32(reg, offset) \
(readl(hw->hw_addr + reg + ((offset) << 2)))
#endif

300
drivers/net/igb/igb.h Normal file
View file

@ -0,0 +1,300 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
Copyright(c) 2007 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information:
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/
/* Linux PRO/1000 Ethernet Driver main header file */
#ifndef _IGB_H_
#define _IGB_H_
#include "e1000_mac.h"
#include "e1000_82575.h"
struct igb_adapter;
/* Interrupt defines */
#define IGB_MAX_TX_CLEAN 72
#define IGB_MIN_DYN_ITR 3000
#define IGB_MAX_DYN_ITR 96000
#define IGB_START_ITR 6000
#define IGB_DYN_ITR_PACKET_THRESHOLD 2
#define IGB_DYN_ITR_LENGTH_LOW 200
#define IGB_DYN_ITR_LENGTH_HIGH 1000
/* TX/RX descriptor defines */
#define IGB_DEFAULT_TXD 256
#define IGB_MIN_TXD 80
#define IGB_MAX_TXD 4096
#define IGB_DEFAULT_RXD 256
#define IGB_MIN_RXD 80
#define IGB_MAX_RXD 4096
#define IGB_DEFAULT_ITR 3 /* dynamic */
#define IGB_MAX_ITR_USECS 10000
#define IGB_MIN_ITR_USECS 10
/* Transmit and receive queues */
#define IGB_MAX_RX_QUEUES 4
/* RX descriptor control thresholds.
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
* descriptors available in its onboard memory.
* Setting this to 0 disables RX descriptor prefetch.
* HTHRESH - MAC will only prefetch if there are at least this many descriptors
* available in host memory.
* If PTHRESH is 0, this should also be 0.
* WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
* descriptors until either it has this many to write back, or the
* ITR timer expires.
*/
#define IGB_RX_PTHRESH 16
#define IGB_RX_HTHRESH 8
#define IGB_RX_WTHRESH 1
/* this is the size past which hardware will drop packets when setting LPE=0 */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
/* Supported Rx Buffer Sizes */
#define IGB_RXBUFFER_128 128 /* Used for packet split */
#define IGB_RXBUFFER_256 256 /* Used for packet split */
#define IGB_RXBUFFER_512 512
#define IGB_RXBUFFER_1024 1024
#define IGB_RXBUFFER_2048 2048
#define IGB_RXBUFFER_4096 4096
#define IGB_RXBUFFER_8192 8192
#define IGB_RXBUFFER_16384 16384
/* Packet Buffer allocations */
/* How many Tx Descriptors do we need to call netif_wake_queue ? */
#define IGB_TX_QUEUE_WAKE 16
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define IGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#define AUTO_ALL_MODES 0
#define IGB_EEPROM_APME 0x0400
#ifndef IGB_MASTER_SLAVE
/* Switch to override PHY master/slave setting */
#define IGB_MASTER_SLAVE e1000_ms_hw_default
#endif
#define IGB_MNG_VLAN_NONE -1
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */
struct igb_buffer {
struct sk_buff *skb;
dma_addr_t dma;
union {
/* TX */
struct {
unsigned long time_stamp;
u32 length;
};
/* RX */
struct {
struct page *page;
u64 page_dma;
};
};
};
struct igb_queue_stats {
u64 packets;
u64 bytes;
};
struct igb_ring {
struct igb_adapter *adapter; /* backlink */
void *desc; /* descriptor ring memory */
dma_addr_t dma; /* phys address of the ring */
unsigned int size; /* length of desc. ring in bytes */
unsigned int count; /* number of desc. in the ring */
u16 next_to_use;
u16 next_to_clean;
u16 head;
u16 tail;
struct igb_buffer *buffer_info; /* array of buffer info structs */
u32 eims_value;
u32 itr_val;
u16 itr_register;
u16 cpu;
unsigned int total_bytes;
unsigned int total_packets;
union {
/* TX */
struct {
spinlock_t tx_clean_lock;
spinlock_t tx_lock;
bool detect_tx_hung;
};
/* RX */
struct {
/* arrays of page information for packet split */
struct sk_buff *pending_skb;
int pending_skb_page;
int no_itr_adjust;
struct igb_queue_stats rx_stats;
struct napi_struct napi;
};
};
char name[IFNAMSIZ + 5];
};
#define IGB_DESC_UNUSED(R) \
((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
(R)->next_to_clean - (R)->next_to_use - 1)
#define E1000_RX_DESC_ADV(R, i) \
(&(((union e1000_adv_rx_desc *)((R).desc))[i]))
#define E1000_TX_DESC_ADV(R, i) \
(&(((union e1000_adv_tx_desc *)((R).desc))[i]))
#define E1000_TX_CTXTDESC_ADV(R, i) \
(&(((struct e1000_adv_tx_context_desc *)((R).desc))[i]))
#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
#define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc)
#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
/* board specific private data structure */
struct igb_adapter {
struct timer_list watchdog_timer;
struct timer_list phy_info_timer;
struct vlan_group *vlgrp;
u16 mng_vlan_id;
u32 bd_number;
u32 rx_buffer_len;
u32 wol;
u32 en_mng_pt;
u16 link_speed;
u16 link_duplex;
unsigned int total_tx_bytes;
unsigned int total_tx_packets;
unsigned int total_rx_bytes;
unsigned int total_rx_packets;
/* Interrupt Throttle Rate */
u32 itr;
u32 itr_setting;
u16 tx_itr;
u16 rx_itr;
int set_itr;
struct work_struct reset_task;
struct work_struct watchdog_task;
bool fc_autoneg;
u8 tx_timeout_factor;
struct timer_list blink_timer;
unsigned long led_status;
/* TX */
struct igb_ring *tx_ring; /* One per active queue */
unsigned int restart_queue;
unsigned long tx_queue_len;
u32 txd_cmd;
u32 gotc;
u64 gotc_old;
u64 tpt_old;
u64 colc_old;
u32 tx_timeout_count;
/* RX */
struct igb_ring *rx_ring; /* One per active queue */
int num_tx_queues;
int num_rx_queues;
u64 hw_csum_err;
u64 hw_csum_good;
u64 rx_hdr_split;
u32 alloc_rx_buff_failed;
bool rx_csum;
u32 gorc;
u64 gorc_old;
u16 rx_ps_hdr_size;
u32 max_frame_size;
u32 min_frame_size;
/* OS defined structs */
struct net_device *netdev;
struct napi_struct napi;
struct pci_dev *pdev;
struct net_device_stats net_stats;
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
struct e1000_hw_stats stats;
struct e1000_phy_info phy_info;
struct e1000_phy_stats phy_stats;
u32 test_icr;
struct igb_ring test_tx_ring;
struct igb_ring test_rx_ring;
int msg_enable;
struct msix_entry *msix_entries;
u32 eims_enable_mask;
/* to not mess up cache alignment, always add to the bottom */
unsigned long state;
unsigned int msi_enabled;
u32 eeprom_wol;
};
enum e1000_state_t {
__IGB_TESTING,
__IGB_RESETTING,
__IGB_DOWN
};
enum igb_boards {
board_82575,
};
extern char igb_driver_name[];
extern char igb_driver_version[];
extern char *igb_get_hw_dev_name(struct e1000_hw *hw);
extern int igb_up(struct igb_adapter *);
extern void igb_down(struct igb_adapter *);
extern void igb_reinit_locked(struct igb_adapter *);
extern void igb_reset(struct igb_adapter *);
extern int igb_set_spd_dplx(struct igb_adapter *, u16);
extern int igb_setup_tx_resources(struct igb_adapter *, struct igb_ring *);
extern int igb_setup_rx_resources(struct igb_adapter *, struct igb_ring *);
extern void igb_update_stats(struct igb_adapter *);
extern void igb_set_ethtool_ops(struct net_device *);
#endif /* _IGB_H_ */

File diff suppressed because it is too large Load diff

4138
drivers/net/igb/igb_main.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -34,9 +34,9 @@
IPG_AC_DMA | IPG_AC_FIFO | IPG_AC_NETWORK | IPG_AC_HOST | \
IPG_AC_AUTO_INIT)
#define ipg_w32(val32,reg) iowrite32((val32), ioaddr + (reg))
#define ipg_w16(val16,reg) iowrite16((val16), ioaddr + (reg))
#define ipg_w8(val8,reg) iowrite8((val8), ioaddr + (reg))
#define ipg_w32(val32, reg) iowrite32((val32), ioaddr + (reg))
#define ipg_w16(val16, reg) iowrite16((val16), ioaddr + (reg))
#define ipg_w8(val8, reg) iowrite8((val8), ioaddr + (reg))
#define ipg_r32(reg) ioread32(ioaddr + (reg))
#define ipg_r16(reg) ioread16(ioaddr + (reg))
@ -51,24 +51,25 @@ enum {
#define DRV_NAME "ipg"
MODULE_AUTHOR("IC Plus Corp. 2003");
MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver "
DrvVer);
MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver");
MODULE_LICENSE("GPL");
//variable record -- index by leading revision/length
//Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
/*
* Variable record -- index by leading revision/length
* Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
*/
static unsigned short DefaultPhyParam[] = {
// 11/12/03 IP1000A v1-3 rev=0x40
/* 11/12/03 IP1000A v1-3 rev=0x40 */
/*--------------------------------------------------------------------------
(0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6,
31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7, 9, 0x0700,
--------------------------------------------------------------------------*/
// 12/17/03 IP1000A v1-4 rev=0x40
/* 12/17/03 IP1000A v1-4 rev=0x40 */
(0x4000 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
0x0000,
30, 0x005e, 9, 0x0700,
// 01/09/04 IP1000A v1-5 rev=0x41
/* 01/09/04 IP1000A v1-5 rev=0x41 */
(0x4100 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
0x0000,
30, 0x005e, 9, 0x0700,
@ -188,7 +189,7 @@ static void send_end(void __iomem *ioaddr, u8 phyctrlpolarity)
phyctrlpolarity) & IPG_PC_RSVD_MASK, PHY_CTRL);
}
static u16 read_phy_bit(void __iomem * ioaddr, u8 phyctrlpolarity)
static u16 read_phy_bit(void __iomem *ioaddr, u8 phyctrlpolarity)
{
u16 bit_data;
@ -205,7 +206,7 @@ static u16 read_phy_bit(void __iomem * ioaddr, u8 phyctrlpolarity)
* Read a register from the Physical Layer device located
* on the IPG NIC, using the IPG PHYCTRL register.
*/
static int mdio_read(struct net_device * dev, int phy_id, int phy_reg)
static int mdio_read(struct net_device *dev, int phy_id, int phy_reg)
{
void __iomem *ioaddr = ipg_ioaddr(dev);
/*
@ -374,7 +375,6 @@ static void mdio_write(struct net_device *dev, int phy_id, int phy_reg, int val)
}
}
/* Set LED_Mode JES20040127EEPROM */
static void ipg_set_led_mode(struct net_device *dev)
{
struct ipg_nic_private *sp = netdev_priv(dev);
@ -384,19 +384,18 @@ static void ipg_set_led_mode(struct net_device *dev)
mode = ipg_r32(ASIC_CTRL);
mode &= ~(IPG_AC_LED_MODE_BIT_1 | IPG_AC_LED_MODE | IPG_AC_LED_SPEED);
if ((sp->LED_Mode & 0x03) > 1)
if ((sp->led_mode & 0x03) > 1)
mode |= IPG_AC_LED_MODE_BIT_1; /* Write Asic Control Bit 29 */
if ((sp->LED_Mode & 0x01) == 1)
if ((sp->led_mode & 0x01) == 1)
mode |= IPG_AC_LED_MODE; /* Write Asic Control Bit 14 */
if ((sp->LED_Mode & 0x08) == 8)
if ((sp->led_mode & 0x08) == 8)
mode |= IPG_AC_LED_SPEED; /* Write Asic Control Bit 27 */
ipg_w32(mode, ASIC_CTRL);
}
/* Set PHYSet JES20040127EEPROM */
static void ipg_set_phy_set(struct net_device *dev)
{
struct ipg_nic_private *sp = netdev_priv(dev);
@ -405,7 +404,7 @@ static void ipg_set_phy_set(struct net_device *dev)
physet = ipg_r8(PHY_SET);
physet &= ~(IPG_PS_MEM_LENB9B | IPG_PS_MEM_LEN9 | IPG_PS_NON_COMPDET);
physet |= ((sp->LED_Mode & 0x70) >> 4);
physet |= ((sp->led_mode & 0x70) >> 4);
ipg_w8(physet, PHY_SET);
}
@ -415,7 +414,7 @@ static int ipg_reset(struct net_device *dev, u32 resetflags)
* register as specified by the 'resetflags' input
* parameter.
*/
void __iomem *ioaddr = ipg_ioaddr(dev); //JES20040127EEPROM:
void __iomem *ioaddr = ipg_ioaddr(dev);
unsigned int timeout_count = 0;
IPG_DEBUG_MSG("_reset\n");
@ -430,10 +429,10 @@ static int ipg_reset(struct net_device *dev, u32 resetflags)
if (++timeout_count > IPG_AC_RESET_TIMEOUT)
return -ETIME;
}
/* Set LED Mode in Asic Control JES20040127EEPROM */
/* Set LED Mode in Asic Control */
ipg_set_led_mode(dev);
/* Set PHYSet Register Value JES20040127EEPROM */
/* Set PHYSet Register Value */
ipg_set_phy_set(dev);
return 0;
}
@ -551,7 +550,7 @@ static int ipg_config_autoneg(struct net_device *dev)
printk("\n");
} else {
/* Configure IPG for half duplex operation. */
printk(KERN_INFO "%s: setting half duplex, "
printk(KERN_INFO "%s: setting half duplex, "
"no TX flow control, no RX flow control.\n", dev->name);
mac_ctrl_val &= ~IPG_MC_DUPLEX_SELECT_FD &
@ -736,7 +735,7 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry)
skb = netdev_alloc_skb(dev, IPG_RXSUPPORT_SIZE + NET_IP_ALIGN);
if (!skb) {
sp->RxBuff[entry] = NULL;
sp->rx_buff[entry] = NULL;
return -ENOMEM;
}
@ -749,7 +748,7 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry)
skb->dev = dev;
/* Save the address of the sk_buff structure. */
sp->RxBuff[entry] = skb;
sp->rx_buff[entry] = skb;
rxfd->frag_info = cpu_to_le64(pci_map_single(sp->pdev, skb->data,
sp->rx_buf_sz, PCI_DMA_FROMDEVICE));
@ -772,12 +771,12 @@ static int init_rfdlist(struct net_device *dev)
for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
struct ipg_rx *rxfd = sp->rxd + i;
if (sp->RxBuff[i]) {
if (sp->rx_buff[i]) {
pci_unmap_single(sp->pdev,
le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
IPG_DEV_KFREE_SKB(sp->RxBuff[i]);
sp->RxBuff[i] = NULL;
dev_kfree_skb_irq(sp->rx_buff[i]);
sp->rx_buff[i] = NULL;
}
/* Clear out the RFS field. */
@ -828,9 +827,9 @@ static void init_tfdlist(struct net_device *dev)
txfd->tfc = cpu_to_le64(IPG_TFC_TFDDONE);
if (sp->TxBuff[i]) {
IPG_DEV_KFREE_SKB(sp->TxBuff[i]);
sp->TxBuff[i] = NULL;
if (sp->tx_buff[i]) {
dev_kfree_skb_irq(sp->tx_buff[i]);
sp->tx_buff[i] = NULL;
}
txfd->next_desc = cpu_to_le64(sp->txd_map +
@ -847,7 +846,7 @@ static void init_tfdlist(struct net_device *dev)
ipg_w32((u32) sp->txd_map, TFD_LIST_PTR_0);
ipg_w32(0x00000000, TFD_LIST_PTR_1);
sp->ResetCurrentTFD = 1;
sp->reset_current_tfd = 1;
}
/*
@ -865,7 +864,7 @@ static void ipg_nic_txfree(struct net_device *dev)
dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH;
for (released = 0; released < pending; released++) {
struct sk_buff *skb = sp->TxBuff[dirty];
struct sk_buff *skb = sp->tx_buff[dirty];
struct ipg_tx *txfd = sp->txd + dirty;
IPG_DEBUG_MSG("TFC = %16.16lx\n", (unsigned long) txfd->tfc);
@ -884,9 +883,9 @@ static void ipg_nic_txfree(struct net_device *dev)
le64_to_cpu(txfd->frag_info) & ~IPG_TFI_FRAGLEN,
skb->len, PCI_DMA_TODEVICE);
IPG_DEV_KFREE_SKB(skb);
dev_kfree_skb_irq(skb);
sp->TxBuff[dirty] = NULL;
sp->tx_buff[dirty] = NULL;
}
dirty = (dirty + 1) % IPG_TFDLIST_LENGTH;
}
@ -1059,7 +1058,7 @@ static int ipg_nic_rxrestore(struct net_device *dev)
unsigned int entry = dirty % IPG_RFDLIST_LENGTH;
/* rx_copybreak may poke hole here and there. */
if (sp->RxBuff[entry])
if (sp->rx_buff[entry])
continue;
/* Generate a new receive buffer to replace the
@ -1083,22 +1082,22 @@ static int ipg_nic_rxrestore(struct net_device *dev)
#ifdef JUMBO_FRAME
/* use jumboindex and jumbosize to control jumbo frame status
initial status is jumboindex=-1 and jumbosize=0
1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done.
2. jumboindex != -1 and jumbosize != 0 : jumbo frame is not over size and receiving
3. jumboindex = -1 and jumbosize != 0 : jumbo frame is over size, already dump
previous receiving and need to continue dumping the current one
*/
* initial status is jumboindex=-1 and jumbosize=0
* 1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done.
* 2. jumboindex != -1 and jumbosize != 0 : jumbo frame is not over size and receiving
* 3. jumboindex = -1 and jumbosize != 0 : jumbo frame is over size, already dump
* previous receiving and need to continue dumping the current one
*/
enum {
NormalPacket,
ErrorPacket
NORMAL_PACKET,
ERROR_PACKET
};
enum {
Frame_NoStart_NoEnd = 0,
Frame_WithStart = 1,
Frame_WithEnd = 10,
Frame_WithStart_WithEnd = 11
FRAME_NO_START_NO_END = 0,
FRAME_WITH_START = 1,
FRAME_WITH_END = 10,
FRAME_WITH_START_WITH_END = 11
};
inline void ipg_nic_rx_free_skb(struct net_device *dev)
@ -1106,14 +1105,14 @@ inline void ipg_nic_rx_free_skb(struct net_device *dev)
struct ipg_nic_private *sp = netdev_priv(dev);
unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH;
if (sp->RxBuff[entry]) {
if (sp->rx_buff[entry]) {
struct ipg_rx *rxfd = sp->rxd + entry;
pci_unmap_single(sp->pdev,
le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN),
sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
IPG_DEV_KFREE_SKB(sp->RxBuff[entry]);
sp->RxBuff[entry] = NULL;
dev_kfree_skb_irq(sp->rx_buff[entry]);
sp->rx_buff[entry] = NULL;
}
}
@ -1121,12 +1120,12 @@ inline int ipg_nic_rx_check_frame_type(struct net_device *dev)
{
struct ipg_nic_private *sp = netdev_priv(dev);
struct ipg_rx *rxfd = sp->rxd + (sp->rx_current % IPG_RFDLIST_LENGTH);
int type = Frame_NoStart_NoEnd;
int type = FRAME_NO_START_NO_END;
if (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMESTART)
type += Frame_WithStart;
type += FRAME_WITH_START;
if (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMEEND)
type += Frame_WithEnd;
type += FRAME_WITH_END;
return type;
}
@ -1175,43 +1174,43 @@ inline int ipg_nic_rx_check_error(struct net_device *dev)
* buffer since it is erroneous and we will
* not pass it to higher layer processes.
*/
if (sp->RxBuff[entry]) {
if (sp->rx_buff[entry]) {
pci_unmap_single(sp->pdev,
le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN),
sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
IPG_DEV_KFREE_SKB(sp->RxBuff[entry]);
sp->RxBuff[entry] = NULL;
dev_kfree_skb_irq(sp->rx_buff[entry]);
sp->rx_buff[entry] = NULL;
}
return ErrorPacket;
return ERROR_PACKET;
}
return NormalPacket;
return NORMAL_PACKET;
}
static void ipg_nic_rx_with_start_and_end(struct net_device *dev,
struct ipg_nic_private *sp,
struct ipg_rx *rxfd, unsigned entry)
{
struct SJumbo *jumbo = &sp->Jumbo;
struct ipg_jumbo *jumbo = &sp->jumbo;
struct sk_buff *skb;
int framelen;
if (jumbo->FoundStart) {
IPG_DEV_KFREE_SKB(jumbo->skb);
jumbo->FoundStart = 0;
jumbo->CurrentSize = 0;
if (jumbo->found_start) {
dev_kfree_skb_irq(jumbo->skb);
jumbo->found_start = 0;
jumbo->current_size = 0;
jumbo->skb = NULL;
}
// 1: found error, 0 no error
if (ipg_nic_rx_check_error(dev) != NormalPacket)
/* 1: found error, 0 no error */
if (ipg_nic_rx_check_error(dev) != NORMAL_PACKET)
return;
skb = sp->RxBuff[entry];
skb = sp->rx_buff[entry];
if (!skb)
return;
// accept this frame and send to upper layer
/* accept this frame and send to upper layer */
framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;
if (framelen > IPG_RXFRAG_SIZE)
framelen = IPG_RXFRAG_SIZE;
@ -1221,39 +1220,39 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev,
skb->ip_summed = CHECKSUM_NONE;
netif_rx(skb);
dev->last_rx = jiffies;
sp->RxBuff[entry] = NULL;
sp->rx_buff[entry] = NULL;
}
static void ipg_nic_rx_with_start(struct net_device *dev,
struct ipg_nic_private *sp,
struct ipg_rx *rxfd, unsigned entry)
{
struct SJumbo *jumbo = &sp->Jumbo;
struct ipg_jumbo *jumbo = &sp->jumbo;
struct pci_dev *pdev = sp->pdev;
struct sk_buff *skb;
// 1: found error, 0 no error
if (ipg_nic_rx_check_error(dev) != NormalPacket)
/* 1: found error, 0 no error */
if (ipg_nic_rx_check_error(dev) != NORMAL_PACKET)
return;
// accept this frame and send to upper layer
skb = sp->RxBuff[entry];
/* accept this frame and send to upper layer */
skb = sp->rx_buff[entry];
if (!skb)
return;
if (jumbo->FoundStart)
IPG_DEV_KFREE_SKB(jumbo->skb);
if (jumbo->found_start)
dev_kfree_skb_irq(jumbo->skb);
pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN),
sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
skb_put(skb, IPG_RXFRAG_SIZE);
jumbo->FoundStart = 1;
jumbo->CurrentSize = IPG_RXFRAG_SIZE;
jumbo->found_start = 1;
jumbo->current_size = IPG_RXFRAG_SIZE;
jumbo->skb = skb;
sp->RxBuff[entry] = NULL;
sp->rx_buff[entry] = NULL;
dev->last_rx = jiffies;
}
@ -1261,27 +1260,27 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
struct ipg_nic_private *sp,
struct ipg_rx *rxfd, unsigned entry)
{
struct SJumbo *jumbo = &sp->Jumbo;
struct ipg_jumbo *jumbo = &sp->jumbo;
//1: found error, 0 no error
if (ipg_nic_rx_check_error(dev) == NormalPacket) {
struct sk_buff *skb = sp->RxBuff[entry];
/* 1: found error, 0 no error */
if (ipg_nic_rx_check_error(dev) == NORMAL_PACKET) {
struct sk_buff *skb = sp->rx_buff[entry];
if (!skb)
return;
if (jumbo->FoundStart) {
if (jumbo->found_start) {
int framelen, endframelen;
framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;
endframeLen = framelen - jumbo->CurrentSize;
endframeLen = framelen - jumbo->current_size;
/*
if (framelen > IPG_RXFRAG_SIZE)
framelen=IPG_RXFRAG_SIZE;
*/
if (framelen > IPG_RXSUPPORT_SIZE)
IPG_DEV_KFREE_SKB(jumbo->skb);
dev_kfree_skb_irq(jumbo->skb);
else {
memcpy(skb_put(jumbo->skb, endframeLen),
skb->data, endframeLen);
@ -1295,15 +1294,15 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
}
dev->last_rx = jiffies;
jumbo->FoundStart = 0;
jumbo->CurrentSize = 0;
jumbo->found_start = 0;
jumbo->current_size = 0;
jumbo->skb = NULL;
ipg_nic_rx_free_skb(dev);
} else {
IPG_DEV_KFREE_SKB(jumbo->skb);
jumbo->FoundStart = 0;
jumbo->CurrentSize = 0;
dev_kfree_skb_irq(jumbo->skb);
jumbo->found_start = 0;
jumbo->current_size = 0;
jumbo->skb = NULL;
}
}
@ -1312,16 +1311,16 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev,
struct ipg_nic_private *sp,
struct ipg_rx *rxfd, unsigned entry)
{
struct SJumbo *jumbo = &sp->Jumbo;
struct ipg_jumbo *jumbo = &sp->jumbo;
//1: found error, 0 no error
if (ipg_nic_rx_check_error(dev) == NormalPacket) {
struct sk_buff *skb = sp->RxBuff[entry];
/* 1: found error, 0 no error */
if (ipg_nic_rx_check_error(dev) == NORMAL_PACKET) {
struct sk_buff *skb = sp->rx_buff[entry];
if (skb) {
if (jumbo->FoundStart) {
jumbo->CurrentSize += IPG_RXFRAG_SIZE;
if (jumbo->CurrentSize <= IPG_RXSUPPORT_SIZE) {
if (jumbo->found_start) {
jumbo->current_size += IPG_RXFRAG_SIZE;
if (jumbo->current_size <= IPG_RXSUPPORT_SIZE) {
memcpy(skb_put(jumbo->skb,
IPG_RXFRAG_SIZE),
skb->data, IPG_RXFRAG_SIZE);
@ -1331,9 +1330,9 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev,
ipg_nic_rx_free_skb(dev);
}
} else {
IPG_DEV_KFREE_SKB(jumbo->skb);
jumbo->FoundStart = 0;
jumbo->CurrentSize = 0;
dev_kfree_skb_irq(jumbo->skb);
jumbo->found_start = 0;
jumbo->current_size = 0;
jumbo->skb = NULL;
}
}
@ -1355,16 +1354,16 @@ static int ipg_nic_rx(struct net_device *dev)
break;
switch (ipg_nic_rx_check_frame_type(dev)) {
case Frame_WithStart_WithEnd:
case FRAME_WITH_START_WITH_END:
ipg_nic_rx_with_start_and_end(dev, tp, rxfd, entry);
break;
case Frame_WithStart:
case FRAME_WITH_START:
ipg_nic_rx_with_start(dev, tp, rxfd, entry);
break;
case Frame_WithEnd:
case FRAME_WITH_END:
ipg_nic_rx_with_end(dev, tp, rxfd, entry);
break;
case Frame_NoStart_NoEnd:
case FRAME_NO_START_NO_END:
ipg_nic_rx_no_start_no_end(dev, tp, rxfd, entry);
break;
}
@ -1403,7 +1402,7 @@ static int ipg_nic_rx(struct net_device *dev)
for (i = 0; i < IPG_MAXRFDPROCESS_COUNT; i++, curr++) {
unsigned int entry = curr % IPG_RFDLIST_LENGTH;
struct sk_buff *skb = sp->RxBuff[entry];
struct sk_buff *skb = sp->rx_buff[entry];
unsigned int framelen;
rxfd = sp->rxd + entry;
@ -1472,7 +1471,7 @@ static int ipg_nic_rx(struct net_device *dev)
le64_to_cpu(info) & ~IPG_RFI_FRAGLEN,
sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
IPG_DEV_KFREE_SKB(skb);
dev_kfree_skb_irq(skb);
}
} else {
@ -1484,35 +1483,13 @@ static int ipg_nic_rx(struct net_device *dev)
/* Set the buffer's protocol field to Ethernet. */
skb->protocol = eth_type_trans(skb, dev);
/* If the frame contains an IP/TCP/UDP frame,
* determine if upper layer must check IP/TCP/UDP
* checksums.
*
* NOTE: DO NOT RELY ON THE TCP/UDP CHECKSUM
* VERIFICATION FOR SILICON REVISIONS B3
* AND EARLIER!
*
if ((le64_to_cpu(rxfd->rfs &
(IPG_RFS_TCPDETECTED | IPG_RFS_UDPDETECTED |
IPG_RFS_IPDETECTED))) &&
!(le64_to_cpu(rxfd->rfs &
(IPG_RFS_TCPERROR | IPG_RFS_UDPERROR |
IPG_RFS_IPERROR)))) {
* Indicate IP checksums were performed
* by the IPG.
*
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
/* The IPG encountered an error with (or
* there were no) IP/TCP/UDP checksums.
* This may or may not indicate an invalid
* IP/TCP/UDP frame was received. Let the
* upper layer decide.
*/
{
/* The IPG encountered an error with (or
* there were no) IP/TCP/UDP checksums.
* This may or may not indicate an invalid
* IP/TCP/UDP frame was received. Let the
* upper layer decide.
*/
skb->ip_summed = CHECKSUM_NONE;
}
skb->ip_summed = CHECKSUM_NONE;
/* Hand off frame for higher layer processing.
* The function netif_rx() releases the sk_buff
@ -1527,7 +1504,7 @@ static int ipg_nic_rx(struct net_device *dev)
}
/* Assure RX buffer is not reused by IPG. */
sp->RxBuff[entry] = NULL;
sp->rx_buff[entry] = NULL;
}
/*
@ -1561,15 +1538,15 @@ static int ipg_nic_rx(struct net_device *dev)
* buffer since it is erroneous and we will
* not pass it to higher layer processes.
*/
if (sp->RxBuff[entry]) {
if (sp->rx_buff[entry]) {
pci_unmap_single(sp->pdev,
le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
IPG_DEV_KFREE_SKB(sp->RxBuff[entry]);
dev_kfree_skb_irq(sp->rx_buff[entry]);
}
/* Assure RX buffer is not reused by IPG. */
sp->RxBuff[entry] = NULL;
sp->rx_buff[entry] = NULL;
}
sp->rx_current = curr;
@ -1735,11 +1712,11 @@ static void ipg_rx_clear(struct ipg_nic_private *sp)
unsigned int i;
for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
if (sp->RxBuff[i]) {
if (sp->rx_buff[i]) {
struct ipg_rx *rxfd = sp->rxd + i;
IPG_DEV_KFREE_SKB(sp->RxBuff[i]);
sp->RxBuff[i] = NULL;
dev_kfree_skb_irq(sp->rx_buff[i]);
sp->rx_buff[i] = NULL;
pci_unmap_single(sp->pdev,
le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
@ -1752,16 +1729,16 @@ static void ipg_tx_clear(struct ipg_nic_private *sp)
unsigned int i;
for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
if (sp->TxBuff[i]) {
if (sp->tx_buff[i]) {
struct ipg_tx *txfd = sp->txd + i;
pci_unmap_single(sp->pdev,
le64_to_cpu(txfd->frag_info) & ~IPG_TFI_FRAGLEN,
sp->TxBuff[i]->len, PCI_DMA_TODEVICE);
sp->tx_buff[i]->len, PCI_DMA_TODEVICE);
IPG_DEV_KFREE_SKB(sp->TxBuff[i]);
dev_kfree_skb_irq(sp->tx_buff[i]);
sp->TxBuff[i] = NULL;
sp->tx_buff[i] = NULL;
}
}
}
@ -1832,9 +1809,9 @@ static int ipg_nic_open(struct net_device *dev)
#ifdef JUMBO_FRAME
/* initialize JUMBO Frame control variable */
sp->Jumbo.FoundStart = 0;
sp->Jumbo.CurrentSize = 0;
sp->Jumbo.skb = 0;
sp->jumbo.found_start = 0;
sp->jumbo.current_size = 0;
sp->jumbo.skb = 0;
dev->mtu = IPG_TXFRAG_SIZE;
#endif
@ -1909,14 +1886,14 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (sp->tenmbpsmode)
netif_stop_queue(dev);
if (sp->ResetCurrentTFD) {
sp->ResetCurrentTFD = 0;
if (sp->reset_current_tfd) {
sp->reset_current_tfd = 0;
entry = 0;
}
txfd = sp->txd + entry;
sp->TxBuff[entry] = skb;
sp->tx_buff[entry] = skb;
/* Clear all TFC fields, except TFDDONE. */
txfd->tfc = cpu_to_le64(IPG_TFC_TFDDONE);
@ -2029,7 +2006,6 @@ static void ipg_set_phy_default_param(unsigned char rev,
}
}
/* JES20040127EEPROM */
static int read_eeprom(struct net_device *dev, int eep_addr)
{
void __iomem *ioaddr = ipg_ioaddr(dev);
@ -2096,9 +2072,9 @@ static int ipg_hw_init(struct net_device *dev)
unsigned int i;
int rc;
/* Read/Write and Reset EEPROM Value Jesse20040128EEPROM_VALUE */
/* Read/Write and Reset EEPROM Value */
/* Read LED Mode Configuration from EEPROM */
sp->LED_Mode = read_eeprom(dev, 6);
sp->led_mode = read_eeprom(dev, 6);
/* Reset all functions within the IPG. Do not assert
* RST_OUT as not compatible with some PHYs.
@ -2202,7 +2178,7 @@ static struct ethtool_ops ipg_ethtool_ops = {
.nway_reset = ipg_nway_reset,
};
static void ipg_remove(struct pci_dev *pdev)
static void __devexit ipg_remove(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct ipg_nic_private *sp = netdev_priv(dev);

View file

@ -1,20 +1,8 @@
/*
*
* ipg.h
*
* Include file for Gigabit Ethernet device driver for Network
* Interface Cards (NICs) utilizing the Tamarack Microelectronics
* Inc. IPG Gigabit or Triple Speed Ethernet Media Access
* Controller.
*
* Craig Rich
* Sundance Technology, Inc.
* 1485 Saratoga Avenue
* Suite 200
* San Jose, CA 95129
* 408 873 4117
* www.sundanceti.com
* craig_rich@sundanceti.com
*/
#ifndef __LINUX_IPG_H
#define __LINUX_IPG_H
@ -35,11 +23,6 @@
#include <linux/skbuff.h>
#include <linux/version.h>
#include <asm/bitops.h>
/*#include <asm/spinlock.h>*/
#define DrvVer "2.09d"
#define IPG_DEV_KFREE_SKB(skb) dev_kfree_skb_irq(skb)
/*
* Constants
@ -68,7 +51,7 @@
/* I/O register offsets. */
enum ipg_regs {
DMA_CTRL = 0x00,
RX_DMA_STATUS = 0x08, // Unused + reserved
RX_DMA_STATUS = 0x08, /* Unused + reserved */
TFD_LIST_PTR_0 = 0x10,
TFD_LIST_PTR_1 = 0x14,
TX_DMA_BURST_THRESH = 0x18,
@ -81,22 +64,22 @@ enum ipg_regs {
RX_DMA_POLL_PERIOD = 0x26,
DEBUG_CTRL = 0x2c,
ASIC_CTRL = 0x30,
FIFO_CTRL = 0x38, // Unused
FIFO_CTRL = 0x38, /* Unused */
FLOW_OFF_THRESH = 0x3c,
FLOW_ON_THRESH = 0x3e,
EEPROM_DATA = 0x48,
EEPROM_CTRL = 0x4a,
EXPROM_ADDR = 0x4c, // Unused
EXPROM_DATA = 0x50, // Unused
WAKE_EVENT = 0x51, // Unused
COUNTDOWN = 0x54, // Unused
EXPROM_ADDR = 0x4c, /* Unused */
EXPROM_DATA = 0x50, /* Unused */
WAKE_EVENT = 0x51, /* Unused */
COUNTDOWN = 0x54, /* Unused */
INT_STATUS_ACK = 0x5a,
INT_ENABLE = 0x5c,
INT_STATUS = 0x5e, // Unused
INT_STATUS = 0x5e, /* Unused */
TX_STATUS = 0x60,
MAC_CTRL = 0x6c,
VLAN_TAG = 0x70, // Unused
PHY_SET = 0x75, // JES20040127EEPROM
VLAN_TAG = 0x70, /* Unused */
PHY_SET = 0x75,
PHY_CTRL = 0x76,
STATION_ADDRESS_0 = 0x78,
STATION_ADDRESS_1 = 0x7a,
@ -107,11 +90,11 @@ enum ipg_regs {
HASHTABLE_1 = 0x90,
RMON_STATISTICS_MASK = 0x98,
STATISTICS_MASK = 0x9c,
RX_JUMBO_FRAMES = 0xbc, // Unused
TCP_CHECKSUM_ERRORS = 0xc0, // Unused
IP_CHECKSUM_ERRORS = 0xc2, // Unused
UDP_CHECKSUM_ERRORS = 0xc4, // Unused
TX_JUMBO_FRAMES = 0xf4 // Unused
RX_JUMBO_FRAMES = 0xbc, /* Unused */
TCP_CHECKSUM_ERRORS = 0xc0, /* Unused */
IP_CHECKSUM_ERRORS = 0xc2, /* Unused */
UDP_CHECKSUM_ERRORS = 0xc4, /* Unused */
TX_JUMBO_FRAMES = 0xf4 /* Unused */
};
/* Ethernet MIB statistic register offsets. */
@ -329,7 +312,7 @@ enum ipg_regs {
#define IPG_RM_RECEIVEMULTICASTHASH 0x10
#define IPG_RM_RECEIVEIPMULTICAST 0x20
/* PhySet JES20040127EEPROM*/
/* PhySet */
#define IPG_PS_MEM_LENB9B 0x01
#define IPG_PS_MEM_LEN9 0x02
#define IPG_PS_NON_COMPDET 0x04
@ -386,8 +369,8 @@ enum ipg_regs {
#define IPG_AC_RST_OUT 0x01000000
#define IPG_AC_INT_REQUEST 0x02000000
#define IPG_AC_RESET_BUSY 0x04000000
#define IPG_AC_LED_SPEED 0x08000000 //JES20040127EEPROM
#define IPG_AC_LED_MODE_BIT_1 0x20000000 //JES20040127EEPROM
#define IPG_AC_LED_SPEED 0x08000000
#define IPG_AC_LED_MODE_BIT_1 0x20000000
/* EepromCtrl */
#define IPG_EC_RSVD_MASK 0x83FF
@ -490,38 +473,34 @@ enum ipg_regs {
* Tune
*/
/* Miscellaneous Constants. */
#define TRUE 1
#define FALSE 0
/* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS append on TX. */
#define IPG_APPEND_FCS_ON_TX TRUE
#define IPG_APPEND_FCS_ON_TX 1
/* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS strip on RX. */
#define IPG_STRIP_FCS_ON_RX TRUE
#define IPG_STRIP_FCS_ON_RX 1
/* Assign IPG_DROP_ON_RX_ETH_ERRORS > 0 to drop RX frames with
* Ethernet errors.
*/
#define IPG_DROP_ON_RX_ETH_ERRORS TRUE
#define IPG_DROP_ON_RX_ETH_ERRORS 1
/* Assign IPG_INSERT_MANUAL_VLAN_TAG > 0 to insert VLAN tags manually
* (via TFC).
*/
#define IPG_INSERT_MANUAL_VLAN_TAG FALSE
#define IPG_INSERT_MANUAL_VLAN_TAG 0
/* Assign IPG_ADD_IPCHECKSUM_ON_TX > 0 for auto IP checksum on TX. */
#define IPG_ADD_IPCHECKSUM_ON_TX FALSE
#define IPG_ADD_IPCHECKSUM_ON_TX 0
/* Assign IPG_ADD_TCPCHECKSUM_ON_TX > 0 for auto TCP checksum on TX.
* DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER.
*/
#define IPG_ADD_TCPCHECKSUM_ON_TX FALSE
#define IPG_ADD_TCPCHECKSUM_ON_TX 0
/* Assign IPG_ADD_UDPCHECKSUM_ON_TX > 0 for auto UDP checksum on TX.
* DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER.
*/
#define IPG_ADD_UDPCHECKSUM_ON_TX FALSE
#define IPG_ADD_UDPCHECKSUM_ON_TX 0
/* If inserting VLAN tags manually, assign the IPG_MANUAL_VLAN_xx
* constants as desired.
@ -611,7 +590,7 @@ enum ipg_regs {
* Define larger if expecting jumbo frames.
*/
#ifdef JUMBO_FRAME
//IPG_TXFRAG_SIZE must <= 0x2b00, or TX will crash
/* IPG_TXFRAG_SIZE must <= 0x2b00, or TX will crash */
#define IPG_TXFRAG_SIZE JUMBO_FRAME_SIZE
#endif
@ -619,7 +598,7 @@ enum ipg_regs {
* Define larger if expecting jumbo frames.
*/
#ifdef JUMBO_FRAME
//4088=4096-8
/* 4088 = 4096 - 8 */
#define IPG_RXFRAG_SIZE __IPG_RXFRAG_SIZE
#define IPG_RXSUPPORT_SIZE IPG_MAX_RXFRAME_SIZE
#else
@ -647,9 +626,9 @@ enum ipg_regs {
#define IPG_MINUSEDRFDSTOFREE 0x80
/* specify the jumbo frame maximum size
* per unit is 0x600 (the RxBuffer size that one RFD can carry)
* per unit is 0x600 (the rx_buffer size that one RFD can carry)
*/
#define MAX_JUMBOSIZE 0x8 // max is 12K
#define MAX_JUMBOSIZE 0x8 /* max is 12K */
/* Key register values loaded at driver start up. */
@ -753,8 +732,7 @@ enum ipg_regs {
* Miscellaneous macros.
*/
/* Marco for printing debug statements.
# define IPG_DDEBUG_MSG(args...) printk(KERN_DEBUG "IPG: " ## args) */
/* Marco for printing debug statements. */
#ifdef IPG_DEBUG
# define IPG_DEBUG_MSG(args...)
# define IPG_DDEBUG_MSG(args...) printk(KERN_DEBUG "IPG: " args)
@ -789,11 +767,12 @@ struct ipg_rx {
__le64 frag_info;
};
struct SJumbo {
int FoundStart;
int CurrentSize;
struct ipg_jumbo {
int found_start;
int current_size;
struct sk_buff *skb;
};
/* Structure of IPG NIC specific data. */
struct ipg_nic_private {
void __iomem *ioaddr;
@ -801,15 +780,14 @@ struct ipg_nic_private {
struct ipg_rx *rxd;
dma_addr_t txd_map;
dma_addr_t rxd_map;
struct sk_buff *TxBuff[IPG_TFDLIST_LENGTH];
struct sk_buff *RxBuff[IPG_RFDLIST_LENGTH];
struct sk_buff *tx_buff[IPG_TFDLIST_LENGTH];
struct sk_buff *rx_buff[IPG_RFDLIST_LENGTH];
unsigned int tx_current;
unsigned int tx_dirty;
unsigned int rx_current;
unsigned int rx_dirty;
// Add by Grace 2005/05/19
#ifdef JUMBO_FRAME
struct SJumbo Jumbo;
struct ipg_jumbo jumbo;
#endif
unsigned int rx_buf_sz;
struct pci_dev *pdev;
@ -818,13 +796,12 @@ struct ipg_nic_private {
spinlock_t lock;
int tenmbpsmode;
/*Jesse20040128EEPROM_VALUE */
u16 LED_Mode;
u16 led_mode;
u16 station_addr[3]; /* Station Address in EEPROM Reg 0x10..0x12 */
struct mutex mii_mutex;
struct mii_if_info mii_if;
int ResetCurrentTFD;
int reset_current_tfd;
#ifdef IPG_DEBUG
int RFDlistendCount;
int RFDListCheckedCount;

View file

@ -190,147 +190,6 @@ config KS959_DONGLE
To compile it as a module, choose M here: the module will be called
ks959-sir.
comment "Old SIR device drivers"
config IRPORT_SIR
tristate "IrPORT (IrDA serial driver)"
depends on IRDA && BROKEN_ON_SMP
---help---
Say Y here if you want to build support for the IrPORT IrDA device
driver. To compile it as a module, choose M here: the module will be
called irport. IrPORT can be used instead of IrTTY and sometimes
this can be better. One example is if your IrDA port does not
have echo-canceling, which will work OK with IrPORT since this
driver is working in half-duplex mode only. You don't need to use
irattach with IrPORT, but you just insert it the same way as FIR
drivers (insmod irport io=0x3e8 irq=11). Notice that IrPORT is a
SIR device driver which means that speed is limited to 115200 bps.
If unsure, say Y.
comment "Old Serial dongle support"
config DONGLE_OLD
bool "Old Serial dongle support"
depends on IRPORT_SIR && BROKEN_ON_SMP
help
Say Y here if you have an infrared device that connects to your
computer's serial port. These devices are called dongles. Then say Y
or M to the driver for your particular dongle below.
Note that the answer to this question won't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about serial dongles.
config ESI_DONGLE_OLD
tristate "ESI JetEye PC dongle"
depends on DONGLE_OLD && IRDA
help
Say Y here if you want to build support for the Extended Systems
JetEye PC dongle. To compile it as a module, choose M here. The ESI
dongle attaches to the normal 9-pin serial port connector, and can
currently only be used by IrTTY. To activate support for ESI
dongles you will have to start irattach like this:
"irattach -d esi".
config ACTISYS_DONGLE_OLD
tristate "ACTiSYS IR-220L and IR220L+ dongle"
depends on DONGLE_OLD && IRDA
help
Say Y here if you want to build support for the ACTiSYS IR-220L and
IR220L+ dongles. To compile it as a module, choose M here. The
ACTiSYS dongles attaches to the normal 9-pin serial port connector,
and can currently only be used by IrTTY. To activate support for
ACTiSYS dongles you will have to start irattach like this:
"irattach -d actisys" or "irattach -d actisys+".
config TEKRAM_DONGLE_OLD
tristate "Tekram IrMate 210B dongle"
depends on DONGLE_OLD && IRDA
help
Say Y here if you want to build support for the Tekram IrMate 210B
dongle. To compile it as a module, choose M here. The Tekram dongle
attaches to the normal 9-pin serial port connector, and can
currently only be used by IrTTY. To activate support for Tekram
dongles you will have to start irattach like this:
"irattach -d tekram".
config GIRBIL_DONGLE_OLD
tristate "Greenwich GIrBIL dongle"
depends on DONGLE_OLD && IRDA
help
Say Y here if you want to build support for the Greenwich GIrBIL
dongle. To compile it as a module, choose M here. The Greenwich
dongle attaches to the normal 9-pin serial port connector, and can
currently only be used by IrTTY. To activate support for Greenwich
dongles you will have to insert "irattach -d girbil" in the
/etc/irda/drivers script.
config LITELINK_DONGLE_OLD
tristate "Parallax LiteLink dongle"
depends on DONGLE_OLD && IRDA
help
Say Y here if you want to build support for the Parallax Litelink
dongle. To compile it as a module, choose M here. The Parallax
dongle attaches to the normal 9-pin serial port connector, and can
currently only be used by IrTTY. To activate support for Parallax
dongles you will have to start irattach like this:
"irattach -d litelink".
config MCP2120_DONGLE_OLD
tristate "Microchip MCP2120"
depends on DONGLE_OLD && IRDA
help
Say Y here if you want to build support for the Microchip MCP2120
dongle. To compile it as a module, choose M here. The MCP2120 dongle
attaches to the normal 9-pin serial port connector, and can
currently only be used by IrTTY. To activate support for MCP2120
dongles you will have to insert "irattach -d mcp2120" in the
/etc/irda/drivers script.
You must build this dongle yourself. For more information see:
<http://www.eyetap.org/~tangf/irda_sir_linux.html>
config OLD_BELKIN_DONGLE_OLD
tristate "Old Belkin dongle"
depends on DONGLE_OLD && IRDA
help
Say Y here if you want to build support for the Adaptec Airport 1000
and 2000 dongles. To compile it as a module, choose M here: the module
will be called old_belkin. Some information is contained in the
comments at the top of <file:drivers/net/irda/old_belkin.c>.
config ACT200L_DONGLE_OLD
tristate "ACTiSYS IR-200L dongle (EXPERIMENTAL)"
depends on DONGLE_OLD && EXPERIMENTAL && IRDA
help
Say Y here if you want to build support for the ACTiSYS IR-200L
dongle. To compile it as a module, choose M here. The ACTiSYS
IR-200L dongle attaches to the normal 9-pin serial port connector,
and can currently only be used by IrTTY. To activate support for
ACTiSYS IR-200L dongles you will have to start irattach like this:
"irattach -d act200l".
config MA600_DONGLE_OLD
tristate "Mobile Action MA600 dongle (EXPERIMENTAL)"
depends on DONGLE_OLD && EXPERIMENTAL && IRDA
---help---
Say Y here if you want to build support for the Mobile Action MA600
dongle. To compile it as a module, choose M here. The MA600 dongle
attaches to the normal 9-pin serial port connector, and can
currently only be tested on IrCOMM. To activate support for MA600
dongles you will have to insert "irattach -d ma600" in the
/etc/irda/drivers script. Note: irutils 0.9.15 requires no
modification. irutils 0.9.9 needs modification. For more
information, download the following tar gzip file.
There is a pre-compiled module on
<http://engsvr.ust.hk/~eetwl95/ma600.html>
config EP7211_IR
tristate "EP7211 I/R support"
depends on DONGLE_OLD && ARCH_EP7211 && IRDA
comment "FIR device drivers"
config USB_IRDA

View file

@ -5,8 +5,6 @@
# Rewritten to use lists instead of if-statements.
#
# Old SIR drivers
obj-$(CONFIG_IRPORT_SIR) += irport.o
# FIR drivers
obj-$(CONFIG_USB_IRDA) += irda-usb.o
obj-$(CONFIG_SIGMATEL_FIR) += stir4200.o
@ -20,21 +18,10 @@ obj-$(CONFIG_VLSI_FIR) += vlsi_ir.o
obj-$(CONFIG_VIA_FIR) += via-ircc.o
obj-$(CONFIG_PXA_FICP) += pxaficp_ir.o
obj-$(CONFIG_MCS_FIR) += mcs7780.o
# Old dongle drivers for old SIR drivers
obj-$(CONFIG_ESI_DONGLE_OLD) += esi.o
obj-$(CONFIG_TEKRAM_DONGLE_OLD) += tekram.o
obj-$(CONFIG_ACTISYS_DONGLE_OLD) += actisys.o
obj-$(CONFIG_GIRBIL_DONGLE_OLD) += girbil.o
obj-$(CONFIG_LITELINK_DONGLE_OLD) += litelink.o
obj-$(CONFIG_OLD_BELKIN_DONGLE_OLD) += old_belkin.o
obj-$(CONFIG_MCP2120_DONGLE_OLD) += mcp2120.o
obj-$(CONFIG_ACT200L_DONGLE_OLD) += act200l.o
obj-$(CONFIG_MA600_DONGLE_OLD) += ma600.o
obj-$(CONFIG_EP7211_IR) += ep7211_ir.o
obj-$(CONFIG_AU1000_FIR) += au1k_ir.o
# New SIR drivers
# SIR drivers
obj-$(CONFIG_IRTTY_SIR) += irtty-sir.o sir-dev.o
# New dongles drivers for new SIR drivers
# dongle drivers for SIR drivers
obj-$(CONFIG_ESI_DONGLE) += esi-sir.o
obj-$(CONFIG_TEKRAM_DONGLE) += tekram-sir.o
obj-$(CONFIG_ACTISYS_DONGLE) += actisys-sir.o

View file

@ -1,297 +0,0 @@
/*********************************************************************
*
* Filename: act200l.c
* Version: 0.8
* Description: Implementation for the ACTiSYS ACT-IR200L dongle
* Status: Experimental.
* Author: SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp>
* Created at: Fri Aug 3 17:35:42 2001
* Modified at: Fri Aug 17 10:22:40 2001
* Modified by: SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp>
*
* Copyright (c) 2001 SHIMIZU Takuya, 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.
*
********************************************************************/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/tty.h>
#include <linux/init.h>
#include <net/irda/irda.h>
#include <net/irda/irda_device.h>
static int act200l_reset(struct irda_task *task);
static void act200l_open(dongle_t *self, struct qos_info *qos);
static void act200l_close(dongle_t *self);
static int act200l_change_speed(struct irda_task *task);
/* Regsiter 0: Control register #1 */
#define ACT200L_REG0 0x00
#define ACT200L_TXEN 0x01 /* Enable transmitter */
#define ACT200L_RXEN 0x02 /* Enable receiver */
/* Register 1: Control register #2 */
#define ACT200L_REG1 0x10
#define ACT200L_LODB 0x01 /* Load new baud rate count value */
#define ACT200L_WIDE 0x04 /* Expand the maximum allowable pulse */
/* Register 4: Output Power register */
#define ACT200L_REG4 0x40
#define ACT200L_OP0 0x01 /* Enable LED1C output */
#define ACT200L_OP1 0x02 /* Enable LED2C output */
#define ACT200L_BLKR 0x04
/* Register 5: Receive Mode register */
#define ACT200L_REG5 0x50
#define ACT200L_RWIDL 0x01 /* fixed 1.6us pulse mode */
/* Register 6: Receive Sensitivity register #1 */
#define ACT200L_REG6 0x60
#define ACT200L_RS0 0x01 /* receive threshold bit 0 */
#define ACT200L_RS1 0x02 /* receive threshold bit 1 */
/* Register 7: Receive Sensitivity register #2 */
#define ACT200L_REG7 0x70
#define ACT200L_ENPOS 0x04 /* Ignore the falling edge */
/* Register 8,9: Baud Rate Dvider register #1,#2 */
#define ACT200L_REG8 0x80
#define ACT200L_REG9 0x90
#define ACT200L_2400 0x5f
#define ACT200L_9600 0x17
#define ACT200L_19200 0x0b
#define ACT200L_38400 0x05
#define ACT200L_57600 0x03
#define ACT200L_115200 0x01
/* Register 13: Control register #3 */
#define ACT200L_REG13 0xd0
#define ACT200L_SHDW 0x01 /* Enable access to shadow registers */
/* Register 15: Status register */
#define ACT200L_REG15 0xf0
/* Register 21: Control register #4 */
#define ACT200L_REG21 0x50
#define ACT200L_EXCK 0x02 /* Disable clock output driver */
#define ACT200L_OSCL 0x04 /* oscillator in low power, medium accuracy mode */
static struct dongle_reg dongle = {
.type = IRDA_ACT200L_DONGLE,
.open = act200l_open,
.close = act200l_close,
.reset = act200l_reset,
.change_speed = act200l_change_speed,
.owner = THIS_MODULE,
};
static int __init act200l_init(void)
{
return irda_device_register_dongle(&dongle);
}
static void __exit act200l_cleanup(void)
{
irda_device_unregister_dongle(&dongle);
}
static void act200l_open(dongle_t *self, struct qos_info *qos)
{
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
/* Power on the dongle */
self->set_dtr_rts(self->dev, TRUE, TRUE);
/* Set the speeds we can accept */
qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
qos->min_turn_time.bits = 0x03;
}
static void act200l_close(dongle_t *self)
{
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
/* Power off the dongle */
self->set_dtr_rts(self->dev, FALSE, FALSE);
}
/*
* Function act200l_change_speed (dev, speed)
*
* Set the speed for the ACTiSYS ACT-IR200L type dongle.
*
*/
static int act200l_change_speed(struct irda_task *task)
{
dongle_t *self = (dongle_t *) task->instance;
__u32 speed = (__u32) task->param;
__u8 control[3];
int ret = 0;
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
self->speed_task = task;
switch (task->state) {
case IRDA_TASK_INIT:
if (irda_task_execute(self, act200l_reset, NULL, task,
(void *) speed))
{
/* Dongle need more time to reset */
irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
/* Give reset 1 sec to finish */
ret = msecs_to_jiffies(1000);
}
break;
case IRDA_TASK_CHILD_WAIT:
IRDA_WARNING("%s(), resetting dongle timed out!\n",
__FUNCTION__);
ret = -1;
break;
case IRDA_TASK_CHILD_DONE:
/* Clear DTR and set RTS to enter command mode */
self->set_dtr_rts(self->dev, FALSE, TRUE);
switch (speed) {
case 9600:
default:
control[0] = ACT200L_REG8 | (ACT200L_9600 & 0x0f);
control[1] = ACT200L_REG9 | ((ACT200L_9600 >> 4) & 0x0f);
break;
case 19200:
control[0] = ACT200L_REG8 | (ACT200L_19200 & 0x0f);
control[1] = ACT200L_REG9 | ((ACT200L_19200 >> 4) & 0x0f);
break;
case 38400:
control[0] = ACT200L_REG8 | (ACT200L_38400 & 0x0f);
control[1] = ACT200L_REG9 | ((ACT200L_38400 >> 4) & 0x0f);
break;
case 57600:
control[0] = ACT200L_REG8 | (ACT200L_57600 & 0x0f);
control[1] = ACT200L_REG9 | ((ACT200L_57600 >> 4) & 0x0f);
break;
case 115200:
control[0] = ACT200L_REG8 | (ACT200L_115200 & 0x0f);
control[1] = ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f);
break;
}
control[2] = ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE;
/* Write control bytes */
self->write(self->dev, control, 3);
irda_task_next_state(task, IRDA_TASK_WAIT);
ret = msecs_to_jiffies(5);
break;
case IRDA_TASK_WAIT:
/* Go back to normal mode */
self->set_dtr_rts(self->dev, TRUE, TRUE);
irda_task_next_state(task, IRDA_TASK_DONE);
self->speed_task = NULL;
break;
default:
IRDA_ERROR("%s(), unknown state %d\n",
__FUNCTION__, task->state);
irda_task_next_state(task, IRDA_TASK_DONE);
self->speed_task = NULL;
ret = -1;
break;
}
return ret;
}
/*
* Function act200l_reset (driver)
*
* Reset the ACTiSYS ACT-IR200L type dongle.
*/
static int act200l_reset(struct irda_task *task)
{
dongle_t *self = (dongle_t *) task->instance;
__u8 control[9] = {
ACT200L_REG15,
ACT200L_REG13 | ACT200L_SHDW,
ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL,
ACT200L_REG13,
ACT200L_REG7 | ACT200L_ENPOS,
ACT200L_REG6 | ACT200L_RS0 | ACT200L_RS1,
ACT200L_REG5 | ACT200L_RWIDL,
ACT200L_REG4 | ACT200L_OP0 | ACT200L_OP1 | ACT200L_BLKR,
ACT200L_REG0 | ACT200L_TXEN | ACT200L_RXEN
};
int ret = 0;
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
self->reset_task = task;
switch (task->state) {
case IRDA_TASK_INIT:
/* Power on the dongle */
self->set_dtr_rts(self->dev, TRUE, TRUE);
irda_task_next_state(task, IRDA_TASK_WAIT1);
ret = msecs_to_jiffies(50);
break;
case IRDA_TASK_WAIT1:
/* Reset the dongle : set RTS low for 25 ms */
self->set_dtr_rts(self->dev, TRUE, FALSE);
irda_task_next_state(task, IRDA_TASK_WAIT2);
ret = msecs_to_jiffies(50);
break;
case IRDA_TASK_WAIT2:
/* Clear DTR and set RTS to enter command mode */
self->set_dtr_rts(self->dev, FALSE, TRUE);
/* Write control bytes */
self->write(self->dev, control, 9);
irda_task_next_state(task, IRDA_TASK_WAIT3);
ret = msecs_to_jiffies(15);
break;
case IRDA_TASK_WAIT3:
/* Go back to normal mode */
self->set_dtr_rts(self->dev, TRUE, TRUE);
irda_task_next_state(task, IRDA_TASK_DONE);
self->reset_task = NULL;
break;
default:
IRDA_ERROR("%s(), unknown state %d\n",
__FUNCTION__, task->state);
irda_task_next_state(task, IRDA_TASK_DONE);
self->reset_task = NULL;
ret = -1;
break;
}
return ret;
}
MODULE_AUTHOR("SHIMIZU Takuya <[email protected]>");
MODULE_DESCRIPTION("ACTiSYS ACT-IR200L dongle driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("irda-dongle-10"); /* IRDA_ACT200L_DONGLE */
/*
* Function init_module (void)
*
* Initialize ACTiSYS ACT-IR200L module
*
*/
module_init(act200l_init);
/*
* Function cleanup_module (void)
*
* Cleanup ACTiSYS ACT-IR200L module
*
*/
module_exit(act200l_cleanup);

View file

@ -1,288 +0,0 @@
/*********************************************************************
*
* Filename: actisys.c
* Version: 1.0
* Description: Implementation for the ACTiSYS IR-220L and IR-220L+
* dongles
* Status: Beta.
* Authors: Dag Brattli <dagb@cs.uit.no> (initially)
* Jean Tourrilhes <jt@hpl.hp.com> (new version)
* Created at: Wed Oct 21 20:02:35 1998
* Modified at: Fri Dec 17 09:10:43 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
* Copyright (c) 1999 Jean Tourrilhes
*
* 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.
*
* Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
********************************************************************/
/*
* Changelog
*
* 0.8 -> 0.9999 - Jean
* o New initialisation procedure : much safer and correct
* o New procedure the change speed : much faster and simpler
* o Other cleanups & comments
* Thanks to Lichen Wang @ Actisys for his excellent help...
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/tty.h>
#include <linux/init.h>
#include <net/irda/irda.h>
#include <net/irda/irda_device.h>
/*
* Define the timing of the pulses we send to the dongle (to reset it, and
* to toggle speeds). Basically, the limit here is the propagation speed of
* the signals through the serial port, the dongle being much faster. Any
* serial port support 115 kb/s, so we are sure that pulses 8.5 us wide can
* go through cleanly . If you are on the wild side, you can try to lower
* this value (Actisys recommended me 2 us, and 0 us work for me on a P233!)
*/
#define MIN_DELAY 10 /* 10 us to be on the conservative side */
static int actisys_change_speed(struct irda_task *task);
static int actisys_reset(struct irda_task *task);
static void actisys_open(dongle_t *self, struct qos_info *qos);
static void actisys_close(dongle_t *self);
/* These are the baudrates supported, in the order available */
/* Note : the 220L doesn't support 38400, but we will fix that below */
static __u32 baud_rates[] = { 9600, 19200, 57600, 115200, 38400 };
#define MAX_SPEEDS 5
static struct dongle_reg dongle = {
.type = IRDA_ACTISYS_DONGLE,
.open = actisys_open,
.close = actisys_close,
.reset = actisys_reset,
.change_speed = actisys_change_speed,
.owner = THIS_MODULE,
};
static struct dongle_reg dongle_plus = {
.type = IRDA_ACTISYS_PLUS_DONGLE,
.open = actisys_open,
.close = actisys_close,
.reset = actisys_reset,
.change_speed = actisys_change_speed,
.owner = THIS_MODULE,
};
/*
* Function actisys_change_speed (task)
*
* There is two model of Actisys dongle we are dealing with,
* the 220L and 220L+. At this point, only irattach knows with
* kind the user has requested (it was an argument on irattach
* command line).
* So, we register a dongle of each sort and let irattach
* pick the right one...
*/
static int __init actisys_init(void)
{
int ret;
/* First, register an Actisys 220L dongle */
ret = irda_device_register_dongle(&dongle);
if (ret < 0)
return ret;
/* Now, register an Actisys 220L+ dongle */
ret = irda_device_register_dongle(&dongle_plus);
if (ret < 0) {
irda_device_unregister_dongle(&dongle);
return ret;
}
return 0;
}
static void __exit actisys_cleanup(void)
{
/* We have to remove both dongles */
irda_device_unregister_dongle(&dongle);
irda_device_unregister_dongle(&dongle_plus);
}
static void actisys_open(dongle_t *self, struct qos_info *qos)
{
/* Power on the dongle */
self->set_dtr_rts(self->dev, TRUE, TRUE);
/* Set the speeds we can accept */
qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
/* Remove support for 38400 if this is not a 220L+ dongle */
if (self->issue->type == IRDA_ACTISYS_DONGLE)
qos->baud_rate.bits &= ~IR_38400;
qos->min_turn_time.bits = 0x7f; /* Needs 0.01 ms */
}
static void actisys_close(dongle_t *self)
{
/* Power off the dongle */
self->set_dtr_rts(self->dev, FALSE, FALSE);
}
/*
* Function actisys_change_speed (task)
*
* Change speed of the ACTiSYS IR-220L and IR-220L+ type IrDA dongles.
* To cycle through the available baud rates, pulse RTS low for a few us.
*
* First, we reset the dongle to always start from a known state.
* Then, we cycle through the speeds by pulsing RTS low and then up.
* The dongle allow us to pulse quite fast, se we can set speed in one go,
* which is must faster ( < 100 us) and less complex than what is found
* in some other dongle drivers...
* Note that even if the new speed is the same as the current speed,
* we reassert the speed. This make sure that things are all right,
* and it's fast anyway...
* By the way, this function will work for both type of dongles,
* because the additional speed is at the end of the sequence...
*/
static int actisys_change_speed(struct irda_task *task)
{
dongle_t *self = (dongle_t *) task->instance;
__u32 speed = (__u32) task->param; /* Target speed */
int ret = 0;
int i = 0;
IRDA_DEBUG(4, "%s(), speed=%d (was %d)\n", __FUNCTION__, speed,
self->speed);
/* Go to a known state by reseting the dongle */
/* Reset the dongle : set DTR low for 10 us */
self->set_dtr_rts(self->dev, FALSE, TRUE);
udelay(MIN_DELAY);
/* Go back to normal mode (we are now at 9600 b/s) */
self->set_dtr_rts(self->dev, TRUE, TRUE);
/*
* Now, we can set the speed requested. Send RTS pulses until we
* reach the target speed
*/
for (i=0; i<MAX_SPEEDS; i++) {
if (speed == baud_rates[i]) {
self->speed = baud_rates[i];
break;
}
/* Make sure previous pulse is finished */
udelay(MIN_DELAY);
/* Set RTS low for 10 us */
self->set_dtr_rts(self->dev, TRUE, FALSE);
udelay(MIN_DELAY);
/* Set RTS high for 10 us */
self->set_dtr_rts(self->dev, TRUE, TRUE);
}
/* Check if life is sweet... */
if (i >= MAX_SPEEDS)
ret = -1; /* This should not happen */
/* Basta lavoro, on se casse d'ici... */
irda_task_next_state(task, IRDA_TASK_DONE);
return ret;
}
/*
* Function actisys_reset (task)
*
* Reset the Actisys type dongle. Warning, this function must only be
* called with a process context!
*
* We need to do two things in this function :
* o first make sure that the dongle is in a state where it can operate
* o second put the dongle in a know state
*
* The dongle is powered of the RTS and DTR lines. In the dongle, there
* is a big capacitor to accommodate the current spikes. This capacitor
* takes a least 50 ms to be charged. In theory, the Bios set those lines
* up, so by the time we arrive here we should be set. It doesn't hurt
* to be on the conservative side, so we will wait...
* Then, we set the speed to 9600 b/s to get in a known state (see in
* change_speed for details). It is needed because the IrDA stack
* has tried to set the speed immediately after our first return,
* so before we can be sure the dongle is up and running.
*/
static int actisys_reset(struct irda_task *task)
{
dongle_t *self = (dongle_t *) task->instance;
int ret = 0;
IRDA_ASSERT(task != NULL, return -1;);
self->reset_task = task;
switch (task->state) {
case IRDA_TASK_INIT:
/* Set both DTR & RTS to power up the dongle */
/* In theory redundant with power up in actisys_open() */
self->set_dtr_rts(self->dev, TRUE, TRUE);
/* Sleep 50 ms to make sure capacitor is charged */
ret = msecs_to_jiffies(50);
irda_task_next_state(task, IRDA_TASK_WAIT);
break;
case IRDA_TASK_WAIT:
/* Reset the dongle : set DTR low for 10 us */
self->set_dtr_rts(self->dev, FALSE, TRUE);
udelay(MIN_DELAY);
/* Go back to normal mode */
self->set_dtr_rts(self->dev, TRUE, TRUE);
irda_task_next_state(task, IRDA_TASK_DONE);
self->reset_task = NULL;
self->speed = 9600; /* That's the default */
break;
default:
IRDA_ERROR("%s(), unknown state %d\n",
__FUNCTION__, task->state);
irda_task_next_state(task, IRDA_TASK_DONE);
self->reset_task = NULL;
ret = -1;
break;
}
return ret;
}
MODULE_AUTHOR("Dag Brattli <[email protected]> - Jean Tourrilhes <[email protected]>");
MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("irda-dongle-2"); /* IRDA_ACTISYS_DONGLE */
MODULE_ALIAS("irda-dongle-3"); /* IRDA_ACTISYS_PLUS_DONGLE */
/*
* Function init_module (void)
*
* Initialize Actisys module
*
*/
module_init(actisys_init);
/*
* Function cleanup_module (void)
*
* Cleanup Actisys module
*
*/
module_exit(actisys_cleanup);

View file

@ -1,125 +0,0 @@
/*
* IR port driver for the Cirrus Logic EP7211 processor.
*
* Copyright 2001, Blue Mug Inc. All rights reserved.
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/tty.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <net/irda/irda.h>
#include <net/irda/irda_device.h>
#include <asm/io.h>
#include <asm/hardware.h>
#define MIN_DELAY 25 /* 15 us, but wait a little more to be sure */
#define MAX_DELAY 10000 /* 1 ms */
static void ep7211_ir_open(dongle_t *self, struct qos_info *qos);
static void ep7211_ir_close(dongle_t *self);
static int ep7211_ir_change_speed(struct irda_task *task);
static int ep7211_ir_reset(struct irda_task *task);
static DEFINE_SPINLOCK(ep7211_lock);
static struct dongle_reg dongle = {
.type = IRDA_EP7211_IR,
.open = ep7211_ir_open,
.close = ep7211_ir_close,
.reset = ep7211_ir_reset,
.change_speed = ep7211_ir_change_speed,
.owner = THIS_MODULE,
};
static void ep7211_ir_open(dongle_t *self, struct qos_info *qos)
{
unsigned int syscon1, flags;
spin_lock_irqsave(&ep7211_lock, flags);
/* Turn on the SIR encoder. */
syscon1 = clps_readl(SYSCON1);
syscon1 |= SYSCON1_SIREN;
clps_writel(syscon1, SYSCON1);
/* XXX: We should disable modem status interrupts on the first
UART (interrupt #14). */
spin_unlock_irqrestore(&ep7211_lock, flags);
}
static void ep7211_ir_close(dongle_t *self)
{
unsigned int syscon1, flags;
spin_lock_irqsave(&ep7211_lock, flags);
/* Turn off the SIR encoder. */
syscon1 = clps_readl(SYSCON1);
syscon1 &= ~SYSCON1_SIREN;
clps_writel(syscon1, SYSCON1);
/* XXX: If we've disabled the modem status interrupts, we should
reset them back to their original state. */
spin_unlock_irqrestore(&ep7211_lock, flags);
}
/*
* Function ep7211_ir_change_speed (task)
*
* Change speed of the EP7211 I/R port. We don't really have to do anything
* for the EP7211 as long as the rate is being changed at the serial port
* level.
*/
static int ep7211_ir_change_speed(struct irda_task *task)
{
irda_task_next_state(task, IRDA_TASK_DONE);
return 0;
}
/*
* Function ep7211_ir_reset (task)
*
* Reset the EP7211 I/R. We don't really have to do anything.
*
*/
static int ep7211_ir_reset(struct irda_task *task)
{
irda_task_next_state(task, IRDA_TASK_DONE);
return 0;
}
/*
* Function ep7211_ir_init(void)
*
* Initialize EP7211 I/R module
*
*/
static int __init ep7211_ir_init(void)
{
return irda_device_register_dongle(&dongle);
}
/*
* Function ep7211_ir_cleanup(void)
*
* Cleanup EP7211 I/R module
*
*/
static void __exit ep7211_ir_cleanup(void)
{
irda_device_unregister_dongle(&dongle);
}
MODULE_AUTHOR("Jon McClintock <[email protected]>");
MODULE_DESCRIPTION("EP7211 I/R driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("irda-dongle-8"); /* IRDA_EP7211_IR */
module_init(ep7211_ir_init);
module_exit(ep7211_ir_cleanup);

Some files were not shown because too many files have changed in this diff Show more