Commit f5106b15 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.6

into ppc970.osdl.org:/home/torvalds/v2.5/linux
parents ad920594 5b4f4d19
......@@ -31,6 +31,7 @@ Verifying Bond Configuration
Frequently Asked Questions
High Availability
Promiscuous Sniffing notes
8021q VLAN support
Limitations
Resources and Links
......@@ -140,10 +141,6 @@ probeall bond0 eth0 eth1 bonding
Be careful not to reference bond0 itself at the end of the line, or modprobe
will die in an endless recursive loop.
To have device characteristics (such as MTU size) propagate to slave devices,
set the bond characteristics before enslaving the device. The characteristics
are propagated during the enslave process.
If running SNMP agents, the bonding driver should be loaded before any network
drivers participating in a bond. This requirement is due to the the interface
index (ipAdEntIfIndex) being associated to the first interface found with a
......@@ -601,7 +598,7 @@ Frequently Asked Questions
For ethernet cards not supporting MII status, the arp_interval and
arp_ip_target parameters must be specified for bonding to work
correctly. If packets have not been sent or received during the
specified arp_interval durration, an ARP request is sent to the
specified arp_interval duration, an ARP request is sent to the
targets to generate send and receive traffic. If after this
interval, either the successful send and/or receive count has not
incremented, the next slave in the sequence will become the active
......@@ -669,16 +666,8 @@ Frequently Asked Questions
that will be added.
To restore your slaves' MAC addresses, you need to detach them
from the bond (`ifenslave -d bond0 eth0'), set them down
(`ifconfig eth0 down'), unload the drivers (`rmmod 3c59x', for
example) and reload them to get the MAC addresses from their
eeproms. If the driver is shared by several devices, you need
to turn them all down. Another solution is to look for the MAC
address at boot time (dmesg or tail /var/log/messages) and to
reset it by hand with ifconfig :
# ifconfig eth0 down
# ifconfig eth0 hw ether 00:20:40:60:80:A0
from the bond (`ifenslave -d bond0 eth0'). The bonding driver will then
restore the MAC addresses that the slaves had before they were enslaved.
9. Which transmit polices can be used?
......@@ -843,7 +832,7 @@ point of failure" solution.
In this configuration, there is an ISL - Inter Switch Link (could be a trunk),
several servers (host1, host2 ...) attached to both switches each, and one or
more ports to the outside world (port3...). One an only one slave on each host
more ports to the outside world (port3...). One and only one slave on each host
is active at a time, while all links are still monitored (the system can
detect a failure of active and backup links).
......@@ -933,6 +922,41 @@ capacity aggregating; but it works fine for unnumbered interfaces;
just ignore all the warnings it emits.
8021q VLAN support
==================
It is possible to configure VLAN devices over a bond interface using the 8021q
driver. However, only packets coming from the 8021q driver and passing through
bonding will be tagged by default. Self generated packets, like bonding's
learning packets or ARP packets generated by either ALB mode or the ARP
monitor mechanism, are tagged internally by bonding itself. As a result,
bonding has to "learn" what VLAN IDs are configured on top of it, and it uses
those IDs to tag self generated packets.
For simplicity reasons, and to support the use of adapters that can do VLAN
hardware acceleration offloding, the bonding interface declares itself as
fully hardware offloaing capable, it gets the add_vid/kill_vid notifications
to gather the necessary information, and it propagates those actions to the
slaves.
In case of mixed adapter types, hardware accelerated tagged packets that should
go through an adapter that is not offloading capable are "un-accelerated" by the
bonding driver so the VLAN tag sits in the regular location.
VLAN interfaces *must* be added on top of a bonding interface only after
enslaving at least one slave. This is because until the first slave is added the
bonding interface has a HW address of 00:00:00:00:00:00, which will be copied by
the VLAN interface when it is created.
Notice that a problem would occur if all slaves are released from a bond that
still has VLAN interfaces on top of it. When later coming to add new slaves, the
bonding interface would get a HW address from the first slave, which might not
match that of the VLAN interfaces. It is recommended that either all VLANs are
removed and then re-added, or to manually set the bonding interface's HW
address so it matches the VLAN's. (Note: changing a VLAN interface's HW address
would set the underlying device -- i.e. the bonding interface -- to promiscouos
mode, which might not be what you want).
Limitations
===========
The main limitations are :
......
(C)Copyright 1999-2003 Marvell(R).
(C)Copyright 1999-2004 Marvell(R).
All rights reserved
===========================================================================
sk98lin.txt created 15-Dec-2003
sk98lin.txt created 13-Feb-2004
Readme File for sk98lin v6.21
Readme File for sk98lin v6.23
Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
This file contains
......
......@@ -1985,6 +1985,7 @@ config SK98LIN
- Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
- Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
- Allied Telesyn AT-2971T Gigabit Ethernet Adapter
- Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
- DGE-530T Gigabit Ethernet Adapter
- EG1032 v2 Instant Gigabit Network Adapter
- EG1064 v2 Instant Gigabit Network Adapter
......@@ -1996,6 +1997,7 @@ config SK98LIN
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
- Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
- Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
- Marvell RDK-8001 Adapter
- Marvell RDK-8002 Adapter
- Marvell RDK-8003 Adapter
......@@ -2007,6 +2009,7 @@ config SK98LIN
- Marvell RDK-8010 Adapter
- Marvell RDK-8011 Adapter
- Marvell RDK-8012 Adapter
- Marvell RDK-8052 Adapter
- Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
- Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
- N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
......
......@@ -2362,6 +2362,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
int agg_id;
int i;
struct ad_info ad_info;
int res = 1;
/* make sure that the slaves list will
* not change during tx
......@@ -2369,12 +2370,12 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
read_lock(&bond->lock);
if (!BOND_IS_OK(bond)) {
goto free_out;
goto out;
}
if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
goto free_out;
goto out;
}
slaves_in_agg = ad_info.ports;
......@@ -2383,7 +2384,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if (slaves_in_agg == 0) {
/*the aggregator is empty*/
printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
goto free_out;
goto out;
}
slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg;
......@@ -2401,7 +2402,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
if (slave_agg_no >= 0) {
printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
goto free_out;
goto out;
}
start_at = slave;
......@@ -2414,24 +2415,19 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
slave_agg_id = agg->aggregator_identifier;
}
if (SLAVE_IS_OK(slave) &&
agg && (slave_agg_id == agg_id)) {
skb->dev = slave->dev;
skb->priority = 1;
dev_queue_xmit(skb);
goto out;
if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
break;
}
}
out:
read_unlock(&bond->lock);
return 0;
free_out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
goto out;
}
read_unlock(&bond->lock);
return 0;
}
int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype)
......
......@@ -34,6 +34,9 @@
*
* 2003/12/30 - Amir Noam <amir.noam at intel dot com>
* - Fixed: Cannot remove and re-enslave the original active slave.
*
* 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
* - Add capability to tag self generated packets in ALB/TLB modes.
*/
//#define BONDING_DEBUG 1
......@@ -50,6 +53,7 @@
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_bonding.h>
#include <linux/if_vlan.h>
#include <net/ipx.h>
#include <net/arp.h>
#include <asm/byteorder.h>
......@@ -79,7 +83,7 @@
#define TLB_NULL_INDEX 0xffffffff
#define MAX_LP_RETRY 3
#define MAX_LP_BURST 3
/* rlb defs */
#define RLB_HASH_TABLE_SIZE 256
......@@ -498,13 +502,33 @@ static void rlb_update_client(struct rlb_client_info *client_info)
}
for (i = 0; i < RLB_ARP_BURST_SIZE; i++) {
arp_send(ARPOP_REPLY, ETH_P_ARP,
struct sk_buff *skb;
skb = arp_create(ARPOP_REPLY, ETH_P_ARP,
client_info->ip_dst,
client_info->slave->dev,
client_info->ip_src,
client_info->mac_dst,
client_info->slave->dev->dev_addr,
client_info->mac_dst);
if (!skb) {
printk(KERN_ERR DRV_NAME
": Error: failed to create an ARP packet\n");
continue;
}
skb->dev = client_info->slave->dev;
if (client_info->tag) {
skb = vlan_put_tag(skb, client_info->vlan_id);
if (!skb) {
printk(KERN_ERR DRV_NAME
": Error: failed to insert VLAN tag\n");
continue;
}
}
arp_xmit(skb);
}
}
......@@ -603,9 +627,10 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, u32 src_ip)
}
/* Caller must hold both bond and ptr locks for read */
struct slave *rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
struct arp_pkt *arp = (struct arp_pkt *)skb->nh.raw;
struct slave *assigned_slave;
struct rlb_client_info *client_info;
u32 hash_index = 0;
......@@ -661,6 +686,15 @@ struct slave *rlb_choose_channel(struct bonding *bond, struct arp_pkt *arp)
client_info->ntt = 0;
}
if (!list_empty(&bond->vlan_list)) {
unsigned short vlan_id;
int res = vlan_get_tag(skb, &vlan_id);
if (!res) {
client_info->tag = 1;
client_info->vlan_id = vlan_id;
}
}
if (!client_info->assigned) {
u32 prev_tbl_head = bond_info->rx_hashtbl_head;
bond_info->rx_hashtbl_head = hash_index;
......@@ -691,7 +725,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
/* the arp must be sent on the selected
* rx channel
*/
tx_slave = rlb_choose_channel(bond, arp);
tx_slave = rlb_choose_channel(skb, bond);
if (tx_slave) {
memcpy(arp->mac_src,tx_slave->dev->dev_addr, ETH_ALEN);
}
......@@ -702,7 +736,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
* When the arp reply is received the entry will be updated
* with the correct unicast address of the client.
*/
rlb_choose_channel(bond, arp);
rlb_choose_channel(skb, bond);
/* The ARP relpy packets must be delayed so that
* they can cancel out the influence of the ARP request.
......@@ -808,6 +842,40 @@ static void rlb_deinitialize(struct bonding *bond)
kfree(bond_info->rx_hashtbl);
bond_info->rx_hashtbl = NULL;
bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
_unlock_rx_hashtbl(bond);
}
static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
u32 curr_index;
_lock_rx_hashtbl(bond);
curr_index = bond_info->rx_hashtbl_head;
while (curr_index != RLB_NULL_INDEX) {
struct rlb_client_info *curr = &(bond_info->rx_hashtbl[curr_index]);
u32 next_index = bond_info->rx_hashtbl[curr_index].next;
u32 prev_index = bond_info->rx_hashtbl[curr_index].prev;
if (curr->tag && (curr->vlan_id == vlan_id)) {
if (curr_index == bond_info->rx_hashtbl_head) {
bond_info->rx_hashtbl_head = next_index;
}
if (prev_index != RLB_NULL_INDEX) {
bond_info->rx_hashtbl[prev_index].next = next_index;
}
if (next_index != RLB_NULL_INDEX) {
bond_info->rx_hashtbl[next_index].prev = prev_index;
}
rlb_init_table_entry(curr);
}
curr_index = next_index;
}
_unlock_rx_hashtbl(bond);
}
......@@ -816,6 +884,7 @@ static void rlb_deinitialize(struct bonding *bond)
static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
{
struct bonding *bond = bond_get_bond_by_slave(slave);
struct learning_pkt pkt;
int size = sizeof(struct learning_pkt);
int i;
......@@ -825,7 +894,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
pkt.type = __constant_htons(ETH_P_LOOP);
for (i = 0; i < MAX_LP_RETRY; i++) {
for (i = 0; i < MAX_LP_BURST; i++) {
struct sk_buff *skb;
char *data;
......@@ -843,6 +912,26 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
skb->priority = TC_PRIO_CONTROL;
skb->dev = slave->dev;
if (!list_empty(&bond->vlan_list)) {
struct vlan_entry *vlan;
vlan = bond_next_vlan(bond,
bond->alb_info.current_alb_vlan);
bond->alb_info.current_alb_vlan = vlan;
if (!vlan) {
kfree_skb(skb);
continue;
}
skb = vlan_put_tag(skb, vlan->vlan_id);
if (!skb) {
printk(KERN_ERR DRV_NAME
": Error: failed to insert VLAN tag\n");
continue;
}
}
dev_queue_xmit(skb);
}
}
......@@ -1193,6 +1282,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
int do_tx_balance = 1;
u32 hash_index = 0;
u8 *hash_start = NULL;
int res = 1;
/* make sure that the curr_active_slave and the slaves list do
* not change during tx
......@@ -1201,7 +1291,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
read_lock(&bond->curr_slave_lock);
if (!BOND_IS_OK(bond)) {
goto free_out;
goto out;
}
switch (ntohs(skb->protocol)) {
......@@ -1266,29 +1356,27 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
}
if (tx_slave && SLAVE_IS_OK(tx_slave)) {
skb->dev = tx_slave->dev;
if (tx_slave != bond->curr_active_slave) {
memcpy(eth_data->h_source,
tx_slave->dev->dev_addr,
ETH_ALEN);
}
dev_queue_xmit(skb);
res = bond_dev_queue_xmit(bond, skb, tx_slave->dev);
} else {
/* no suitable interface, frame not sent */
if (tx_slave) {
tlb_clear_slave(bond, tx_slave, 0);
}
goto free_out;
}
out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
read_unlock(&bond->curr_slave_lock);
read_unlock(&bond->lock);
return 0;
free_out:
dev_kfree_skb(skb);
goto out;
}
void bond_alb_monitor(struct bonding *bond)
......@@ -1589,3 +1677,15 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
return 0;
}
void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
{
if (bond->alb_info.current_alb_vlan &&
(bond->alb_info.current_alb_vlan->vlan_id == vlan_id)) {
bond->alb_info.current_alb_vlan = NULL;
}
if (bond->alb_info.rlb_enabled) {
rlb_clear_vlan(bond, vlan_id);
}
}
......@@ -77,6 +77,8 @@ struct rlb_client_info {
u8 assigned; /* checking whether this entry is assigned */
u8 ntt; /* flag - need to transmit client info */
struct slave *slave; /* the slave assigned to this client */
u8 tag; /* flag - need to tag skb */
unsigned short vlan_id; /* VLAN tag associated with IP address */
};
struct tlb_slave_info {
......@@ -122,6 +124,7 @@ struct alb_bond_info {
* rx traffic should be
* rebalanced
*/
struct vlan_entry *current_alb_vlan;
};
int bond_alb_initialize(struct bonding *bond, int rlb_enabled);
......@@ -133,6 +136,6 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
void bond_alb_monitor(struct bonding *bond);
int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
#endif /* __BOND_ALB_H__ */
This diff is collapsed.
......@@ -36,8 +36,8 @@
#include "bond_3ad.h"
#include "bond_alb.h"
#define DRV_VERSION "2.5.4"
#define DRV_RELDATE "December 30, 2003"
#define DRV_VERSION "2.6.0"
#define DRV_RELDATE "January 14, 2004"
#define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
......@@ -147,6 +147,11 @@ struct bond_params {
u32 arp_targets[BOND_MAX_ARP_TARGETS];
};
struct vlan_entry {
struct list_head vlan_list;
unsigned short vlan_id;
};
struct slave {
struct net_device *dev; /* first - usefull for panic debug */
struct slave *next;
......@@ -196,6 +201,8 @@ struct bonding {
struct ad_bond_info ad_info;
struct alb_bond_info alb_info;
struct bond_params params;
struct list_head vlan_list;
struct vlan_group *vlgrp;
};
/**
......@@ -238,5 +245,8 @@ extern inline void bond_set_slave_active_flags(struct slave *slave)
slave->dev->flags &= ~IFF_NOARP;
}
struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
#endif /* _LINUX_BONDING_H */
......@@ -1461,7 +1461,7 @@ static int __init depca_mca_probe(struct device *device)
out_unclaim:
mca_device_set_claim(mdev, 0);
return err;;
return err;
}
#endif
......
......@@ -178,6 +178,7 @@ static inline struct sixpack *sp_alloc(void)
(sixpack_ctrls[i] = (sixpack_ctrl_t *)kmalloc(sizeof(sixpack_ctrl_t),
GFP_KERNEL)) != NULL) {
spp = sixpack_ctrls[i];
}
memset(spp, 0, sizeof(sixpack_ctrl_t));
/* Initialize channel control data */
......@@ -188,7 +189,6 @@ static inline struct sixpack *sp_alloc(void)
spp->dev.priv = (void *) &spp->ctrl;
spp->dev.next = NULL;
spp->dev.init = sixpack_init;
}
if (spp != NULL) {
/* register device so that it can be ifconfig'ed */
......
......@@ -3043,14 +3043,27 @@ static int __init hp100_module_init(void)
int err;
err = hp100_isa_init();
if (err && err != -ENODEV)
goto out;
#ifdef CONFIG_EISA
err |= eisa_driver_register(&hp100_eisa_driver);
err = eisa_driver_register(&hp100_eisa_driver);
if (err && err != -ENODEV)
goto out2;
#endif
#ifdef CONFIG_PCI
err |= pci_module_init(&hp100_pci_driver);
err = pci_module_init(&hp100_pci_driver);
if (err && err != -ENODEV)
goto out3;
#endif
out:
return err;
out3:
#ifdef CONFIG_EISA
eisa_driver_unregister (&hp100_eisa_driver);
out2:
#endif
hp100_isa_cleanup();
goto out;
}
......
......@@ -720,6 +720,8 @@ pcnet32_probe1(unsigned long ioaddr, unsigned int irq_line, int shared,
lp->name = chipname;
lp->shared_irq = shared;
lp->mii_if.full_duplex = fdx;
lp->mii_if.phy_id_mask = 0x1f;
lp->mii_if.reg_num_mask = 0x1f;
lp->dxsuflo = dxsuflo;
lp->ltint = ltint;
lp->mii = mii;
......@@ -1006,9 +1008,10 @@ pcnet32_init_ring(struct net_device *dev)
}
if (lp->rx_dma_addr[i] == 0)
lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, rx_skbuff->len, PCI_DMA_FROMDEVICE);
lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev,
rx_skbuff->tail, PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]);
lp->rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ);
lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
lp->rx_ring[i].status = le16_to_cpu(0x8000);
}
/* The Tx buffer address is filled in as needed, but we do need to clear
......@@ -1079,7 +1082,7 @@ pcnet32_tx_timeout (struct net_device *dev)
pcnet32_restart(dev, 0x0042);
dev->trans_start = jiffies;
netif_start_queue(dev);
netif_wake_queue(dev);
spin_unlock_irqrestore(&lp->lock, flags);
}
......@@ -1105,9 +1108,10 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
* interrupt when that option is available to us.
*/
status = 0x8300;
entry = (lp->cur_tx - lp->dirty_tx) & TX_RING_MOD_MASK;
if ((lp->ltint) &&
((lp->cur_tx - lp->dirty_tx == TX_RING_SIZE/2) ||
(lp->cur_tx - lp->dirty_tx >= TX_RING_SIZE-2)))
((entry == TX_RING_SIZE/2) ||
(entry >= TX_RING_SIZE-2)))
{
/* Enable Successful-TxDone interrupt if we have
* 1/2 of, or nearly all of, our ring buffer Tx'd
......@@ -1122,7 +1126,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Mask to ring buffer boundary. */
entry = lp->cur_tx & TX_RING_MOD_MASK;
/* Caution: the write order is important here, set the base address
/* Caution: the write order is important here, set the status
with the "ownership" bits last. */
lp->tx_ring[entry].length = le16_to_cpu(-skb->len);
......@@ -1144,7 +1148,7 @@ pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
netif_start_queue(dev);
netif_wake_queue(dev);
else {
lp->tx_full = 1;
netif_stop_queue(dev);
......@@ -1191,8 +1195,9 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if (csr0 & 0x0200) { /* Tx-done interrupt */
unsigned int dirty_tx = lp->dirty_tx;
int delta;
while (dirty_tx < lp->cur_tx) {
while (dirty_tx != lp->cur_tx) {
int entry = dirty_tx & TX_RING_MOD_MASK;
int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
......@@ -1246,15 +1251,17 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs)
dirty_tx++;
}
if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE);
if (delta >= TX_RING_SIZE) {
printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
dirty_tx += TX_RING_SIZE;
delta -= TX_RING_SIZE;
}
if (lp->tx_full &&
netif_queue_stopped(dev) &&
dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
delta < TX_RING_SIZE - 2) {
/* The ring is no longer full, clear tbusy. */
lp->tx_full = 0;
netif_wake_queue (dev);
......@@ -1344,13 +1351,14 @@ pcnet32_rx(struct net_device *dev)
if ((newskb = dev_alloc_skb (PKT_BUF_SZ))) {
skb_reserve (newskb, 2);
skb = lp->rx_skbuff[entry];
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[entry], skb->len, PCI_DMA_FROMDEVICE);
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[entry],
PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
skb_put (skb, pkt_len);
lp->rx_skbuff[entry] = newskb;
newskb->dev = dev;
lp->rx_dma_addr[entry] =
pci_map_single(lp->pci_dev, newskb->tail,
newskb->len, PCI_DMA_FROMDEVICE);
PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]);
rx_in_place = 1;
} else
......@@ -1379,7 +1387,7 @@ pcnet32_rx(struct net_device *dev)
skb_put(skb,pkt_len); /* Make room */
pci_dma_sync_single(lp->pci_dev,
lp->rx_dma_addr[entry],
PKT_BUF_SZ,
PKT_BUF_SZ-2,
PCI_DMA_FROMDEVICE);
eth_copy_and_sum(skb,
(unsigned char *)(lp->rx_skbuff[entry]->tail),
......@@ -1396,7 +1404,7 @@ pcnet32_rx(struct net_device *dev)
* The docs say that the buffer length isn't touched, but Andrew Boyd
* of QNX reports that some revs of the 79C965 clear it.
*/
lp->rx_ring[entry].buf_length = le16_to_cpu(-PKT_BUF_SZ);
lp->rx_ring[entry].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
}
......@@ -1436,7 +1444,8 @@ pcnet32_close(struct net_device *dev)
for (i = 0; i < RX_RING_SIZE; i++) {
lp->rx_ring[i].status = 0;
if (lp->rx_skbuff[i]) {
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], lp->rx_skbuff[i]->len, PCI_DMA_FROMDEVICE);
pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2,
PCI_DMA_FROMDEVICE);
dev_kfree_skb(lp->rx_skbuff[i]);
}
lp->rx_skbuff[i] = NULL;
......@@ -1625,12 +1634,18 @@ static int pcnet32_ethtool_ioctl (struct net_device *dev, void *useraddr)
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
return mii_nway_restart(&lp->mii_if);
int r;
spin_lock_irq(&lp->lock);
r = mii_nway_restart(&lp->mii_if);
spin_unlock_irq(&lp->lock);
return r;
}
/* get link status */
case ETHTOOL_GLINK: {
struct ethtool_value edata = {ETHTOOL_GLINK};
spin_lock_irq(&lp->lock);
edata.data = mii_link_ok(&lp->mii_if);
spin_unlock_irq(&lp->lock);
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
......@@ -1661,45 +1676,37 @@ static int pcnet32_ethtool_ioctl (struct net_device *dev, void *useraddr)
static int pcnet32_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
unsigned long ioaddr = dev->base_addr;
struct pcnet32_private *lp = dev->priv;
struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
int phyaddr = lp->a.read_bcr (ioaddr, 33);
int rc;
unsigned long flags;
if (cmd == SIOCETHTOOL)
return pcnet32_ethtool_ioctl(dev, (void *) rq->ifr_data);
/* SIOC[GS]MIIxxx ioctls */
if (lp->mii) {
switch(cmd) {
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
data->phy_id = (phyaddr >> 5) & 0x1f;
/* Fall Through */
case SIOCGMIIREG: /* Read MII PHY register. */
lp->a.write_bcr (ioaddr, 33, ((data->phy_id & 0x1f) << 5) | (data->reg_num & 0x1f));
data->val_out = lp->a.read_bcr (ioaddr, 34);
lp->a.write_bcr (ioaddr, 33, phyaddr);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
lp->a.write_bcr (ioaddr, 33, ((data->phy_id & 0x1f) << 5) | (data->reg_num & 0x1f));
lp->a.write_bcr (ioaddr, 34, data->val_in);
lp->a.write_bcr (ioaddr, 33, phyaddr);
return 0;
default:
return -EOPNOTSUPP;
}
spin_lock_irqsave(&lp->lock, flags);
rc = generic_mii_ioctl(&lp->mii_if, data, cmd, NULL);
spin_unlock_irqrestore(&lp->lock, flags);
} else {
rc = -EOPNOTSUPP;
}
return -EOPNOTSUPP;
return rc;
}
static void pcnet32_watchdog(struct net_device *dev)
{
struct pcnet32_private *lp = dev->priv;
unsigned long flags;
/* Print the link status if it has changed */
if (lp->mii)
if (lp->mii) {
spin_lock_irqsave(&lp->lock, flags);
mii_check_media (&lp->mii_if, 1, 0);
spin_unlock_irqrestore(&lp->lock, flags);
}
mod_timer (&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT);
}
......
......@@ -954,8 +954,7 @@ static void
SiS190_tx_interrupt(struct net_device *dev, struct sis190_private *tp,
void *ioaddr)
{
unsigned long dirty_tx, tx_left = 0;
int entry = tp->cur_tx % NUM_TX_DESC;
unsigned long dirty_tx, tx_left;
assert(dev != NULL);
assert(tp != NULL);
......@@ -965,6 +964,8 @@ SiS190_tx_interrupt(struct net_device *dev, struct sis190_private *tp,
tx_left = tp->cur_tx - dirty_tx;
while (tx_left > 0) {
int entry = dirty_tx % NUM_TX_DESC;
if ((le32_to_cpu(tp->TxDescArray[entry].status) & OWNbit) == 0) {
struct sk_buff *skb;
......@@ -980,7 +981,6 @@ SiS190_tx_interrupt(struct net_device *dev, struct sis190_private *tp,
tp->stats.tx_packets++;
dirty_tx++;
tx_left--;
entry++;
}
}
......
......@@ -2093,7 +2093,7 @@ static void set_rx_mode(struct net_device *net_dev)
i++, mclist = mclist->next) {
unsigned int bit_nr =
sis900_mcast_bitnr(mclist->dmi_addr, revision);
mc_filter[bit_nr >> 4] |= (1 << bit_nr);
mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf));
}
}
......
......@@ -2,6 +2,8 @@
*
* Name: lm80.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.6 $
* Date: $Date: 2003/05/13 17:26:52 $
* Purpose: Contains all defines for the LM80 Chip
* (National Semiconductor).
*
......
......@@ -2,6 +2,8 @@
*
* Name: skaddr.h
* Project: Gigabit Ethernet Adapters, ADDR-Modul
* Version: $Revision: 1.29 $
* Date: $Date: 2003/05/13 16:57:24 $
* Purpose: Header file for Address Management (MC, UC, Prom).
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skcsum.h
* Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
* Version: $Revision: 1.10 $
* Date: $Date: 2003/08/20 13:59:57 $
* Purpose: Store/verify Internet checksum in send/receive packets.
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skdebug.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.14 $
* Date: $Date: 2003/05/13 17:26:00 $
* Purpose: SK specific DEBUG support
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skdrv1st.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.4 $
* Date: $Date: 2003/11/12 14:28:14 $
* Purpose: First header file for driver and all other modules
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skdrv2nd.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.10 $
* Date: $Date: 2003/12/11 16:04:45 $
* Purpose: Second header file for driver and all other modules
*
******************************************************************************/
......@@ -76,7 +78,13 @@
/* Marvell (0x11ab) */ \
} else if (pdev->vendor == 0x11ab) { \
/* Gigabit Ethernet Adapter (0x4320) */ \
if ((pdev->device == 0x4320)) { \
/* Gigabit Ethernet Adapter (0x4360) */ \
/* Gigabit Ethernet Adapter (0x4361) */ \
/* Belkin (0x5005) */ \
if ((pdev->device == 0x4320) || \
(pdev->device == 0x4360) || \
(pdev->device == 0x4361) || \
(pdev->device == 0x5005)) { \
result = SK_TRUE; \
} \
/* CNet (0x1371) */ \
......
......@@ -2,6 +2,8 @@
*
* Name: skerror.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.7 $
* Date: $Date: 2003/05/13 17:25:13 $
* Purpose: SK specific Error log support
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skgedrv.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.10 $
* Date: $Date: 2003/07/04 12:25:01 $
* Purpose: Interface with the driver
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skgehw.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.56 $
* Date: $Date: 2003/09/23 09:01:00 $
* Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skhwt.h
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.7 $
* Date: $Date: 2003/09/16 12:55:08 $
* Purpose: Defines for the hardware timer functions
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skgei2c.h
* Project: Gigabit Ethernet Adapters, TWSI-Module
* Version: $Revision: 1.25 $
* Date: $Date: 2003/10/20 09:06:05 $
* Purpose: Special defines for TWSI
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skgeinit.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.83 $
* Date: $Date: 2003/09/16 14:07:37 $
* Purpose: Structures and prototypes for the GE Init Module
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skgepnm2.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.36 $
* Date: $Date: 2003/05/23 12:45:13 $
* Purpose: Defines for Private Network Management Interface
*
****************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skgepnmi.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.62 $
* Date: $Date: 2003/08/15 12:31:52 $
* Purpose: Defines for Private Network Management Interface
*
****************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skgesirq.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.30 $
* Date: $Date: 2003/07/04 12:34:13 $
* Purpose: SK specific Gigabit Ethernet special IRQ functions
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: ski2c.h
* Project: Gigabit Ethernet Adapters, TWSI-Module
* Version: $Revision: 1.35 $
* Date: $Date: 2003/10/20 09:06:30 $
* Purpose: Defines to access Voltage and Temperature Sensor
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skqueue.h
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.16 $
* Date: $Date: 2003/09/16 12:50:32 $
* Purpose: Defines for the Event queue
*
******************************************************************************/
......@@ -20,6 +22,10 @@
*
******************************************************************************/
/*
* SKQUEUE.H contains all defines and types for the event queue
*/
#ifndef _SKQUEUE_H_
#define _SKQUEUE_H_
......
......@@ -2,6 +2,8 @@
*
* Name: skrlmt.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.37 $
* Date: $Date: 2003/04/15 09:43:43 $
* Purpose: Header file for Redundant Link ManagemenT.
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: sktimer.h
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.11 $
* Date: $Date: 2003/09/16 12:58:18 $
* Purpose: Defines for the timer functions
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: sktypes.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.2 $
* Date: $Date: 2003/10/07 08:16:51 $
* Purpose: Define data types for Linux
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: version.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.5 $
* Date: $Date: 2003/10/07 08:16:51 $
* Purpose: SK specific Error log support
*
******************************************************************************/
......@@ -23,14 +25,14 @@
#ifdef lint
static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
static const char SysKonnectBuildNumber[] =
"@(#)SK-BUILD: 6.22 PL: 01";
"@(#)SK-BUILD: 6.23 PL: 01";
#endif /* !defined(lint) */
#define BOOT_STRING "sk98lin: Network Device Driver v6.22\n" \
#define BOOT_STRING "sk98lin: Network Device Driver v6.23\n" \
"(C)Copyright 1999-2004 Marvell(R)."
#define VER_STRING "6.22"
#define VER_STRING "6.23"
#define DRIVER_FILE_NAME "sk98lin"
#define DRIVER_REL_DATE "Jan-30-2004"
#define DRIVER_REL_DATE "Feb-13-2004"
......@@ -2,6 +2,8 @@
*
* Name: skvpd.h
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.15 $
* Date: $Date: 2003/01/13 10:39:38 $
* Purpose: Defines and Macros for VPD handling
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: xmac_ii.h
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.52 $
* Date: $Date: 2003/10/02 16:35:50 $
* Purpose: Defines and Macros for Gigabit Ethernet Controller
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skaddr.c
* Project: Gigabit Ethernet Adapters, ADDR-Module
* Version: $Revision: 1.52 $
* Date: $Date: 2003/06/02 13:46:15 $
* Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skcsum.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.12 $
* Date: $Date: 2003/08/20 13:55:53 $
* Purpose: Store/verify Internet checksum in send/receive packets.
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skdim.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.5 $
* Date: $Date: 2003/11/28 12:55:40 $
* Purpose: All functions to maintain interrupt moderation
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skge.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.45 $
* Date: $Date: 2004/02/12 14:41:02 $
* Purpose: The main driver source module
*
******************************************************************************/
......@@ -294,7 +296,6 @@ static int __init skge_probe (void)
SK_BOOL BootStringCount = SK_FALSE;
int retval;
#ifdef CONFIG_PROC_FS
int proc_root_initialized = 0;
struct proc_dir_entry *pProcFile;
#endif
......@@ -311,6 +312,12 @@ static int __init skge_probe (void)
dev = NULL;
pNet = NULL;
/* Don't handle Yukon2 cards at the moment */
/* 12-feb-2004 ---- mlindner@syskonnect.de */
if (pdev->vendor == 0x11ab) {
if ( (pdev->device == 0x4360) || (pdev->device == 0x4361) )
continue;
}
SK_PCI_ISCOMPLIANT(vendor_flag, pdev);
if (!vendor_flag)
......
......@@ -2,6 +2,8 @@
*
* Name: skgehwt.c
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.15 $
* Date: $Date: 2003/09/16 13:41:23 $
* Purpose: Hardware Timer
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skgeinit.c
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.97 $
* Date: $Date: 2003/10/02 16:45:31 $
* Purpose: Contains functions to initialize the adapter
*
******************************************************************************/
......@@ -20,7 +22,6 @@
*
******************************************************************************/
#include "h/skdrv1st.h"
#include "h/skdrv2nd.h"
......
......@@ -2,6 +2,8 @@
*
* Name: skgemib.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.11 $
* Date: $Date: 2003/09/15 13:38:12 $
* Purpose: Private Network Management Interface Management Database
*
****************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skgepnmi.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.111 $
* Date: $Date: 2003/09/15 13:35:35 $
* Purpose: Private Network Management Interface
*
****************************************************************************/
......@@ -20,6 +22,7 @@
*
******************************************************************************/
#ifndef _lint
static const char SysKonnectFileId[] =
"@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
......
......@@ -2,6 +2,8 @@
*
* Name: skgesirq.c
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.92 $
* Date: $Date: 2003/09/16 14:37:07 $
* Purpose: Special IRQ module
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: ski2c.c
* Project: Gigabit Ethernet Adapters, TWSI-Module
* Version: $Revision: 1.59 $
* Date: $Date: 2003/10/20 09:07:25 $
* Purpose: Functions to access Voltage and Temperature Sensor
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: sklm80.c
* Project: Gigabit Ethernet Adapters, TWSI-Module
* Version: $Revision: 1.22 $
* Date: $Date: 2003/10/20 09:08:21 $
* Purpose: Functions to access Voltage and Temperature Sensor (LM80)
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skproc.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.11 $
* Date: $Date: 2003/12/11 16:03:57 $
* Purpose: Funktions to display statictic data
*
******************************************************************************/
......@@ -22,7 +24,6 @@
* The information in this file is provided "AS IS" without warranty.
*
******************************************************************************/
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
......
......@@ -2,6 +2,8 @@
*
* Name: skqueue.c
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.20 $
* Date: $Date: 2003/09/16 13:44:00 $
* Purpose: Management of an event queue.
*
******************************************************************************/
......@@ -20,6 +22,7 @@
*
******************************************************************************/
/*
* Event queue and dispatcher
*/
......
......@@ -2,6 +2,8 @@
*
* Name: skrlmt.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.69 $
* Date: $Date: 2003/04/15 09:39:22 $
* Purpose: Manage links on SK-NET Adapters, esp. redundant ones.
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: sktimer.c
* Project: Gigabit Ethernet Adapters, Event Scheduler Module
* Version: $Revision: 1.14 $
* Date: $Date: 2003/09/16 13:46:51 $
* Purpose: High level timer functions.
*
******************************************************************************/
......@@ -20,6 +22,7 @@
*
******************************************************************************/
/*
* Event queue and dispatcher
*/
......
......@@ -2,6 +2,8 @@
*
* Name: skvpd.c
* Project: GEnesis, PCI Gigabit Ethernet Adapter
* Version: $Revision: 1.37 $
* Date: $Date: 2003/01/13 10:42:45 $
* Purpose: Shared software to read and write VPD data
*
******************************************************************************/
......
......@@ -2,6 +2,8 @@
*
* Name: skxmac2.c
* Project: Gigabit Ethernet Adapters, Common Modules
* Version: $Revision: 1.102 $
* Date: $Date: 2003/10/02 16:53:58 $
* Purpose: Contains functions to initialize the MACs and PHYs
*
******************************************************************************/
......
......@@ -641,7 +641,20 @@ static int xl_open(struct net_device *dev)
*/
/* These MUST be on 8 byte boundaries */
xl_priv->xl_tx_ring = kmalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL) ;
if (xl_priv->xl_tx_ring == NULL) {
printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers.\n",
dev->name);
free_irq(dev->irq,dev);
return -ENOMEM;
}
xl_priv->xl_rx_ring = kmalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL) ;
if (xl_priv->xl_tx_ring == NULL) {
printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers.\n",
dev->name);
free_irq(dev->irq,dev);
kfree(xl_priv->xl_tx_ring);
return -ENOMEM;
}
memset(xl_priv->xl_tx_ring,0,sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) ;
memset(xl_priv->xl_rx_ring,0,sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) ;
......
......@@ -211,10 +211,10 @@ int tulip_poll(struct net_device *dev, int *budget)
if (tp->rx_buffers[entry].mapping !=
le32_to_cpu(tp->rx_ring[entry].buffer1)) {
printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
"do not match in tulip_rx: %08x vs. %08x %p / %p.\n",
"do not match in tulip_rx: %08x vs. %llx %p / %p.\n",
dev->name,
le32_to_cpu(tp->rx_ring[entry].buffer1),
tp->rx_buffers[entry].mapping,
(unsigned long long)tp->rx_buffers[entry].mapping,
skb->head, temp);
}
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment