summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/Space.c62
-rw-r--r--drivers/net/bonding/bond_3ad.c18
-rw-r--r--drivers/net/bonding/bond_3ad.h2
-rw-r--r--drivers/net/bonding/bond_alb.c70
-rw-r--r--drivers/net/bonding/bond_main.c18
-rw-r--r--drivers/net/bonding/bonding.h2
-rw-r--r--drivers/net/ethernet/3com/3c509.c123
-rw-r--r--drivers/net/ethernet/8390/Kconfig24
-rw-r--r--drivers/net/ethernet/8390/Makefile1
-rw-r--r--drivers/net/ethernet/8390/ne2.c798
-rw-r--r--drivers/net/ethernet/8390/smc-mca.c575
-rw-r--r--drivers/net/ethernet/amd/ariadne.c8
-rw-r--r--drivers/net/ethernet/amd/atarilance.c11
-rw-r--r--drivers/net/ethernet/amd/depca.c213
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c38
-rw-r--r--drivers/net/ethernet/broadcom/tg3.h2
-rw-r--r--drivers/net/ethernet/cirrus/cs89x0.c2221
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_main.c12
-rw-r--r--drivers/net/ethernet/davicom/Kconfig2
-rw-r--r--drivers/net/ethernet/dec/ewrk3.c3
-rw-r--r--drivers/net/ethernet/dec/tulip/de4x5.c2
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h25
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c56
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h57
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c77
-rw-r--r--drivers/net/ethernet/emulex/benet/be_hw.h2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c236
-rw-r--r--drivers/net/ethernet/fujitsu/at1700.c120
-rw-r--r--drivers/net/ethernet/i825xx/3c523.c1312
-rw-r--r--drivers/net/ethernet/i825xx/3c523.h355
-rw-r--r--drivers/net/ethernet/i825xx/3c527.c1660
-rw-r--r--drivers/net/ethernet/i825xx/3c527.h81
-rw-r--r--drivers/net/ethernet/i825xx/Kconfig22
-rw-r--r--drivers/net/ethernet/i825xx/Makefile2
-rw-r--r--drivers/net/ethernet/i825xx/eexpress.c60
-rw-r--r--drivers/net/ethernet/ibm/ehea/ehea_main.c2
-rw-r--r--drivers/net/ethernet/intel/Kconfig11
-rw-r--r--drivers/net/ethernet/intel/e1000/e1000_main.c36
-rw-r--r--drivers/net/ethernet/intel/e1000e/defines.h2
-rw-r--r--drivers/net/ethernet/intel/e1000e/param.c56
-rw-r--r--drivers/net/ethernet/intel/igb/Makefile3
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.c276
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.h3
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_defines.h35
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_hw.h14
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.c603
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.h76
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mac.c1
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_nvm.c1
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.c147
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.h22
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_regs.h14
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h9
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c141
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c130
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ptp.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/Makefile2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h37
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c69
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c93
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c98
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c71
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c198
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c900
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c13
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c36
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_type.h47
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_main.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c41
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c15
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c47
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mcg.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h12
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h9
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c5
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/pd.c39
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/port.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c271
-rw-r--r--drivers/net/ethernet/micrel/ks8851.c7
-rw-r--r--drivers/net/ethernet/natsemi/Kconfig20
-rw-r--r--drivers/net/ethernet/natsemi/Makefile1
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h2
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c25
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic.h20
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c5
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c18
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h26
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c4
-rw-r--r--drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c140
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c7
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c5
-rw-r--r--drivers/net/ethernet/realtek/r8169.c16
-rw-r--r--drivers/net/ethernet/sfc/efx.c38
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c37
-rw-r--r--drivers/net/ethernet/sfc/mcdi_phy.c76
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h8
-rw-r--r--drivers/net/ethernet/sfc/qt202x_phy.c33
-rw-r--r--drivers/net/ethernet/sfc/rx.c31
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000.h12
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c11
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c2
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c8
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c22
-rw-r--r--drivers/net/ethernet/sun/sunvnet.c2
-rw-r--r--drivers/net/ethernet/tile/tilepro.c2
-rw-r--r--drivers/net/ethernet/toshiba/ps3_gelic_wireless.c8
-rw-r--r--drivers/net/hyperv/hyperv_net.h290
-rw-r--r--drivers/net/hyperv/rndis_filter.c46
-rw-r--r--drivers/net/macvlan.c9
-rw-r--r--drivers/net/macvtap.c43
-rw-r--r--drivers/net/phy/mdio_bus.c2
-rw-r--r--drivers/net/phy/phy_device.c3
-rw-r--r--drivers/net/ppp/ppp_async.c2
-rw-r--r--drivers/net/ppp/ppp_generic.c14
-rw-r--r--drivers/net/ppp/ppp_synctty.c4
-rw-r--r--drivers/net/ppp/pppoe.c18
-rw-r--r--drivers/net/ppp/pptp.c2
-rw-r--r--drivers/net/tokenring/3c359.c1831
-rw-r--r--drivers/net/tokenring/3c359.h291
-rw-r--r--drivers/net/tokenring/Kconfig199
-rw-r--r--drivers/net/tokenring/Makefile16
-rw-r--r--drivers/net/tokenring/abyss.c468
-rw-r--r--drivers/net/tokenring/abyss.h58
-rw-r--r--drivers/net/tokenring/ibmtr.c1964
-rw-r--r--drivers/net/tokenring/ibmtr_cs.c370
-rw-r--r--drivers/net/tokenring/lanstreamer.c1909
-rw-r--r--drivers/net/tokenring/lanstreamer.h343
-rw-r--r--drivers/net/tokenring/madgemc.c761
-rw-r--r--drivers/net/tokenring/madgemc.h70
-rw-r--r--drivers/net/tokenring/olympic.c1737
-rw-r--r--drivers/net/tokenring/olympic.h321
-rw-r--r--drivers/net/tokenring/proteon.c422
-rw-r--r--drivers/net/tokenring/skisa.c432
-rw-r--r--drivers/net/tokenring/smctr.c5717
-rw-r--r--drivers/net/tokenring/smctr.h1585
-rw-r--r--drivers/net/tokenring/tms380tr.c2306
-rw-r--r--drivers/net/tokenring/tms380tr.h1141
-rw-r--r--drivers/net/tokenring/tmspci.c236
-rw-r--r--drivers/net/tun.c2
-rw-r--r--drivers/net/usb/cdc_ether.c72
-rw-r--r--drivers/net/usb/qmi_wwan.c39
-rw-r--r--drivers/net/usb/rndis_host.c83
-rw-r--r--drivers/net/usb/usbnet.c54
-rw-r--r--drivers/net/virtio_net.c2
-rw-r--r--drivers/net/wireless/at76c50x-usb.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c2
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c16
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c4
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c2
-rw-r--r--drivers/net/wireless/iwlegacy/common.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c6
-rw-r--r--drivers/net/wireless/mwl8k.c2
-rw-r--r--drivers/net/wireless/p54/txrx.c2
-rw-r--r--drivers/net/wireless/rndis_wlan.c373
-rw-r--r--drivers/net/wireless/rtlwifi/base.c2
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c10
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.c10
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/trx.c11
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c11
173 files changed, 5648 insertions, 30205 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b98285446a5a..0c2bd806950e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -66,10 +66,7 @@ config DUMMY
<http://www.tldp.org/docs.html#guide>.
To compile this driver as a module, choose M here: the module
- will be called dummy. If you want to use more than one dummy
- device at a time, you need to compile this driver as a module.
- Instead of 'dummy', the devices will then be called 'dummy0',
- 'dummy1' etc.
+ will be called dummy.
config EQUALIZER
tristate "EQL (serial line load balancing) support"
@@ -285,8 +282,6 @@ source "drivers/net/slip/Kconfig"
source "drivers/s390/net/Kconfig"
-source "drivers/net/tokenring/Kconfig"
-
source "drivers/net/usb/Kconfig"
source "drivers/net/wireless/Kconfig"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index a6b8ce11a22f..3d375ca128a6 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -50,7 +50,6 @@ obj-$(CONFIG_SLIP) += slip/
obj-$(CONFIG_SLHC) += slip/
obj-$(CONFIG_NET_SB1000) += sb1000.o
obj-$(CONFIG_SUNGEM_PHY) += sungem_phy.o
-obj-$(CONFIG_TR) += tokenring/
obj-$(CONFIG_WAN) += wan/
obj-$(CONFIG_WLAN) += wireless/
obj-$(CONFIG_WIMAX) += wimax/
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 88bbd8ffa7fe..e3f0faca98d0 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -29,7 +29,6 @@
*/
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/trdevice.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netlink.h>
@@ -134,22 +133,9 @@ static struct devprobe2 eisa_probes[] __initdata = {
{NULL, 0},
};
-static struct devprobe2 mca_probes[] __initdata = {
-#ifdef CONFIG_NE2_MCA
- {ne2_probe, 0},
-#endif
-#ifdef CONFIG_ELMC /* 3c523 */
- {elmc_probe, 0},
-#endif
-#ifdef CONFIG_ELMC_II /* 3c527 */
- {mc32_probe, 0},
-#endif
- {NULL, 0},
-};
-
/*
* ISA probes that touch addresses < 0x400 (including those that also
- * look for EISA/PCI/MCA cards in addition to ISA cards).
+ * look for EISA/PCI cards in addition to ISA cards).
*/
static struct devprobe2 isa_probes[] __initdata = {
#if defined(CONFIG_HP100) && defined(CONFIG_ISA) /* ISA, EISA */
@@ -279,51 +265,10 @@ static void __init ethif_probe2(int unit)
(void)( probe_list2(unit, m68k_probes, base_addr == 0) &&
probe_list2(unit, eisa_probes, base_addr == 0) &&
- probe_list2(unit, mca_probes, base_addr == 0) &&
probe_list2(unit, isa_probes, base_addr == 0) &&
probe_list2(unit, parport_probes, base_addr == 0));
}
-#ifdef CONFIG_TR
-/* Token-ring device probe */
-extern int ibmtr_probe_card(struct net_device *);
-extern struct net_device *smctr_probe(int unit);
-
-static struct devprobe2 tr_probes2[] __initdata = {
-#ifdef CONFIG_SMCTR
- {smctr_probe, 0},
-#endif
- {NULL, 0},
-};
-
-static __init int trif_probe(int unit)
-{
- int err = -ENODEV;
-#ifdef CONFIG_IBMTR
- struct net_device *dev = alloc_trdev(0);
- if (!dev)
- return -ENOMEM;
-
- sprintf(dev->name, "tr%d", unit);
- netdev_boot_setup_check(dev);
- err = ibmtr_probe_card(dev);
- if (err)
- free_netdev(dev);
-#endif
- return err;
-}
-
-static void __init trif_probe2(int unit)
-{
- unsigned long base_addr = netdev_boot_base("tr", unit);
-
- if (base_addr == 1)
- return;
- probe_list2(unit, tr_probes2, base_addr == 0);
-}
-#endif
-
-
/* Statically configured drivers -- order matters here. */
static int __init net_olddevs_init(void)
{
@@ -333,11 +278,6 @@ static int __init net_olddevs_init(void)
for (num = 0; num < 8; ++num)
sbni_probe(num);
#endif
-#ifdef CONFIG_TR
- for (num = 0; num < 8; ++num)
- if (!trif_probe(num))
- trif_probe2(num);
-#endif
for (num = 0; num < 8; ++num)
ethif_probe2(num);
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 793b00138275..3463b469e657 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2173,9 +2173,10 @@ re_arm:
* received frames (loopback). Since only the payload is given to this
* function, it check for loopback.
*/
-static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length)
+static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length)
{
struct port *port;
+ int ret = RX_HANDLER_ANOTHER;
if (length >= sizeof(struct lacpdu)) {
@@ -2184,11 +2185,12 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
if (!port->slave) {
pr_warning("%s: Warning: port of slave %s is uninitialized\n",
slave->dev->name, slave->dev->master->name);
- return;
+ return ret;
}
switch (lacpdu->subtype) {
case AD_TYPE_LACPDU:
+ ret = RX_HANDLER_CONSUMED;
pr_debug("Received LACPDU on port %d\n",
port->actor_port_number);
/* Protect against concurrent state machines */
@@ -2198,6 +2200,7 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
break;
case AD_TYPE_MARKER:
+ ret = RX_HANDLER_CONSUMED;
// No need to convert fields to Little Endian since we don't use the marker's fields.
switch (((struct bond_marker *)lacpdu)->tlv_type) {
@@ -2219,6 +2222,7 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
}
}
}
+ return ret;
}
/**
@@ -2456,18 +2460,20 @@ out:
return NETDEV_TX_OK;
}
-void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
+int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
struct slave *slave)
{
+ int ret = RX_HANDLER_ANOTHER;
if (skb->protocol != PKT_TYPE_LACPDU)
- return;
+ return ret;
if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
- return;
+ return ret;
read_lock(&bond->lock);
- bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
+ ret = bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
read_unlock(&bond->lock);
+ return ret;
}
/*
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 235b2cc58b28..5ee7e3c45db7 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -274,7 +274,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave);
void bond_3ad_handle_link_change(struct slave *slave, char link);
int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
-void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
+int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
struct slave *slave);
int bond_3ad_set_carrier(struct bonding *bond);
void bond_3ad_update_lacp_rate(struct bonding *bond);
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 9abfde479316..0f59c1564e53 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -332,7 +332,7 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
if ((client_info->assigned) &&
(client_info->ip_src == arp->ip_dst) &&
(client_info->ip_dst == arp->ip_src) &&
- (compare_ether_addr_64bits(client_info->mac_dst, arp->mac_src))) {
+ (!ether_addr_equal_64bits(client_info->mac_dst, arp->mac_src))) {
/* update the clients MAC address */
memcpy(client_info->mac_dst, arp->mac_src, ETH_ALEN);
client_info->ntt = 1;
@@ -342,26 +342,26 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
_unlock_rx_hashtbl_bh(bond);
}
-static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond,
+static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond,
struct slave *slave)
{
struct arp_pkt *arp;
if (skb->protocol != cpu_to_be16(ETH_P_ARP))
- return;
+ goto out;
arp = (struct arp_pkt *) skb->data;
if (!arp) {
pr_debug("Packet has no ARP data\n");
- return;
+ goto out;
}
if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
- return;
+ goto out;
if (skb->len < sizeof(struct arp_pkt)) {
pr_debug("Packet is too small to be an ARP\n");
- return;
+ goto out;
}
if (arp->op_code == htons(ARPOP_REPLY)) {
@@ -369,6 +369,8 @@ static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond,
rlb_update_entry_from_arp(bond, arp);
pr_debug("Server received an ARP Reply from client\n");
}
+out:
+ return RX_HANDLER_ANOTHER;
}
/* Caller must hold bond lock for read */
@@ -448,8 +450,8 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
if (assigned_slave) {
rx_hash_table[index].slave = assigned_slave;
- if (compare_ether_addr_64bits(rx_hash_table[index].mac_dst,
- mac_bcast)) {
+ if (!ether_addr_equal_64bits(rx_hash_table[index].mac_dst,
+ mac_bcast)) {
bond_info->rx_hashtbl[index].ntt = 1;
bond_info->rx_ntt = 1;
/* A slave has been removed from the
@@ -561,7 +563,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla
client_info = &(bond_info->rx_hashtbl[hash_index]);
if ((client_info->slave == slave) &&
- compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) {
+ !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) {
client_info->ntt = 1;
ntt = 1;
}
@@ -600,9 +602,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
* unicast mac address.
*/
if ((client_info->ip_src == src_ip) &&
- compare_ether_addr_64bits(client_info->slave->dev->dev_addr,
- bond->dev->dev_addr) &&
- compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) {
+ !ether_addr_equal_64bits(client_info->slave->dev->dev_addr,
+ bond->dev->dev_addr) &&
+ !ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) {
client_info->ntt = 1;
bond_info->rx_ntt = 1;
}
@@ -629,7 +631,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
if ((client_info->ip_src == arp->ip_src) &&
(client_info->ip_dst == arp->ip_dst)) {
/* the entry is already assigned to this client */
- if (compare_ether_addr_64bits(arp->mac_dst, mac_bcast)) {
+ if (!ether_addr_equal_64bits(arp->mac_dst, mac_bcast)) {
/* update mac address from arp */
memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
}
@@ -664,7 +666,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
client_info->slave = assigned_slave;
- if (compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) {
+ if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) {
client_info->ntt = 1;
bond->alb_info.rx_ntt = 1;
} else {
@@ -1009,18 +1011,18 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla
int perm_curr_diff;
int perm_bond_diff;
- perm_curr_diff = compare_ether_addr_64bits(slave->perm_hwaddr,
- slave->dev->dev_addr);
- perm_bond_diff = compare_ether_addr_64bits(slave->perm_hwaddr,
- bond->dev->dev_addr);
+ perm_curr_diff = !ether_addr_equal_64bits(slave->perm_hwaddr,
+ slave->dev->dev_addr);
+ perm_bond_diff = !ether_addr_equal_64bits(slave->perm_hwaddr,
+ bond->dev->dev_addr);
if (perm_curr_diff && perm_bond_diff) {
struct slave *tmp_slave;
int i, found = 0;
bond_for_each_slave(bond, tmp_slave, i) {
- if (!compare_ether_addr_64bits(slave->perm_hwaddr,
- tmp_slave->dev->dev_addr)) {
+ if (ether_addr_equal_64bits(slave->perm_hwaddr,
+ tmp_slave->dev->dev_addr)) {
found = 1;
break;
}
@@ -1074,10 +1076,10 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
* check uniqueness of slave's mac address against the other
* slaves in the bond.
*/
- if (compare_ether_addr_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) {
+ if (!ether_addr_equal_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) {
bond_for_each_slave(bond, tmp_slave1, i) {
- if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr,
- slave->dev->dev_addr)) {
+ if (ether_addr_equal_64bits(tmp_slave1->dev->dev_addr,
+ slave->dev->dev_addr)) {
found = 1;
break;
}
@@ -1099,8 +1101,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
bond_for_each_slave(bond, tmp_slave1, i) {
found = 0;
bond_for_each_slave(bond, tmp_slave2, j) {
- if (!compare_ether_addr_64bits(tmp_slave1->perm_hwaddr,
- tmp_slave2->dev->dev_addr)) {
+ if (ether_addr_equal_64bits(tmp_slave1->perm_hwaddr,
+ tmp_slave2->dev->dev_addr)) {
found = 1;
break;
}
@@ -1115,8 +1117,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
}
if (!has_bond_addr) {
- if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr,
- bond->dev->dev_addr)) {
+ if (ether_addr_equal_64bits(tmp_slave1->dev->dev_addr,
+ bond->dev->dev_addr)) {
has_bond_addr = tmp_slave1;
}
@@ -1257,7 +1259,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
case ETH_P_IP: {
const struct iphdr *iph = ip_hdr(skb);
- if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast) ||
+ if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast) ||
(iph->daddr == ip_bcast) ||
(iph->protocol == IPPROTO_IGMP)) {
do_tx_balance = 0;
@@ -1271,7 +1273,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
/* IPv6 doesn't really use broadcast mac address, but leave
* that here just in case.
*/
- if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast)) {
+ if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast)) {
do_tx_balance = 0;
break;
}
@@ -1279,7 +1281,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
/* IPv6 uses all-nodes multicast as an equivalent to
* broadcasts in IPv4.
*/
- if (!compare_ether_addr_64bits(eth_data->h_dest, mac_v6_allmcast)) {
+ if (ether_addr_equal_64bits(eth_data->h_dest, mac_v6_allmcast)) {
do_tx_balance = 0;
break;
}
@@ -1603,8 +1605,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
struct slave *tmp_slave;
/* find slave that is holding the bond's mac address */
bond_for_each_slave(bond, tmp_slave, i) {
- if (!compare_ether_addr_64bits(tmp_slave->dev->dev_addr,
- bond->dev->dev_addr)) {
+ if (ether_addr_equal_64bits(tmp_slave->dev->dev_addr,
+ bond->dev->dev_addr)) {
swap_slave = tmp_slave;
break;
}
@@ -1681,8 +1683,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
swap_slave = NULL;
bond_for_each_slave(bond, slave, i) {
- if (!compare_ether_addr_64bits(slave->dev->dev_addr,
- bond_dev->dev_addr)) {
+ if (ether_addr_equal_64bits(slave->dev->dev_addr,
+ bond_dev->dev_addr)) {
swap_slave = slave;
break;
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 16dbf53e314b..2ee8cf9e8a3b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1444,8 +1444,9 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
struct sk_buff *skb = *pskb;
struct slave *slave;
struct bonding *bond;
- void (*recv_probe)(struct sk_buff *, struct bonding *,
+ int (*recv_probe)(struct sk_buff *, struct bonding *,
struct slave *);
+ int ret = RX_HANDLER_ANOTHER;
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
@@ -1464,8 +1465,12 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
if (likely(nskb)) {
- recv_probe(nskb, bond, slave);
+ ret = recv_probe(nskb, bond, slave);
dev_kfree_skb(nskb);
+ if (ret == RX_HANDLER_CONSUMED) {
+ consume_skb(skb);
+ return ret;
+ }
}
}
@@ -1487,7 +1492,7 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
memcpy(eth_hdr(skb)->h_dest, bond->dev->dev_addr, ETH_ALEN);
}
- return RX_HANDLER_ANOTHER;
+ return ret;
}
/* enslave device <slave> to bond device <master> */
@@ -1961,7 +1966,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
write_lock_bh(&bond->lock);
if (!bond->params.fail_over_mac) {
- if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr) &&
+ if (ether_addr_equal(bond_dev->dev_addr, slave->perm_hwaddr) &&
bond->slave_cnt > 1)
pr_warning("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n",
bond_dev->name, slave_dev->name,
@@ -2732,7 +2737,7 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32
}
}
-static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
+static int bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
struct slave *slave)
{
struct arphdr *arp;
@@ -2740,7 +2745,7 @@ static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
__be32 sip, tip;
if (skb->protocol != __cpu_to_be16(ETH_P_ARP))
- return;
+ return RX_HANDLER_ANOTHER;
read_lock(&bond->lock);
@@ -2785,6 +2790,7 @@ static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
out_unlock:
read_unlock(&bond->lock);
+ return RX_HANDLER_ANOTHER;
}
/*
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 9f2bae6616d3..4581aa5ccaba 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -218,7 +218,7 @@ struct bonding {
struct slave *primary_slave;
bool force_primary;
s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
- void (*recv_probe)(struct sk_buff *, struct bonding *,
+ int (*recv_probe)(struct sk_buff *, struct bonding *,
struct slave *);
rwlock_t lock;
rwlock_t curr_slave_lock;
diff --git a/drivers/net/ethernet/3com/3c509.c b/drivers/net/ethernet/3com/3c509.c
index 41719da2e178..1a8eef2c3d58 100644
--- a/drivers/net/ethernet/3com/3c509.c
+++ b/drivers/net/ethernet/3com/3c509.c
@@ -69,7 +69,6 @@
#define TX_TIMEOUT (400*HZ/1000)
#include <linux/module.h>
-#include <linux/mca.h>
#include <linux/isa.h>
#include <linux/pnp.h>
#include <linux/string.h>
@@ -102,7 +101,7 @@ static int el3_debug = 2;
#endif
/* Used to do a global count of all the cards in the system. Must be
- * a global variable so that the mca/eisa probe routines can increment
+ * a global variable so that the eisa probe routines can increment
* it */
static int el3_cards = 0;
#define EL3_MAX_CARDS 8
@@ -163,7 +162,7 @@ enum RxFilter {
*/
#define SKB_QUEUE_SIZE 64
-enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_MCA, EL3_EISA };
+enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_EISA };
struct el3_private {
spinlock_t lock;
@@ -505,41 +504,6 @@ static struct eisa_driver el3_eisa_driver = {
static int eisa_registered;
#endif
-#ifdef CONFIG_MCA
-static int el3_mca_probe(struct device *dev);
-
-static short el3_mca_adapter_ids[] __initdata = {
- 0x627c,
- 0x627d,
- 0x62db,
- 0x62f6,
- 0x62f7,
- 0x0000
-};
-
-static char *el3_mca_adapter_names[] __initdata = {
- "3Com 3c529 EtherLink III (10base2)",
- "3Com 3c529 EtherLink III (10baseT)",
- "3Com 3c529 EtherLink III (test mode)",
- "3Com 3c529 EtherLink III (TP or coax)",
- "3Com 3c529 EtherLink III (TP)",
- NULL
-};
-
-static struct mca_driver el3_mca_driver = {
- .id_table = el3_mca_adapter_ids,
- .driver = {
- .name = "3c529",
- .bus = &mca_bus_type,
- .probe = el3_mca_probe,
- .remove = __devexit_p(el3_device_remove),
- .suspend = el3_suspend,
- .resume = el3_resume,
- },
-};
-static int mca_registered;
-#endif /* CONFIG_MCA */
-
static const struct net_device_ops netdev_ops = {
.ndo_open = el3_open,
.ndo_stop = el3_close,
@@ -600,76 +564,6 @@ static void el3_common_remove (struct net_device *dev)
free_netdev (dev);
}
-#ifdef CONFIG_MCA
-static int __init el3_mca_probe(struct device *device)
-{
- /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
- * heavily modified by Chris Beauregard
- * (cpbeaure@csclub.uwaterloo.ca) to support standard MCA
- * probing.
- *
- * redone for multi-card detection by ZP Gu (zpg@castle.net)
- * now works as a module */
-
- short i;
- int ioaddr, irq, if_port;
- __be16 phys_addr[3];
- struct net_device *dev = NULL;
- u_char pos4, pos5;
- struct mca_device *mdev = to_mca_device(device);
- int slot = mdev->slot;
- int err;
-
- pos4 = mca_device_read_stored_pos(mdev, 4);
- pos5 = mca_device_read_stored_pos(mdev, 5);
-
- ioaddr = ((short)((pos4&0xfc)|0x02)) << 8;
- irq = pos5 & 0x0f;
-
-
- pr_info("3c529: found %s at slot %d\n",
- el3_mca_adapter_names[mdev->index], slot + 1);
-
- /* claim the slot */
- strncpy(mdev->name, el3_mca_adapter_names[mdev->index],
- sizeof(mdev->name));
- mca_device_set_claim(mdev, 1);
-
- if_port = pos4 & 0x03;
-
- irq = mca_device_transform_irq(mdev, irq);
- ioaddr = mca_device_transform_ioport(mdev, ioaddr);
- if (el3_debug > 2) {
- pr_debug("3c529: irq %d ioaddr 0x%x ifport %d\n", irq, ioaddr, if_port);
- }
- EL3WINDOW(0);
- for (i = 0; i < 3; i++)
- phys_addr[i] = htons(read_eeprom(ioaddr, i));
-
- dev = alloc_etherdev(sizeof (struct el3_private));
- if (dev == NULL) {
- release_region(ioaddr, EL3_IO_EXTENT);
- return -ENOMEM;
- }
-
- netdev_boot_setup_check(dev);
-
- el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
- dev_set_drvdata(device, dev);
- err = el3_common_init(dev);
-
- if (err) {
- dev_set_drvdata(device, NULL);
- free_netdev(dev);
- return -ENOMEM;
- }
-
- el3_devs[el3_cards++] = dev;
- return 0;
-}
-
-#endif /* CONFIG_MCA */
-
#ifdef CONFIG_EISA
static int __init el3_eisa_probe (struct device *device)
{
@@ -1547,11 +1441,6 @@ static int __init el3_init_module(void)
if (!ret)
eisa_registered = 1;
#endif
-#ifdef CONFIG_MCA
- ret = mca_register_driver(&el3_mca_driver);
- if (!ret)
- mca_registered = 1;
-#endif
#ifdef CONFIG_PNP
if (pnp_registered)
@@ -1563,10 +1452,6 @@ static int __init el3_init_module(void)
if (eisa_registered)
ret = 0;
#endif
-#ifdef CONFIG_MCA
- if (mca_registered)
- ret = 0;
-#endif
return ret;
}
@@ -1584,10 +1469,6 @@ static void __exit el3_cleanup_module(void)
if (eisa_registered)
eisa_driver_unregister(&el3_eisa_driver);
#endif
-#ifdef CONFIG_MCA
- if (mca_registered)
- mca_unregister_driver(&el3_mca_driver);
-#endif
}
module_init (el3_init_module);
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig
index 910895c5ec97..2e538676924d 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -182,18 +182,6 @@ config NE2000
To compile this driver as a module, choose M here. The module
will be called ne.
-config NE2_MCA
- tristate "NE/2 (ne2000 MCA version) support"
- depends on MCA_LEGACY
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called ne2.
-
config NE2K_PCI
tristate "PCI NE2000 and clones support (see help)"
depends on PCI
@@ -267,18 +255,6 @@ config STNIC
If unsure, say N.
-config ULTRAMCA
- tristate "SMC Ultra MCA support"
- depends on MCA
- select CRC32
- ---help---
- If you have a network (Ethernet) card of this type and are running
- an MCA based system (PS/2), say Y and read the Ethernet-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called smc-mca.
-
config ULTRA
tristate "SMC Ultra support"
depends on ISA
diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile
index 3337d7fb4344..d13790b7fd27 100644
--- a/drivers/net/ethernet/8390/Makefile
+++ b/drivers/net/ethernet/8390/Makefile
@@ -24,6 +24,5 @@ obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o
obj-$(CONFIG_STNIC) += stnic.o 8390.o
obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o
obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o
-obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o
obj-$(CONFIG_WD80x3) += wd.o 8390.o
obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o
diff --git a/drivers/net/ethernet/8390/ne2.c b/drivers/net/ethernet/8390/ne2.c
deleted file mode 100644
index ef85839f43d8..000000000000
--- a/drivers/net/ethernet/8390/ne2.c
+++ /dev/null
@@ -1,798 +0,0 @@
-/* ne2.c: A NE/2 Ethernet Driver for Linux. */
-/*
- Based on the NE2000 driver written by Donald Becker (1992-94).
- modified by Wim Dumon (Apr 1996)
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached as wimpie@linux.cc.kuleuven.ac.be
-
- Currently supported: NE/2
- This patch was never tested on other MCA-ethernet adapters, but it
- might work. Just give it a try and let me know if you have problems.
- Also mail me if it really works, please!
-
- Changelog:
- Mon Feb 3 16:26:02 MET 1997
- - adapted the driver to work with the 2.1.25 kernel
- - multiple ne2 support (untested)
- - module support (untested)
-
- Fri Aug 28 00:18:36 CET 1998 (David Weinehall)
- - fixed a few minor typos
- - made the MODULE_PARM conditional (it only works with the v2.1.x kernels)
- - fixed the module support (Now it's working...)
-
- Mon Sep 7 19:01:44 CET 1998 (David Weinehall)
- - added support for Arco Electronics AE/2-card (experimental)
-
- Mon Sep 14 09:53:42 CET 1998 (David Weinehall)
- - added support for Compex ENET-16MC/P (experimental)
-
- Tue Sep 15 16:21:12 CET 1998 (David Weinehall, Magnus Jonsson, Tomas Ogren)
- - Miscellaneous bugfixes
-
- Tue Sep 19 16:21:12 CET 1998 (Magnus Jonsson)
- - Cleanup
-
- Wed Sep 23 14:33:34 CET 1998 (David Weinehall)
- - Restructuring and rewriting for v2.1.x compliance
-
- Wed Oct 14 17:19:21 CET 1998 (David Weinehall)
- - Added code that unregisters irq and proc-info
- - Version# bump
-
- Mon Nov 16 15:28:23 CET 1998 (Wim Dumon)
- - pass 'dev' as last parameter of request_irq in stead of 'NULL'
-
- Wed Feb 7 21:24:00 CET 2001 (Alfred Arnold)
- - added support for the D-Link DE-320CT
-
- * WARNING
- -------
- This is alpha-test software. It is not guaranteed to work. As a
- matter of fact, I'm quite sure there are *LOTS* of bugs in here. I
- would like to hear from you if you use this driver, even if it works.
- If it doesn't work, be sure to send me a mail with the problems !
-*/
-
-static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.org>\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/mca-legacy.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include "8390.h"
-
-#define DRV_NAME "ne2"
-
-/* Some defines that people can play with if so inclined. */
-
-/* Do we perform extra sanity checks on stuff ? */
-/* #define NE_SANITY_CHECK */
-
-/* Do we implement the read before write bugfix ? */
-/* #define NE_RW_BUGFIX */
-
-/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
-/* #define PACKETBUF_MEMSIZE 0x40 */
-
-
-/* ---- No user-serviceable parts below ---- */
-
-#define NE_BASE (dev->base_addr)
-#define NE_CMD 0x00
-#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */
-#define NE_RESET 0x20 /* Issue a read to reset, a write to clear. */
-#define NE_IO_EXTENT 0x30
-
-#define NE1SM_START_PG 0x20 /* First page of TX buffer */
-#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
-#define NESM_START_PG 0x40 /* First page of TX buffer */
-#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
-
-/* From the .ADF file: */
-static unsigned int addresses[7] __initdata =
- {0x1000, 0x2020, 0x8020, 0xa0a0, 0xb0b0, 0xc0c0, 0xc3d0};
-static int irqs[4] __initdata = {3, 4, 5, 9};
-
-/* From the D-Link ADF file: */
-static unsigned int dlink_addresses[4] __initdata =
- {0x300, 0x320, 0x340, 0x360};
-static int dlink_irqs[8] __initdata = {3, 4, 5, 9, 10, 11, 14, 15};
-
-struct ne2_adapters_t {
- unsigned int id;
- char *name;
-};
-
-static struct ne2_adapters_t ne2_adapters[] __initdata = {
- { 0x6354, "Arco Ethernet Adapter AE/2" },
- { 0x70DE, "Compex ENET-16 MC/P" },
- { 0x7154, "Novell Ethernet Adapter NE/2" },
- { 0x56ea, "D-Link DE-320CT" },
- { 0x0000, NULL }
-};
-
-extern int netcard_probe(struct net_device *dev);
-
-static int ne2_probe1(struct net_device *dev, int slot);
-
-static void ne_reset_8390(struct net_device *dev);
-static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static void ne_block_input(struct net_device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void ne_block_output(struct net_device *dev, const int count,
- const unsigned char *buf, const int start_page);
-
-
-/*
- * special code to read the DE-320's MAC address EEPROM. In contrast to a
- * standard NE design, this is a serial EEPROM (93C46) that has to be read
- * bit by bit. The EEPROM cotrol port at base + 0x1e has the following
- * layout:
- *
- * Bit 0 = Data out (read from EEPROM)
- * Bit 1 = Data in (write to EEPROM)
- * Bit 2 = Clock
- * Bit 3 = Chip Select
- * Bit 7 = ~50 kHz clock for defined delays
- *
- */
-
-static void __init dlink_put_eeprom(unsigned char value, unsigned int addr)
-{
- int z;
- unsigned char v1, v2;
-
- /* write the value to the NIC EEPROM register */
-
- outb(value, addr + 0x1e);
-
- /* now wait the clock line to toggle twice. Effectively, we are
- waiting (at least) for one clock cycle */
-
- for (z = 0; z < 2; z++) {
- do {
- v1 = inb(addr + 0x1e);
- v2 = inb(addr + 0x1e);
- }
- while (!((v1 ^ v2) & 0x80));
- }
-}
-
-static void __init dlink_send_eeprom_bit(unsigned int bit, unsigned int addr)
-{
- /* shift data bit into correct position */
-
- bit = bit << 1;
-
- /* write value, keep clock line high for two cycles */
-
- dlink_put_eeprom(0x09 | bit, addr);
- dlink_put_eeprom(0x0d | bit, addr);
- dlink_put_eeprom(0x0d | bit, addr);
- dlink_put_eeprom(0x09 | bit, addr);
-}
-
-static void __init dlink_send_eeprom_word(unsigned int value, unsigned int len, unsigned int addr)
-{
- int z;
-
- /* adjust bits so that they are left-aligned in a 16-bit-word */
-
- value = value << (16 - len);
-
- /* shift bits out to the EEPROM */
-
- for (z = 0; z < len; z++) {
- dlink_send_eeprom_bit((value & 0x8000) >> 15, addr);
- value = value << 1;
- }
-}
-
-static unsigned int __init dlink_get_eeprom(unsigned int eeaddr, unsigned int addr)
-{
- int z;
- unsigned int value = 0;
-
- /* pull the CS line low for a moment. This resets the EEPROM-
- internal logic, and makes it ready for a new command. */
-
- dlink_put_eeprom(0x01, addr);
- dlink_put_eeprom(0x09, addr);
-
- /* send one start bit, read command (1 - 0), plus the address to
- the EEPROM */
-
- dlink_send_eeprom_word(0x0180 | (eeaddr & 0x3f), 9, addr);
-
- /* get the data word. We clock by sending 0s to the EEPROM, which
- get ignored during the read process */
-
- for (z = 0; z < 16; z++) {
- dlink_send_eeprom_bit(0, addr);
- value = (value << 1) | (inb(addr + 0x1e) & 0x01);
- }
-
- return value;
-}
-
-/*
- * Note that at boot, this probe only picks up one card at a time.
- */
-
-static int __init do_ne2_probe(struct net_device *dev)
-{
- static int current_mca_slot = -1;
- int i;
- int adapter_found = 0;
-
- /* Do not check any supplied i/o locations.
- POS registers usually don't fail :) */
-
- /* MCA cards have POS registers.
- Autodetecting MCA cards is extremely simple.
- Just search for the card. */
-
- for(i = 0; (ne2_adapters[i].name != NULL) && !adapter_found; i++) {
- current_mca_slot =
- mca_find_unused_adapter(ne2_adapters[i].id, 0);
-
- if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) {
- int res;
- mca_set_adapter_name(current_mca_slot,
- ne2_adapters[i].name);
- mca_mark_as_used(current_mca_slot);
-
- res = ne2_probe1(dev, current_mca_slot);
- if (res)
- mca_mark_as_unused(current_mca_slot);
- return res;
- }
- }
- return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init ne2_probe(int unit)
-{
- struct net_device *dev = alloc_eip_netdev();
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_ne2_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-static int ne2_procinfo(char *buf, int slot, struct net_device *dev)
-{
- int len=0;
-
- len += sprintf(buf+len, "The NE/2 Ethernet Adapter\n" );
- len += sprintf(buf+len, "Driver written by Wim Dumon ");
- len += sprintf(buf+len, "<wimpie@kotnet.org>\n");
- len += sprintf(buf+len, "Modified by ");
- len += sprintf(buf+len, "David Weinehall <tao@acc.umu.se>\n");
- len += sprintf(buf+len, "and by Magnus Jonsson <bigfoot@acc.umu.se>\n");
- len += sprintf(buf+len, "Based on the original NE2000 drivers\n" );
- len += sprintf(buf+len, "Base IO: %#x\n", (unsigned int)dev->base_addr);
- len += sprintf(buf+len, "IRQ : %d\n", dev->irq);
- len += sprintf(buf+len, "HW addr : %pM\n", dev->dev_addr);
-
- return len;
-}
-
-static int __init ne2_probe1(struct net_device *dev, int slot)
-{
- int i, base_addr, irq, retval;
- unsigned char POS;
- unsigned char SA_prom[32];
- const char *name = "NE/2";
- int start_page, stop_page;
- static unsigned version_printed;
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- printk("NE/2 ethercard found in slot %d:", slot);
-
- /* Read base IO and IRQ from the POS-registers */
- POS = mca_read_stored_pos(slot, 2);
- if(!(POS % 2)) {
- printk(" disabled.\n");
- return -ENODEV;
- }
-
- /* handle different POS register structure for D-Link card */
-
- if (mca_read_stored_pos(slot, 0) == 0xea) {
- base_addr = dlink_addresses[(POS >> 5) & 0x03];
- irq = dlink_irqs[(POS >> 2) & 0x07];
- }
- else {
- i = (POS & 0xE)>>1;
- /* printk("Halleluja sdog, als er na de pijl een 1 staat is 1 - 1 == 0"
- " en zou het moeten werken -> %d\n", i);
- The above line was for remote testing, thanx to sdog ... */
- base_addr = addresses[i - 1];
- irq = irqs[(POS & 0x60)>>5];
- }
-
- if (!request_region(base_addr, NE_IO_EXTENT, DRV_NAME))
- return -EBUSY;
-
-#ifdef DEBUG
- printk("POS info : pos 2 = %#x ; base = %#x ; irq = %ld\n", POS,
- base_addr, irq);
-#endif
-
-#ifndef CRYNWR_WAY
- /* Reset the card the way they do it in the Crynwr packet driver */
- for (i=0; i<8; i++)
- outb(0x0, base_addr + NE_RESET);
- inb(base_addr + NE_RESET);
- outb(0x21, base_addr + NE_CMD);
- if (inb(base_addr + NE_CMD) != 0x21) {
- printk("NE/2 adapter not responding\n");
- retval = -ENODEV;
- goto out;
- }
-
- /* In the crynwr sources they do a RAM-test here. I skip it. I suppose
- my RAM is okay. Suppose your memory is broken. Then this test
- should fail and you won't be able to use your card. But if I do not
- test, you won't be able to use your card, neither. So this test
- won't help you. */
-
-#else /* _I_ never tested it this way .. Go ahead and try ...*/
- /* Reset card. Who knows what dain-bramaged state it was left in. */
- {
- unsigned long reset_start_time = jiffies;
-
- /* DON'T change these to inb_p/outb_p or reset will fail on
- clones.. */
- outb(inb(base_addr + NE_RESET), base_addr + NE_RESET);
-
- while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0)
- if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
- printk(" not found (no reset ack).\n");
- retval = -ENODEV;
- goto out;
- }
-
- outb_p(0xff, base_addr + EN0_ISR); /* Ack all intr. */
- }
-#endif
-
-
- /* Read the 16 bytes of station address PROM.
- We must first initialize registers, similar to
- NS8390p_init(eifdev, 0).
- We can't reliably read the SAPROM address without this.
- (I learned the hard way!). */
- {
- struct {
- unsigned char value, offset;
- } program_seq[] = {
- /* Select page 0 */
- {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD},
- {0x49, EN0_DCFG}, /* Set WORD-wide (0x49) access. */
- {0x00, EN0_RCNTLO}, /* Clear the count regs. */
- {0x00, EN0_RCNTHI},
- {0x00, EN0_IMR}, /* Mask completion irq. */
- {0xFF, EN0_ISR},
- {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
- {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
- {32, EN0_RCNTLO},
- {0x00, EN0_RCNTHI},
- {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
- {0x00, EN0_RSARHI},
- {E8390_RREAD+E8390_START, E8390_CMD},
- };
-
- for (i = 0; i < ARRAY_SIZE(program_seq); i++)
- outb_p(program_seq[i].value, base_addr +
- program_seq[i].offset);
-
- }
- for(i = 0; i < 6 /*sizeof(SA_prom)*/; i+=1) {
- SA_prom[i] = inb(base_addr + NE_DATAPORT);
- }
-
- /* I don't know whether the previous sequence includes the general
- board reset procedure, so better don't omit it and just overwrite
- the garbage read from a DE-320 with correct stuff. */
-
- if (mca_read_stored_pos(slot, 0) == 0xea) {
- unsigned int v;
-
- for (i = 0; i < 3; i++) {
- v = dlink_get_eeprom(i, base_addr);
- SA_prom[(i << 1) ] = v & 0xff;
- SA_prom[(i << 1) + 1] = (v >> 8) & 0xff;
- }
- }
-
- start_page = NESM_START_PG;
- stop_page = NESM_STOP_PG;
-
- dev->irq=irq;
-
- /* Snarf the interrupt now. There's no point in waiting since we cannot
- share and the board will usually be enabled. */
- retval = request_irq(dev->irq, eip_interrupt, 0, DRV_NAME, dev);
- if (retval) {
- printk (" unable to get IRQ %d (irqval=%d).\n",
- dev->irq, retval);
- goto out;
- }
-
- dev->base_addr = base_addr;
-
- for (i = 0; i < ETH_ALEN; i++)
- dev->dev_addr[i] = SA_prom[i];
-
- printk(" %pM\n", dev->dev_addr);
-
- printk("%s: %s found at %#x, using IRQ %d.\n",
- dev->name, name, base_addr, dev->irq);
-
- mca_set_adapter_procfn(slot, (MCA_ProcFn) ne2_procinfo, dev);
-
- ei_status.name = name;
- ei_status.tx_start_page = start_page;
- ei_status.stop_page = stop_page;
- ei_status.word16 = (2 == 2);
-
- ei_status.rx_start_page = start_page + TX_PAGES;
-#ifdef PACKETBUF_MEMSIZE
- /* Allow the packet buffer size to be overridden by know-it-alls. */
- ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
-#endif
-
- ei_status.reset_8390 = &ne_reset_8390;
- ei_status.block_input = &ne_block_input;
- ei_status.block_output = &ne_block_output;
- ei_status.get_8390_hdr = &ne_get_8390_hdr;
-
- ei_status.priv = slot;
-
- dev->netdev_ops = &eip_netdev_ops;
- NS8390p_init(dev, 0);
-
- retval = register_netdev(dev);
- if (retval)
- goto out1;
- return 0;
-out1:
- mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
- free_irq(dev->irq, dev);
-out:
- release_region(base_addr, NE_IO_EXTENT);
- return retval;
-}
-
-/* Hard reset the card. This used to pause for the same period that a
- 8390 reset command required, but that shouldn't be necessary. */
-static void ne_reset_8390(struct net_device *dev)
-{
- unsigned long reset_start_time = jiffies;
-
- if (ei_debug > 1)
- printk("resetting the 8390 t=%ld...", jiffies);
-
- /* DON'T change these to inb_p/outb_p or reset will fail on clones. */
- outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
-
- ei_status.txing = 0;
- ei_status.dmaing = 0;
-
- /* This check _should_not_ be necessary, omit eventually. */
- while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
- if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
- printk("%s: ne_reset_8390() did not complete.\n",
- dev->name);
- break;
- }
- outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */
-}
-
-/* Grab the 8390 specific header. Similar to the block_input routine, but
- we don't need to be concerned with ring wrap as the header will be at
- the start of a page, so we optimize accordingly. */
-
-static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page)
-{
-
- int nic_base = dev->base_addr;
-
- /* This *shouldn't* happen.
- If it does, it's the last thing you'll see */
- if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne_get_8390_hdr "
- "[DMAstat:%d][irqlock:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
- return;
- }
-
- ei_status.dmaing |= 0x01;
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
- outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
- outb_p(0, nic_base + EN0_RCNTHI);
- outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */
- outb_p(ring_page, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
-
- if (ei_status.word16)
- insw(NE_BASE + NE_DATAPORT, hdr,
- sizeof(struct e8390_pkt_hdr)>>1);
- else
- insb(NE_BASE + NE_DATAPORT, hdr,
- sizeof(struct e8390_pkt_hdr));
-
- outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
- ei_status.dmaing &= ~0x01;
-}
-
-/* Block input and output, similar to the Crynwr packet driver. If you
- are porting to a new ethercard, look at the packet driver source for
- hints. The NEx000 doesn't share the on-board packet memory -- you have
- to put the packet out through the "remote DMA" dataport using outb. */
-
-static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb,
- int ring_offset)
-{
-#ifdef NE_SANITY_CHECK
- int xfer_count = count;
-#endif
- int nic_base = dev->base_addr;
- char *buf = skb->data;
-
- /* This *shouldn't* happen.
- If it does, it's the last thing you'll see */
- if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne_block_input "
- "[DMAstat:%d][irqlock:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
- return;
- }
- ei_status.dmaing |= 0x01;
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
- outb_p(count & 0xff, nic_base + EN0_RCNTLO);
- outb_p(count >> 8, nic_base + EN0_RCNTHI);
- outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
- outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
- if (ei_status.word16) {
- insw(NE_BASE + NE_DATAPORT,buf,count>>1);
- if (count & 0x01) {
- buf[count-1] = inb(NE_BASE + NE_DATAPORT);
-#ifdef NE_SANITY_CHECK
- xfer_count++;
-#endif
- }
- } else {
- insb(NE_BASE + NE_DATAPORT, buf, count);
- }
-
-#ifdef NE_SANITY_CHECK
- /* This was for the ALPHA version only, but enough people have
- been encountering problems so it is still here. If you see
- this message you either 1) have a slightly incompatible clone
- or 2) have noise/speed problems with your bus. */
- if (ei_debug > 1) { /* DMA termination address check... */
- int addr, tries = 20;
- do {
- /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
- -- it's broken for Rx on some cards! */
- int high = inb_p(nic_base + EN0_RSARHI);
- int low = inb_p(nic_base + EN0_RSARLO);
- addr = (high << 8) + low;
- if (((ring_offset + xfer_count) & 0xff) == low)
- break;
- } while (--tries > 0);
- if (tries <= 0)
- printk("%s: RX transfer address mismatch,"
- "%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, ring_offset + xfer_count, addr);
- }
-#endif
- outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
- ei_status.dmaing &= ~0x01;
-}
-
-static void ne_block_output(struct net_device *dev, int count,
- const unsigned char *buf, const int start_page)
-{
- int nic_base = NE_BASE;
- unsigned long dma_start;
-#ifdef NE_SANITY_CHECK
- int retries = 0;
-#endif
-
- /* Round the count up for word writes. Do we need to do this?
- What effect will an odd byte count have on the 8390?
- I should check someday. */
- if (ei_status.word16 && (count & 0x01))
- count++;
-
- /* This *shouldn't* happen.
- If it does, it's the last thing you'll see */
- if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne_block_output."
- "[DMAstat:%d][irqlock:%d]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock);
- return;
- }
- ei_status.dmaing |= 0x01;
- /* We should already be in page 0, but to be safe... */
- outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
-
-#ifdef NE_SANITY_CHECK
-retry:
-#endif
-
-#ifdef NE8390_RW_BUGFIX
- /* Handle the read-before-write bug the same way as the
- Crynwr packet driver -- the NatSemi method doesn't work.
- Actually this doesn't always work either, but if you have
- problems with your NEx000 this is better than nothing! */
- outb_p(0x42, nic_base + EN0_RCNTLO);
- outb_p(0x00, nic_base + EN0_RCNTHI);
- outb_p(0x42, nic_base + EN0_RSARLO);
- outb_p(0x00, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
- /* Make certain that the dummy read has occurred. */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
-#endif
-
- outb_p(ENISR_RDC, nic_base + EN0_ISR);
-
- /* Now the normal output. */
- outb_p(count & 0xff, nic_base + EN0_RCNTLO);
- outb_p(count >> 8, nic_base + EN0_RCNTHI);
- outb_p(0x00, nic_base + EN0_RSARLO);
- outb_p(start_page, nic_base + EN0_RSARHI);
-
- outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
- if (ei_status.word16) {
- outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
- } else {
- outsb(NE_BASE + NE_DATAPORT, buf, count);
- }
-
- dma_start = jiffies;
-
-#ifdef NE_SANITY_CHECK
- /* This was for the ALPHA version only, but enough people have
- been encountering problems so it is still here. */
-
- if (ei_debug > 1) { /* DMA termination address check... */
- int addr, tries = 20;
- do {
- int high = inb_p(nic_base + EN0_RSARHI);
- int low = inb_p(nic_base + EN0_RSARLO);
- addr = (high << 8) + low;
- if ((start_page << 8) + count == addr)
- break;
- } while (--tries > 0);
- if (tries <= 0) {
- printk("%s: Tx packet transfer address mismatch,"
- "%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, (start_page << 8) + count, addr);
- if (retries++ == 0)
- goto retry;
- }
- }
-#endif
-
- while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
- if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */
- printk("%s: timeout waiting for Tx RDC.\n", dev->name);
- ne_reset_8390(dev);
- NS8390p_init(dev, 1);
- break;
- }
-
- outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
- ei_status.dmaing &= ~0x01;
-}
-
-
-#ifdef MODULE
-#define MAX_NE_CARDS 4 /* Max number of NE cards per module */
-static struct net_device *dev_ne[MAX_NE_CARDS];
-static int io[MAX_NE_CARDS];
-static int irq[MAX_NE_CARDS];
-static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */
-MODULE_LICENSE("GPL");
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(bad, int, NULL, 0);
-MODULE_PARM_DESC(io, "(ignored)");
-MODULE_PARM_DESC(irq, "(ignored)");
-MODULE_PARM_DESC(bad, "(ignored)");
-
-/* Module code fixed by David Weinehall */
-
-int __init init_module(void)
-{
- struct net_device *dev;
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
- dev = alloc_eip_netdev();
- if (!dev)
- break;
- dev->irq = irq[this_dev];
- dev->mem_end = bad[this_dev];
- dev->base_addr = io[this_dev];
- if (do_ne2_probe(dev) == 0) {
- dev_ne[found++] = dev;
- continue;
- }
- free_netdev(dev);
- break;
- }
- if (found)
- return 0;
- printk(KERN_WARNING "ne2.c: No NE/2 card found\n");
- return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
- mca_mark_as_unused(ei_status.priv);
- mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, NE_IO_EXTENT);
-}
-
-void __exit cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
- struct net_device *dev = dev_ne[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/8390/smc-mca.c b/drivers/net/ethernet/8390/smc-mca.c
deleted file mode 100644
index 7a68590f2804..000000000000
--- a/drivers/net/ethernet/8390/smc-mca.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* smc-mca.c: A SMC Ultra ethernet driver for linux. */
-/*
- Most of this driver, except for ultramca_probe is nearly
- verbatim from smc-ultra.c by Donald Becker. The rest is
- written and copyright 1996 by David Weis, weisd3458@uni.edu
-
- This is a driver for the SMC Ultra and SMC EtherEZ ethercards.
-
- This driver uses the cards in the 8390-compatible, shared memory mode.
- Most of the run-time complexity is handled by the generic code in
- 8390.c.
-
- This driver enables the shared memory only when doing the actual data
- transfers to avoid a bug in early version of the card that corrupted
- data transferred by a AHA1542.
-
- This driver does not support the programmed-I/O data transfer mode of
- the EtherEZ. That support (if available) is smc-ez.c. Nor does it
- use the non-8390-compatible "Altego" mode. (No support currently planned.)
-
- Changelog:
-
- Paul Gortmaker : multiple card support for module users.
- David Weis : Micro Channel-ized it.
- Tom Sightler : Added support for IBM PS/2 Ethernet Adapter/A
- Christopher Turcksin : Changed MCA-probe so that multiple adapters are
- found correctly (Jul 16, 1997)
- Chris Beauregard : Tried to merge the two changes above (Dec 15, 1997)
- Tom Sightler : Fixed minor detection bug caused by above merge
- Tom Sightler : Added support for three more Western Digital
- MCA-adapters
- Tom Sightler : Added support for 2.2.x mca_find_unused_adapter
- Hartmut Schmidt : - Modified parameter detection to handle each
- card differently depending on a switch-list
- - 'card_ver' removed from the adapter list
- - Some minor bug fixes
-*/
-
-#include <linux/mca.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-#include <asm/io.h>
-
-#include "8390.h"
-
-#define DRV_NAME "smc-mca"
-
-static int ultramca_open(struct net_device *dev);
-static void ultramca_reset_8390(struct net_device *dev);
-static void ultramca_get_8390_hdr(struct net_device *dev,
- struct e8390_pkt_hdr *hdr,
- int ring_page);
-static void ultramca_block_input(struct net_device *dev, int count,
- struct sk_buff *skb,
- int ring_offset);
-static void ultramca_block_output(struct net_device *dev, int count,
- const unsigned char *buf,
- const int start_page);
-static int ultramca_close_card(struct net_device *dev);
-
-#define START_PG 0x00 /* First page of TX buffer */
-
-#define ULTRA_CMDREG 0 /* Offset to ASIC command register. */
-#define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */
-#define ULTRA_MEMENB 0x40 /* Enable the shared memory. */
-#define ULTRA_NIC_OFFSET 16 /* NIC register offset from the base_addr. */
-#define ULTRA_IO_EXTENT 32
-#define EN0_ERWCNT 0x08 /* Early receive warning count. */
-
-#define _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A 0
-#define _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A 1
-#define _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A 2
-#define _6fc1_WD_Starcard_PLUS_A_WD8003ST_A 3
-#define _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A 4
-#define _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A 5
-#define _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A 6
-#define _efe5_IBM_PS2_Adapter_A_for_Ethernet 7
-
-struct smc_mca_adapters_t {
- unsigned int id;
- char *name;
-};
-
-#define MAX_ULTRAMCA_CARDS 4 /* Max number of Ultra cards per module */
-
-static int ultra_io[MAX_ULTRAMCA_CARDS];
-static int ultra_irq[MAX_ULTRAMCA_CARDS];
-MODULE_LICENSE("GPL");
-
-module_param_array(ultra_io, int, NULL, 0);
-module_param_array(ultra_irq, int, NULL, 0);
-MODULE_PARM_DESC(ultra_io, "SMC Ultra/EtherEZ MCA I/O base address(es)");
-MODULE_PARM_DESC(ultra_irq, "SMC Ultra/EtherEZ MCA IRQ number(s)");
-
-static const struct {
- unsigned int base_addr;
-} addr_table[] = {
- { 0x0800 },
- { 0x1800 },
- { 0x2800 },
- { 0x3800 },
- { 0x4800 },
- { 0x5800 },
- { 0x6800 },
- { 0x7800 },
- { 0x8800 },
- { 0x9800 },
- { 0xa800 },
- { 0xb800 },
- { 0xc800 },
- { 0xd800 },
- { 0xe800 },
- { 0xf800 }
-};
-
-#define MEM_MASK 64
-
-static const struct {
- unsigned char mem_index;
- unsigned long mem_start;
- unsigned char num_pages;
-} mem_table[] = {
- { 16, 0x0c0000, 40 },
- { 18, 0x0c4000, 40 },
- { 20, 0x0c8000, 40 },
- { 22, 0x0cc000, 40 },
- { 24, 0x0d0000, 40 },
- { 26, 0x0d4000, 40 },
- { 28, 0x0d8000, 40 },
- { 30, 0x0dc000, 40 },
- {144, 0xfc0000, 40 },
- {148, 0xfc8000, 40 },
- {154, 0xfd0000, 40 },
- {156, 0xfd8000, 40 },
- { 0, 0x0c0000, 20 },
- { 1, 0x0c2000, 20 },
- { 2, 0x0c4000, 20 },
- { 3, 0x0c6000, 20 }
-};
-
-#define IRQ_MASK 243
-static const struct {
- unsigned char new_irq;
- unsigned char old_irq;
-} irq_table[] = {
- { 3, 3 },
- { 4, 4 },
- { 10, 10 },
- { 14, 15 }
-};
-
-static short smc_mca_adapter_ids[] __initdata = {
- 0x61c8,
- 0x61c9,
- 0x6fc0,
- 0x6fc1,
- 0x6fc2,
- 0xefd4,
- 0xefd5,
- 0xefe5,
- 0x0000
-};
-
-static char *smc_mca_adapter_names[] __initdata = {
- "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)",
- "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)",
- "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)",
- "WD Starcard PLUS/A (WD8003ST/A)",
- "WD Ethercard PLUS 10T/A (WD8003W/A)",
- "IBM PS/2 Adapter/A for Ethernet UTP/AUI (WD8013WP/A)",
- "IBM PS/2 Adapter/A for Ethernet BNC/AUI (WD8013EP/A)",
- "IBM PS/2 Adapter/A for Ethernet",
- NULL
-};
-
-static int ultra_found = 0;
-
-
-static const struct net_device_ops ultramca_netdev_ops = {
- .ndo_open = ultramca_open,
- .ndo_stop = ultramca_close_card,
-
- .ndo_start_xmit = ei_start_xmit,
- .ndo_tx_timeout = ei_tx_timeout,
- .ndo_get_stats = ei_get_stats,
- .ndo_set_rx_mode = ei_set_multicast_list,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_change_mtu = eth_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = ei_poll,
-#endif
-};
-
-static int __init ultramca_probe(struct device *gen_dev)
-{
- unsigned short ioaddr;
- struct net_device *dev;
- unsigned char reg4, num_pages;
- struct mca_device *mca_dev = to_mca_device(gen_dev);
- char slot = mca_dev->slot;
- unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff;
- int i, rc;
- int adapter = mca_dev->index;
- int tbase = 0;
- int tirq = 0;
- int base_addr = ultra_io[ultra_found];
- int irq = ultra_irq[ultra_found];
-
- if (base_addr || irq) {
- printk(KERN_INFO "Probing for SMC MCA adapter");
- if (base_addr) {
- printk(KERN_INFO " at I/O address 0x%04x%c",
- base_addr, irq ? ' ' : '\n');
- }
- if (irq) {
- printk(KERN_INFO "using irq %d\n", irq);
- }
- }
-
- tirq = 0;
- tbase = 0;
-
- /* If we're trying to match a specificied irq or io address,
- * we'll reject the adapter found unless it's the one we're
- * looking for */
-
- pos2 = mca_device_read_stored_pos(mca_dev, 2); /* io_addr */
- pos3 = mca_device_read_stored_pos(mca_dev, 3); /* shared mem */
- pos4 = mca_device_read_stored_pos(mca_dev, 4); /* ROM bios addr range */
- pos5 = mca_device_read_stored_pos(mca_dev, 5); /* irq, media and RIPL */
-
- /* Test the following conditions:
- * - If an irq parameter is supplied, compare it
- * with the irq of the adapter we found
- * - If a base_addr paramater is given, compare it
- * with the base_addr of the adapter we found
- * - Check that the irq and the base_addr of the
- * adapter we found is not already in use by
- * this driver
- */
-
- switch (mca_dev->index) {
- case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A:
- case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A:
- case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A:
- case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A:
- {
- tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr;
- tirq = irq_table[(pos5 & 0xc) >> 2].new_irq;
- break;
- }
- case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A:
- case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A:
- case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A:
- case _efe5_IBM_PS2_Adapter_A_for_Ethernet:
- {
- tbase = ((pos2 & 0x0fe) * 0x10);
- tirq = irq_table[(pos5 & 3)].old_irq;
- break;
- }
- }
-
- if(!tirq || !tbase ||
- (irq && irq != tirq) ||
- (base_addr && tbase != base_addr))
- /* FIXME: we're trying to force the ordering of the
- * devices here, there should be a way of getting this
- * to happen */
- return -ENXIO;
-
- /* Adapter found. */
- dev = alloc_ei_netdev();
- if(!dev)
- return -ENODEV;
-
- SET_NETDEV_DEV(dev, gen_dev);
- mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]);
- mca_device_set_claim(mca_dev, 1);
-
- printk(KERN_INFO "smc_mca: %s found in slot %d\n",
- smc_mca_adapter_names[adapter], slot + 1);
-
- ultra_found++;
-
- dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase);
- dev->irq = mca_device_transform_irq(mca_dev, tirq);
- dev->mem_start = 0;
- num_pages = 40;
-
- switch (adapter) { /* card-# in const array above [hs] */
- case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A:
- case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A:
- {
- for (i = 0; i < 16; i++) { /* taking 16 counts
- * up to 15 [hs] */
- if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) {
- dev->mem_start = (unsigned long)
- mca_device_transform_memory(mca_dev, (void *)mem_table[i].mem_start);
- num_pages = mem_table[i].num_pages;
- }
- }
- break;
- }
- case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A:
- case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A:
- case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A:
- case _efe5_IBM_PS2_Adapter_A_for_Ethernet:
- {
- dev->mem_start = (unsigned long)
- mca_device_transform_memory(mca_dev, (void *)((pos3 & 0xfc) * 0x1000));
- num_pages = 0x40;
- break;
- }
- case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A:
- case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A:
- {
- /* courtesy of gamera@quartz.ocn.ne.jp, pos3 indicates
- * the index of the 0x2000 step.
- * beware different number of pages [hs]
- */
- dev->mem_start = (unsigned long)
- mca_device_transform_memory(mca_dev, (void *)(0xc0000 + (0x2000 * (pos3 & 0xf))));
- num_pages = 0x20 + (2 * (pos3 & 0x10));
- break;
- }
- }
-
- /* sanity check, shouldn't happen */
- if (dev->mem_start == 0) {
- rc = -ENODEV;
- goto err_unclaim;
- }
-
- if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) {
- rc = -ENODEV;
- goto err_unclaim;
- }
-
- reg4 = inb(ioaddr + 4) & 0x7f;
- outb(reg4, ioaddr + 4);
-
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + 8 + i);
-
- printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x, %pM",
- slot + 1, ioaddr, dev->dev_addr);
-
- /* Switch from the station address to the alternate register set
- * and read the useful registers there.
- */
-
- outb(0x80 | reg4, ioaddr + 4);
-
- /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot.
- */
-
- outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);
-
- /* Switch back to the station address register set so that
- * the MS-DOS driver can find the card after a warm boot.
- */
-
- outb(reg4, ioaddr + 4);
-
- dev_set_drvdata(gen_dev, dev);
-
- /* The 8390 isn't at the base address, so fake the offset
- */
-
- dev->base_addr = ioaddr + ULTRA_NIC_OFFSET;
-
- ei_status.name = "SMC Ultra MCA";
- ei_status.word16 = 1;
- ei_status.tx_start_page = START_PG;
- ei_status.rx_start_page = START_PG + TX_PAGES;
- ei_status.stop_page = num_pages;
-
- ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG) * 256);
- if (!ei_status.mem) {
- rc = -ENOMEM;
- goto err_release_region;
- }
-
- dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG) * 256;
-
- printk(", IRQ %d memory %#lx-%#lx.\n",
- dev->irq, dev->mem_start, dev->mem_end - 1);
-
- ei_status.reset_8390 = &ultramca_reset_8390;
- ei_status.block_input = &ultramca_block_input;
- ei_status.block_output = &ultramca_block_output;
- ei_status.get_8390_hdr = &ultramca_get_8390_hdr;
-
- ei_status.priv = slot;
-
- dev->netdev_ops = &ultramca_netdev_ops;
-
- NS8390_init(dev, 0);
-
- rc = register_netdev(dev);
- if (rc)
- goto err_unmap;
-
- return 0;
-
-err_unmap:
- iounmap(ei_status.mem);
-err_release_region:
- release_region(ioaddr, ULTRA_IO_EXTENT);
-err_unclaim:
- mca_device_set_claim(mca_dev, 0);
- free_netdev(dev);
- return rc;
-}
-
-static int ultramca_open(struct net_device *dev)
-{
- int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
- int retval;
-
- if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev)))
- return retval;
-
- outb(ULTRA_MEMENB, ioaddr); /* Enable memory */
- outb(0x80, ioaddr + 5); /* ??? */
- outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */
- outb(0x04, ioaddr + 5); /* ??? */
-
- /* Set the early receive warning level in window 0 high enough not
- * to receive ERW interrupts.
- */
-
- /* outb_p(E8390_NODMA + E8390_PAGE0, dev->base_addr);
- * outb(0xff, dev->base_addr + EN0_ERWCNT);
- */
-
- ei_open(dev);
- return 0;
-}
-
-static void ultramca_reset_8390(struct net_device *dev)
-{
- int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
-
- outb(ULTRA_RESET, ioaddr);
- if (ei_debug > 1)
- printk("resetting Ultra, t=%ld...", jiffies);
- ei_status.txing = 0;
-
- outb(0x80, ioaddr + 5); /* ??? */
- outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */
-
- if (ei_debug > 1)
- printk("reset done\n");
-}
-
-/* Grab the 8390 specific header. Similar to the block_input routine, but
- * we don't need to be concerned with ring wrap as the header will be at
- * the start of a page, so we optimize accordingly.
- */
-
-static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG) << 8);
-
-#ifdef notdef
- /* Officially this is what we are doing, but the readl() is faster */
- memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
-#else
- ((unsigned int*)hdr)[0] = readl(hdr_start);
-#endif
-}
-
-/* Block input and output are easy on shared memory ethercards, the only
- * complication is when the ring buffer wraps.
- */
-
-static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- void __iomem *xfer_start = ei_status.mem + ring_offset - START_PG * 256;
-
- if (ring_offset + count > ei_status.stop_page * 256) {
- /* We must wrap the input move. */
- int semi_count = ei_status.stop_page * 256 - ring_offset;
- memcpy_fromio(skb->data, xfer_start, semi_count);
- count -= semi_count;
- memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
- } else {
- memcpy_fromio(skb->data, xfer_start, count);
- }
-
-}
-
-static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf,
- int start_page)
-{
- void __iomem *shmem = ei_status.mem + ((start_page - START_PG) << 8);
-
- memcpy_toio(shmem, buf, count);
-}
-
-static int ultramca_close_card(struct net_device *dev)
-{
- int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
-
- netif_stop_queue(dev);
-
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
-
- outb(0x00, ioaddr + 6); /* Disable interrupts. */
- free_irq(dev->irq, dev);
-
- NS8390_init(dev, 0);
- /* We should someday disable shared memory and change to 8-bit mode
- * "just in case"...
- */
-
- return 0;
-}
-
-static int ultramca_remove(struct device *gen_dev)
-{
- struct mca_device *mca_dev = to_mca_device(gen_dev);
- struct net_device *dev = dev_get_drvdata(gen_dev);
-
- if (dev) {
- /* NB: ultra_close_card() does free_irq */
- int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
-
- unregister_netdev(dev);
- mca_device_set_claim(mca_dev, 0);
- release_region(ioaddr, ULTRA_IO_EXTENT);
- iounmap(ei_status.mem);
- free_netdev(dev);
- }
- return 0;
-}
-
-
-static struct mca_driver ultra_driver = {
- .id_table = smc_mca_adapter_ids,
- .driver = {
- .name = "smc-mca",
- .bus = &mca_bus_type,
- .probe = ultramca_probe,
- .remove = ultramca_remove,
- }
-};
-
-static int __init ultramca_init_module(void)
-{
- if(!MCA_bus)
- return -ENXIO;
-
- mca_register_driver(&ultra_driver);
-
- return ultra_found ? 0 : -ENXIO;
-}
-
-static void __exit ultramca_cleanup_module(void)
-{
- mca_unregister_driver(&ultra_driver);
-}
-module_init(ultramca_init_module);
-module_exit(ultramca_cleanup_module);
-
diff --git a/drivers/net/ethernet/amd/ariadne.c b/drivers/net/ethernet/amd/ariadne.c
index f4c228e4d76c..f2958df9a1e4 100644
--- a/drivers/net/ethernet/amd/ariadne.c
+++ b/drivers/net/ethernet/amd/ariadne.c
@@ -213,10 +213,10 @@ static int ariadne_rx(struct net_device *dev)
(const void *)priv->rx_buff[entry],
pkt_len);
skb->protocol = eth_type_trans(skb, dev);
- netdev_dbg(dev, "RX pkt type 0x%04x from %pM to %pM data 0x%08x len %d\n",
+ netdev_dbg(dev, "RX pkt type 0x%04x from %pM to %pM data %p len %u\n",
((u_short *)skb->data)[6],
skb->data + 6, skb->data,
- (int)skb->data, (int)skb->len);
+ skb->data, skb->len);
netif_rx(skb);
dev->stats.rx_packets++;
@@ -566,10 +566,10 @@ static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb,
/* Fill in a Tx ring entry */
- netdev_dbg(dev, "TX pkt type 0x%04x from %pM to %pM data 0x%08x len %d\n",
+ netdev_dbg(dev, "TX pkt type 0x%04x from %pM to %pM data %p len %u\n",
((u_short *)skb->data)[6],
skb->data + 6, skb->data,
- (int)skb->data, (int)skb->len);
+ skb->data, skb->len);
local_irq_save(flags);
diff --git a/drivers/net/ethernet/amd/atarilance.c b/drivers/net/ethernet/amd/atarilance.c
index 70ed79c46245..84219df72f51 100644
--- a/drivers/net/ethernet/amd/atarilance.c
+++ b/drivers/net/ethernet/amd/atarilance.c
@@ -558,21 +558,18 @@ static unsigned long __init lance_probe1( struct net_device *dev,
printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 );
return 0;
}
- dev->irq = (unsigned short)IRQ_AUTO_5;
+ dev->irq = IRQ_AUTO_5;
}
else {
- /* For VME-RieblCards, request a free VME int;
- * (This must be unsigned long, since dev->irq is short and the
- * IRQ_MACHSPEC bit would be cut off...)
- */
- unsigned long irq = atari_register_vme_int();
+ /* For VME-RieblCards, request a free VME int */
+ unsigned int irq = atari_register_vme_int();
if (!irq) {
printk( "Lance: request for VME interrupt failed\n" );
return 0;
}
if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
"Riebl-VME Ethernet", dev)) {
- printk( "Lance: request for irq %ld failed\n", irq );
+ printk( "Lance: request for irq %u failed\n", irq );
return 0;
}
dev->irq = irq;
diff --git a/drivers/net/ethernet/amd/depca.c b/drivers/net/ethernet/amd/depca.c
index 86dd95766a64..c771de71612a 100644
--- a/drivers/net/ethernet/amd/depca.c
+++ b/drivers/net/ethernet/amd/depca.c
@@ -155,23 +155,10 @@
2 depca's in a PC).
************************************************************************
- Support for MCA EtherWORKS cards added 11-3-98.
+ Support for MCA EtherWORKS cards added 11-3-98. (MCA since deleted)
Verified to work with up to 2 DE212 cards in a system (although not
fully stress-tested).
- Currently known bugs/limitations:
-
- Note: with the MCA stuff as a module, it trusts the MCA configuration,
- not the command line for IRQ and memory address. You can
- specify them if you want, but it will throw your values out.
- You still have to pass the IO address it was configured as
- though.
-
- ************************************************************************
- TO DO:
- ------
-
-
Revision History
----------------
@@ -261,10 +248,6 @@
#include <asm/io.h>
#include <asm/dma.h>
-#ifdef CONFIG_MCA
-#include <linux/mca.h>
-#endif
-
#ifdef CONFIG_EISA
#include <linux/eisa.h>
#endif
@@ -360,44 +343,6 @@ static struct eisa_driver depca_eisa_driver = {
};
#endif
-#ifdef CONFIG_MCA
-/*
-** Adapter ID for the MCA EtherWORKS DE210/212 adapter
-*/
-#define DE210_ID 0x628d
-#define DE212_ID 0x6def
-
-static short depca_mca_adapter_ids[] = {
- DE210_ID,
- DE212_ID,
- 0x0000
-};
-
-static char *depca_mca_adapter_name[] = {
- "DEC EtherWORKS MC Adapter (DE210)",
- "DEC EtherWORKS MC Adapter (DE212)",
- NULL
-};
-
-static enum depca_type depca_mca_adapter_type[] = {
- de210,
- de212,
- 0
-};
-
-static int depca_mca_probe (struct device *);
-
-static struct mca_driver depca_mca_driver = {
- .id_table = depca_mca_adapter_ids,
- .driver = {
- .name = depca_string,
- .bus = &mca_bus_type,
- .probe = depca_mca_probe,
- .remove = __devexit_p(depca_device_remove),
- },
-};
-#endif
-
static int depca_isa_probe (struct platform_device *);
static int __devexit depca_isa_remove(struct platform_device *pdev)
@@ -464,8 +409,7 @@ struct depca_private {
char adapter_name[DEPCA_STRLEN]; /* /proc/ioports string */
enum depca_type adapter; /* Adapter type */
enum {
- DEPCA_BUS_MCA = 1,
- DEPCA_BUS_ISA,
+ DEPCA_BUS_ISA = 1,
DEPCA_BUS_EISA,
} depca_bus; /* type of bus */
struct depca_init init_block; /* Shadow Initialization block */
@@ -624,12 +568,6 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
dev_name(device), depca_signature[lp->adapter], ioaddr);
switch (lp->depca_bus) {
-#ifdef CONFIG_MCA
- case DEPCA_BUS_MCA:
- printk(" (MCA slot %d)", to_mca_device(device)->slot + 1);
- break;
-#endif
-
#ifdef CONFIG_EISA
case DEPCA_BUS_EISA:
printk(" (EISA slot %d)", to_eisa_device(device)->slot);
@@ -661,10 +599,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
if (nicsr & BUF) {
nicsr &= ~BS; /* DEPCA RAM in top 32k */
netRAM -= 32;
-
- /* Only EISA/ISA needs start address to be re-computed */
- if (lp->depca_bus != DEPCA_BUS_MCA)
- mem_start += 0x8000;
+ mem_start += 0x8000;
}
if ((mem_len = (NUM_RX_DESC * (sizeof(struct depca_rx_desc) + RX_BUFF_SZ) + NUM_TX_DESC * (sizeof(struct depca_tx_desc) + TX_BUFF_SZ) + sizeof(struct depca_init)))
@@ -1079,7 +1014,8 @@ static int depca_rx(struct net_device *dev)
} else {
lp->pktStats.multicast++;
}
- } else if (compare_ether_addr(buf, dev->dev_addr) == 0) {
+ } else if (ether_addr_equal(buf,
+ dev->dev_addr)) {
lp->pktStats.unicast++;
}
@@ -1324,130 +1260,6 @@ static int __init depca_common_init (u_long ioaddr, struct net_device **devp)
return status;
}
-#ifdef CONFIG_MCA
-/*
-** Microchannel bus I/O device probe
-*/
-static int __init depca_mca_probe(struct device *device)
-{
- unsigned char pos[2];
- unsigned char where;
- unsigned long iobase, mem_start;
- int irq, err;
- struct mca_device *mdev = to_mca_device (device);
- struct net_device *dev;
- struct depca_private *lp;
-
- /*
- ** Search for the adapter. If an address has been given, search
- ** specifically for the card at that address. Otherwise find the
- ** first card in the system.
- */
-
- pos[0] = mca_device_read_stored_pos(mdev, 2);
- pos[1] = mca_device_read_stored_pos(mdev, 3);
-
- /*
- ** IO of card is handled by bits 1 and 2 of pos0.
- **
- ** bit2 bit1 IO
- ** 0 0 0x2c00
- ** 0 1 0x2c10
- ** 1 0 0x2c20
- ** 1 1 0x2c30
- */
- where = (pos[0] & 6) >> 1;
- iobase = 0x2c00 + (0x10 * where);
-
- /*
- ** Found the adapter we were looking for. Now start setting it up.
- **
- ** First work on decoding the IRQ. It's stored in the lower 4 bits
- ** of pos1. Bits are as follows (from the ADF file):
- **
- ** Bits
- ** 3 2 1 0 IRQ
- ** --------------------
- ** 0 0 1 0 5
- ** 0 0 0 1 9
- ** 0 1 0 0 10
- ** 1 0 0 0 11
- */
- where = pos[1] & 0x0f;
- switch (where) {
- case 1:
- irq = 9;
- break;
- case 2:
- irq = 5;
- break;
- case 4:
- irq = 10;
- break;
- case 8:
- irq = 11;
- break;
- default:
- printk("%s: mca_probe IRQ error. You should never get here (%d).\n", mdev->name, where);
- return -EINVAL;
- }
-
- /*
- ** Shared memory address of adapter is stored in bits 3-5 of pos0.
- ** They are mapped as follows:
- **
- ** Bit
- ** 5 4 3 Memory Addresses
- ** 0 0 0 C0000-CFFFF (64K)
- ** 1 0 0 C8000-CFFFF (32K)
- ** 0 0 1 D0000-DFFFF (64K)
- ** 1 0 1 D8000-DFFFF (32K)
- ** 0 1 0 E0000-EFFFF (64K)
- ** 1 1 0 E8000-EFFFF (32K)
- */
- where = (pos[0] & 0x18) >> 3;
- mem_start = 0xc0000 + (where * 0x10000);
- if (pos[0] & 0x20) {
- mem_start += 0x8000;
- }
-
- /* claim the slot */
- strncpy(mdev->name, depca_mca_adapter_name[mdev->index],
- sizeof(mdev->name));
- mca_device_set_claim(mdev, 1);
-
- /*
- ** Get everything allocated and initialized... (almost just
- ** like the ISA and EISA probes)
- */
- irq = mca_device_transform_irq(mdev, irq);
- iobase = mca_device_transform_ioport(mdev, iobase);
-
- if ((err = depca_common_init (iobase, &dev)))
- goto out_unclaim;
-
- dev->irq = irq;
- dev->base_addr = iobase;
- lp = netdev_priv(dev);
- lp->depca_bus = DEPCA_BUS_MCA;
- lp->adapter = depca_mca_adapter_type[mdev->index];
- lp->mem_start = mem_start;
-
- if ((err = depca_hw_init(dev, device)))
- goto out_free;
-
- return 0;
-
- out_free:
- free_netdev (dev);
- release_region (iobase, DEPCA_TOTAL_SIZE);
- out_unclaim:
- mca_device_set_claim(mdev, 0);
-
- return err;
-}
-#endif
-
/*
** ISA bus I/O device probe
*/
@@ -2058,15 +1870,10 @@ static int __init depca_module_init (void)
{
int err = 0;
-#ifdef CONFIG_MCA
- err = mca_register_driver(&depca_mca_driver);
- if (err)
- goto err;
-#endif
#ifdef CONFIG_EISA
err = eisa_driver_register(&depca_eisa_driver);
if (err)
- goto err_mca;
+ goto err_eisa;
#endif
err = platform_driver_register(&depca_isa_driver);
if (err)
@@ -2078,11 +1885,6 @@ static int __init depca_module_init (void)
err_eisa:
#ifdef CONFIG_EISA
eisa_driver_unregister(&depca_eisa_driver);
-err_mca:
-#endif
-#ifdef CONFIG_MCA
- mca_unregister_driver(&depca_mca_driver);
-err:
#endif
return err;
}
@@ -2090,9 +1892,6 @@ err:
static void __exit depca_module_exit (void)
{
int i;
-#ifdef CONFIG_MCA
- mca_unregister_driver (&depca_mca_driver);
-#endif
#ifdef CONFIG_EISA
eisa_driver_unregister (&depca_eisa_driver);
#endif
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 39b92f5ed7dd..d55df3290174 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -195,15 +195,6 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
#define TG3_RX_OFFSET(tp) (NET_SKB_PAD)
#endif
-/* This driver uses the new build_skb() API providing a frag as skb->head
- * This strategy permits better GRO aggregation, better TCP coalescing, and
- * better splice() implementation (avoids a copy from head to a page), at
- * minimal memory cost.
- * In this 2048 bytes block, we have enough room to store the MTU=1500 frame
- * and the struct skb_shared_info.
- */
-#define TG3_FRAGSIZE 2048
-
/* minimum number of free TX descriptors required to wake up TX process */
#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4)
#define TG3_TX_BD_DMA_MAX_2K 2048
@@ -5631,25 +5622,6 @@ static void tg3_tx(struct tg3_napi *tnapi)
}
}
-static void *tg3_frag_alloc(struct tg3_rx_prodring_set *tpr)
-{
- void *data;
-
- if (tpr->rx_page_size < TG3_FRAGSIZE) {
- struct page *page = alloc_page(GFP_ATOMIC);
-
- if (!page)
- return NULL;
- atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count);
- tpr->rx_page_addr = page_address(page);
- tpr->rx_page_size = PAGE_SIZE;
- }
- data = tpr->rx_page_addr;
- tpr->rx_page_addr += TG3_FRAGSIZE;
- tpr->rx_page_size -= TG3_FRAGSIZE;
- return data;
-}
-
static void tg3_frag_free(bool is_frag, void *data)
{
if (is_frag)
@@ -5668,7 +5640,7 @@ static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping),
map_sz, PCI_DMA_FROMDEVICE);
- tg3_frag_free(skb_size <= TG3_FRAGSIZE, ri->data);
+ tg3_frag_free(skb_size <= PAGE_SIZE, ri->data);
ri->data = NULL;
}
@@ -5721,9 +5693,9 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
*/
skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) +
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
- if (skb_size <= TG3_FRAGSIZE) {
- data = tg3_frag_alloc(tpr);
- *frag_size = TG3_FRAGSIZE;
+ if (skb_size <= PAGE_SIZE) {
+ data = netdev_alloc_frag(skb_size);
+ *frag_size = skb_size;
} else {
data = kmalloc(skb_size, GFP_ATOMIC);
*frag_size = 0;
@@ -5736,7 +5708,7 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
data_size,
PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(tp->pdev, mapping))) {
- tg3_frag_free(skb_size <= TG3_FRAGSIZE, data);
+ tg3_frag_free(skb_size <= PAGE_SIZE, data);
return -EIO;
}
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 7c855455d937..93865f899a4f 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2815,8 +2815,6 @@ struct tg3_rx_prodring_set {
struct ring_info *rx_jmb_buffers;
dma_addr_t rx_std_mapping;
dma_addr_t rx_jmb_mapping;
- void *rx_page_addr;
- unsigned int rx_page_size;
};
#define TG3_IRQ_MAX_VECS_RSS 5
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c
index b9406cbfc180..845b2020f291 100644
--- a/drivers/net/ethernet/cirrus/cs89x0.c
+++ b/drivers/net/ethernet/cirrus/cs89x0.c
@@ -1,105 +1,27 @@
/* cs89x0.c: A Crystal Semiconductor (Now Cirrus Logic) CS89[02]0
- * driver for linux.
+ * driver for linux.
+ * Written 1996 by Russell Nelson, with reference to skeleton.c
+ * written 1993-1994 by Donald Becker.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * The author may be reached at nelson@crynwr.com, Crynwr
+ * Software, 521 Pleasant Valley Rd., Potsdam, NY 13676
+ *
+ * Other contributors:
+ * Mike Cruse : mcruse@cti-ltd.com
+ * Russ Nelson
+ * Melody Lee : ethernet@crystal.cirrus.com
+ * Alan Cox
+ * Andrew Morton
+ * Oskar Schirmer : oskar@scara.com
+ * Deepak Saxena : dsaxena@plexity.net
+ * Dmitry Pervushin : dpervushin@ru.mvista.com
+ * Deepak Saxena : dsaxena@plexity.net
+ * Domenico Andreoli : cavokz@gmail.com
*/
-/*
- Written 1996 by Russell Nelson, with reference to skeleton.c
- written 1993-1994 by Donald Becker.
-
- This software may be used and distributed according to the terms
- of the GNU General Public License, incorporated herein by reference.
-
- The author may be reached at nelson@crynwr.com, Crynwr
- Software, 521 Pleasant Valley Rd., Potsdam, NY 13676
-
- Changelog:
-
- Mike Cruse : mcruse@cti-ltd.com
- : Changes for Linux 2.0 compatibility.
- : Added dev_id parameter in net_interrupt(),
- : request_irq() and free_irq(). Just NULL for now.
-
- Mike Cruse : Added MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros
- : in net_open() and net_close() so kerneld would know
- : that the module is in use and wouldn't eject the
- : driver prematurely.
-
- Mike Cruse : Rewrote init_module() and cleanup_module using 8390.c
- : as an example. Disabled autoprobing in init_module(),
- : not a good thing to do to other devices while Linux
- : is running from all accounts.
-
- Russ Nelson : Jul 13 1998. Added RxOnly DMA support.
-
- Melody Lee : Aug 10 1999. Changes for Linux 2.2.5 compatibility.
- : email: ethernet@crystal.cirrus.com
-
- Alan Cox : Removed 1.2 support, added 2.1 extra counters.
-
- Andrew Morton : Kernel 2.3.48
- : Handle kmalloc() failures
- : Other resource allocation fixes
- : Add SMP locks
- : Integrate Russ Nelson's ALLOW_DMA functionality back in.
- : If ALLOW_DMA is true, make DMA runtime selectable
- : Folded in changes from Cirrus (Melody Lee
- : <klee@crystal.cirrus.com>)
- : Don't call netif_wake_queue() in net_send_packet()
- : Fixed an out-of-mem bug in dma_rx()
- : Updated Documentation/networking/cs89x0.txt
-
- Andrew Morton : Kernel 2.3.99-pre1
- : Use skb_reserve to longword align IP header (two places)
- : Remove a delay loop from dma_rx()
- : Replace '100' with HZ
- : Clean up a couple of skb API abuses
- : Added 'cs89x0_dma=N' kernel boot option
- : Correctly initialise lp->lock in non-module compile
-
- Andrew Morton : Kernel 2.3.99-pre4-1
- : MOD_INC/DEC race fix (see
- : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html)
-
- Andrew Morton : Kernel 2.4.0-test7-pre2
- : Enhanced EEPROM support to cover more devices,
- : abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch
- : (Jason Gunthorpe <jgg@ualberta.ca>)
-
- Andrew Morton : Kernel 2.4.0-test11-pre4
- : Use dev->name in request_*() (Andrey Panin)
- : Fix an error-path memleak in init_module()
- : Preserve return value from request_irq()
- : Fix type of `media' module parm (Keith Owens)
- : Use SET_MODULE_OWNER()
- : Tidied up strange request_irq() abuse in net_open().
-
- Andrew Morton : Kernel 2.4.3-pre1
- : Request correct number of pages for DMA (Hugh Dickens)
- : Select PP_ChipID _after_ unregister_netdev in cleanup_module()
- : because unregister_netdev() calls get_stats.
- : Make `version[]' __initdata
- : Uninlined the read/write reg/word functions.
-
- Oskar Schirmer : oskar@scara.com
- : HiCO.SH4 (superh) support added (irq#1, cs89x0_media=)
-
- Deepak Saxena : dsaxena@plexity.net
- : Intel IXDP2x01 (XScale ixp2x00 NPU) platform support
-
- Dmitry Pervushin : dpervushin@ru.mvista.com
- : PNX010X platform support
-
- Deepak Saxena : dsaxena@plexity.net
- : Intel IXDP2351 platform support
-
- Dmitry Pervushin : dpervushin@ru.mvista.com
- : PNX010X platform support
-
- Domenico Andreoli : cavokz@gmail.com
- : QQ2440 platform support
-
-*/
-
/*
* Set this to zero to disable DMA code
@@ -119,14 +41,12 @@
*/
#define DEBUGGING 1
-/*
- Sources:
-
- Crynwr packet driver epktisa.
-
- Crystal Semiconductor data sheets.
+/* Sources:
+ * Crynwr packet driver epktisa.
+ * Crystal Semiconductor data sheets.
+ */
-*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/printk.h>
@@ -147,8 +67,8 @@
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/gfp.h>
+#include <linux/io.h>
-#include <asm/io.h>
#include <asm/irq.h>
#include <linux/atomic.h>
#if ALLOW_DMA
@@ -157,35 +77,55 @@
#include "cs89x0.h"
+#define cs89_dbg(val, level, fmt, ...) \
+do { \
+ if (val <= net_debug) \
+ pr_##level(fmt, ##__VA_ARGS__); \
+} while (0)
+
static char version[] __initdata =
-"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton\n";
+ "v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton";
#define DRV_NAME "cs89x0"
/* First, a few definitions that the brave might change.
- A zero-terminated list of I/O addresses to be probed. Some special flags..
- Addr & 1 = Read back the address port, look for signature and reset
- the page window before probing
- Addr & 3 = Reset the page window and probe
- The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space,
- but it is possible that a Cirrus board could be plugged into the ISA
- slots. */
+ * A zero-terminated list of I/O addresses to be probed. Some special flags..
+ * Addr & 1 = Read back the address port, look for signature and reset
+ * the page window before probing
+ * Addr & 3 = Reset the page window and probe
+ * The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space,
+ * but it is possible that a Cirrus board could be plugged into the ISA
+ * slots.
+ */
/* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps
- them to system IRQ numbers. This mapping is card specific and is set to
- the configuration of the Cirrus Eval board for this chip. */
+ * them to system IRQ numbers. This mapping is card specific and is set to
+ * the configuration of the Cirrus Eval board for this chip.
+ */
#if defined(CONFIG_MACH_IXDP2351)
#define CS89x0_NONISA_IRQ
-static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
-static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
+static unsigned int netcard_portlist[] __used __initdata = {
+ IXDP2351_VIRT_CS8900_BASE, 0
+};
+static unsigned int cs8900_irq_map[] = {
+ IRQ_IXDP2351_CS8900, 0, 0, 0
+};
#elif defined(CONFIG_ARCH_IXDP2X01)
#define CS89x0_NONISA_IRQ
-static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
-static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
+static unsigned int netcard_portlist[] __used __initdata = {
+ IXDP2X01_CS8900_VIRT_BASE, 0
+};
+static unsigned int cs8900_irq_map[] = {
+ IRQ_IXDP2X01_CS8900, 0, 0, 0
+};
#else
#ifndef CONFIG_CS89x0_PLATFORM
-static unsigned int netcard_portlist[] __used __initdata =
- { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
-static unsigned int cs8900_irq_map[] = {10,11,12,5};
+static unsigned int netcard_portlist[] __used __initdata = {
+ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240,
+ 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0
+};
+static unsigned int cs8900_irq_map[] = {
+ 10, 11, 12, 5
+};
#endif
#endif
@@ -222,6 +162,8 @@ struct net_local {
int send_underrun; /* keep track of how many underruns in a row we get */
int force; /* force various values; see FORCE* above. */
spinlock_t lock;
+ void __iomem *virt_addr;/* CS89x0 virtual address. */
+ unsigned long size; /* Length of CS89x0 memory region. */
#if ALLOW_DMA
int use_dma; /* Flag: we're using dma */
int dma; /* DMA channel */
@@ -230,119 +172,42 @@ struct net_local {
unsigned char *end_dma_buff; /* points to the end of the buffer */
unsigned char *rx_dma_ptr; /* points to the next packet */
#endif
-#ifdef CONFIG_CS89x0_PLATFORM
- void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */
- unsigned long phys_addr;/* Physical address for accessing the CS89x0. */
- unsigned long size; /* Length of CS89x0 memory region. */
-#endif
};
-/* Index to functions, as function prototypes. */
-
-static int cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular);
-static int net_open(struct net_device *dev);
-static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id);
-static void set_multicast_list(struct net_device *dev);
-static void net_timeout(struct net_device *dev);
-static void net_rx(struct net_device *dev);
-static int net_close(struct net_device *dev);
-static struct net_device_stats *net_get_stats(struct net_device *dev);
-static void reset_chip(struct net_device *dev);
-static int get_eeprom_data(struct net_device *dev, int off, int len, int *buffer);
-static int get_eeprom_cksum(int off, int len, int *buffer);
-static int set_mac_address(struct net_device *dev, void *addr);
-static void count_rx_errors(int status, struct net_device *dev);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void net_poll_controller(struct net_device *dev);
-#endif
-#if ALLOW_DMA
-static void get_dma_channel(struct net_device *dev);
-static void release_dma_buff(struct net_local *lp);
-#endif
-
/* Example routines you must write ;->. */
#define tx_done(dev) 1
/*
* Permit 'cs89x0_dma=N' in the kernel boot environment
*/
-#if !defined(MODULE) && (ALLOW_DMA != 0)
+#if !defined(MODULE)
+#if ALLOW_DMA
static int g_cs89x0_dma;
static int __init dma_fn(char *str)
{
- g_cs89x0_dma = simple_strtol(str,NULL,0);
+ g_cs89x0_dma = simple_strtol(str, NULL, 0);
return 1;
}
__setup("cs89x0_dma=", dma_fn);
-#endif /* !defined(MODULE) && (ALLOW_DMA != 0) */
+#endif /* ALLOW_DMA */
-#ifndef MODULE
static int g_cs89x0_media__force;
static int __init media_fn(char *str)
{
- if (!strcmp(str, "rj45")) g_cs89x0_media__force = FORCE_RJ45;
- else if (!strcmp(str, "aui")) g_cs89x0_media__force = FORCE_AUI;
- else if (!strcmp(str, "bnc")) g_cs89x0_media__force = FORCE_BNC;
+ if (!strcmp(str, "rj45"))
+ g_cs89x0_media__force = FORCE_RJ45;
+ else if (!strcmp(str, "aui"))
+ g_cs89x0_media__force = FORCE_AUI;
+ else if (!strcmp(str, "bnc"))
+ g_cs89x0_media__force = FORCE_BNC;
+
return 1;
}
__setup("cs89x0_media=", media_fn);
-
-
-#ifndef CONFIG_CS89x0_PLATFORM
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- Return 0 on success.
- */
-
-struct net_device * __init cs89x0_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
- unsigned *port;
- int err = 0;
- int irq;
- int io;
-
- if (!dev)
- return ERR_PTR(-ENODEV);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
- io = dev->base_addr;
- irq = dev->irq;
-
- if (net_debug)
- printk("cs89x0:cs89x0_probe(0x%x)\n", io);
-
- if (io > 0x1ff) { /* Check a single specified location. */
- err = cs89x0_probe1(dev, io, 0);
- } else if (io != 0) { /* Don't probe at all. */
- err = -ENXIO;
- } else {
- for (port = netcard_portlist; *port; port++) {
- if (cs89x0_probe1(dev, *port, 0) == 0)
- break;
- dev->irq = irq;
- }
- if (!*port)
- err = -ENODEV;
- }
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
- return ERR_PTR(err);
-}
-#endif
#endif
#if defined(CONFIG_MACH_IXDP2351)
@@ -369,36 +234,22 @@ writeword(unsigned long base_addr, int portno, u16 value)
{
__raw_writel(value, base_addr + (portno << 1));
}
-#else
-static u16
-readword(unsigned long base_addr, int portno)
-{
- return inw(base_addr + portno);
-}
-
-static void
-writeword(unsigned long base_addr, int portno, u16 value)
-{
- outw(value, base_addr + portno);
-}
#endif
-static void
-readwords(unsigned long base_addr, int portno, void *buf, int length)
+static void readwords(struct net_local *lp, int portno, void *buf, int length)
{
u8 *buf8 = (u8 *)buf;
do {
u16 tmp16;
- tmp16 = readword(base_addr, portno);
+ tmp16 = ioread16(lp->virt_addr + portno);
*buf8++ = (u8)tmp16;
*buf8++ = (u8)(tmp16 >> 8);
} while (--length);
}
-static void
-writewords(unsigned long base_addr, int portno, void *buf, int length)
+static void writewords(struct net_local *lp, int portno, void *buf, int length)
{
u8 *buf8 = (u8 *)buf;
@@ -407,32 +258,37 @@ writewords(unsigned long base_addr, int portno, void *buf, int length)
tmp16 = *buf8++;
tmp16 |= (*buf8++) << 8;
- writeword(base_addr, portno, tmp16);
+ iowrite16(tmp16, lp->virt_addr + portno);
} while (--length);
}
static u16
readreg(struct net_device *dev, u16 regno)
{
- writeword(dev->base_addr, ADD_PORT, regno);
- return readword(dev->base_addr, DATA_PORT);
+ struct net_local *lp = netdev_priv(dev);
+
+ iowrite16(regno, lp->virt_addr + ADD_PORT);
+ return ioread16(lp->virt_addr + DATA_PORT);
}
static void
writereg(struct net_device *dev, u16 regno, u16 value)
{
- writeword(dev->base_addr, ADD_PORT, regno);
- writeword(dev->base_addr, DATA_PORT, value);
+ struct net_local *lp = netdev_priv(dev);
+
+ iowrite16(regno, lp->virt_addr + ADD_PORT);
+ iowrite16(value, lp->virt_addr + DATA_PORT);
}
static int __init
wait_eeprom_ready(struct net_device *dev)
{
int timeout = jiffies;
- /* check to see if the EEPROM is ready, a timeout is used -
- just in case EEPROM is ready when SI_BUSY in the
- PP_SelfST is clear */
- while(readreg(dev, PP_SelfST) & SI_BUSY)
+ /* check to see if the EEPROM is ready,
+ * a timeout is used just in case EEPROM is ready when
+ * SI_BUSY in the PP_SelfST is clear
+ */
+ while (readreg(dev, PP_SelfST) & SI_BUSY)
if (jiffies - timeout >= 40)
return -1;
return 0;
@@ -443,17 +299,19 @@ get_eeprom_data(struct net_device *dev, int off, int len, int *buffer)
{
int i;
- if (net_debug > 3) printk("EEPROM data from %x for %x:\n",off,len);
+ cs89_dbg(3, info, "EEPROM data from %x for %x:", off, len);
for (i = 0; i < len; i++) {
- if (wait_eeprom_ready(dev) < 0) return -1;
+ if (wait_eeprom_ready(dev) < 0)
+ return -1;
/* Now send the EEPROM read command and EEPROM location to read */
writereg(dev, PP_EECMD, (off + i) | EEPROM_READ_CMD);
- if (wait_eeprom_ready(dev) < 0) return -1;
+ if (wait_eeprom_ready(dev) < 0)
+ return -1;
buffer[i] = readreg(dev, PP_EEData);
- if (net_debug > 3) printk("%04x ", buffer[i]);
+ cs89_dbg(3, cont, " %04x", buffer[i]);
}
- if (net_debug > 3) printk("\n");
- return 0;
+ cs89_dbg(3, cont, "\n");
+ return 0;
}
static int __init
@@ -470,341 +328,52 @@ get_eeprom_cksum(int off, int len, int *buffer)
return -1;
}
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling receive - used by netconsole and other diagnostic tools
- * to allow network i/o with interrupts disabled.
- */
-static void net_poll_controller(struct net_device *dev)
-{
- disable_irq(dev->irq);
- net_interrupt(dev->irq, dev);
- enable_irq(dev->irq);
-}
-#endif
-
-static const struct net_device_ops net_ops = {
- .ndo_open = net_open,
- .ndo_stop = net_close,
- .ndo_tx_timeout = net_timeout,
- .ndo_start_xmit = net_send_packet,
- .ndo_get_stats = net_get_stats,
- .ndo_set_rx_mode = set_multicast_list,
- .ndo_set_mac_address = set_mac_address,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = net_poll_controller,
-#endif
- .ndo_change_mtu = eth_change_mtu,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/* This is the real probe routine. Linux has a history of friendly device
- probes on the ISA bus. A good device probes avoids doing writes, and
- verifies that the correct device exists and functions.
- Return 0 on success.
- */
-
-static int __init
-cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular)
+static void
+write_irq(struct net_device *dev, int chip_type, int irq)
{
- struct net_local *lp = netdev_priv(dev);
- static unsigned version_printed;
int i;
- int tmp;
- unsigned rev_type = 0;
- int eeprom_buff[CHKSUM_LEN];
- int retval;
-
- /* Initialize the device structure. */
- if (!modular) {
- memset(lp, 0, sizeof(*lp));
- spin_lock_init(&lp->lock);
-#ifndef MODULE
-#if ALLOW_DMA
- if (g_cs89x0_dma) {
- lp->use_dma = 1;
- lp->dma = g_cs89x0_dma;
- lp->dmasize = 16; /* Could make this an option... */
- }
-#endif
- lp->force = g_cs89x0_media__force;
-#endif
-
- }
-
- /* Grab the region so we can find another board if autoIRQ fails. */
- /* WTF is going on here? */
- if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
- printk(KERN_ERR "%s: request_region(0x%lx, 0x%x) failed\n",
- DRV_NAME, ioaddr, NETCARD_IO_EXTENT);
- retval = -EBUSY;
- goto out1;
- }
-
- /* if they give us an odd I/O address, then do ONE write to
- the address port, to get it back to address zero, where we
- expect to find the EISA signature word. An IO with a base of 0x3
- will skip the test for the ADD_PORT. */
- if (ioaddr & 1) {
- if (net_debug > 1)
- printk(KERN_INFO "%s: odd ioaddr 0x%lx\n", dev->name, ioaddr);
- if ((ioaddr & 2) != 2)
- if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) {
- printk(KERN_ERR "%s: bad signature 0x%x\n",
- dev->name, readword(ioaddr & ~3, ADD_PORT));
- retval = -ENODEV;
- goto out2;
- }
- }
-
- ioaddr &= ~3;
- printk(KERN_DEBUG "PP_addr at %lx[%x]: 0x%x\n",
- ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT));
- writeword(ioaddr, ADD_PORT, PP_ChipID);
-
- tmp = readword(ioaddr, DATA_PORT);
- if (tmp != CHIP_EISA_ID_SIG) {
- printk(KERN_DEBUG "%s: incorrect signature at %lx[%x]: 0x%x!="
- CHIP_EISA_ID_SIG_STR "\n",
- dev->name, ioaddr, DATA_PORT, tmp);
- retval = -ENODEV;
- goto out2;
- }
-
- /* Fill in the 'dev' fields. */
- dev->base_addr = ioaddr;
-
- /* get the chip type */
- rev_type = readreg(dev, PRODUCT_ID_ADD);
- lp->chip_type = rev_type &~ REVISON_BITS;
- lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
-
- /* Check the chip type and revision in order to set the correct send command
- CS8920 revision C and CS8900 revision F can use the faster send. */
- lp->send_cmd = TX_AFTER_381;
- if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
- lp->send_cmd = TX_NOW;
- if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
- lp->send_cmd = TX_NOW;
-
- if (net_debug && version_printed++ == 0)
- printk(version);
-
- printk(KERN_INFO "%s: cs89%c0%s rev %c found at %#3lx ",
- dev->name,
- lp->chip_type==CS8900?'0':'2',
- lp->chip_type==CS8920M?"M":"",
- lp->chip_revision,
- dev->base_addr);
-
- reset_chip(dev);
-
- /* Here we read the current configuration of the chip. If there
- is no Extended EEPROM then the idea is to not disturb the chip
- configuration, it should have been correctly setup by automatic
- EEPROM read on reset. So, if the chip says it read the EEPROM
- the driver will always do *something* instead of complain that
- adapter_cnf is 0. */
-
-
- if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) ==
- (EEPROM_OK|EEPROM_PRESENT)) {
- /* Load the MAC. */
- for (i=0; i < ETH_ALEN/2; i++) {
- unsigned int Addr;
- Addr = readreg(dev, PP_IA+i*2);
- dev->dev_addr[i*2] = Addr & 0xFF;
- dev->dev_addr[i*2+1] = Addr >> 8;
- }
-
- /* Load the Adapter Configuration.
- Note: Barring any more specific information from some
- other source (ie EEPROM+Schematics), we would not know
- how to operate a 10Base2 interface on the AUI port.
- However, since we do read the status of HCB1 and use
- settings that always result in calls to control_dc_dc(dev,0)
- a BNC interface should work if the enable pin
- (dc/dc converter) is on HCB1. It will be called AUI
- however. */
-
- lp->adapter_cnf = 0;
- i = readreg(dev, PP_LineCTL);
- /* Preserve the setting of the HCB1 pin. */
- if ((i & (HCB1 | HCB1_ENBL)) == (HCB1 | HCB1_ENBL))
- lp->adapter_cnf |= A_CNF_DC_DC_POLARITY;
- /* Save the sqelch bit */
- if ((i & LOW_RX_SQUELCH) == LOW_RX_SQUELCH)
- lp->adapter_cnf |= A_CNF_EXTND_10B_2 | A_CNF_LOW_RX_SQUELCH;
- /* Check if the card is in 10Base-t only mode */
- if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == 0)
- lp->adapter_cnf |= A_CNF_10B_T | A_CNF_MEDIA_10B_T;
- /* Check if the card is in AUI only mode */
- if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUI_ONLY)
- lp->adapter_cnf |= A_CNF_AUI | A_CNF_MEDIA_AUI;
- /* Check if the card is in Auto mode. */
- if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUTO_AUI_10BASET)
- lp->adapter_cnf |= A_CNF_AUI | A_CNF_10B_T |
- A_CNF_MEDIA_AUI | A_CNF_MEDIA_10B_T | A_CNF_MEDIA_AUTO;
-
- if (net_debug > 1)
- printk(KERN_INFO "%s: PP_LineCTL=0x%x, adapter_cnf=0x%x\n",
- dev->name, i, lp->adapter_cnf);
-
- /* IRQ. Other chips already probe, see below. */
- if (lp->chip_type == CS8900)
- lp->isa_config = readreg(dev, PP_CS8900_ISAINT) & INT_NO_MASK;
-
- printk( "[Cirrus EEPROM] ");
- }
-
- printk("\n");
-
- /* First check to see if an EEPROM is attached. */
-
- if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
- printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n");
- else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) {
- printk(KERN_WARNING "\ncs89x0: EEPROM read failed, relying on command line.\n");
- } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) {
- /* Check if the chip was able to read its own configuration starting
- at 0 in the EEPROM*/
- if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) !=
- (EEPROM_OK|EEPROM_PRESENT))
- printk(KERN_WARNING "cs89x0: Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command line\n");
-
- } else {
- /* This reads an extended EEPROM that is not documented
- in the CS8900 datasheet. */
-
- /* get transmission control word but keep the autonegotiation bits */
- if (!lp->auto_neg_cnf) lp->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
- /* Store adapter configuration */
- if (!lp->adapter_cnf) lp->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
- /* Store ISA configuration */
- lp->isa_config = eeprom_buff[ISA_CNF_OFFSET/2];
- dev->mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
-
- /* eeprom_buff has 32-bit ints, so we can't just memcpy it */
- /* store the initial memory base address */
- for (i = 0; i < ETH_ALEN/2; i++) {
- dev->dev_addr[i*2] = eeprom_buff[i];
- dev->dev_addr[i*2+1] = eeprom_buff[i] >> 8;
- }
- if (net_debug > 1)
- printk(KERN_DEBUG "%s: new adapter_cnf: 0x%x\n",
- dev->name, lp->adapter_cnf);
- }
-
- /* allow them to force multiple transceivers. If they force multiple, autosense */
- {
- int count = 0;
- if (lp->force & FORCE_RJ45) {lp->adapter_cnf |= A_CNF_10B_T; count++; }
- if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_AUI; count++; }
- if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_10B_2; count++; }
- if (count > 1) {lp->adapter_cnf |= A_CNF_MEDIA_AUTO; }
- else if (lp->force & FORCE_RJ45){lp->adapter_cnf |= A_CNF_MEDIA_10B_T; }
- else if (lp->force & FORCE_AUI) {lp->adapter_cnf |= A_CNF_MEDIA_AUI; }
- else if (lp->force & FORCE_BNC) {lp->adapter_cnf |= A_CNF_MEDIA_10B_2; }
- }
-
- if (net_debug > 1)
- printk(KERN_DEBUG "%s: after force 0x%x, adapter_cnf=0x%x\n",
- dev->name, lp->force, lp->adapter_cnf);
-
- /* FIXME: We don't let you set dc-dc polarity or low RX squelch from the command line: add it here */
-
- /* FIXME: We don't let you set the IMM bit from the command line: add it to lp->auto_neg_cnf here */
-
- /* FIXME: we don't set the Ethernet address on the command line. Use
- ifconfig IFACE hw ether AABBCCDDEEFF */
-
- printk(KERN_INFO "cs89x0 media %s%s%s",
- (lp->adapter_cnf & A_CNF_10B_T)?"RJ-45,":"",
- (lp->adapter_cnf & A_CNF_AUI)?"AUI,":"",
- (lp->adapter_cnf & A_CNF_10B_2)?"BNC,":"");
-
- lp->irq_map = 0xffff;
- /* If this is a CS8900 then no pnp soft */
- if (lp->chip_type != CS8900 &&
- /* Check if the ISA IRQ has been set */
- (i = readreg(dev, PP_CS8920_ISAINT) & 0xff,
- (i != 0 && i < CS8920_NO_INTS))) {
- if (!dev->irq)
- dev->irq = i;
- } else {
- i = lp->isa_config & INT_NO_MASK;
+ if (chip_type == CS8900) {
#ifndef CONFIG_CS89x0_PLATFORM
- if (lp->chip_type == CS8900) {
-#ifdef CS89x0_NONISA_IRQ
- i = cs8900_irq_map[0];
+ /* Search the mapping table for the corresponding IRQ pin. */
+ for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
+ if (cs8900_irq_map[i] == irq)
+ break;
+ /* Not found */
+ if (i == ARRAY_SIZE(cs8900_irq_map))
+ i = 3;
#else
- /* Translate the IRQ using the IRQ mapping table. */
- if (i >= ARRAY_SIZE(cs8900_irq_map))
- printk("\ncs89x0: invalid ISA interrupt number %d\n", i);
- else
- i = cs8900_irq_map[i];
-
- lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */
- } else {
- int irq_map_buff[IRQ_MAP_LEN/2];
-
- if (get_eeprom_data(dev, IRQ_MAP_EEPROM_DATA,
- IRQ_MAP_LEN/2,
- irq_map_buff) >= 0) {
- if ((irq_map_buff[0] & 0xff) == PNP_IRQ_FRMT)
- lp->irq_map = (irq_map_buff[0]>>8) | (irq_map_buff[1] << 8);
- }
-#endif
- }
-#endif
- if (!dev->irq)
- dev->irq = i;
- }
-
- printk(" IRQ %d", dev->irq);
-
-#if ALLOW_DMA
- if (lp->use_dma) {
- get_dma_channel(dev);
- printk(", DMA %d", dev->dma);
- }
- else
+ /* INTRQ0 pin is used for interrupt generation. */
+ i = 0;
#endif
- {
- printk(", programmed I/O");
+ writereg(dev, PP_CS8900_ISAINT, i);
+ } else {
+ writereg(dev, PP_CS8920_ISAINT, irq);
}
-
- /* print the ethernet address. */
- printk(", MAC %pM", dev->dev_addr);
-
- dev->netdev_ops = &net_ops;
- dev->watchdog_timeo = HZ;
-
- printk("\n");
- if (net_debug)
- printk("cs89x0_probe1() successful\n");
-
- retval = register_netdev(dev);
- if (retval)
- goto out3;
- return 0;
-out3:
- writeword(dev->base_addr, ADD_PORT, PP_ChipID);
-out2:
- release_region(ioaddr & ~3, NETCARD_IO_EXTENT);
-out1:
- return retval;
}
+static void
+count_rx_errors(int status, struct net_device *dev)
+{
+ dev->stats.rx_errors++;
+ if (status & RX_RUNT)
+ dev->stats.rx_length_errors++;
+ if (status & RX_EXTRA_DATA)
+ dev->stats.rx_length_errors++;
+ if ((status & RX_CRC_ERROR) && !(status & (RX_EXTRA_DATA | RX_RUNT)))
+ /* per str 172 */
+ dev->stats.rx_crc_errors++;
+ if (status & RX_DRIBBLE)
+ dev->stats.rx_frame_errors++;
+}
/*********************************
* This page contains DMA routines
-**********************************/
+ *********************************/
#if ALLOW_DMA
-#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17)
+#define dma_page_eq(ptr1, ptr2) ((long)(ptr1) >> 17 == (long)(ptr2) >> 17)
static void
get_dma_channel(struct net_device *dev)
@@ -833,11 +402,10 @@ write_dma(struct net_device *dev, int chip_type, int dma)
struct net_local *lp = netdev_priv(dev);
if ((lp->isa_config & ANY_ISA_DMA) == 0)
return;
- if (chip_type == CS8900) {
- writereg(dev, PP_CS8900_ISADMA, dma-5);
- } else {
+ if (chip_type == CS8900)
+ writereg(dev, PP_CS8900_ISADMA, dma - 5);
+ else
writereg(dev, PP_CS8920_ISADMA, dma);
- }
}
static void
@@ -847,18 +415,15 @@ set_dma_cfg(struct net_device *dev)
if (lp->use_dma) {
if ((lp->isa_config & ANY_ISA_DMA) == 0) {
- if (net_debug > 3)
- printk("set_dma_cfg(): no DMA\n");
+ cs89_dbg(3, err, "set_dma_cfg(): no DMA\n");
return;
}
if (lp->isa_config & ISA_RxDMA) {
lp->curr_rx_cfg |= RX_DMA_ONLY;
- if (net_debug > 3)
- printk("set_dma_cfg(): RX_DMA_ONLY\n");
+ cs89_dbg(3, info, "set_dma_cfg(): RX_DMA_ONLY\n");
} else {
lp->curr_rx_cfg |= AUTO_RX_DMA; /* not that we support it... */
- if (net_debug > 3)
- printk("set_dma_cfg(): AUTO_RX_DMA\n");
+ cs89_dbg(3, info, "set_dma_cfg(): AUTO_RX_DMA\n");
}
}
}
@@ -868,7 +433,7 @@ dma_bufcfg(struct net_device *dev)
{
struct net_local *lp = netdev_priv(dev);
if (lp->use_dma)
- return (lp->isa_config & ANY_ISA_DMA)? RX_DMA_ENBL : 0;
+ return (lp->isa_config & ANY_ISA_DMA) ? RX_DMA_ENBL : 0;
else
return 0;
}
@@ -898,13 +463,13 @@ dma_rx(struct net_device *dev)
int status, length;
unsigned char *bp = lp->rx_dma_ptr;
- status = bp[0] + (bp[1]<<8);
- length = bp[2] + (bp[3]<<8);
+ status = bp[0] + (bp[1] << 8);
+ length = bp[2] + (bp[3] << 8);
bp += 4;
- if (net_debug > 5) {
- printk( "%s: receiving DMA packet at %lx, status %x, length %x\n",
- dev->name, (unsigned long)bp, status, length);
- }
+
+ cs89_dbg(5, debug, "%s: receiving DMA packet at %lx, status %x, length %x\n",
+ dev->name, (unsigned long)bp, status, length);
+
if ((status & RX_OK) == 0) {
count_rx_errors(status, dev);
goto skip_this_frame;
@@ -913,14 +478,16 @@ dma_rx(struct net_device *dev)
/* Malloc up new buffer. */
skb = netdev_alloc_skb(dev, length + 2);
if (skb == NULL) {
- if (net_debug) /* I don't think we want to do this to a stressed system */
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+ /* I don't think we want to do this to a stressed system */
+ cs89_dbg(0, err, "%s: Memory squeeze, dropping packet\n",
+ dev->name);
dev->stats.rx_dropped++;
/* AKPM: advance bp to the next frame */
skip_this_frame:
bp += (length + 3) & ~3;
- if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024;
+ if (bp >= lp->end_dma_buff)
+ bp -= lp->dmasize * 1024;
lp->rx_dma_ptr = bp;
return;
}
@@ -928,63 +495,38 @@ skip_this_frame:
if (bp + length > lp->end_dma_buff) {
int semi_cnt = lp->end_dma_buff - bp;
- memcpy(skb_put(skb,semi_cnt), bp, semi_cnt);
- memcpy(skb_put(skb,length - semi_cnt), lp->dma_buff,
+ memcpy(skb_put(skb, semi_cnt), bp, semi_cnt);
+ memcpy(skb_put(skb, length - semi_cnt), lp->dma_buff,
length - semi_cnt);
} else {
- memcpy(skb_put(skb,length), bp, length);
+ memcpy(skb_put(skb, length), bp, length);
}
bp += (length + 3) & ~3;
- if (bp >= lp->end_dma_buff) bp -= lp->dmasize*1024;
+ if (bp >= lp->end_dma_buff)
+ bp -= lp->dmasize*1024;
lp->rx_dma_ptr = bp;
- if (net_debug > 3) {
- printk( "%s: received %d byte DMA packet of type %x\n",
- dev->name, length,
- (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
- }
- skb->protocol=eth_type_trans(skb,dev);
+ cs89_dbg(3, info, "%s: received %d byte DMA packet of type %x\n",
+ dev->name, length,
+ ((skb->data[ETH_ALEN + ETH_ALEN] << 8) |
+ skb->data[ETH_ALEN + ETH_ALEN + 1]));
+
+ skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
dev->stats.rx_packets++;
dev->stats.rx_bytes += length;
}
-#endif /* ALLOW_DMA */
-
-static void __init reset_chip(struct net_device *dev)
+static void release_dma_buff(struct net_local *lp)
{
-#if !defined(CONFIG_MACH_MX31ADS)
-#if !defined(CS89x0_NONISA_IRQ)
- struct net_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-#endif /* CS89x0_NONISA_IRQ */
- int reset_start_time;
-
- writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
-
- /* wait 30 ms */
- msleep(30);
-
-#if !defined(CS89x0_NONISA_IRQ)
- if (lp->chip_type != CS8900) {
- /* Hardware problem requires PNP registers to be reconfigured after a reset */
- writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT);
- outb(dev->irq, ioaddr + DATA_PORT);
- outb(0, ioaddr + DATA_PORT + 1);
-
- writeword(ioaddr, ADD_PORT, PP_CS8920_ISAMemB);
- outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT);
- outb((dev->mem_start >> 8) & 0xff, ioaddr + DATA_PORT + 1);
+ if (lp->dma_buff) {
+ free_pages((unsigned long)(lp->dma_buff),
+ get_order(lp->dmasize * 1024));
+ lp->dma_buff = NULL;
}
-#endif /* CS89x0_NONISA_IRQ */
-
- /* Wait until the chip is reset */
- reset_start_time = jiffies;
- while( (readreg(dev, PP_SelfST) & INIT_DONE) == 0 && jiffies - reset_start_time < 2)
- ;
-#endif /* !CONFIG_MACH_MX31ADS */
}
+#endif /* ALLOW_DMA */
static void
control_dc_dc(struct net_device *dev, int on_not_off)
@@ -993,8 +535,9 @@ control_dc_dc(struct net_device *dev, int on_not_off)
unsigned int selfcontrol;
int timenow = jiffies;
/* control the DC to DC convertor in the SelfControl register.
- Note: This is hooked up to a general purpose pin, might not
- always be a DC to DC convertor. */
+ * Note: This is hooked up to a general purpose pin, might not
+ * always be a DC to DC convertor.
+ */
selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
if (((lp->adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
@@ -1008,6 +551,49 @@ control_dc_dc(struct net_device *dev, int on_not_off)
;
}
+/* send a test packet - return true if carrier bits are ok */
+static int
+send_test_pkt(struct net_device *dev)
+{
+ struct net_local *lp = netdev_priv(dev);
+ char test_packet[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 46, /* A 46 in network order */
+ 0, 0, /* DSAP=0 & SSAP=0 fields */
+ 0xf3, 0 /* Control (Test Req + P bit set) */
+ };
+ long timenow = jiffies;
+
+ writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON);
+
+ memcpy(test_packet, dev->dev_addr, ETH_ALEN);
+ memcpy(test_packet + ETH_ALEN, dev->dev_addr, ETH_ALEN);
+
+ iowrite16(TX_AFTER_ALL, lp->virt_addr + TX_CMD_PORT);
+ iowrite16(ETH_ZLEN, lp->virt_addr + TX_LEN_PORT);
+
+ /* Test to see if the chip has allocated memory for the packet */
+ while (jiffies - timenow < 5)
+ if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW)
+ break;
+ if (jiffies - timenow >= 5)
+ return 0; /* this shouldn't happen */
+
+ /* Write the contents of the packet */
+ writewords(lp, TX_FRAME_PORT, test_packet, (ETH_ZLEN + 1) >> 1);
+
+ cs89_dbg(1, debug, "Sending test packet ");
+ /* wait a couple of jiffies for packet to be received */
+ for (timenow = jiffies; jiffies - timenow < 3;)
+ ;
+ if ((readreg(dev, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
+ cs89_dbg(1, cont, "succeeded\n");
+ return 1;
+ }
+ cs89_dbg(1, cont, "failed\n");
+ return 0;
+}
+
#define DETECTED_NONE 0
#define DETECTED_RJ45H 1
#define DETECTED_RJ45F 2
@@ -1021,40 +607,46 @@ detect_tp(struct net_device *dev)
int timenow = jiffies;
int fdx;
- if (net_debug > 1) printk("%s: Attempting TP\n", dev->name);
+ cs89_dbg(1, debug, "%s: Attempting TP\n", dev->name);
- /* If connected to another full duplex capable 10-Base-T card the link pulses
- seem to be lost when the auto detect bit in the LineCTL is set.
- To overcome this the auto detect bit will be cleared whilst testing the
- 10-Base-T interface. This would not be necessary for the sparrow chip but
- is simpler to do it anyway. */
- writereg(dev, PP_LineCTL, lp->linectl &~ AUI_ONLY);
+ /* If connected to another full duplex capable 10-Base-T card
+ * the link pulses seem to be lost when the auto detect bit in
+ * the LineCTL is set. To overcome this the auto detect bit will
+ * be cleared whilst testing the 10-Base-T interface. This would
+ * not be necessary for the sparrow chip but is simpler to do it
+ * anyway.
+ */
+ writereg(dev, PP_LineCTL, lp->linectl & ~AUI_ONLY);
control_dc_dc(dev, 0);
- /* Delay for the hardware to work out if the TP cable is present - 150ms */
- for (timenow = jiffies; jiffies - timenow < 15; )
- ;
+ /* Delay for the hardware to work out if the TP cable is present
+ * - 150ms
+ */
+ for (timenow = jiffies; jiffies - timenow < 15;)
+ ;
if ((readreg(dev, PP_LineST) & LINK_OK) == 0)
return DETECTED_NONE;
if (lp->chip_type == CS8900) {
- switch (lp->force & 0xf0) {
+ switch (lp->force & 0xf0) {
#if 0
- case FORCE_AUTO:
- printk("%s: cs8900 doesn't autonegotiate\n",dev->name);
- return DETECTED_NONE;
+ case FORCE_AUTO:
+ pr_info("%s: cs8900 doesn't autonegotiate\n",
+ dev->name);
+ return DETECTED_NONE;
#endif
- /* CS8900 doesn't support AUTO, change to HALF*/
- case FORCE_AUTO:
+ /* CS8900 doesn't support AUTO, change to HALF*/
+ case FORCE_AUTO:
lp->force &= ~FORCE_AUTO;
- lp->force |= FORCE_HALF;
+ lp->force |= FORCE_HALF;
break;
case FORCE_HALF:
break;
- case FORCE_FULL:
- writereg(dev, PP_TestCTL, readreg(dev, PP_TestCTL) | FDX_8900);
+ case FORCE_FULL:
+ writereg(dev, PP_TestCTL,
+ readreg(dev, PP_TestCTL) | FDX_8900);
break;
- }
+ }
fdx = readreg(dev, PP_TestCTL) & FDX_8900;
} else {
switch (lp->force & 0xf0) {
@@ -1067,15 +659,15 @@ detect_tp(struct net_device *dev)
case FORCE_FULL:
lp->auto_neg_cnf = RE_NEG_NOW | ALLOW_FDX;
break;
- }
+ }
writereg(dev, PP_AutoNegCTL, lp->auto_neg_cnf & AUTO_NEG_MASK);
if ((lp->auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
- printk(KERN_INFO "%s: negotiating duplex...\n",dev->name);
+ pr_info("%s: negotiating duplex...\n", dev->name);
while (readreg(dev, PP_AutoNegST) & AUTO_NEG_BUSY) {
if (jiffies - timenow > 4000) {
- printk(KERN_ERR "**** Full / half duplex auto-negotiation timed out ****\n");
+ pr_err("**** Full / half duplex auto-negotiation timed out ****\n");
break;
}
}
@@ -1088,56 +680,31 @@ detect_tp(struct net_device *dev)
return DETECTED_RJ45H;
}
-/* send a test packet - return true if carrier bits are ok */
static int
-send_test_pkt(struct net_device *dev)
+detect_bnc(struct net_device *dev)
{
- char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
- 0, 46, /* A 46 in network order */
- 0, 0, /* DSAP=0 & SSAP=0 fields */
- 0xf3, 0 /* Control (Test Req + P bit set) */ };
- long timenow = jiffies;
-
- writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_TX_ON);
-
- memcpy(test_packet, dev->dev_addr, ETH_ALEN);
- memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN);
-
- writeword(dev->base_addr, TX_CMD_PORT, TX_AFTER_ALL);
- writeword(dev->base_addr, TX_LEN_PORT, ETH_ZLEN);
+ struct net_local *lp = netdev_priv(dev);
- /* Test to see if the chip has allocated memory for the packet */
- while (jiffies - timenow < 5)
- if (readreg(dev, PP_BusST) & READY_FOR_TX_NOW)
- break;
- if (jiffies - timenow >= 5)
- return 0; /* this shouldn't happen */
+ cs89_dbg(1, debug, "%s: Attempting BNC\n", dev->name);
+ control_dc_dc(dev, 1);
- /* Write the contents of the packet */
- writewords(dev->base_addr, TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1);
+ writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
- if (net_debug > 1) printk("Sending test packet ");
- /* wait a couple of jiffies for packet to be received */
- for (timenow = jiffies; jiffies - timenow < 3; )
- ;
- if ((readreg(dev, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
- if (net_debug > 1) printk("succeeded\n");
- return 1;
- }
- if (net_debug > 1) printk("failed\n");
- return 0;
+ if (send_test_pkt(dev))
+ return DETECTED_BNC;
+ else
+ return DETECTED_NONE;
}
-
static int
detect_aui(struct net_device *dev)
{
struct net_local *lp = netdev_priv(dev);
- if (net_debug > 1) printk("%s: Attempting AUI\n", dev->name);
+ cs89_dbg(1, debug, "%s: Attempting AUI\n", dev->name);
control_dc_dc(dev, 0);
- writereg(dev, PP_LineCTL, (lp->linectl &~ AUTO_AUI_10BASET) | AUI_ONLY);
+ writereg(dev, PP_LineCTL, (lp->linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
if (send_test_pkt(dev))
return DETECTED_AUI;
@@ -1145,45 +712,154 @@ detect_aui(struct net_device *dev)
return DETECTED_NONE;
}
-static int
-detect_bnc(struct net_device *dev)
+/* We have a good packet(s), get it/them out of the buffers. */
+static void
+net_rx(struct net_device *dev)
{
struct net_local *lp = netdev_priv(dev);
+ struct sk_buff *skb;
+ int status, length;
- if (net_debug > 1) printk("%s: Attempting BNC\n", dev->name);
- control_dc_dc(dev, 1);
+ status = ioread16(lp->virt_addr + RX_FRAME_PORT);
+ length = ioread16(lp->virt_addr + RX_FRAME_PORT);
- writereg(dev, PP_LineCTL, (lp->linectl &~ AUTO_AUI_10BASET) | AUI_ONLY);
+ if ((status & RX_OK) == 0) {
+ count_rx_errors(status, dev);
+ return;
+ }
- if (send_test_pkt(dev))
- return DETECTED_BNC;
- else
- return DETECTED_NONE;
+ /* Malloc up new buffer. */
+ skb = netdev_alloc_skb(dev, length + 2);
+ if (skb == NULL) {
+#if 0 /* Again, this seems a cruel thing to do */
+ pr_warn("%s: Memory squeeze, dropping packet\n", dev->name);
+#endif
+ dev->stats.rx_dropped++;
+ return;
+ }
+ skb_reserve(skb, 2); /* longword align L3 header */
+
+ readwords(lp, RX_FRAME_PORT, skb_put(skb, length), length >> 1);
+ if (length & 1)
+ skb->data[length-1] = ioread16(lp->virt_addr + RX_FRAME_PORT);
+
+ cs89_dbg(3, debug, "%s: received %d byte packet of type %x\n",
+ dev->name, length,
+ (skb->data[ETH_ALEN + ETH_ALEN] << 8) |
+ skb->data[ETH_ALEN + ETH_ALEN + 1]);
+
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += length;
}
+/* The typical workload of the driver:
+ * Handle the network interface interrupts.
+ */
-static void
-write_irq(struct net_device *dev, int chip_type, int irq)
+static irqreturn_t net_interrupt(int irq, void *dev_id)
{
- int i;
+ struct net_device *dev = dev_id;
+ struct net_local *lp;
+ int status;
+ int handled = 0;
- if (chip_type == CS8900) {
-#ifndef CONFIG_CS89x0_PLATFORM
- /* Search the mapping table for the corresponding IRQ pin. */
- for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
- if (cs8900_irq_map[i] == irq)
- break;
- /* Not found */
- if (i == ARRAY_SIZE(cs8900_irq_map))
- i = 3;
-#else
- /* INTRQ0 pin is used for interrupt generation. */
- i = 0;
+ lp = netdev_priv(dev);
+
+ /* we MUST read all the events out of the ISQ, otherwise we'll never
+ * get interrupted again. As a consequence, we can't have any limit
+ * on the number of times we loop in the interrupt handler. The
+ * hardware guarantees that eventually we'll run out of events. Of
+ * course, if you're on a slow machine, and packets are arriving
+ * faster than you can read them off, you're screwed. Hasta la
+ * vista, baby!
+ */
+ while ((status = ioread16(lp->virt_addr + ISQ_PORT))) {
+ cs89_dbg(4, debug, "%s: event=%04x\n", dev->name, status);
+ handled = 1;
+ switch (status & ISQ_EVENT_MASK) {
+ case ISQ_RECEIVER_EVENT:
+ /* Got a packet(s). */
+ net_rx(dev);
+ break;
+ case ISQ_TRANSMITTER_EVENT:
+ dev->stats.tx_packets++;
+ netif_wake_queue(dev); /* Inform upper layers. */
+ if ((status & (TX_OK |
+ TX_LOST_CRS |
+ TX_SQE_ERROR |
+ TX_LATE_COL |
+ TX_16_COL)) != TX_OK) {
+ if ((status & TX_OK) == 0)
+ dev->stats.tx_errors++;
+ if (status & TX_LOST_CRS)
+ dev->stats.tx_carrier_errors++;
+ if (status & TX_SQE_ERROR)
+ dev->stats.tx_heartbeat_errors++;
+ if (status & TX_LATE_COL)
+ dev->stats.tx_window_errors++;
+ if (status & TX_16_COL)
+ dev->stats.tx_aborted_errors++;
+ }
+ break;
+ case ISQ_BUFFER_EVENT:
+ if (status & READY_FOR_TX) {
+ /* we tried to transmit a packet earlier,
+ * but inexplicably ran out of buffers.
+ * That shouldn't happen since we only ever
+ * load one packet. Shrug. Do the right
+ * thing anyway.
+ */
+ netif_wake_queue(dev); /* Inform upper layers. */
+ }
+ if (status & TX_UNDERRUN) {
+ cs89_dbg(0, err, "%s: transmit underrun\n",
+ dev->name);
+ lp->send_underrun++;
+ if (lp->send_underrun == 3)
+ lp->send_cmd = TX_AFTER_381;
+ else if (lp->send_underrun == 6)
+ lp->send_cmd = TX_AFTER_ALL;
+ /* transmit cycle is done, although
+ * frame wasn't transmitted - this
+ * avoids having to wait for the upper
+ * layers to timeout on us, in the
+ * event of a tx underrun
+ */
+ netif_wake_queue(dev); /* Inform upper layers. */
+ }
+#if ALLOW_DMA
+ if (lp->use_dma && (status & RX_DMA)) {
+ int count = readreg(dev, PP_DmaFrameCnt);
+ while (count) {
+ cs89_dbg(5, debug,
+ "%s: receiving %d DMA frames\n",
+ dev->name, count);
+ if (count > 1)
+ cs89_dbg(2, debug,
+ "%s: receiving %d DMA frames\n",
+ dev->name, count);
+ dma_rx(dev);
+ if (--count == 0)
+ count = readreg(dev, PP_DmaFrameCnt);
+ if (count > 0)
+ cs89_dbg(2, debug,
+ "%s: continuing with %d DMA frames\n",
+ dev->name, count);
+ }
+ }
#endif
- writereg(dev, PP_CS8900_ISAINT, i);
- } else {
- writereg(dev, PP_CS8920_ISAINT, irq);
+ break;
+ case ISQ_RX_MISS_EVENT:
+ dev->stats.rx_missed_errors += (status >> 6);
+ break;
+ case ISQ_TX_COL_EVENT:
+ dev->stats.collisions += (status >> 6);
+ break;
+ }
}
+ return IRQ_RETVAL(handled);
}
/* Open/initialize the board. This is called (in the current kernel)
@@ -1192,7 +868,7 @@ write_irq(struct net_device *dev, int chip_type, int irq)
This routine should set everything up anew at each open, even
registers that "should" only need to be set once at boot, so that
there is non-reboot way to recover if something goes wrong.
- */
+*/
/* AKPM: do we need to do any locking here? */
@@ -1208,14 +884,15 @@ net_open(struct net_device *dev)
/* Allow interrupts to be generated by the chip */
/* Cirrus' release had this: */
#if 0
- writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );
+ writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
#endif
/* And 2.3.47 had this: */
writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
for (i = 2; i < CS8920_NO_INTS; i++) {
if ((1 << i) & lp->irq_map) {
- if (request_irq(i, net_interrupt, 0, dev->name, dev) == 0) {
+ if (request_irq(i, net_interrupt, 0, dev->name,
+ dev) == 0) {
dev->irq = i;
write_irq(dev, lp->chip_type, i);
/* writereg(dev, PP_BufCFG, GENERATE_SW_INTERRUPT); */
@@ -1226,23 +903,21 @@ net_open(struct net_device *dev)
if (i >= CS8920_NO_INTS) {
writereg(dev, PP_BusCTL, 0); /* disable interrupts. */
- printk(KERN_ERR "cs89x0: can't get an interrupt\n");
+ pr_err("can't get an interrupt\n");
ret = -EAGAIN;
goto bad_out;
}
- }
- else
- {
+ } else {
#if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM)
if (((1 << dev->irq) & lp->irq_map) == 0) {
- printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
- dev->name, dev->irq, lp->irq_map);
+ pr_err("%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
+ dev->name, dev->irq, lp->irq_map);
ret = -EAGAIN;
goto bad_out;
}
#endif
/* FIXME: Cirrus' release had this: */
- writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ );
+ writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ);
/* And 2.3.47 had this: */
#if 0
writereg(dev, PP_BusCTL, ENABLE_IRQ | MEMORY_ON);
@@ -1250,147 +925,168 @@ net_open(struct net_device *dev)
write_irq(dev, lp->chip_type, dev->irq);
ret = request_irq(dev->irq, net_interrupt, 0, dev->name, dev);
if (ret) {
- printk(KERN_ERR "cs89x0: request_irq(%d) failed\n", dev->irq);
+ pr_err("request_irq(%d) failed\n", dev->irq);
goto bad_out;
}
}
#if ALLOW_DMA
- if (lp->use_dma) {
- if (lp->isa_config & ANY_ISA_DMA) {
- unsigned long flags;
- lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL,
- get_order(lp->dmasize * 1024));
-
- if (!lp->dma_buff) {
- printk(KERN_ERR "%s: cannot get %dK memory for DMA\n", dev->name, lp->dmasize);
- goto release_irq;
- }
- if (net_debug > 1) {
- printk( "%s: dma %lx %lx\n",
- dev->name,
- (unsigned long)lp->dma_buff,
- (unsigned long)isa_virt_to_bus(lp->dma_buff));
- }
- if ((unsigned long) lp->dma_buff >= MAX_DMA_ADDRESS ||
- !dma_page_eq(lp->dma_buff, lp->dma_buff+lp->dmasize*1024-1)) {
- printk(KERN_ERR "%s: not usable as DMA buffer\n", dev->name);
- goto release_irq;
- }
- memset(lp->dma_buff, 0, lp->dmasize * 1024); /* Why? */
- if (request_dma(dev->dma, dev->name)) {
- printk(KERN_ERR "%s: cannot get dma channel %d\n", dev->name, dev->dma);
- goto release_irq;
- }
- write_dma(dev, lp->chip_type, dev->dma);
- lp->rx_dma_ptr = lp->dma_buff;
- lp->end_dma_buff = lp->dma_buff + lp->dmasize*1024;
- spin_lock_irqsave(&lp->lock, flags);
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, DMA_RX_MODE); /* auto_init as well */
- set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff));
- set_dma_count(dev->dma, lp->dmasize*1024);
- enable_dma(dev->dma);
- spin_unlock_irqrestore(&lp->lock, flags);
+ if (lp->use_dma && (lp->isa_config & ANY_ISA_DMA)) {
+ unsigned long flags;
+ lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL,
+ get_order(lp->dmasize * 1024));
+ if (!lp->dma_buff) {
+ pr_err("%s: cannot get %dK memory for DMA\n",
+ dev->name, lp->dmasize);
+ goto release_irq;
+ }
+ cs89_dbg(1, debug, "%s: dma %lx %lx\n",
+ dev->name,
+ (unsigned long)lp->dma_buff,
+ (unsigned long)isa_virt_to_bus(lp->dma_buff));
+ if ((unsigned long)lp->dma_buff >= MAX_DMA_ADDRESS ||
+ !dma_page_eq(lp->dma_buff,
+ lp->dma_buff + lp->dmasize * 1024 - 1)) {
+ pr_err("%s: not usable as DMA buffer\n", dev->name);
+ goto release_irq;
}
+ memset(lp->dma_buff, 0, lp->dmasize * 1024); /* Why? */
+ if (request_dma(dev->dma, dev->name)) {
+ pr_err("%s: cannot get dma channel %d\n",
+ dev->name, dev->dma);
+ goto release_irq;
+ }
+ write_dma(dev, lp->chip_type, dev->dma);
+ lp->rx_dma_ptr = lp->dma_buff;
+ lp->end_dma_buff = lp->dma_buff + lp->dmasize * 1024;
+ spin_lock_irqsave(&lp->lock, flags);
+ disable_dma(dev->dma);
+ clear_dma_ff(dev->dma);
+ set_dma_mode(dev->dma, DMA_RX_MODE); /* auto_init as well */
+ set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff));
+ set_dma_count(dev->dma, lp->dmasize * 1024);
+ enable_dma(dev->dma);
+ spin_unlock_irqrestore(&lp->lock, flags);
}
#endif /* ALLOW_DMA */
/* set the Ethernet address */
- for (i=0; i < ETH_ALEN/2; i++)
- writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
+ for (i = 0; i < ETH_ALEN / 2; i++)
+ writereg(dev, PP_IA + i * 2,
+ (dev->dev_addr[i * 2] |
+ (dev->dev_addr[i * 2 + 1] << 8)));
/* while we're testing the interface, leave interrupts disabled */
writereg(dev, PP_BusCTL, MEMORY_ON);
/* Set the LineCTL quintuplet based on adapter configuration read from EEPROM */
- if ((lp->adapter_cnf & A_CNF_EXTND_10B_2) && (lp->adapter_cnf & A_CNF_LOW_RX_SQUELCH))
- lp->linectl = LOW_RX_SQUELCH;
+ if ((lp->adapter_cnf & A_CNF_EXTND_10B_2) &&
+ (lp->adapter_cnf & A_CNF_LOW_RX_SQUELCH))
+ lp->linectl = LOW_RX_SQUELCH;
else
- lp->linectl = 0;
-
- /* check to make sure that they have the "right" hardware available */
- switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
- case A_CNF_MEDIA_10B_T: result = lp->adapter_cnf & A_CNF_10B_T; break;
- case A_CNF_MEDIA_AUI: result = lp->adapter_cnf & A_CNF_AUI; break;
- case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
- default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
- }
- if (!result) {
- printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name);
+ lp->linectl = 0;
+
+ /* check to make sure that they have the "right" hardware available */
+ switch (lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
+ case A_CNF_MEDIA_10B_T:
+ result = lp->adapter_cnf & A_CNF_10B_T;
+ break;
+ case A_CNF_MEDIA_AUI:
+ result = lp->adapter_cnf & A_CNF_AUI;
+ break;
+ case A_CNF_MEDIA_10B_2:
+ result = lp->adapter_cnf & A_CNF_10B_2;
+ break;
+ default:
+ result = lp->adapter_cnf & (A_CNF_10B_T |
+ A_CNF_AUI |
+ A_CNF_10B_2);
+ }
+ if (!result) {
+ pr_err("%s: EEPROM is configured for unavailable media\n",
+ dev->name);
release_dma:
#if ALLOW_DMA
free_dma(dev->dma);
release_irq:
release_dma_buff(lp);
#endif
- writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
- free_irq(dev->irq, dev);
+ writereg(dev, PP_LineCTL,
+ readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
+ free_irq(dev->irq, dev);
ret = -EAGAIN;
goto bad_out;
}
- /* set the hardware to the configured choice */
- switch(lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
+ /* set the hardware to the configured choice */
+ switch (lp->adapter_cnf & A_CNF_MEDIA_TYPE) {
case A_CNF_MEDIA_10B_T:
- result = detect_tp(dev);
- if (result==DETECTED_NONE) {
- printk(KERN_WARNING "%s: 10Base-T (RJ-45) has no cable\n", dev->name);
- if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
- result = DETECTED_RJ45H; /* Yes! I don't care if I see a link pulse */
- }
+ result = detect_tp(dev);
+ if (result == DETECTED_NONE) {
+ pr_warn("%s: 10Base-T (RJ-45) has no cable\n",
+ dev->name);
+ if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
+ result = DETECTED_RJ45H; /* Yes! I don't care if I see a link pulse */
+ }
break;
case A_CNF_MEDIA_AUI:
- result = detect_aui(dev);
- if (result==DETECTED_NONE) {
- printk(KERN_WARNING "%s: 10Base-5 (AUI) has no cable\n", dev->name);
- if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
- result = DETECTED_AUI; /* Yes! I don't care if I see a carrrier */
- }
+ result = detect_aui(dev);
+ if (result == DETECTED_NONE) {
+ pr_warn("%s: 10Base-5 (AUI) has no cable\n", dev->name);
+ if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
+ result = DETECTED_AUI; /* Yes! I don't care if I see a carrrier */
+ }
break;
case A_CNF_MEDIA_10B_2:
- result = detect_bnc(dev);
- if (result==DETECTED_NONE) {
- printk(KERN_WARNING "%s: 10Base-2 (BNC) has no cable\n", dev->name);
- if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
- result = DETECTED_BNC; /* Yes! I don't care if I can xmit a packet */
- }
+ result = detect_bnc(dev);
+ if (result == DETECTED_NONE) {
+ pr_warn("%s: 10Base-2 (BNC) has no cable\n", dev->name);
+ if (lp->auto_neg_cnf & IMM_BIT) /* check "ignore missing media" bit */
+ result = DETECTED_BNC; /* Yes! I don't care if I can xmit a packet */
+ }
break;
case A_CNF_MEDIA_AUTO:
writereg(dev, PP_LineCTL, lp->linectl | AUTO_AUI_10BASET);
- if (lp->adapter_cnf & A_CNF_10B_T)
- if ((result = detect_tp(dev)) != DETECTED_NONE)
+ if (lp->adapter_cnf & A_CNF_10B_T) {
+ result = detect_tp(dev);
+ if (result != DETECTED_NONE)
break;
- if (lp->adapter_cnf & A_CNF_AUI)
- if ((result = detect_aui(dev)) != DETECTED_NONE)
+ }
+ if (lp->adapter_cnf & A_CNF_AUI) {
+ result = detect_aui(dev);
+ if (result != DETECTED_NONE)
break;
- if (lp->adapter_cnf & A_CNF_10B_2)
- if ((result = detect_bnc(dev)) != DETECTED_NONE)
+ }
+ if (lp->adapter_cnf & A_CNF_10B_2) {
+ result = detect_bnc(dev);
+ if (result != DETECTED_NONE)
break;
- printk(KERN_ERR "%s: no media detected\n", dev->name);
+ }
+ pr_err("%s: no media detected\n", dev->name);
goto release_dma;
}
- switch(result) {
+ switch (result) {
case DETECTED_NONE:
- printk(KERN_ERR "%s: no network cable attached to configured media\n", dev->name);
+ pr_err("%s: no network cable attached to configured media\n",
+ dev->name);
goto release_dma;
case DETECTED_RJ45H:
- printk(KERN_INFO "%s: using half-duplex 10Base-T (RJ-45)\n", dev->name);
+ pr_info("%s: using half-duplex 10Base-T (RJ-45)\n", dev->name);
break;
case DETECTED_RJ45F:
- printk(KERN_INFO "%s: using full-duplex 10Base-T (RJ-45)\n", dev->name);
+ pr_info("%s: using full-duplex 10Base-T (RJ-45)\n", dev->name);
break;
case DETECTED_AUI:
- printk(KERN_INFO "%s: using 10Base-5 (AUI)\n", dev->name);
+ pr_info("%s: using 10Base-5 (AUI)\n", dev->name);
break;
case DETECTED_BNC:
- printk(KERN_INFO "%s: using 10Base-2 (BNC)\n", dev->name);
+ pr_info("%s: using 10Base-2 (BNC)\n", dev->name);
break;
}
/* Turn on both receive and transmit operations */
- writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
+ writereg(dev, PP_LineCTL,
+ readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
/* Receive only error free packets addressed to this card */
lp->rx_mode = 0;
@@ -1405,358 +1101,653 @@ release_irq:
#endif
writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
- writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
- TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
+ writereg(dev, PP_TxCFG, (TX_LOST_CRS_ENBL |
+ TX_SQE_ERROR_ENBL |
+ TX_OK_ENBL |
+ TX_LATE_COL_ENBL |
+ TX_JBR_ENBL |
+ TX_ANY_COL_ENBL |
+ TX_16_COL_ENBL));
- writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
+ writereg(dev, PP_BufCFG, (READY_FOR_TX_ENBL |
+ RX_MISS_COUNT_OVRFLOW_ENBL |
#if ALLOW_DMA
- dma_bufcfg(dev) |
+ dma_bufcfg(dev) |
#endif
- TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
+ TX_COL_COUNT_OVRFLOW_ENBL |
+ TX_UNDERRUN_ENBL));
/* now that we've got our act together, enable everything */
- writereg(dev, PP_BusCTL, ENABLE_IRQ
- | (dev->mem_start?MEMORY_ON : 0) /* turn memory on */
+ writereg(dev, PP_BusCTL, (ENABLE_IRQ
+ | (dev->mem_start ? MEMORY_ON : 0) /* turn memory on */
#if ALLOW_DMA
- | dma_busctl(dev)
+ | dma_busctl(dev)
#endif
- );
- netif_start_queue(dev);
- if (net_debug > 1)
- printk("cs89x0: net_open() succeeded\n");
+ ));
+ netif_start_queue(dev);
+ cs89_dbg(1, debug, "net_open() succeeded\n");
return 0;
bad_out:
return ret;
}
+/* The inverse routine to net_open(). */
+static int
+net_close(struct net_device *dev)
+{
+#if ALLOW_DMA
+ struct net_local *lp = netdev_priv(dev);
+#endif
+
+ netif_stop_queue(dev);
+
+ writereg(dev, PP_RxCFG, 0);
+ writereg(dev, PP_TxCFG, 0);
+ writereg(dev, PP_BufCFG, 0);
+ writereg(dev, PP_BusCTL, 0);
+
+ free_irq(dev->irq, dev);
+
+#if ALLOW_DMA
+ if (lp->use_dma && lp->dma) {
+ free_dma(dev->dma);
+ release_dma_buff(lp);
+ }
+#endif
+
+ /* Update the statistics here. */
+ return 0;
+}
+
+/* Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *
+net_get_stats(struct net_device *dev)
+{
+ struct net_local *lp = netdev_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&lp->lock, flags);
+ /* Update the statistics from the device registers. */
+ dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
+ dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
+ spin_unlock_irqrestore(&lp->lock, flags);
+
+ return &dev->stats;
+}
+
static void net_timeout(struct net_device *dev)
{
/* If we get here, some higher level has decided we are broken.
There should really be a "kick me" function call instead. */
- if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict ?" : "network cable problem");
+ cs89_dbg(0, err, "%s: transmit timed out, %s?\n",
+ dev->name,
+ tx_done(dev) ? "IRQ conflict" : "network cable problem");
/* Try to restart the adaptor. */
netif_wake_queue(dev);
}
-static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev)
+static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev)
{
struct net_local *lp = netdev_priv(dev);
unsigned long flags;
- if (net_debug > 3) {
- printk("%s: sent %d byte packet of type %x\n",
- dev->name, skb->len,
- (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
- }
+ cs89_dbg(3, debug, "%s: sent %d byte packet of type %x\n",
+ dev->name, skb->len,
+ ((skb->data[ETH_ALEN + ETH_ALEN] << 8) |
+ skb->data[ETH_ALEN + ETH_ALEN + 1]));
/* keep the upload from being interrupted, since we
- ask the chip to start transmitting before the
- whole packet has been completely uploaded. */
+ * ask the chip to start transmitting before the
+ * whole packet has been completely uploaded.
+ */
spin_lock_irqsave(&lp->lock, flags);
netif_stop_queue(dev);
/* initiate a transmit sequence */
- writeword(dev->base_addr, TX_CMD_PORT, lp->send_cmd);
- writeword(dev->base_addr, TX_LEN_PORT, skb->len);
+ iowrite16(lp->send_cmd, lp->virt_addr + TX_CMD_PORT);
+ iowrite16(skb->len, lp->virt_addr + TX_LEN_PORT);
/* Test to see if the chip has allocated memory for the packet */
if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
- /*
- * Gasp! It hasn't. But that shouldn't happen since
+ /* Gasp! It hasn't. But that shouldn't happen since
* we're waiting for TxOk, so return 1 and requeue this packet.
*/
spin_unlock_irqrestore(&lp->lock, flags);
- if (net_debug) printk("cs89x0: Tx buffer not free!\n");
+ cs89_dbg(0, err, "Tx buffer not free!\n");
return NETDEV_TX_BUSY;
}
/* Write the contents of the packet */
- writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
+ writewords(lp, TX_FRAME_PORT, skb->data, (skb->len + 1) >> 1);
spin_unlock_irqrestore(&lp->lock, flags);
dev->stats.tx_bytes += skb->len;
- dev_kfree_skb (skb);
+ dev_kfree_skb(skb);
- /*
- * We DO NOT call netif_wake_queue() here.
+ /* We DO NOT call netif_wake_queue() here.
* We also DO NOT call netif_start_queue().
*
* Either of these would cause another bottom half run through
- * net_send_packet() before this packet has fully gone out. That causes
- * us to hit the "Gasp!" above and the send is rescheduled. it runs like
- * a dog. We just return and wait for the Tx completion interrupt handler
- * to restart the netdevice layer
+ * net_send_packet() before this packet has fully gone out.
+ * That causes us to hit the "Gasp!" above and the send is rescheduled.
+ * it runs like a dog. We just return and wait for the Tx completion
+ * interrupt handler to restart the netdevice layer
*/
return NETDEV_TX_OK;
}
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
+static void set_multicast_list(struct net_device *dev)
+{
+ struct net_local *lp = netdev_priv(dev);
+ unsigned long flags;
-static irqreturn_t net_interrupt(int irq, void *dev_id)
+ spin_lock_irqsave(&lp->lock, flags);
+ if (dev->flags & IFF_PROMISC)
+ lp->rx_mode = RX_ALL_ACCEPT;
+ else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
+ /* The multicast-accept list is initialized to accept-all,
+ * and we rely on higher-level filtering for now.
+ */
+ lp->rx_mode = RX_MULTCAST_ACCEPT;
+ else
+ lp->rx_mode = 0;
+
+ writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
+
+ /* in promiscuous mode, we accept errored packets,
+ * so we have to enable interrupts on them also
+ */
+ writereg(dev, PP_RxCFG,
+ (lp->curr_rx_cfg |
+ (lp->rx_mode == RX_ALL_ACCEPT)
+ ? (RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL)
+ : 0));
+ spin_unlock_irqrestore(&lp->lock, flags);
+}
+
+static int set_mac_address(struct net_device *dev, void *p)
{
- struct net_device *dev = dev_id;
- struct net_local *lp;
- int ioaddr, status;
- int handled = 0;
+ int i;
+ struct sockaddr *addr = p;
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
+ if (netif_running(dev))
+ return -EBUSY;
- /* we MUST read all the events out of the ISQ, otherwise we'll never
- get interrupted again. As a consequence, we can't have any limit
- on the number of times we loop in the interrupt handler. The
- hardware guarantees that eventually we'll run out of events. Of
- course, if you're on a slow machine, and packets are arriving
- faster than you can read them off, you're screwed. Hasta la
- vista, baby! */
- while ((status = readword(dev->base_addr, ISQ_PORT))) {
- if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
- handled = 1;
- switch(status & ISQ_EVENT_MASK) {
- case ISQ_RECEIVER_EVENT:
- /* Got a packet(s). */
- net_rx(dev);
- break;
- case ISQ_TRANSMITTER_EVENT:
- dev->stats.tx_packets++;
- netif_wake_queue(dev); /* Inform upper layers. */
- if ((status & ( TX_OK |
- TX_LOST_CRS |
- TX_SQE_ERROR |
- TX_LATE_COL |
- TX_16_COL)) != TX_OK) {
- if ((status & TX_OK) == 0)
- dev->stats.tx_errors++;
- if (status & TX_LOST_CRS)
- dev->stats.tx_carrier_errors++;
- if (status & TX_SQE_ERROR)
- dev->stats.tx_heartbeat_errors++;
- if (status & TX_LATE_COL)
- dev->stats.tx_window_errors++;
- if (status & TX_16_COL)
- dev->stats.tx_aborted_errors++;
- }
- break;
- case ISQ_BUFFER_EVENT:
- if (status & READY_FOR_TX) {
- /* we tried to transmit a packet earlier,
- but inexplicably ran out of buffers.
- That shouldn't happen since we only ever
- load one packet. Shrug. Do the right
- thing anyway. */
- netif_wake_queue(dev); /* Inform upper layers. */
- }
- if (status & TX_UNDERRUN) {
- if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
- lp->send_underrun++;
- if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
- else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
- /* transmit cycle is done, although
- frame wasn't transmitted - this
- avoids having to wait for the upper
- layers to timeout on us, in the
- event of a tx underrun */
- netif_wake_queue(dev); /* Inform upper layers. */
- }
-#if ALLOW_DMA
- if (lp->use_dma && (status & RX_DMA)) {
- int count = readreg(dev, PP_DmaFrameCnt);
- while(count) {
- if (net_debug > 5)
- printk("%s: receiving %d DMA frames\n", dev->name, count);
- if (net_debug > 2 && count >1)
- printk("%s: receiving %d DMA frames\n", dev->name, count);
- dma_rx(dev);
- if (--count == 0)
- count = readreg(dev, PP_DmaFrameCnt);
- if (net_debug > 2 && count > 0)
- printk("%s: continuing with %d DMA frames\n", dev->name, count);
- }
- }
-#endif
- break;
- case ISQ_RX_MISS_EVENT:
- dev->stats.rx_missed_errors += (status >> 6);
- break;
- case ISQ_TX_COL_EVENT:
- dev->stats.collisions += (status >> 6);
- break;
- }
- }
- return IRQ_RETVAL(handled);
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ cs89_dbg(0, debug, "%s: Setting MAC address to %pM\n",
+ dev->name, dev->dev_addr);
+
+ /* set the Ethernet address */
+ for (i = 0; i < ETH_ALEN / 2; i++)
+ writereg(dev, PP_IA + i * 2,
+ (dev->dev_addr[i * 2] |
+ (dev->dev_addr[i * 2 + 1] << 8)));
+
+ return 0;
}
-static void
-count_rx_errors(int status, struct net_device *dev)
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void net_poll_controller(struct net_device *dev)
{
- dev->stats.rx_errors++;
- if (status & RX_RUNT)
- dev->stats.rx_length_errors++;
- if (status & RX_EXTRA_DATA)
- dev->stats.rx_length_errors++;
- if ((status & RX_CRC_ERROR) && !(status & (RX_EXTRA_DATA|RX_RUNT)))
- /* per str 172 */
- dev->stats.rx_crc_errors++;
- if (status & RX_DRIBBLE)
- dev->stats.rx_frame_errors++;
+ disable_irq(dev->irq);
+ net_interrupt(dev->irq, dev);
+ enable_irq(dev->irq);
}
+#endif
-/* We have a good packet(s), get it/them out of the buffers. */
-static void
-net_rx(struct net_device *dev)
+static const struct net_device_ops net_ops = {
+ .ndo_open = net_open,
+ .ndo_stop = net_close,
+ .ndo_tx_timeout = net_timeout,
+ .ndo_start_xmit = net_send_packet,
+ .ndo_get_stats = net_get_stats,
+ .ndo_set_rx_mode = set_multicast_list,
+ .ndo_set_mac_address = set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = net_poll_controller,
+#endif
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static void __init reset_chip(struct net_device *dev)
{
- struct sk_buff *skb;
- int status, length;
+#if !defined(CONFIG_MACH_MX31ADS)
+#if !defined(CS89x0_NONISA_IRQ)
+ struct net_local *lp = netdev_priv(dev);
+#endif /* CS89x0_NONISA_IRQ */
+ int reset_start_time;
- int ioaddr = dev->base_addr;
- status = readword(ioaddr, RX_FRAME_PORT);
- length = readword(ioaddr, RX_FRAME_PORT);
+ writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
- if ((status & RX_OK) == 0) {
- count_rx_errors(status, dev);
- return;
+ /* wait 30 ms */
+ msleep(30);
+
+#if !defined(CS89x0_NONISA_IRQ)
+ if (lp->chip_type != CS8900) {
+ /* Hardware problem requires PNP registers to be reconfigured after a reset */
+ iowrite16(PP_CS8920_ISAINT, lp->virt_addr + ADD_PORT);
+ iowrite8(dev->irq, lp->virt_addr + DATA_PORT);
+ iowrite8(0, lp->virt_addr + DATA_PORT + 1);
+
+ iowrite16(PP_CS8920_ISAMemB, lp->virt_addr + ADD_PORT);
+ iowrite8((dev->mem_start >> 16) & 0xff,
+ lp->virt_addr + DATA_PORT);
+ iowrite8((dev->mem_start >> 8) & 0xff,
+ lp->virt_addr + DATA_PORT + 1);
}
+#endif /* CS89x0_NONISA_IRQ */
- /* Malloc up new buffer. */
- skb = netdev_alloc_skb(dev, length + 2);
- if (skb == NULL) {
-#if 0 /* Again, this seems a cruel thing to do */
- printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
+ /* Wait until the chip is reset */
+ reset_start_time = jiffies;
+ while ((readreg(dev, PP_SelfST) & INIT_DONE) == 0 &&
+ jiffies - reset_start_time < 2)
+ ;
+#endif /* !CONFIG_MACH_MX31ADS */
+}
+
+/* This is the real probe routine.
+ * Linux has a history of friendly device probes on the ISA bus.
+ * A good device probes avoids doing writes, and
+ * verifies that the correct device exists and functions.
+ * Return 0 on success.
+ */
+static int __init
+cs89x0_probe1(struct net_device *dev, void __iomem *ioaddr, int modular)
+{
+ struct net_local *lp = netdev_priv(dev);
+ int i;
+ int tmp;
+ unsigned rev_type = 0;
+ int eeprom_buff[CHKSUM_LEN];
+ int retval;
+
+ /* Initialize the device structure. */
+ if (!modular) {
+ memset(lp, 0, sizeof(*lp));
+ spin_lock_init(&lp->lock);
+#ifndef MODULE
+#if ALLOW_DMA
+ if (g_cs89x0_dma) {
+ lp->use_dma = 1;
+ lp->dma = g_cs89x0_dma;
+ lp->dmasize = 16; /* Could make this an option... */
+ }
+#endif
+ lp->force = g_cs89x0_media__force;
#endif
- dev->stats.rx_dropped++;
- return;
}
- skb_reserve(skb, 2); /* longword align L3 header */
- readwords(ioaddr, RX_FRAME_PORT, skb_put(skb, length), length >> 1);
- if (length & 1)
- skb->data[length-1] = readword(ioaddr, RX_FRAME_PORT);
+ pr_debug("PP_addr at %p[%x]: 0x%x\n",
+ ioaddr, ADD_PORT, ioread16(ioaddr + ADD_PORT));
+ iowrite16(PP_ChipID, ioaddr + ADD_PORT);
- if (net_debug > 3) {
- printk( "%s: received %d byte packet of type %x\n",
- dev->name, length,
- (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]);
+ tmp = ioread16(ioaddr + DATA_PORT);
+ if (tmp != CHIP_EISA_ID_SIG) {
+ pr_debug("%s: incorrect signature at %p[%x]: 0x%x!="
+ CHIP_EISA_ID_SIG_STR "\n",
+ dev->name, ioaddr, DATA_PORT, tmp);
+ retval = -ENODEV;
+ goto out1;
}
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += length;
-}
+ lp->virt_addr = ioaddr;
-#if ALLOW_DMA
-static void release_dma_buff(struct net_local *lp)
-{
- if (lp->dma_buff) {
- free_pages((unsigned long)(lp->dma_buff), get_order(lp->dmasize * 1024));
- lp->dma_buff = NULL;
+ /* get the chip type */
+ rev_type = readreg(dev, PRODUCT_ID_ADD);
+ lp->chip_type = rev_type & ~REVISON_BITS;
+ lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
+
+ /* Check the chip type and revision in order to set the correct
+ * send command. CS8920 revision C and CS8900 revision F can use
+ * the faster send.
+ */
+ lp->send_cmd = TX_AFTER_381;
+ if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
+ lp->send_cmd = TX_NOW;
+ if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
+ lp->send_cmd = TX_NOW;
+
+ pr_info_once("%s\n", version);
+
+ pr_info("%s: cs89%c0%s rev %c found at %p ",
+ dev->name,
+ lp->chip_type == CS8900 ? '0' : '2',
+ lp->chip_type == CS8920M ? "M" : "",
+ lp->chip_revision,
+ lp->virt_addr);
+
+ reset_chip(dev);
+
+ /* Here we read the current configuration of the chip.
+ * If there is no Extended EEPROM then the idea is to not disturb
+ * the chip configuration, it should have been correctly setup by
+ * automatic EEPROM read on reset. So, if the chip says it read
+ * the EEPROM the driver will always do *something* instead of
+ * complain that adapter_cnf is 0.
+ */
+
+ if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) ==
+ (EEPROM_OK | EEPROM_PRESENT)) {
+ /* Load the MAC. */
+ for (i = 0; i < ETH_ALEN / 2; i++) {
+ unsigned int Addr;
+ Addr = readreg(dev, PP_IA + i * 2);
+ dev->dev_addr[i * 2] = Addr & 0xFF;
+ dev->dev_addr[i * 2 + 1] = Addr >> 8;
+ }
+
+ /* Load the Adapter Configuration.
+ * Note: Barring any more specific information from some
+ * other source (ie EEPROM+Schematics), we would not know
+ * how to operate a 10Base2 interface on the AUI port.
+ * However, since we do read the status of HCB1 and use
+ * settings that always result in calls to control_dc_dc(dev,0)
+ * a BNC interface should work if the enable pin
+ * (dc/dc converter) is on HCB1.
+ * It will be called AUI however.
+ */
+
+ lp->adapter_cnf = 0;
+ i = readreg(dev, PP_LineCTL);
+ /* Preserve the setting of the HCB1 pin. */
+ if ((i & (HCB1 | HCB1_ENBL)) == (HCB1 | HCB1_ENBL))
+ lp->adapter_cnf |= A_CNF_DC_DC_POLARITY;
+ /* Save the sqelch bit */
+ if ((i & LOW_RX_SQUELCH) == LOW_RX_SQUELCH)
+ lp->adapter_cnf |= A_CNF_EXTND_10B_2 | A_CNF_LOW_RX_SQUELCH;
+ /* Check if the card is in 10Base-t only mode */
+ if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == 0)
+ lp->adapter_cnf |= A_CNF_10B_T | A_CNF_MEDIA_10B_T;
+ /* Check if the card is in AUI only mode */
+ if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUI_ONLY)
+ lp->adapter_cnf |= A_CNF_AUI | A_CNF_MEDIA_AUI;
+ /* Check if the card is in Auto mode. */
+ if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUTO_AUI_10BASET)
+ lp->adapter_cnf |= A_CNF_AUI | A_CNF_10B_T |
+ A_CNF_MEDIA_AUI | A_CNF_MEDIA_10B_T | A_CNF_MEDIA_AUTO;
+
+ cs89_dbg(1, info, "%s: PP_LineCTL=0x%x, adapter_cnf=0x%x\n",
+ dev->name, i, lp->adapter_cnf);
+
+ /* IRQ. Other chips already probe, see below. */
+ if (lp->chip_type == CS8900)
+ lp->isa_config = readreg(dev, PP_CS8900_ISAINT) & INT_NO_MASK;
+
+ pr_cont("[Cirrus EEPROM] ");
}
-}
-#endif
-/* The inverse routine to net_open(). */
-static int
-net_close(struct net_device *dev)
-{
-#if ALLOW_DMA
- struct net_local *lp = netdev_priv(dev);
-#endif
+ pr_cont("\n");
- netif_stop_queue(dev);
+ /* First check to see if an EEPROM is attached. */
- writereg(dev, PP_RxCFG, 0);
- writereg(dev, PP_TxCFG, 0);
- writereg(dev, PP_BufCFG, 0);
- writereg(dev, PP_BusCTL, 0);
+ if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
+ pr_warn("No EEPROM, relying on command line....\n");
+ else if (get_eeprom_data(dev, START_EEPROM_DATA, CHKSUM_LEN, eeprom_buff) < 0) {
+ pr_warn("EEPROM read failed, relying on command line\n");
+ } else if (get_eeprom_cksum(START_EEPROM_DATA, CHKSUM_LEN, eeprom_buff) < 0) {
+ /* Check if the chip was able to read its own configuration starting
+ at 0 in the EEPROM*/
+ if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) !=
+ (EEPROM_OK | EEPROM_PRESENT))
+ pr_warn("Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command line\n");
- free_irq(dev->irq, dev);
+ } else {
+ /* This reads an extended EEPROM that is not documented
+ * in the CS8900 datasheet.
+ */
-#if ALLOW_DMA
- if (lp->use_dma && lp->dma) {
- free_dma(dev->dma);
- release_dma_buff(lp);
+ /* get transmission control word but keep the autonegotiation bits */
+ if (!lp->auto_neg_cnf)
+ lp->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET / 2];
+ /* Store adapter configuration */
+ if (!lp->adapter_cnf)
+ lp->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET / 2];
+ /* Store ISA configuration */
+ lp->isa_config = eeprom_buff[ISA_CNF_OFFSET / 2];
+ dev->mem_start = eeprom_buff[PACKET_PAGE_OFFSET / 2] << 8;
+
+ /* eeprom_buff has 32-bit ints, so we can't just memcpy it */
+ /* store the initial memory base address */
+ for (i = 0; i < ETH_ALEN / 2; i++) {
+ dev->dev_addr[i * 2] = eeprom_buff[i];
+ dev->dev_addr[i * 2 + 1] = eeprom_buff[i] >> 8;
+ }
+ cs89_dbg(1, debug, "%s: new adapter_cnf: 0x%x\n",
+ dev->name, lp->adapter_cnf);
}
+
+ /* allow them to force multiple transceivers. If they force multiple, autosense */
+ {
+ int count = 0;
+ if (lp->force & FORCE_RJ45) {
+ lp->adapter_cnf |= A_CNF_10B_T;
+ count++;
+ }
+ if (lp->force & FORCE_AUI) {
+ lp->adapter_cnf |= A_CNF_AUI;
+ count++;
+ }
+ if (lp->force & FORCE_BNC) {
+ lp->adapter_cnf |= A_CNF_10B_2;
+ count++;
+ }
+ if (count > 1)
+ lp->adapter_cnf |= A_CNF_MEDIA_AUTO;
+ else if (lp->force & FORCE_RJ45)
+ lp->adapter_cnf |= A_CNF_MEDIA_10B_T;
+ else if (lp->force & FORCE_AUI)
+ lp->adapter_cnf |= A_CNF_MEDIA_AUI;
+ else if (lp->force & FORCE_BNC)
+ lp->adapter_cnf |= A_CNF_MEDIA_10B_2;
+ }
+
+ cs89_dbg(1, debug, "%s: after force 0x%x, adapter_cnf=0x%x\n",
+ dev->name, lp->force, lp->adapter_cnf);
+
+ /* FIXME: We don't let you set dc-dc polarity or low RX squelch from the command line: add it here */
+
+ /* FIXME: We don't let you set the IMM bit from the command line: add it to lp->auto_neg_cnf here */
+
+ /* FIXME: we don't set the Ethernet address on the command line. Use
+ * ifconfig IFACE hw ether AABBCCDDEEFF
+ */
+
+ pr_info("media %s%s%s",
+ (lp->adapter_cnf & A_CNF_10B_T) ? "RJ-45," : "",
+ (lp->adapter_cnf & A_CNF_AUI) ? "AUI," : "",
+ (lp->adapter_cnf & A_CNF_10B_2) ? "BNC," : "");
+
+ lp->irq_map = 0xffff;
+
+ /* If this is a CS8900 then no pnp soft */
+ if (lp->chip_type != CS8900 &&
+ /* Check if the ISA IRQ has been set */
+ (i = readreg(dev, PP_CS8920_ISAINT) & 0xff,
+ (i != 0 && i < CS8920_NO_INTS))) {
+ if (!dev->irq)
+ dev->irq = i;
+ } else {
+ i = lp->isa_config & INT_NO_MASK;
+#ifndef CONFIG_CS89x0_PLATFORM
+ if (lp->chip_type == CS8900) {
+#ifdef CS89x0_NONISA_IRQ
+ i = cs8900_irq_map[0];
+#else
+ /* Translate the IRQ using the IRQ mapping table. */
+ if (i >= ARRAY_SIZE(cs8900_irq_map))
+ pr_err("invalid ISA interrupt number %d\n", i);
+ else
+ i = cs8900_irq_map[i];
+
+ lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */
+ } else {
+ int irq_map_buff[IRQ_MAP_LEN/2];
+
+ if (get_eeprom_data(dev, IRQ_MAP_EEPROM_DATA,
+ IRQ_MAP_LEN / 2,
+ irq_map_buff) >= 0) {
+ if ((irq_map_buff[0] & 0xff) == PNP_IRQ_FRMT)
+ lp->irq_map = ((irq_map_buff[0] >> 8) |
+ (irq_map_buff[1] << 8));
+ }
#endif
+ }
+#endif
+ if (!dev->irq)
+ dev->irq = i;
+ }
- /* Update the statistics here. */
- return 0;
-}
+ pr_cont(" IRQ %d", dev->irq);
-/* Get the current statistics. This may be called with the card open or
- closed. */
-static struct net_device_stats *
-net_get_stats(struct net_device *dev)
-{
- struct net_local *lp = netdev_priv(dev);
- unsigned long flags;
+#if ALLOW_DMA
+ if (lp->use_dma) {
+ get_dma_channel(dev);
+ pr_cont(", DMA %d", dev->dma);
+ } else
+#endif
+ pr_cont(", programmed I/O");
- spin_lock_irqsave(&lp->lock, flags);
- /* Update the statistics from the device registers. */
- dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
- dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
- spin_unlock_irqrestore(&lp->lock, flags);
+ /* print the ethernet address. */
+ pr_cont(", MAC %pM\n", dev->dev_addr);
- return &dev->stats;
+ dev->netdev_ops = &net_ops;
+ dev->watchdog_timeo = HZ;
+
+ cs89_dbg(0, info, "cs89x0_probe1() successful\n");
+
+ retval = register_netdev(dev);
+ if (retval)
+ goto out2;
+ return 0;
+out2:
+ iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
+out1:
+ return retval;
}
-static void set_multicast_list(struct net_device *dev)
+#ifndef CONFIG_CS89x0_PLATFORM
+/*
+ * This function converts the I/O port addres used by the cs89x0_probe() and
+ * init_module() functions to the I/O memory address used by the
+ * cs89x0_probe1() function.
+ */
+static int __init
+cs89x0_ioport_probe(struct net_device *dev, unsigned long ioport, int modular)
{
struct net_local *lp = netdev_priv(dev);
- unsigned long flags;
+ int ret;
+ void __iomem *io_mem;
- spin_lock_irqsave(&lp->lock, flags);
- if(dev->flags&IFF_PROMISC)
- {
- lp->rx_mode = RX_ALL_ACCEPT;
+ if (!lp)
+ return -ENOMEM;
+
+ dev->base_addr = ioport;
+
+ if (!request_region(ioport, NETCARD_IO_EXTENT, DRV_NAME)) {
+ ret = -EBUSY;
+ goto out;
}
- else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
- {
- /* The multicast-accept list is initialized to accept-all, and we
- rely on higher-level filtering for now. */
- lp->rx_mode = RX_MULTCAST_ACCEPT;
+
+ io_mem = ioport_map(ioport & ~3, NETCARD_IO_EXTENT);
+ if (!io_mem) {
+ ret = -ENOMEM;
+ goto release;
}
- else
- lp->rx_mode = 0;
- writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
+ /* if they give us an odd I/O address, then do ONE write to
+ * the address port, to get it back to address zero, where we
+ * expect to find the EISA signature word. An IO with a base of 0x3
+ * will skip the test for the ADD_PORT.
+ */
+ if (ioport & 1) {
+ cs89_dbg(1, info, "%s: odd ioaddr 0x%lx\n", dev->name, ioport);
+ if ((ioport & 2) != 2) {
+ if ((ioread16(io_mem + ADD_PORT) & ADD_MASK) !=
+ ADD_SIG) {
+ pr_err("%s: bad signature 0x%x\n",
+ dev->name, ioread16(io_mem + ADD_PORT));
+ ret = -ENODEV;
+ goto unmap;
+ }
+ }
+ }
- /* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
- writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
- (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
- spin_unlock_irqrestore(&lp->lock, flags);
+ ret = cs89x0_probe1(dev, io_mem, modular);
+ if (!ret)
+ goto out;
+unmap:
+ ioport_unmap(io_mem);
+release:
+ release_region(ioport, NETCARD_IO_EXTENT);
+out:
+ return ret;
}
+#ifndef MODULE
+/* Check for a network adaptor of this type, and return '0' iff one exists.
+ * If dev->base_addr == 0, probe all likely locations.
+ * If dev->base_addr == 1, always return failure.
+ * If dev->base_addr == 2, allocate space for the device and return success
+ * (detachable devices only).
+ * Return 0 on success.
+ */
-static int set_mac_address(struct net_device *dev, void *p)
+struct net_device * __init cs89x0_probe(int unit)
{
- int i;
- struct sockaddr *addr = p;
-
- if (netif_running(dev))
- return -EBUSY;
+ struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+ unsigned *port;
+ int err = 0;
+ int irq;
+ int io;
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ if (!dev)
+ return ERR_PTR(-ENODEV);
- if (net_debug)
- printk("%s: Setting MAC address to %pM.\n",
- dev->name, dev->dev_addr);
+ sprintf(dev->name, "eth%d", unit);
+ netdev_boot_setup_check(dev);
+ io = dev->base_addr;
+ irq = dev->irq;
- /* set the Ethernet address */
- for (i=0; i < ETH_ALEN/2; i++)
- writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
+ cs89_dbg(0, info, "cs89x0_probe(0x%x)\n", io);
- return 0;
+ if (io > 0x1ff) { /* Check a single specified location. */
+ err = cs89x0_ioport_probe(dev, io, 0);
+ } else if (io != 0) { /* Don't probe at all. */
+ err = -ENXIO;
+ } else {
+ for (port = netcard_portlist; *port; port++) {
+ if (cs89x0_ioport_probe(dev, *port, 0) == 0)
+ break;
+ dev->irq = irq;
+ }
+ if (!*port)
+ err = -ENODEV;
+ }
+ if (err)
+ goto out;
+ return dev;
+out:
+ free_netdev(dev);
+ pr_warn("no cs8900 or cs8920 detected. Be sure to disable PnP with SETUP\n");
+ return ERR_PTR(err);
}
+#endif
+#endif
#if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM)
static struct net_device *dev_cs89x0;
-/*
- * Support the 'debug' module parm even if we're compiled for non-debug to
+/* Support the 'debug' module parm even if we're compiled for non-debug to
* avoid breaking someone's startup scripts
*/
@@ -1764,11 +1755,11 @@ static int io;
static int irq;
static int debug;
static char media[8];
-static int duplex=-1;
+static int duplex = -1;
static int use_dma; /* These generate unused var warnings if ALLOW_DMA = 0 */
static int dma;
-static int dmasize=16; /* or 64 */
+static int dmasize = 16; /* or 64 */
module_param(io, int, 0);
module_param(irq, int, 0);
@@ -1801,32 +1792,28 @@ MODULE_PARM_DESC(use_dma , "(ignored)");
MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton");
MODULE_LICENSE("GPL");
-
/*
-* media=t - specify media type
- or media=2
- or media=aui
- or medai=auto
-* duplex=0 - specify forced half/full/autonegotiate duplex
-* debug=# - debug level
-
-
-* Default Chip Configuration:
- * DMA Burst = enabled
- * IOCHRDY Enabled = enabled
- * UseSA = enabled
- * CS8900 defaults to half-duplex if not specified on command-line
- * CS8920 defaults to autoneg if not specified on command-line
- * Use reset defaults for other config parameters
-
-* Assumptions:
- * media type specified is supported (circuitry is present)
- * if memory address is > 1MB, then required mem decode hw is present
- * if 10B-2, then agent other than driver will enable DC/DC converter
- (hw or software util)
-
-
-*/
+ * media=t - specify media type
+ * or media=2
+ * or media=aui
+ * or medai=auto
+ * duplex=0 - specify forced half/full/autonegotiate duplex
+ * debug=# - debug level
+ *
+ * Default Chip Configuration:
+ * DMA Burst = enabled
+ * IOCHRDY Enabled = enabled
+ * UseSA = enabled
+ * CS8900 defaults to half-duplex if not specified on command-line
+ * CS8920 defaults to autoneg if not specified on command-line
+ * Use reset defaults for other config parameters
+ *
+ * Assumptions:
+ * media type specified is supported (circuitry is present)
+ * if memory address is > 1MB, then required mem decode hw is present
+ * if 10B-2, then agent other than driver will enable DC/DC converter
+ * (hw or software util)
+ */
int __init init_module(void)
{
@@ -1856,8 +1843,8 @@ int __init init_module(void)
spin_lock_init(&lp->lock);
- /* boy, they'd better get these right */
- if (!strcmp(media, "rj45"))
+ /* boy, they'd better get these right */
+ if (!strcmp(media, "rj45"))
lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
else if (!strcmp(media, "aui"))
lp->adapter_cnf = A_CNF_MEDIA_AUI | A_CNF_AUI;
@@ -1866,27 +1853,28 @@ int __init init_module(void)
else
lp->adapter_cnf = A_CNF_MEDIA_10B_T | A_CNF_10B_T;
- if (duplex==-1)
+ if (duplex == -1)
lp->auto_neg_cnf = AUTO_NEG_ENABLE;
- if (io == 0) {
- printk(KERN_ERR "cs89x0.c: Module autoprobing not allowed.\n");
- printk(KERN_ERR "cs89x0.c: Append io=0xNNN\n");
- ret = -EPERM;
+ if (io == 0) {
+ pr_err("Module autoprobing not allowed\n");
+ pr_err("Append io=0xNNN\n");
+ ret = -EPERM;
goto out;
- } else if (io <= 0x1ff) {
+ } else if (io <= 0x1ff) {
ret = -ENXIO;
goto out;
}
#if ALLOW_DMA
if (use_dma && dmasize != 16 && dmasize != 64) {
- printk(KERN_ERR "cs89x0.c: dma size must be either 16K or 64K, not %dK\n", dmasize);
+ pr_err("dma size must be either 16K or 64K, not %dK\n",
+ dmasize);
ret = -EPERM;
goto out;
}
#endif
- ret = cs89x0_probe1(dev, io, 1);
+ ret = cs89x0_ioport_probe(dev, io, 1);
if (ret)
goto out;
@@ -1900,8 +1888,11 @@ out:
void __exit
cleanup_module(void)
{
+ struct net_local *lp = netdev_priv(dev_cs89x0);
+
unregister_netdev(dev_cs89x0);
- writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID);
+ iowrite16(PP_ChipID, lp->virt_addr + ADD_PORT);
+ ioport_unmap(lp->virt_addr);
release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
free_netdev(dev_cs89x0);
}
@@ -1913,6 +1904,7 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev)
struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
struct net_local *lp;
struct resource *mem_res;
+ void __iomem *virt_addr;
int err;
if (!dev)
@@ -1923,29 +1915,28 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev)
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->irq = platform_get_irq(pdev, 0);
if (mem_res == NULL || dev->irq <= 0) {
- dev_warn(&dev->dev, "memory/interrupt resource missing.\n");
+ dev_warn(&dev->dev, "memory/interrupt resource missing\n");
err = -ENXIO;
goto free;
}
- lp->phys_addr = mem_res->start;
lp->size = resource_size(mem_res);
- if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) {
- dev_warn(&dev->dev, "request_mem_region() failed.\n");
+ if (!request_mem_region(mem_res->start, lp->size, DRV_NAME)) {
+ dev_warn(&dev->dev, "request_mem_region() failed\n");
err = -EBUSY;
goto free;
}
- lp->virt_addr = ioremap(lp->phys_addr, lp->size);
- if (!lp->virt_addr) {
- dev_warn(&dev->dev, "ioremap() failed.\n");
+ virt_addr = ioremap(mem_res->start, lp->size);
+ if (!virt_addr) {
+ dev_warn(&dev->dev, "ioremap() failed\n");
err = -ENOMEM;
goto release;
}
- err = cs89x0_probe1(dev, (unsigned long)lp->virt_addr, 0);
+ err = cs89x0_probe1(dev, virt_addr, 0);
if (err) {
- dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n");
+ dev_warn(&dev->dev, "no cs8900 or cs8920 detected\n");
goto unmap;
}
@@ -1953,9 +1944,9 @@ static int __init cs89x0_platform_probe(struct platform_device *pdev)
return 0;
unmap:
- iounmap(lp->virt_addr);
+ iounmap(virt_addr);
release:
- release_mem_region(lp->phys_addr, lp->size);
+ release_mem_region(mem_res->start, lp->size);
free:
free_netdev(dev);
return err;
@@ -1965,10 +1956,16 @@ static int cs89x0_platform_remove(struct platform_device *pdev)
{
struct net_device *dev = platform_get_drvdata(pdev);
struct net_local *lp = netdev_priv(dev);
+ struct resource *mem_res;
+ /* This platform_get_resource() call will not return NULL, because
+ * the same call in cs89x0_platform_probe() has returned a non NULL
+ * value.
+ */
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
unregister_netdev(dev);
iounmap(lp->virt_addr);
- release_mem_region(lp->phys_addr, lp->size);
+ release_mem_region(mem_res->start, lp->size);
free_netdev(dev);
return 0;
}
@@ -1996,13 +1993,3 @@ static void __exit cs89x0_cleanup(void)
module_exit(cs89x0_cleanup);
#endif /* CONFIG_CS89x0_PLATFORM */
-
-/*
- * Local variables:
- * version-control: t
- * kept-new-versions: 5
- * c-indent-level: 8
- * tab-width: 8
- * End:
- *
- */
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index d7ac6c17547c..8132c785cea8 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -944,8 +944,7 @@ static void enic_update_multicast_addr_list(struct enic *enic)
for (i = 0; i < enic->mc_count; i++) {
for (j = 0; j < mc_count; j++)
- if (compare_ether_addr(enic->mc_addr[i],
- mc_addr[j]) == 0)
+ if (ether_addr_equal(enic->mc_addr[i], mc_addr[j]))
break;
if (j == mc_count)
enic_dev_del_addr(enic, enic->mc_addr[i]);
@@ -953,8 +952,7 @@ static void enic_update_multicast_addr_list(struct enic *enic)
for (i = 0; i < mc_count; i++) {
for (j = 0; j < enic->mc_count; j++)
- if (compare_ether_addr(mc_addr[i],
- enic->mc_addr[j]) == 0)
+ if (ether_addr_equal(mc_addr[i], enic->mc_addr[j]))
break;
if (j == enic->mc_count)
enic_dev_add_addr(enic, mc_addr[i]);
@@ -999,8 +997,7 @@ static void enic_update_unicast_addr_list(struct enic *enic)
for (i = 0; i < enic->uc_count; i++) {
for (j = 0; j < uc_count; j++)
- if (compare_ether_addr(enic->uc_addr[i],
- uc_addr[j]) == 0)
+ if (ether_addr_equal(enic->uc_addr[i], uc_addr[j]))
break;
if (j == uc_count)
enic_dev_del_addr(enic, enic->uc_addr[i]);
@@ -1008,8 +1005,7 @@ static void enic_update_unicast_addr_list(struct enic *enic)
for (i = 0; i < uc_count; i++) {
for (j = 0; j < enic->uc_count; j++)
- if (compare_ether_addr(uc_addr[i],
- enic->uc_addr[j]) == 0)
+ if (ether_addr_equal(uc_addr[i], enic->uc_addr[j]))
break;
if (j == enic->uc_count)
enic_dev_add_addr(enic, uc_addr[i]);
diff --git a/drivers/net/ethernet/davicom/Kconfig b/drivers/net/ethernet/davicom/Kconfig
index 972b62b31837..9745fe5e8039 100644
--- a/drivers/net/ethernet/davicom/Kconfig
+++ b/drivers/net/ethernet/davicom/Kconfig
@@ -4,7 +4,7 @@
config DM9000
tristate "DM9000 support"
- depends on ARM || BLACKFIN || MIPS
+ depends on ARM || BLACKFIN || MIPS || COLDFIRE
select CRC32
select NET_CORE
select MII
diff --git a/drivers/net/ethernet/dec/ewrk3.c b/drivers/net/ethernet/dec/ewrk3.c
index 1879f84a25a3..17ae8c619680 100644
--- a/drivers/net/ethernet/dec/ewrk3.c
+++ b/drivers/net/ethernet/dec/ewrk3.c
@@ -1016,7 +1016,8 @@ static int ewrk3_rx(struct net_device *dev)
} else {
lp->pktStats.multicast++;
}
- } else if (compare_ether_addr(p, dev->dev_addr) == 0) {
+ } else if (ether_addr_equal(p,
+ dev->dev_addr)) {
lp->pktStats.unicast++;
}
lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c
index 18b106cc6d2b..d3cd489d11a2 100644
--- a/drivers/net/ethernet/dec/tulip/de4x5.c
+++ b/drivers/net/ethernet/dec/tulip/de4x5.c
@@ -1874,7 +1874,7 @@ de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len)
} else {
lp->pktStats.multicast++;
}
- } else if (compare_ether_addr(buf, dev->dev_addr) == 0) {
+ } else if (ether_addr_equal(buf, dev->dev_addr)) {
lp->pktStats.unicast++;
}
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index c3ee9103ff4f..ff4eb8fe25d5 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -313,6 +313,11 @@ struct be_vf_cfg {
u32 tx_rate;
};
+enum vf_state {
+ ENABLED = 0,
+ ASSIGNED = 1
+};
+
#define BE_FLAGS_LINK_STATUS_INIT 1
#define BE_FLAGS_WORKER_SCHEDULED (1 << 3)
#define BE_UC_PMAC_COUNT 30
@@ -403,8 +408,9 @@ struct be_adapter {
u32 flash_status;
struct completion flash_compl;
- u32 num_vfs;
- u8 is_virtfn;
+ u32 num_vfs; /* Number of VFs provisioned by PF driver */
+ u32 dev_num_vfs; /* Number of VFs supported by HW */
+ u8 virtfn;
struct be_vf_cfg *vf_cfg;
bool be3_native;
u32 sli_family;
@@ -415,10 +421,13 @@ struct be_adapter {
bool wol;
u32 max_pmac_cnt; /* Max secondary UC MACs programmable */
u32 uc_macs; /* Count of secondary UC MAC programmed */
+ u32 msg_enable;
};
-#define be_physfn(adapter) (!adapter->is_virtfn)
+#define be_physfn(adapter) (!adapter->virtfn)
#define sriov_enabled(adapter) (adapter->num_vfs > 0)
+#define sriov_want(adapter) (adapter->dev_num_vfs && num_vfs && \
+ be_physfn(adapter))
#define for_all_vfs(adapter, vf_cfg, i) \
for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \
i++, vf_cfg++)
@@ -547,14 +556,6 @@ static inline u8 is_udp_pkt(struct sk_buff *skb)
return val;
}
-static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
-{
- u32 sli_intf;
-
- pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
- adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
-}
-
static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
{
u32 addr;
@@ -603,4 +604,6 @@ extern void be_parse_stats(struct be_adapter *adapter);
extern int be_load_fw(struct be_adapter *adapter, u8 *func);
extern bool be_is_wol_supported(struct be_adapter *adapter);
extern bool be_pause_supported(struct be_adapter *adapter);
+extern u32 be_get_fw_log_level(struct be_adapter *adapter);
+
#endif /* BE_H */
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 43167e863955..b24623cce07b 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2589,4 +2589,60 @@ err:
mutex_unlock(&adapter->mbox_lock);
pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
return status;
+
+}
+int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
+ struct be_dma_mem *cmd)
+{
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_get_ext_fat_caps *req;
+ int status;
+
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
+
+ wrb = wrb_from_mbox(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+
+ req = cmd->va;
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_EXT_FAT_CAPABILITES,
+ cmd->size, wrb, cmd);
+ req->parameter_type = cpu_to_le32(1);
+
+ status = be_mbox_notify_wait(adapter);
+err:
+ mutex_unlock(&adapter->mbox_lock);
+ return status;
+}
+
+int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
+ struct be_dma_mem *cmd,
+ struct be_fat_conf_params *configs)
+{
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_set_ext_fat_caps *req;
+ int status;
+
+ spin_lock_bh(&adapter->mcc_lock);
+
+ wrb = wrb_from_mccq(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+
+ req = cmd->va;
+ memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params));
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_SET_EXT_FAT_CAPABILITES,
+ cmd->size, wrb, cmd);
+
+ status = be_mcc_notify_wait(adapter);
+err:
+ spin_unlock_bh(&adapter->mcc_lock);
+ return status;
}
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 944f031bd31e..0b1029b60f69 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -189,6 +189,8 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_PHY_DETAILS 102
#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103
#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
+#define OPCODE_COMMON_GET_EXT_FAT_CAPABILITES 125
+#define OPCODE_COMMON_SET_EXT_FAT_CAPABILITES 126
#define OPCODE_COMMON_GET_MAC_LIST 147
#define OPCODE_COMMON_SET_MAC_LIST 148
#define OPCODE_COMMON_GET_HSW_CONFIG 152
@@ -1602,6 +1604,56 @@ static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter)
}
}
+
+/************** get fat capabilites *******************/
+#define MAX_MODULES 27
+#define MAX_MODES 4
+#define MODE_UART 0
+#define FW_LOG_LEVEL_DEFAULT 48
+#define FW_LOG_LEVEL_FATAL 64
+
+struct ext_fat_mode {
+ u8 mode;
+ u8 rsvd0;
+ u16 port_mask;
+ u32 dbg_lvl;
+ u64 fun_mask;
+} __packed;
+
+struct ext_fat_modules {
+ u8 modules_str[32];
+ u32 modules_id;
+ u32 num_modes;
+ struct ext_fat_mode trace_lvl[MAX_MODES];
+} __packed;
+
+struct be_fat_conf_params {
+ u32 max_log_entries;
+ u32 log_entry_size;
+ u8 log_type;
+ u8 max_log_funs;
+ u8 max_log_ports;
+ u8 rsvd0;
+ u32 supp_modes;
+ u32 num_modules;
+ struct ext_fat_modules module[MAX_MODULES];
+} __packed;
+
+struct be_cmd_req_get_ext_fat_caps {
+ struct be_cmd_req_hdr hdr;
+ u32 parameter_type;
+};
+
+struct be_cmd_resp_get_ext_fat_caps {
+ struct be_cmd_resp_hdr hdr;
+ struct be_fat_conf_params get_params;
+};
+
+struct be_cmd_req_set_ext_fat_caps {
+ struct be_cmd_req_hdr hdr;
+ struct be_fat_conf_params set_params;
+};
+
extern int be_pci_fnum_get(struct be_adapter *adapter);
extern int be_cmd_POST(struct be_adapter *adapter);
extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
@@ -1707,4 +1759,9 @@ extern int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
extern int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
u32 domain, u16 intf_id);
extern int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
+extern int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
+ struct be_dma_mem *cmd);
+extern int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
+ struct be_dma_mem *cmd,
+ struct be_fat_conf_params *cfgs);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 747f68fa976d..63e51d476900 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -878,6 +878,81 @@ be_read_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
return status;
}
+static u32 be_get_msg_level(struct net_device *netdev)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ if (lancer_chip(adapter)) {
+ dev_err(&adapter->pdev->dev, "Operation not supported\n");
+ return -EOPNOTSUPP;
+ }
+
+ return adapter->msg_enable;
+}
+
+static void be_set_fw_log_level(struct be_adapter *adapter, u32 level)
+{
+ struct be_dma_mem extfat_cmd;
+ struct be_fat_conf_params *cfgs;
+ int status;
+ int i, j;
+
+ memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
+ extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
+ extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
+ &extfat_cmd.dma);
+ if (!extfat_cmd.va) {
+ dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
+ __func__);
+ goto err;
+ }
+ status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
+ if (!status) {
+ cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
+ sizeof(struct be_cmd_resp_hdr));
+ for (i = 0; i < cfgs->num_modules; i++) {
+ for (j = 0; j < cfgs->module[i].num_modes; j++) {
+ if (cfgs->module[i].trace_lvl[j].mode ==
+ MODE_UART)
+ cfgs->module[i].trace_lvl[j].dbg_lvl =
+ cpu_to_le32(level);
+ }
+ }
+ status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd,
+ cfgs);
+ if (status)
+ dev_err(&adapter->pdev->dev,
+ "Message level set failed\n");
+ } else {
+ dev_err(&adapter->pdev->dev, "Message level get failed\n");
+ }
+
+ pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
+ extfat_cmd.dma);
+err:
+ return;
+}
+
+static void be_set_msg_level(struct net_device *netdev, u32 level)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+
+ if (lancer_chip(adapter)) {
+ dev_err(&adapter->pdev->dev, "Operation not supported\n");
+ return;
+ }
+
+ if (adapter->msg_enable == level)
+ return;
+
+ if ((level & NETIF_MSG_HW) != (adapter->msg_enable & NETIF_MSG_HW))
+ be_set_fw_log_level(adapter, level & NETIF_MSG_HW ?
+ FW_LOG_LEVEL_DEFAULT : FW_LOG_LEVEL_FATAL);
+ adapter->msg_enable = level;
+
+ return;
+}
+
const struct ethtool_ops be_ethtool_ops = {
.get_settings = be_get_settings,
.get_drvinfo = be_get_drvinfo,
@@ -893,6 +968,8 @@ const struct ethtool_ops be_ethtool_ops = {
.set_pauseparam = be_set_pauseparam,
.get_strings = be_get_stat_strings,
.set_phys_id = be_set_phys_id,
+ .get_msglevel = be_get_msg_level,
+ .set_msglevel = be_set_msg_level,
.get_sset_count = be_get_sset_count,
.get_ethtool_stats = be_get_ethtool_stats,
.get_regs_len = be_get_reg_len,
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
index 0949aa609164..f38b58c8dbba 100644
--- a/drivers/net/ethernet/emulex/benet/be_hw.h
+++ b/drivers/net/ethernet/emulex/benet/be_hw.h
@@ -58,6 +58,8 @@
#define SLI_PORT_CONTROL_IP_MASK 0x08000000
+#define PCICFG_CUST_SCRATCHPAD_CSR 0x1EC
+
/********* Memory BAR register ************/
#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
/* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 6d5d30be0481..081c77701168 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1049,6 +1049,29 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
return status;
}
+static int be_find_vfs(struct be_adapter *adapter, int vf_state)
+{
+ struct pci_dev *dev, *pdev = adapter->pdev;
+ int vfs = 0, assigned_vfs = 0, pos, vf_fn;
+ u16 offset, stride;
+
+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
+ pci_read_config_word(pdev, pos + PCI_SRIOV_VF_OFFSET, &offset);
+ pci_read_config_word(pdev, pos + PCI_SRIOV_VF_STRIDE, &stride);
+
+ dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL);
+ while (dev) {
+ vf_fn = (pdev->devfn + offset + stride * vfs) & 0xFFFF;
+ if (dev->is_virtfn && dev->devfn == vf_fn) {
+ vfs++;
+ if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
+ assigned_vfs++;
+ }
+ dev = pci_get_device(pdev->vendor, PCI_ANY_ID, dev);
+ }
+ return (vf_state == ASSIGNED) ? assigned_vfs : vfs;
+}
+
static void be_eqd_update(struct be_adapter *adapter, struct be_eq_obj *eqo)
{
struct be_rx_stats *stats = rx_stats(&adapter->rx_obj[eqo->idx]);
@@ -1789,9 +1812,9 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
static int be_num_txqs_want(struct be_adapter *adapter)
{
- if (sriov_enabled(adapter) || be_is_mc(adapter) ||
- lancer_chip(adapter) || !be_physfn(adapter) ||
- adapter->generation == BE_GEN2)
+ if (sriov_want(adapter) || be_is_mc(adapter) ||
+ lancer_chip(adapter) || !be_physfn(adapter) ||
+ adapter->generation == BE_GEN2)
return 1;
else
return MAX_TX_QS;
@@ -2118,7 +2141,7 @@ static void be_msix_disable(struct be_adapter *adapter)
static uint be_num_rss_want(struct be_adapter *adapter)
{
if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
- adapter->num_vfs == 0 && be_physfn(adapter) &&
+ !sriov_want(adapter) && be_physfn(adapter) &&
!be_is_mc(adapter))
return (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
else
@@ -2152,53 +2175,6 @@ done:
return;
}
-static int be_sriov_enable(struct be_adapter *adapter)
-{
- be_check_sriov_fn_type(adapter);
-
-#ifdef CONFIG_PCI_IOV
- if (be_physfn(adapter) && num_vfs) {
- int status, pos;
- u16 dev_vfs;
-
- pos = pci_find_ext_capability(adapter->pdev,
- PCI_EXT_CAP_ID_SRIOV);
- pci_read_config_word(adapter->pdev,
- pos + PCI_SRIOV_TOTAL_VF, &dev_vfs);
-
- adapter->num_vfs = min_t(u16, num_vfs, dev_vfs);
- if (adapter->num_vfs != num_vfs)
- dev_info(&adapter->pdev->dev,
- "Device supports %d VFs and not %d\n",
- adapter->num_vfs, num_vfs);
-
- status = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
- if (status)
- adapter->num_vfs = 0;
-
- if (adapter->num_vfs) {
- adapter->vf_cfg = kcalloc(num_vfs,
- sizeof(struct be_vf_cfg),
- GFP_KERNEL);
- if (!adapter->vf_cfg)
- return -ENOMEM;
- }
- }
-#endif
- return 0;
-}
-
-static void be_sriov_disable(struct be_adapter *adapter)
-{
-#ifdef CONFIG_PCI_IOV
- if (sriov_enabled(adapter)) {
- pci_disable_sriov(adapter->pdev);
- kfree(adapter->vf_cfg);
- adapter->num_vfs = 0;
- }
-#endif
-}
-
static inline int be_msix_vec_get(struct be_adapter *adapter,
struct be_eq_obj *eqo)
{
@@ -2500,6 +2476,11 @@ static void be_vf_clear(struct be_adapter *adapter)
struct be_vf_cfg *vf_cfg;
u32 vf;
+ if (be_find_vfs(adapter, ASSIGNED)) {
+ dev_warn(&adapter->pdev->dev, "VFs are assigned to VMs\n");
+ goto done;
+ }
+
for_all_vfs(adapter, vf_cfg, vf) {
if (lancer_chip(adapter))
be_cmd_set_mac_list(adapter, NULL, 0, vf + 1);
@@ -2509,6 +2490,10 @@ static void be_vf_clear(struct be_adapter *adapter)
be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1);
}
+ pci_disable_sriov(adapter->pdev);
+done:
+ kfree(adapter->vf_cfg);
+ adapter->num_vfs = 0;
}
static int be_clear(struct be_adapter *adapter)
@@ -2538,29 +2523,60 @@ static int be_clear(struct be_adapter *adapter)
be_cmd_fw_clean(adapter);
be_msix_disable(adapter);
- kfree(adapter->pmac_id);
+ pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 0);
return 0;
}
-static void be_vf_setup_init(struct be_adapter *adapter)
+static int be_vf_setup_init(struct be_adapter *adapter)
{
struct be_vf_cfg *vf_cfg;
int vf;
+ adapter->vf_cfg = kcalloc(adapter->num_vfs, sizeof(*vf_cfg),
+ GFP_KERNEL);
+ if (!adapter->vf_cfg)
+ return -ENOMEM;
+
for_all_vfs(adapter, vf_cfg, vf) {
vf_cfg->if_handle = -1;
vf_cfg->pmac_id = -1;
}
+ return 0;
}
static int be_vf_setup(struct be_adapter *adapter)
{
struct be_vf_cfg *vf_cfg;
+ struct device *dev = &adapter->pdev->dev;
u32 cap_flags, en_flags, vf;
u16 def_vlan, lnk_speed;
- int status;
+ int status, enabled_vfs;
- be_vf_setup_init(adapter);
+ enabled_vfs = be_find_vfs(adapter, ENABLED);
+ if (enabled_vfs) {
+ dev_warn(dev, "%d VFs are already enabled\n", enabled_vfs);
+ dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
+ return 0;
+ }
+
+ if (num_vfs > adapter->dev_num_vfs) {
+ dev_warn(dev, "Device supports %d VFs and not %d\n",
+ adapter->dev_num_vfs, num_vfs);
+ num_vfs = adapter->dev_num_vfs;
+ }
+
+ status = pci_enable_sriov(adapter->pdev, num_vfs);
+ if (!status) {
+ adapter->num_vfs = num_vfs;
+ } else {
+ /* Platform doesn't support SRIOV though device supports it */
+ dev_warn(dev, "SRIOV enable failed\n");
+ return 0;
+ }
+
+ status = be_vf_setup_init(adapter);
+ if (status)
+ goto err;
cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
BE_IF_FLAGS_MULTICAST;
@@ -2571,9 +2587,11 @@ static int be_vf_setup(struct be_adapter *adapter)
goto err;
}
- status = be_vf_eth_addr_config(adapter);
- if (status)
- goto err;
+ if (!enabled_vfs) {
+ status = be_vf_eth_addr_config(adapter);
+ if (status)
+ goto err;
+ }
for_all_vfs(adapter, vf_cfg, vf) {
status = be_cmd_link_status_query(adapter, NULL, &lnk_speed,
@@ -2630,9 +2648,25 @@ do_none:
return status;
}
+/* Routine to query per function resource limits */
+static int be_get_config(struct be_adapter *adapter)
+{
+ int pos;
+ u16 dev_num_vfs;
+
+ pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV);
+ if (pos) {
+ pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF,
+ &dev_num_vfs);
+ adapter->dev_num_vfs = dev_num_vfs;
+ }
+ return 0;
+}
+
static int be_setup(struct be_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
+ struct device *dev = &adapter->pdev->dev;
u32 cap_flags, en_flags;
u32 tx_fc, rx_fc;
int status;
@@ -2640,6 +2674,8 @@ static int be_setup(struct be_adapter *adapter)
be_setup_init(adapter);
+ be_get_config(adapter);
+
be_cmd_req_native_mode(adapter);
be_msix_enable(adapter);
@@ -2718,10 +2754,11 @@ static int be_setup(struct be_adapter *adapter)
pcie_set_readrq(adapter->pdev, 4096);
- if (sriov_enabled(adapter)) {
- status = be_vf_setup(adapter);
- if (status)
- goto err;
+ if (be_physfn(adapter) && num_vfs) {
+ if (adapter->dev_num_vfs)
+ be_vf_setup(adapter);
+ else
+ dev_warn(dev, "device doesn't support SRIOV\n");
}
be_cmd_get_phy_info(adapter);
@@ -2731,6 +2768,7 @@ static int be_setup(struct be_adapter *adapter)
schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
+ pci_write_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, 1);
return 0;
err:
be_clear(adapter);
@@ -3352,8 +3390,6 @@ static void __devexit be_remove(struct pci_dev *pdev)
be_ctrl_cleanup(adapter);
- be_sriov_disable(adapter);
-
pci_set_drvdata(pdev, NULL);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -3367,9 +3403,43 @@ bool be_is_wol_supported(struct be_adapter *adapter)
!be_is_wol_excluded(adapter)) ? true : false;
}
-static int be_get_config(struct be_adapter *adapter)
+u32 be_get_fw_log_level(struct be_adapter *adapter)
+{
+ struct be_dma_mem extfat_cmd;
+ struct be_fat_conf_params *cfgs;
+ int status;
+ u32 level = 0;
+ int j;
+
+ memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
+ extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
+ extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
+ &extfat_cmd.dma);
+
+ if (!extfat_cmd.va) {
+ dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
+ __func__);
+ goto err;
+ }
+
+ status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
+ if (!status) {
+ cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
+ sizeof(struct be_cmd_resp_hdr));
+ for (j = 0; j < cfgs->module[0].num_modes; j++) {
+ if (cfgs->module[0].trace_lvl[j].mode == MODE_UART)
+ level = cfgs->module[0].trace_lvl[j].dbg_lvl;
+ }
+ }
+ pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
+ extfat_cmd.dma);
+err:
+ return level;
+}
+static int be_get_initial_config(struct be_adapter *adapter)
{
int status;
+ u32 level;
status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
&adapter->function_mode, &adapter->function_caps);
@@ -3407,10 +3477,13 @@ static int be_get_config(struct be_adapter *adapter)
if (be_is_wol_supported(adapter))
adapter->wol = true;
+ level = be_get_fw_log_level(adapter);
+ adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0;
+
return 0;
}
-static int be_dev_family_check(struct be_adapter *adapter)
+static int be_dev_type_check(struct be_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
u32 sli_intf = 0, if_type;
@@ -3443,6 +3516,9 @@ static int be_dev_family_check(struct be_adapter *adapter)
default:
adapter->generation = 0;
}
+
+ pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
+ adapter->virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
return 0;
}
@@ -3586,6 +3662,14 @@ reschedule:
schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
}
+static bool be_reset_required(struct be_adapter *adapter)
+{
+ u32 reg;
+
+ pci_read_config_dword(adapter->pdev, PCICFG_CUST_SCRATCHPAD_CSR, &reg);
+ return reg;
+}
+
static int __devinit be_probe(struct pci_dev *pdev,
const struct pci_device_id *pdev_id)
{
@@ -3611,7 +3695,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
adapter->pdev = pdev;
pci_set_drvdata(pdev, adapter);
- status = be_dev_family_check(adapter);
+ status = be_dev_type_check(adapter);
if (status)
goto free_netdev;
@@ -3629,13 +3713,9 @@ static int __devinit be_probe(struct pci_dev *pdev,
}
}
- status = be_sriov_enable(adapter);
- if (status)
- goto free_netdev;
-
status = be_ctrl_init(adapter);
if (status)
- goto disable_sriov;
+ goto free_netdev;
if (lancer_chip(adapter)) {
status = lancer_wait_ready(adapter);
@@ -3662,9 +3742,11 @@ static int __devinit be_probe(struct pci_dev *pdev,
if (status)
goto ctrl_clean;
- status = be_cmd_reset_function(adapter);
- if (status)
- goto ctrl_clean;
+ if (be_reset_required(adapter)) {
+ status = be_cmd_reset_function(adapter);
+ if (status)
+ goto ctrl_clean;
+ }
/* The INTR bit may be set in the card when probed by a kdump kernel
* after a crash.
@@ -3676,7 +3758,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
if (status)
goto ctrl_clean;
- status = be_get_config(adapter);
+ status = be_get_initial_config(adapter);
if (status)
goto stats_clean;
@@ -3705,8 +3787,6 @@ stats_clean:
be_stats_cleanup(adapter);
ctrl_clean:
be_ctrl_cleanup(adapter);
-disable_sriov:
- be_sriov_disable(adapter);
free_netdev:
free_netdev(netdev);
pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/ethernet/fujitsu/at1700.c b/drivers/net/ethernet/fujitsu/at1700.c
index 3d94797c8f9b..4b80dc4531ad 100644
--- a/drivers/net/ethernet/fujitsu/at1700.c
+++ b/drivers/net/ethernet/fujitsu/at1700.c
@@ -27,7 +27,7 @@
ATI provided their EEPROM configuration code header file.
Thanks to NIIBE Yutaka <gniibe@mri.co.jp> for bug fixes.
- MCA bus (AT1720) support by Rene Schmit <rene@bss.lu>
+ MCA bus (AT1720) support (now deleted) by Rene Schmit <rene@bss.lu>
Bugs:
The MB86965 has a design flaw that makes all probes unreliable. Not
@@ -38,7 +38,6 @@
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/mca-legacy.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
@@ -79,24 +78,6 @@ static unsigned at1700_probe_list[] __initdata = {
0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
};
-/*
- * MCA
- */
-#ifdef CONFIG_MCA_LEGACY
-static int at1700_ioaddr_pattern[] __initdata = {
- 0x00, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07
-};
-
-static int at1700_mca_probe_list[] __initdata = {
- 0x400, 0x1400, 0x2400, 0x3400, 0x4400, 0x5400, 0x6400, 0x7400, 0
-};
-
-static int at1700_irq_pattern[] __initdata = {
- 0x00, 0x00, 0x00, 0x30, 0x70, 0xb0, 0x00, 0x00,
- 0x00, 0xf0, 0x34, 0x74, 0xb4, 0x00, 0x00, 0xf4, 0x00
-};
-#endif
-
/* use 0 for production, 1 for verification, >2 for debug */
#ifndef NET_DEBUG
#define NET_DEBUG 1
@@ -114,7 +95,6 @@ struct net_local {
uint tx_queue_ready:1; /* Tx queue is ready to be sent. */
uint rx_started:1; /* Packets are Rxing. */
uchar tx_queue; /* Number of packet on the Tx queue. */
- char mca_slot; /* -1 means ISA */
ushort tx_queue_len; /* Current length of the Tx queue. */
};
@@ -166,21 +146,6 @@ static void set_rx_mode(struct net_device *dev);
static void net_tx_timeout (struct net_device *dev);
-#ifdef CONFIG_MCA_LEGACY
-struct at1720_mca_adapters_struct {
- char* name;
- int id;
-};
-/* rEnE : maybe there are others I don't know off... */
-
-static struct at1720_mca_adapters_struct at1720_mca_adapters[] __initdata = {
- { "Allied Telesys AT1720AT", 0x6410 },
- { "Allied Telesys AT1720BT", 0x6413 },
- { "Allied Telesys AT1720T", 0x6416 },
- { NULL, 0 },
-};
-#endif
-
/* Check for a network adaptor of this type, and return '0' iff one exists.
If dev->base_addr == 0, probe all likely locations.
If dev->base_addr == 1, always return failure.
@@ -194,11 +159,6 @@ static int irq;
static void cleanup_card(struct net_device *dev)
{
-#ifdef CONFIG_MCA_LEGACY
- struct net_local *lp = netdev_priv(dev);
- if (lp->mca_slot >= 0)
- mca_mark_as_unused(lp->mca_slot);
-#endif
free_irq(dev->irq, NULL);
release_region(dev->base_addr, AT1700_IO_EXTENT);
}
@@ -273,7 +233,7 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
static const char fmv_irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
static const char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
- int slot, ret = -ENODEV;
+ int ret = -ENODEV;
struct net_local *lp = netdev_priv(dev);
if (!request_region(ioaddr, AT1700_IO_EXTENT, DRV_NAME))
@@ -288,64 +248,6 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
read_eeprom(ioaddr, 6), inw(ioaddr + EEPROM_Ctrl));
#endif
-
-#ifdef CONFIG_MCA_LEGACY
- /* rEnE (rene@bss.lu): got this from 3c509 driver source , adapted for AT1720 */
-
- /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily
- modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca)
- to support standard MCA probing. */
-
- /* redone for multi-card detection by ZP Gu (zpg@castle.net) */
- /* now works as a module */
-
- if (MCA_bus) {
- int j;
- int l_i;
- u_char pos3, pos4;
-
- for (j = 0; at1720_mca_adapters[j].name != NULL; j ++) {
- slot = 0;
- while (slot != MCA_NOTFOUND) {
-
- slot = mca_find_unused_adapter( at1720_mca_adapters[j].id, slot );
- if (slot == MCA_NOTFOUND) break;
-
- /* if we get this far, an adapter has been detected and is
- enabled */
-
- pos3 = mca_read_stored_pos( slot, 3 );
- pos4 = mca_read_stored_pos( slot, 4 );
-
- for (l_i = 0; l_i < 8; l_i++)
- if (( pos3 & 0x07) == at1700_ioaddr_pattern[l_i])
- break;
- ioaddr = at1700_mca_probe_list[l_i];
-
- for (irq = 0; irq < 0x10; irq++)
- if (((((pos4>>4) & 0x0f) | (pos3 & 0xf0)) & 0xff) == at1700_irq_pattern[irq])
- break;
-
- /* probing for a card at a particular IO/IRQ */
- if ((dev->irq && dev->irq != irq) ||
- (dev->base_addr && dev->base_addr != ioaddr)) {
- slot++; /* probing next slot */
- continue;
- }
-
- dev->irq = irq;
-
- /* claim the slot */
- mca_set_adapter_name( slot, at1720_mca_adapters[j].name );
- mca_mark_as_used(slot);
-
- goto found;
- }
- }
- /* if we get here, we didn't find an MCA adapter - try ISA */
- }
-#endif
- slot = -1;
/* We must check for the EEPROM-config boards first, else accessing
IOCONFIG0 will move the board! */
if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr &&
@@ -360,11 +262,7 @@ static int __init at1700_probe1(struct net_device *dev, int ioaddr)
goto err_out;
}
-#ifdef CONFIG_MCA_LEGACY
-found:
-#endif
-
- /* Reset the internal state machines. */
+ /* Reset the internal state machines. */
outb(0, ioaddr + RESET);
if (is_at1700) {
@@ -380,11 +278,11 @@ found:
break;
}
if (i == 8) {
- goto err_mca;
+ goto err_out;
}
} else {
if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr)
- goto err_mca;
+ goto err_out;
irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
}
}
@@ -464,23 +362,17 @@ found:
spin_lock_init(&lp->lock);
lp->jumpered = is_fmv18x;
- lp->mca_slot = slot;
/* Snarf the interrupt vector now. */
ret = request_irq(irq, net_interrupt, 0, DRV_NAME, dev);
if (ret) {
printk(KERN_ERR "AT1700 at %#3x is unusable due to a "
"conflict on IRQ %d.\n",
ioaddr, irq);
- goto err_mca;
+ goto err_out;
}
return 0;
-err_mca:
-#ifdef CONFIG_MCA_LEGACY
- if (slot >= 0)
- mca_mark_as_unused(slot);
-#endif
err_out:
release_region(ioaddr, AT1700_IO_EXTENT);
return ret;
diff --git a/drivers/net/ethernet/i825xx/3c523.c b/drivers/net/ethernet/i825xx/3c523.c
deleted file mode 100644
index 8451ecd4c1ec..000000000000
--- a/drivers/net/ethernet/i825xx/3c523.c
+++ /dev/null
@@ -1,1312 +0,0 @@
-/*
- net-3-driver for the 3c523 Etherlink/MC card (i82586 Ethernet chip)
-
-
- This is an extension to the Linux operating system, and is covered by the
- same GNU General Public License that covers that work.
-
- Copyright 1995, 1996 by Chris Beauregard (cpbeaure@undergrad.math.uwaterloo.ca)
-
- This is basically Michael Hipp's ni52 driver, with a new probing
- algorithm and some minor changes to the 82586 CA and reset routines.
- Thanks a lot Michael for a really clean i82586 implementation! Unless
- otherwise documented in ni52.c, any bugs are mine.
-
- Contrary to the Ethernet-HOWTO, this isn't based on the 3c507 driver in
- any way. The ni52 is a lot easier to modify.
-
- sources:
- ni52.c
-
- Crynwr packet driver collection was a great reference for my first
- attempt at this sucker. The 3c507 driver also helped, until I noticed
- that ni52.c was a lot nicer.
-
- EtherLink/MC: Micro Channel Ethernet Adapter Technical Reference
- Manual, courtesy of 3Com CardFacts, documents the 3c523-specific
- stuff. Information on CardFacts is found in the Ethernet HOWTO.
- Also see <a href="http://www.3com.com/">
-
- Microprocessor Communications Support Chips, T.J. Byers, ISBN
- 0-444-01224-9, has a section on the i82586. It tells you just enough
- to know that you really don't want to learn how to program the chip.
-
- The original device probe code was stolen from ps2esdi.c
-
- Known Problems:
- Since most of the code was stolen from ni52.c, you'll run across the
- same bugs in the 0.62 version of ni52.c, plus maybe a few because of
- the 3c523 idiosynchacies. The 3c523 has 16K of RAM though, so there
- shouldn't be the overrun problem that the 8K ni52 has.
-
- This driver is for a 16K adapter. It should work fine on the 64K
- adapters, but it will only use one of the 4 banks of RAM. Modifying
- this for the 64K version would require a lot of heinous bank
- switching, which I'm sure not interested in doing. If you try to
- implement a bank switching version, you'll basically have to remember
- what bank is enabled and do a switch every time you access a memory
- location that's not current. You'll also have to remap pointers on
- the driver side, because it only knows about 16K of the memory.
- Anyone desperate or masochistic enough to try?
-
- It seems to be stable now when multiple transmit buffers are used. I
- can't see any performance difference, but then I'm working on a 386SX.
-
- Multicast doesn't work. It doesn't even pretend to work. Don't use
- it. Don't compile your kernel with multicast support. I don't know
- why.
-
- Features:
- This driver is useable as a loadable module. If you try to specify an
- IRQ or a IO address (via insmod 3c523.o irq=xx io=0xyyy), it will
- search the MCA slots until it finds a 3c523 with the specified
- parameters.
-
- This driver does support multiple ethernet cards when used as a module
- (up to MAX_3C523_CARDS, the default being 4)
-
- This has been tested with both BNC and TP versions, internal and
- external transceivers. Haven't tested with the 64K version (that I
- know of).
-
- History:
- Jan 1st, 1996
- first public release
- Feb 4th, 1996
- update to 1.3.59, incorporated multicast diffs from ni52.c
- Feb 15th, 1996
- added shared irq support
- Apr 1999
- added support for multiple cards when used as a module
- added option to disable multicast as is causes problems
- Ganesh Sittampalam <ganesh.sittampalam@magdalen.oxford.ac.uk>
- Stuart Adamson <stuart.adamson@compsoc.net>
- Nov 2001
- added support for ethtool (jgarzik)
-
- $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
- */
-
-#define DRV_NAME "3c523"
-#define DRV_VERSION "17-Nov-2001"
-
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/skbuff.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/mca-legacy.h>
-#include <linux/ethtool.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-
-#include "3c523.h"
-
-/*************************************************************************/
-#define DEBUG /* debug on */
-#define SYSBUSVAL 0 /* 1 = 8 Bit, 0 = 16 bit - 3c523 only does 16 bit */
-#undef ELMC_MULTICAST /* Disable multicast support as it is somewhat seriously broken at the moment */
-
-#define make32(ptr16) (p->memtop + (short) (ptr16) )
-#define make24(ptr32) ((char *) (ptr32) - p->base)
-#define make16(ptr32) ((unsigned short) ((unsigned long) (ptr32) - (unsigned long) p->memtop ))
-
-/*************************************************************************/
-/*
- Tables to which we can map values in the configuration registers.
- */
-static int irq_table[] __initdata = {
- 12, 7, 3, 9
-};
-
-static int csr_table[] __initdata = {
- 0x300, 0x1300, 0x2300, 0x3300
-};
-
-static int shm_table[] __initdata = {
- 0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000
-};
-
-/******************* how to calculate the buffers *****************************
-
-
- * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
- * --------------- in a different (more stable?) mode. Only in this mode it's
- * possible to configure the driver with 'NO_NOPCOMMANDS'
-
-sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
-sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
-sizeof(rfd) = 24; sizeof(rbd) = 12;
-sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
-sizeof(nop_cmd) = 8;
-
- * if you don't know the driver, better do not change this values: */
-
-#define RECV_BUFF_SIZE 1524 /* slightly oversized */
-#define XMIT_BUFF_SIZE 1524 /* slightly oversized */
-#define NUM_XMIT_BUFFS 1 /* config for both, 8K and 16K shmem */
-#define NUM_RECV_BUFFS_8 4 /* config for 8K shared mem */
-#define NUM_RECV_BUFFS_16 9 /* config for 16K shared mem */
-
-#if (NUM_XMIT_BUFFS == 1)
-#define NO_NOPCOMMANDS /* only possible with NUM_XMIT_BUFFS=1 */
-#endif
-
-/**************************************************************************/
-
-#define DELAY(x) { mdelay(32 * x); }
-
-/* a much shorter delay: */
-#define DELAY_16(); { udelay(16) ; }
-
-/* wait for command with timeout: */
-#define WAIT_4_SCB_CMD() { int i; \
- for(i=0;i<1024;i++) { \
- if(!p->scb->cmd) break; \
- DELAY_16(); \
- if(i == 1023) { \
- pr_warning("%s:%d: scb_cmd timed out .. resetting i82586\n",\
- dev->name,__LINE__); \
- elmc_id_reset586(); } } }
-
-static irqreturn_t elmc_interrupt(int irq, void *dev_id);
-static int elmc_open(struct net_device *dev);
-static int elmc_close(struct net_device *dev);
-static netdev_tx_t elmc_send_packet(struct sk_buff *, struct net_device *);
-static struct net_device_stats *elmc_get_stats(struct net_device *dev);
-static void elmc_timeout(struct net_device *dev);
-#ifdef ELMC_MULTICAST
-static void set_multicast_list(struct net_device *dev);
-#endif
-static const struct ethtool_ops netdev_ethtool_ops;
-
-/* helper-functions */
-static int init586(struct net_device *dev);
-static int check586(struct net_device *dev, unsigned long where, unsigned size);
-static void alloc586(struct net_device *dev);
-static void startrecv586(struct net_device *dev);
-static void *alloc_rfa(struct net_device *dev, void *ptr);
-static void elmc_rcv_int(struct net_device *dev);
-static void elmc_xmt_int(struct net_device *dev);
-static void elmc_rnr_int(struct net_device *dev);
-
-struct priv {
- unsigned long base;
- char *memtop;
- unsigned long mapped_start; /* Start of ioremap */
- volatile struct rfd_struct *rfd_last, *rfd_top, *rfd_first;
- volatile struct scp_struct *scp; /* volatile is important */
- volatile struct iscp_struct *iscp; /* volatile is important */
- volatile struct scb_struct *scb; /* volatile is important */
- volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
-#if (NUM_XMIT_BUFFS == 1)
- volatile struct transmit_cmd_struct *xmit_cmds[2];
- volatile struct nop_cmd_struct *nop_cmds[2];
-#else
- volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
- volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
-#endif
- volatile int nop_point, num_recv_buffs;
- volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
- volatile int xmit_count, xmit_last;
- volatile int slot;
-};
-
-#define elmc_attn586() {elmc_do_attn586(dev->base_addr,ELMC_CTRL_INTE);}
-#define elmc_reset586() {elmc_do_reset586(dev->base_addr,ELMC_CTRL_INTE);}
-
-/* with interrupts disabled - this will clear the interrupt bit in the
- 3c523 control register, and won't put it back. This effectively
- disables interrupts on the card. */
-#define elmc_id_attn586() {elmc_do_attn586(dev->base_addr,0);}
-#define elmc_id_reset586() {elmc_do_reset586(dev->base_addr,0);}
-
-/*************************************************************************/
-/*
- Do a Channel Attention on the 3c523. This is extremely board dependent.
- */
-static void elmc_do_attn586(int ioaddr, int ints)
-{
- /* the 3c523 requires a minimum of 500 ns. The delays here might be
- a little too large, and hence they may cut the performance of the
- card slightly. If someone who knows a little more about Linux
- timing would care to play with these, I'd appreciate it. */
-
- /* this bit masking stuff is crap. I'd rather have separate
- registers with strobe triggers for each of these functions. <sigh>
- Ya take what ya got. */
-
- outb(ELMC_CTRL_RST | 0x3 | ELMC_CTRL_CA | ints, ioaddr + ELMC_CTRL);
- DELAY_16(); /* > 500 ns */
- outb(ELMC_CTRL_RST | 0x3 | ints, ioaddr + ELMC_CTRL);
-}
-
-/*************************************************************************/
-/*
- Reset the 82586 on the 3c523. Also very board dependent.
- */
-static void elmc_do_reset586(int ioaddr, int ints)
-{
- /* toggle the RST bit low then high */
- outb(0x3 | ELMC_CTRL_LBK, ioaddr + ELMC_CTRL);
- DELAY_16(); /* > 500 ns */
- outb(ELMC_CTRL_RST | ELMC_CTRL_LBK | 0x3, ioaddr + ELMC_CTRL);
-
- elmc_do_attn586(ioaddr, ints);
-}
-
-/**********************************************
- * close device
- */
-
-static int elmc_close(struct net_device *dev)
-{
- netif_stop_queue(dev);
- elmc_id_reset586(); /* the hard way to stop the receiver */
- free_irq(dev->irq, dev);
- return 0;
-}
-
-/**********************************************
- * open device
- */
-
-static int elmc_open(struct net_device *dev)
-{
- int ret;
-
- elmc_id_attn586(); /* disable interrupts */
-
- ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED,
- dev->name, dev);
- if (ret) {
- pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq);
- elmc_id_reset586();
- return ret;
- }
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
- netif_start_queue(dev);
- return 0; /* most done by init */
-}
-
-/**********************************************
- * Check to see if there's an 82586 out there.
- */
-
-static int __init check586(struct net_device *dev, unsigned long where, unsigned size)
-{
- struct priv *p = netdev_priv(dev);
- char *iscp_addrs[2];
- int i = 0;
-
- p->base = (unsigned long) isa_bus_to_virt((unsigned long)where) + size - 0x01000000;
- p->memtop = isa_bus_to_virt((unsigned long)where) + size;
- p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
- memset((char *) p->scp, 0, sizeof(struct scp_struct));
- p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus, 0 = 16 Bit */
-
- iscp_addrs[0] = isa_bus_to_virt((unsigned long)where);
- iscp_addrs[1] = (char *) p->scp - sizeof(struct iscp_struct);
-
- for (i = 0; i < 2; i++) {
- p->iscp = (struct iscp_struct *) iscp_addrs[i];
- memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
-
- p->scp->iscp = make24(p->iscp);
- p->iscp->busy = 1;
-
- elmc_id_reset586();
-
- /* reset586 does an implicit CA */
-
- /* apparently, you sometimes have to kick the 82586 twice... */
- elmc_id_attn586();
- DELAY(1);
-
- if (p->iscp->busy) { /* i82586 clears 'busy' after successful init */
- return 0;
- }
- }
- return 1;
-}
-
-/******************************************************************
- * set iscp at the right place, called by elmc_probe and open586.
- */
-
-static void alloc586(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
-
- elmc_id_reset586();
- DELAY(2);
-
- p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
- p->scb = (struct scb_struct *) isa_bus_to_virt(dev->mem_start);
- p->iscp = (struct iscp_struct *) ((char *) p->scp - sizeof(struct iscp_struct));
-
- memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
- memset((char *) p->scp, 0, sizeof(struct scp_struct));
-
- p->scp->iscp = make24(p->iscp);
- p->scp->sysbus = SYSBUSVAL;
- p->iscp->scb_offset = make16(p->scb);
-
- p->iscp->busy = 1;
- elmc_id_reset586();
- elmc_id_attn586();
-
- DELAY(2);
-
- if (p->iscp->busy)
- pr_err("%s: Init-Problems (alloc).\n", dev->name);
-
- memset((char *) p->scb, 0, sizeof(struct scb_struct));
-}
-
-/*****************************************************************/
-
-static int elmc_getinfo(char *buf, int slot, void *d)
-{
- int len = 0;
- struct net_device *dev = d;
-
- if (dev == NULL)
- return len;
-
- len += sprintf(buf + len, "Revision: 0x%x\n",
- inb(dev->base_addr + ELMC_REVISION) & 0xf);
- len += sprintf(buf + len, "IRQ: %d\n", dev->irq);
- len += sprintf(buf + len, "IO Address: %#lx-%#lx\n", dev->base_addr,
- dev->base_addr + ELMC_IO_EXTENT);
- len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
- dev->mem_end - 1);
- len += sprintf(buf + len, "Transceiver: %s\n", dev->if_port ?
- "External" : "Internal");
- len += sprintf(buf + len, "Device: %s\n", dev->name);
- len += sprintf(buf + len, "Hardware Address: %pM\n",
- dev->dev_addr);
-
- return len;
-} /* elmc_getinfo() */
-
-static const struct net_device_ops netdev_ops = {
- .ndo_open = elmc_open,
- .ndo_stop = elmc_close,
- .ndo_get_stats = elmc_get_stats,
- .ndo_start_xmit = elmc_send_packet,
- .ndo_tx_timeout = elmc_timeout,
-#ifdef ELMC_MULTICAST
- .ndo_set_rx_mode = set_multicast_list,
-#endif
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/*****************************************************************/
-
-static int __init do_elmc_probe(struct net_device *dev)
-{
- static int slot;
- int base_addr = dev->base_addr;
- int irq = dev->irq;
- u_char status = 0;
- u_char revision = 0;
- int i = 0;
- unsigned int size = 0;
- int retval;
- struct priv *pr = netdev_priv(dev);
-
- if (MCA_bus == 0) {
- return -ENODEV;
- }
- /* search through the slots for the 3c523. */
- slot = mca_find_adapter(ELMC_MCA_ID, 0);
- while (slot != -1) {
- status = mca_read_stored_pos(slot, 2);
-
- dev->irq=irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6];
- dev->base_addr=csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1];
-
- /*
- If we're trying to match a specified irq or IO address,
- we'll reject a match unless it's what we're looking for.
- Also reject it if the card is already in use.
- */
-
- if ((irq && irq != dev->irq) ||
- (base_addr && base_addr != dev->base_addr)) {
- slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
- continue;
- }
- if (!request_region(dev->base_addr, ELMC_IO_EXTENT, DRV_NAME)) {
- slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
- continue;
- }
-
- /* found what we're looking for... */
- break;
- }
-
- /* we didn't find any 3c523 in the slots we checked for */
- if (slot == MCA_NOTFOUND)
- return (base_addr || irq) ? -ENXIO : -ENODEV;
-
- mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC");
- mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
-
- /* if we get this far, adapter has been found - carry on */
- pr_info("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
-
- /* Now we extract configuration info from the card.
- The 3c523 provides information in two of the POS registers, but
- the second one is only needed if we want to tell the card what IRQ
- to use. I suspect that whoever sets the thing up initially would
- prefer we don't screw with those things.
-
- Note that we read the status info when we found the card...
-
- See 3c523.h for more details.
- */
-
- /* revision is stored in the first 4 bits of the revision register */
- revision = inb(dev->base_addr + ELMC_REVISION) & 0xf;
-
- /* according to docs, we read the interrupt and write it back to
- the IRQ select register, since the POST might not configure the IRQ
- properly. */
- switch (dev->irq) {
- case 3:
- mca_write_pos(slot, 3, 0x04);
- break;
- case 7:
- mca_write_pos(slot, 3, 0x02);
- break;
- case 9:
- mca_write_pos(slot, 3, 0x08);
- break;
- case 12:
- mca_write_pos(slot, 3, 0x01);
- break;
- }
-
- pr->slot = slot;
-
- pr_info("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
- dev->base_addr);
-
- /* Determine if we're using the on-board transceiver (i.e. coax) or
- an external one. The information is pretty much useless, but I
- guess it's worth brownie points. */
- dev->if_port = (status & ELMC_STATUS_DISABLE_THIN);
-
- /* The 3c523 has a 24K chunk of memory. The first 16K is the
- shared memory, while the last 8K is for the EtherStart BIOS ROM.
- Which we don't care much about here. We'll just tell Linux that
- we're using 16K. MCA won't permit address space conflicts caused
- by not mapping the other 8K. */
- dev->mem_start = shm_table[(status & ELMC_STATUS_MEMORY_SELECT) >> 3];
-
- /* We're using MCA, so it's a given that the information about memory
- size is correct. The Crynwr drivers do something like this. */
-
- elmc_id_reset586(); /* seems like a good idea before checking it... */
-
- size = 0x4000; /* check for 16K mem */
- if (!check586(dev, dev->mem_start, size)) {
- pr_err("%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
- dev->mem_start);
- retval = -ENODEV;
- goto err_out;
- }
- dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
-
- pr->memtop = isa_bus_to_virt(dev->mem_start) + size;
- pr->base = (unsigned long) isa_bus_to_virt(dev->mem_start) + size - 0x01000000;
- alloc586(dev);
-
- elmc_id_reset586(); /* make sure it doesn't generate spurious ints */
-
- /* set number of receive-buffs according to memsize */
- pr->num_recv_buffs = NUM_RECV_BUFFS_16;
-
- /* dump all the assorted information */
- pr_info("%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
- dev->irq, dev->if_port ? "ex" : "in",
- dev->mem_start, dev->mem_end - 1);
-
- /* The hardware address for the 3c523 is stored in the first six
- bytes of the IO address. */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(dev->base_addr + i);
-
- pr_info("%s: hardware address %pM\n",
- dev->name, dev->dev_addr);
-
- dev->netdev_ops = &netdev_ops;
- dev->watchdog_timeo = HZ;
- dev->ethtool_ops = &netdev_ethtool_ops;
-
- /* note that we haven't actually requested the IRQ from the kernel.
- That gets done in elmc_open(). I'm not sure that's such a good idea,
- but it works, so I'll go with it. */
-
-#ifndef ELMC_MULTICAST
- dev->flags&=~IFF_MULTICAST; /* Multicast doesn't work */
-#endif
-
- retval = register_netdev(dev);
- if (retval)
- goto err_out;
-
- return 0;
-err_out:
- mca_set_adapter_procfn(slot, NULL, NULL);
- release_region(dev->base_addr, ELMC_IO_EXTENT);
- return retval;
-}
-
-#ifdef MODULE
-static void cleanup_card(struct net_device *dev)
-{
- mca_set_adapter_procfn(((struct priv *)netdev_priv(dev))->slot,
- NULL, NULL);
- release_region(dev->base_addr, ELMC_IO_EXTENT);
-}
-#else
-struct net_device * __init elmc_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct priv));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- sprintf(dev->name, "eth%d", unit);
- netdev_boot_setup_check(dev);
-
- err = do_elmc_probe(dev);
- if (err)
- goto out;
- return dev;
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-#endif
-
-/**********************************************
- * init the chip (elmc-interrupt should be disabled?!)
- * needs a correct 'allocated' memory
- */
-
-static int init586(struct net_device *dev)
-{
- void *ptr;
- unsigned long s;
- int i, result = 0;
- struct priv *p = netdev_priv(dev);
- volatile struct configure_cmd_struct *cfg_cmd;
- volatile struct iasetup_cmd_struct *ias_cmd;
- volatile struct tdr_cmd_struct *tdr_cmd;
- volatile struct mcsetup_cmd_struct *mc_cmd;
- struct netdev_hw_addr *ha;
- int num_addrs = netdev_mc_count(dev);
-
- ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct));
-
- cfg_cmd = (struct configure_cmd_struct *) ptr; /* configure-command */
- cfg_cmd->cmd_status = 0;
- cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST;
- cfg_cmd->cmd_link = 0xffff;
-
- cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */
- cfg_cmd->fifo = 0x08; /* fifo-limit (8=tx:32/rx:64) */
- cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */
- cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */
- cfg_cmd->priority = 0x00;
- cfg_cmd->ifs = 0x60;
- cfg_cmd->time_low = 0x00;
- cfg_cmd->time_high = 0xf2;
- cfg_cmd->promisc = 0;
- if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC))
- cfg_cmd->promisc = 1;
- cfg_cmd->carr_coll = 0x00;
-
- p->scb->cbl_offset = make16(cfg_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- elmc_id_attn586();
-
- s = jiffies; /* warning: only active with interrupts on !! */
- while (!(cfg_cmd->cmd_status & STAT_COMPL)) {
- if (time_after(jiffies, s + 30*HZ/100))
- break;
- }
-
- if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
- pr_warning("%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
- return 1;
- }
- /*
- * individual address setup
- */
- ias_cmd = (struct iasetup_cmd_struct *) ptr;
-
- ias_cmd->cmd_status = 0;
- ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST;
- ias_cmd->cmd_link = 0xffff;
-
- memcpy((char *) &ias_cmd->iaddr, (char *) dev->dev_addr, ETH_ALEN);
-
- p->scb->cbl_offset = make16(ias_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- elmc_id_attn586();
-
- s = jiffies;
- while (!(ias_cmd->cmd_status & STAT_COMPL)) {
- if (time_after(jiffies, s + 30*HZ/100))
- break;
- }
-
- if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
- pr_warning("%s (elmc): individual address setup command failed: %04x\n",
- dev->name, ias_cmd->cmd_status);
- return 1;
- }
- /*
- * TDR, wire check .. e.g. no resistor e.t.c
- */
- tdr_cmd = (struct tdr_cmd_struct *) ptr;
-
- tdr_cmd->cmd_status = 0;
- tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST;
- tdr_cmd->cmd_link = 0xffff;
- tdr_cmd->status = 0;
-
- p->scb->cbl_offset = make16(tdr_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- elmc_attn586();
-
- s = jiffies;
- while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
- if (time_after(jiffies, s + 30*HZ/100)) {
- pr_warning("%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
- result = 1;
- break;
- }
- }
-
- if (!result) {
- DELAY(2); /* wait for result */
- result = tdr_cmd->status;
-
- p->scb->cmd = p->scb->status & STAT_MASK;
- elmc_id_attn586(); /* ack the interrupts */
-
- if (result & TDR_LNK_OK) {
- /* empty */
- } else if (result & TDR_XCVR_PRB) {
- pr_warning("%s: TDR: Transceiver problem!\n", dev->name);
- } else if (result & TDR_ET_OPN) {
- pr_warning("%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
- } else if (result & TDR_ET_SRT) {
- if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
- pr_warning("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
- } else {
- pr_warning("%s: TDR: Unknown status %04x\n", dev->name, result);
- }
- }
- /*
- * ack interrupts
- */
- p->scb->cmd = p->scb->status & STAT_MASK;
- elmc_id_attn586();
-
- /*
- * alloc nop/xmit-cmds
- */
-#if (NUM_XMIT_BUFFS == 1)
- for (i = 0; i < 2; i++) {
- p->nop_cmds[i] = (struct nop_cmd_struct *) ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
- ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
- }
- p->xmit_cmds[0] = (struct transmit_cmd_struct *) ptr; /* transmit cmd/buff 0 */
- ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
-#else
- for (i = 0; i < NUM_XMIT_BUFFS; i++) {
- p->nop_cmds[i] = (struct nop_cmd_struct *) ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
- ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
- p->xmit_cmds[i] = (struct transmit_cmd_struct *) ptr; /*transmit cmd/buff 0 */
- ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
- }
-#endif
-
- ptr = alloc_rfa(dev, (void *) ptr); /* init receive-frame-area */
-
- /*
- * Multicast setup
- */
-
- if (num_addrs) {
- /* I don't understand this: do we really need memory after the init? */
- int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
- if (len <= 0) {
- pr_err("%s: Ooooops, no memory for MC-Setup!\n", dev->name);
- } else {
- if (len < num_addrs) {
- num_addrs = len;
- pr_warning("%s: Sorry, can only apply %d MC-Address(es).\n",
- dev->name, num_addrs);
- }
- mc_cmd = (struct mcsetup_cmd_struct *) ptr;
- mc_cmd->cmd_status = 0;
- mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
- mc_cmd->cmd_link = 0xffff;
- mc_cmd->mc_cnt = num_addrs * 6;
- i = 0;
- netdev_for_each_mc_addr(ha, dev)
- memcpy((char *) mc_cmd->mc_list[i++],
- ha->addr, 6);
- p->scb->cbl_offset = make16(mc_cmd);
- p->scb->cmd = CUC_START;
- elmc_id_attn586();
- s = jiffies;
- while (!(mc_cmd->cmd_status & STAT_COMPL)) {
- if (time_after(jiffies, s + 30*HZ/100))
- break;
- }
- if (!(mc_cmd->cmd_status & STAT_COMPL)) {
- pr_warning("%s: Can't apply multicast-address-list.\n", dev->name);
- }
- }
- }
- /*
- * alloc xmit-buffs / init xmit_cmds
- */
- for (i = 0; i < NUM_XMIT_BUFFS; i++) {
- p->xmit_cbuffs[i] = (char *) ptr; /* char-buffs */
- ptr = (char *) ptr + XMIT_BUFF_SIZE;
- p->xmit_buffs[i] = (struct tbd_struct *) ptr; /* TBD */
- ptr = (char *) ptr + sizeof(struct tbd_struct);
- if ((void *) ptr > (void *) p->iscp) {
- pr_err("%s: not enough shared-mem for your configuration!\n", dev->name);
- return 1;
- }
- memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct));
- memset((char *) (p->xmit_buffs[i]), 0, sizeof(struct tbd_struct));
- p->xmit_cmds[i]->cmd_status = STAT_COMPL;
- p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
- p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
- p->xmit_buffs[i]->next = 0xffff;
- p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
- }
-
- p->xmit_count = 0;
- p->xmit_last = 0;
-#ifndef NO_NOPCOMMANDS
- p->nop_point = 0;
-#endif
-
- /*
- * 'start transmitter' (nop-loop)
- */
-#ifndef NO_NOPCOMMANDS
- p->scb->cbl_offset = make16(p->nop_cmds[0]);
- p->scb->cmd = CUC_START;
- elmc_id_attn586();
- WAIT_4_SCB_CMD();
-#else
- p->xmit_cmds[0]->cmd_link = 0xffff;
- p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT;
-#endif
-
- return 0;
-}
-
-/******************************************************
- * This is a helper routine for elmc_rnr_int() and init586().
- * It sets up the Receive Frame Area (RFA).
- */
-
-static void *alloc_rfa(struct net_device *dev, void *ptr)
-{
- volatile struct rfd_struct *rfd = (struct rfd_struct *) ptr;
- volatile struct rbd_struct *rbd;
- int i;
- struct priv *p = netdev_priv(dev);
-
- memset((char *) rfd, 0, sizeof(struct rfd_struct) * p->num_recv_buffs);
- p->rfd_first = rfd;
-
- for (i = 0; i < p->num_recv_buffs; i++) {
- rfd[i].next = make16(rfd + (i + 1) % p->num_recv_buffs);
- }
- rfd[p->num_recv_buffs - 1].last = RFD_SUSP; /* RU suspend */
-
- ptr = (void *) (rfd + p->num_recv_buffs);
-
- rbd = (struct rbd_struct *) ptr;
- ptr = (void *) (rbd + p->num_recv_buffs);
-
- /* clr descriptors */
- memset((char *) rbd, 0, sizeof(struct rbd_struct) * p->num_recv_buffs);
-
- for (i = 0; i < p->num_recv_buffs; i++) {
- rbd[i].next = make16((rbd + (i + 1) % p->num_recv_buffs));
- rbd[i].size = RECV_BUFF_SIZE;
- rbd[i].buffer = make24(ptr);
- ptr = (char *) ptr + RECV_BUFF_SIZE;
- }
-
- p->rfd_top = p->rfd_first;
- p->rfd_last = p->rfd_first + p->num_recv_buffs - 1;
-
- p->scb->rfa_offset = make16(p->rfd_first);
- p->rfd_first->rbd_offset = make16(rbd);
-
- return ptr;
-}
-
-
-/**************************************************
- * Interrupt Handler ...
- */
-
-static irqreturn_t
-elmc_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- unsigned short stat;
- struct priv *p;
-
- if (!netif_running(dev)) {
- /* The 3c523 has this habit of generating interrupts during the
- reset. I'm not sure if the ni52 has this same problem, but it's
- really annoying if we haven't finished initializing it. I was
- hoping all the elmc_id_* commands would disable this, but I
- might have missed a few. */
-
- elmc_id_attn586(); /* ack inter. and disable any more */
- return IRQ_HANDLED;
- } else if (!(ELMC_CTRL_INT & inb(dev->base_addr + ELMC_CTRL))) {
- /* wasn't this device */
- return IRQ_NONE;
- }
- /* reading ELMC_CTRL also clears the INT bit. */
-
- p = netdev_priv(dev);
-
- while ((stat = p->scb->status & STAT_MASK))
- {
- p->scb->cmd = stat;
- elmc_attn586(); /* ack inter. */
-
- if (stat & STAT_CX) {
- /* command with I-bit set complete */
- elmc_xmt_int(dev);
- }
- if (stat & STAT_FR) {
- /* received a frame */
- elmc_rcv_int(dev);
- }
-#ifndef NO_NOPCOMMANDS
- if (stat & STAT_CNA) {
- /* CU went 'not ready' */
- if (netif_running(dev)) {
- pr_warning("%s: oops! CU has left active state. stat: %04x/%04x.\n",
- dev->name, (int) stat, (int) p->scb->status);
- }
- }
-#endif
-
- if (stat & STAT_RNR) {
- /* RU went 'not ready' */
-
- if (p->scb->status & RU_SUSPEND) {
- /* special case: RU_SUSPEND */
-
- WAIT_4_SCB_CMD();
- p->scb->cmd = RUC_RESUME;
- elmc_attn586();
- } else {
- pr_warning("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",
- dev->name, (int) stat, (int) p->scb->status);
- elmc_rnr_int(dev);
- }
- }
- WAIT_4_SCB_CMD(); /* wait for ack. (elmc_xmt_int can be faster than ack!!) */
- if (p->scb->cmd) { /* timed out? */
- break;
- }
- }
- return IRQ_HANDLED;
-}
-
-/*******************************************************
- * receive-interrupt
- */
-
-static void elmc_rcv_int(struct net_device *dev)
-{
- int status;
- unsigned short totlen;
- struct sk_buff *skb;
- struct rbd_struct *rbd;
- struct priv *p = netdev_priv(dev);
-
- for (; (status = p->rfd_top->status) & STAT_COMPL;) {
- rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
-
- if (status & STAT_OK) { /* frame received without error? */
- if ((totlen = rbd->status) & RBD_LAST) { /* the first and the last buffer? */
- totlen &= RBD_MASK; /* length of this frame */
- rbd->status = 0;
- skb = netdev_alloc_skb(dev, totlen + 2);
- if (skb != NULL) {
- skb_reserve(skb, 2); /* 16 byte alignment */
- skb_put(skb,totlen);
- skb_copy_to_linear_data(skb, (char *) p->base+(unsigned long) rbd->buffer,totlen);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += totlen;
- } else {
- dev->stats.rx_dropped++;
- }
- } else {
- pr_warning("%s: received oversized frame.\n", dev->name);
- dev->stats.rx_dropped++;
- }
- } else { /* frame !(ok), only with 'save-bad-frames' */
- pr_warning("%s: oops! rfd-error-status: %04x\n", dev->name, status);
- dev->stats.rx_errors++;
- }
- p->rfd_top->status = 0;
- p->rfd_top->last = RFD_SUSP;
- p->rfd_last->last = 0; /* delete RU_SUSP */
- p->rfd_last = p->rfd_top;
- p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
- }
-}
-
-/**********************************************************
- * handle 'Receiver went not ready'.
- */
-
-static void elmc_rnr_int(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
-
- dev->stats.rx_errors++;
-
- WAIT_4_SCB_CMD(); /* wait for the last cmd */
- p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
- elmc_attn586();
- WAIT_4_SCB_CMD(); /* wait for accept cmd. */
-
- alloc_rfa(dev, (char *) p->rfd_first);
- startrecv586(dev); /* restart RU */
-
- pr_warning("%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
-
-}
-
-/**********************************************************
- * handle xmit - interrupt
- */
-
-static void elmc_xmt_int(struct net_device *dev)
-{
- int status;
- struct priv *p = netdev_priv(dev);
-
- status = p->xmit_cmds[p->xmit_last]->cmd_status;
- if (!(status & STAT_COMPL)) {
- pr_warning("%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
- }
- if (status & STAT_OK) {
- dev->stats.tx_packets++;
- dev->stats.collisions += (status & TCMD_MAXCOLLMASK);
- } else {
- dev->stats.tx_errors++;
- if (status & TCMD_LATECOLL) {
- pr_warning("%s: late collision detected.\n", dev->name);
- dev->stats.collisions++;
- } else if (status & TCMD_NOCARRIER) {
- dev->stats.tx_carrier_errors++;
- pr_warning("%s: no carrier detected.\n", dev->name);
- } else if (status & TCMD_LOSTCTS) {
- pr_warning("%s: loss of CTS detected.\n", dev->name);
- } else if (status & TCMD_UNDERRUN) {
- dev->stats.tx_fifo_errors++;
- pr_warning("%s: DMA underrun detected.\n", dev->name);
- } else if (status & TCMD_MAXCOLL) {
- pr_warning("%s: Max. collisions exceeded.\n", dev->name);
- dev->stats.collisions += 16;
- }
- }
-
-#if (NUM_XMIT_BUFFS != 1)
- if ((++p->xmit_last) == NUM_XMIT_BUFFS) {
- p->xmit_last = 0;
- }
-#endif
-
- netif_wake_queue(dev);
-}
-
-/***********************************************************
- * (re)start the receiver
- */
-
-static void startrecv586(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
-
- p->scb->rfa_offset = make16(p->rfd_first);
- p->scb->cmd = RUC_START;
- elmc_attn586(); /* start cmd. */
- WAIT_4_SCB_CMD(); /* wait for accept cmd. (no timeout!!) */
-}
-
-/******************************************************
- * timeout
- */
-
-static void elmc_timeout(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
- /* COMMAND-UNIT active? */
- if (p->scb->status & CU_ACTIVE) {
- pr_debug("%s: strange ... timeout with CU active?!?\n", dev->name);
- pr_debug("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name,
- (int)p->xmit_cmds[0]->cmd_status,
- (int)p->nop_cmds[0]->cmd_status,
- (int)p->nop_cmds[1]->cmd_status, (int)p->nop_point);
- p->scb->cmd = CUC_ABORT;
- elmc_attn586();
- WAIT_4_SCB_CMD();
- p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
- p->scb->cmd = CUC_START;
- elmc_attn586();
- WAIT_4_SCB_CMD();
- netif_wake_queue(dev);
- } else {
- pr_debug("%s: xmitter timed out, try to restart! stat: %04x\n",
- dev->name, p->scb->status);
- pr_debug("%s: command-stats: %04x %04x\n", dev->name,
- p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
- elmc_close(dev);
- elmc_open(dev);
- }
-}
-
-/******************************************************
- * send frame
- */
-
-static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
- int len;
- int i;
-#ifndef NO_NOPCOMMANDS
- int next_nop;
-#endif
- struct priv *p = netdev_priv(dev);
-
- netif_stop_queue(dev);
-
- len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
-
- if (len != skb->len)
- memset((char *) p->xmit_cbuffs[p->xmit_count], 0, ETH_ZLEN);
- skb_copy_from_linear_data(skb, (char *) p->xmit_cbuffs[p->xmit_count], skb->len);
-
-#if (NUM_XMIT_BUFFS == 1)
-#ifdef NO_NOPCOMMANDS
- p->xmit_buffs[0]->size = TBD_LAST | len;
- for (i = 0; i < 16; i++) {
- p->scb->cbl_offset = make16(p->xmit_cmds[0]);
- p->scb->cmd = CUC_START;
- p->xmit_cmds[0]->cmd_status = 0;
- elmc_attn586();
- if (!i) {
- dev_kfree_skb(skb);
- }
- WAIT_4_SCB_CMD();
- if ((p->scb->status & CU_ACTIVE)) { /* test it, because CU sometimes doesn't start immediately */
- break;
- }
- if (p->xmit_cmds[0]->cmd_status) {
- break;
- }
- if (i == 15) {
- pr_warning("%s: Can't start transmit-command.\n", dev->name);
- }
- }
-#else
- next_nop = (p->nop_point + 1) & 0x1;
- p->xmit_buffs[0]->size = TBD_LAST | len;
-
- p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link
- = make16((p->nop_cmds[next_nop]));
- p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
-
- p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
- p->nop_point = next_nop;
- dev_kfree_skb(skb);
-#endif
-#else
- p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
- if ((next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS) {
- next_nop = 0;
- }
- p->xmit_cmds[p->xmit_count]->cmd_status = 0;
- p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link
- = make16((p->nop_cmds[next_nop]));
- p->nop_cmds[next_nop]->cmd_status = 0;
- p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
- p->xmit_count = next_nop;
- if (p->xmit_count != p->xmit_last)
- netif_wake_queue(dev);
- dev_kfree_skb(skb);
-#endif
- return NETDEV_TX_OK;
-}
-
-/*******************************************
- * Someone wanna have the statistics
- */
-
-static struct net_device_stats *elmc_get_stats(struct net_device *dev)
-{
- struct priv *p = netdev_priv(dev);
- unsigned short crc, aln, rsc, ovrn;
-
- crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */
- p->scb->crc_errs -= crc;
- aln = p->scb->aln_errs;
- p->scb->aln_errs -= aln;
- rsc = p->scb->rsc_errs;
- p->scb->rsc_errs -= rsc;
- ovrn = p->scb->ovrn_errs;
- p->scb->ovrn_errs -= ovrn;
-
- dev->stats.rx_crc_errors += crc;
- dev->stats.rx_fifo_errors += ovrn;
- dev->stats.rx_frame_errors += aln;
- dev->stats.rx_dropped += rsc;
-
- return &dev->stats;
-}
-
-/********************************************************
- * Set MC list ..
- */
-
-#ifdef ELMC_MULTICAST
-static void set_multicast_list(struct net_device *dev)
-{
- if (!dev->start) {
- /* without a running interface, promiscuous doesn't work */
- return;
- }
- dev->start = 0;
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
- dev->start = 1;
-}
-#endif
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr);
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
-};
-
-#ifdef MODULE
-
-/* Increase if needed ;) */
-#define MAX_3C523_CARDS 4
-
-static struct net_device *dev_elmc[MAX_3C523_CARDS];
-static int irq[MAX_3C523_CARDS];
-static int io[MAX_3C523_CARDS];
-module_param_array(irq, int, NULL, 0);
-module_param_array(io, int, NULL, 0);
-MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)");
-MODULE_LICENSE("GPL");
-
-int __init init_module(void)
-{
- int this_dev,found = 0;
-
- /* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */
- for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
- struct net_device *dev = alloc_etherdev(sizeof(struct priv));
- if (!dev)
- break;
- dev->irq=irq[this_dev];
- dev->base_addr=io[this_dev];
- if (do_elmc_probe(dev) == 0) {
- dev_elmc[this_dev] = dev;
- found++;
- continue;
- }
- free_netdev(dev);
- if (io[this_dev]==0)
- break;
- pr_warning("3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
- }
-
- if(found==0) {
- if (io[0]==0)
- pr_notice("3c523.c: No 3c523 cards found\n");
- return -ENXIO;
- } else return 0;
-}
-
-void __exit cleanup_module(void)
-{
- int this_dev;
- for (this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
- struct net_device *dev = dev_elmc[this_dev];
- if (dev) {
- unregister_netdev(dev);
- cleanup_card(dev);
- free_netdev(dev);
- }
- }
-}
-
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/i825xx/3c523.h b/drivers/net/ethernet/i825xx/3c523.h
deleted file mode 100644
index 6956441687b9..000000000000
--- a/drivers/net/ethernet/i825xx/3c523.h
+++ /dev/null
@@ -1,355 +0,0 @@
-#ifndef _3c523_INCLUDE_
-#define _3c523_INCLUDE_
-/*
- This is basically a hacked version of ni52.h, for the 3c523
- Etherlink/MC.
-*/
-
-/*
- * Intel i82586 Ethernet definitions
- *
- * This is an extension to the Linux operating system, and is covered by the
- * same GNU General Public License that covers that work.
- *
- * Copyright 1995 by Chris Beauregard (cpbeaure@undergrad.math.uwaterloo.ca)
- *
- * See 3c523.c for details.
- *
- * $Header: /home/chrisb/linux-1.2.13-3c523/drivers/net/RCS/3c523.h,v 1.6 1996/01/20 05:09:00 chrisb Exp chrisb $
- */
-
-/*
- * where to find the System Configuration Pointer (SCP)
- */
-#define SCP_DEFAULT_ADDRESS 0xfffff4
-
-
-/*
- * System Configuration Pointer Struct
- */
-
-struct scp_struct
-{
- unsigned short zero_dum0; /* has to be zero */
- unsigned char sysbus; /* 0=16Bit,1=8Bit */
- unsigned char zero_dum1; /* has to be zero for 586 */
- unsigned short zero_dum2;
- unsigned short zero_dum3;
- char *iscp; /* pointer to the iscp-block */
-};
-
-
-/*
- * Intermediate System Configuration Pointer (ISCP)
- */
-struct iscp_struct
-{
- unsigned char busy; /* 586 clears after successful init */
- unsigned char zero_dummy; /* hast to be zero */
- unsigned short scb_offset; /* pointeroffset to the scb_base */
- char *scb_base; /* base-address of all 16-bit offsets */
-};
-
-/*
- * System Control Block (SCB)
- */
-struct scb_struct
-{
- unsigned short status; /* status word */
- unsigned short cmd; /* command word */
- unsigned short cbl_offset; /* pointeroffset, command block list */
- unsigned short rfa_offset; /* pointeroffset, receive frame area */
- unsigned short crc_errs; /* CRC-Error counter */
- unsigned short aln_errs; /* alignmenterror counter */
- unsigned short rsc_errs; /* Resourceerror counter */
- unsigned short ovrn_errs; /* OVerrunerror counter */
-};
-
-/*
- * possible command values for the command word
- */
-#define RUC_MASK 0x0070 /* mask for RU commands */
-#define RUC_NOP 0x0000 /* NOP-command */
-#define RUC_START 0x0010 /* start RU */
-#define RUC_RESUME 0x0020 /* resume RU after suspend */
-#define RUC_SUSPEND 0x0030 /* suspend RU */
-#define RUC_ABORT 0x0040 /* abort receiver operation immediately */
-
-#define CUC_MASK 0x0700 /* mask for CU command */
-#define CUC_NOP 0x0000 /* NOP-command */
-#define CUC_START 0x0100 /* start execution of 1. cmd on the CBL */
-#define CUC_RESUME 0x0200 /* resume after suspend */
-#define CUC_SUSPEND 0x0300 /* Suspend CU */
-#define CUC_ABORT 0x0400 /* abort command operation immediately */
-
-#define ACK_MASK 0xf000 /* mask for ACK command */
-#define ACK_CX 0x8000 /* acknowledges STAT_CX */
-#define ACK_FR 0x4000 /* ack. STAT_FR */
-#define ACK_CNA 0x2000 /* ack. STAT_CNA */
-#define ACK_RNR 0x1000 /* ack. STAT_RNR */
-
-/*
- * possible status values for the status word
- */
-#define STAT_MASK 0xf000 /* mask for cause of interrupt */
-#define STAT_CX 0x8000 /* CU finished cmd with its I bit set */
-#define STAT_FR 0x4000 /* RU finished receiving a frame */
-#define STAT_CNA 0x2000 /* CU left active state */
-#define STAT_RNR 0x1000 /* RU left ready state */
-
-#define CU_STATUS 0x700 /* CU status, 0=idle */
-#define CU_SUSPEND 0x100 /* CU is suspended */
-#define CU_ACTIVE 0x200 /* CU is active */
-
-#define RU_STATUS 0x70 /* RU status, 0=idle */
-#define RU_SUSPEND 0x10 /* RU suspended */
-#define RU_NOSPACE 0x20 /* RU no resources */
-#define RU_READY 0x40 /* RU is ready */
-
-/*
- * Receive Frame Descriptor (RFD)
- */
-struct rfd_struct
-{
- unsigned short status; /* status word */
- unsigned short last; /* Bit15,Last Frame on List / Bit14,suspend */
- unsigned short next; /* linkoffset to next RFD */
- unsigned short rbd_offset; /* pointeroffset to RBD-buffer */
- unsigned char dest[6]; /* ethernet-address, destination */
- unsigned char source[6]; /* ethernet-address, source */
- unsigned short length; /* 802.3 frame-length */
- unsigned short zero_dummy; /* dummy */
-};
-
-#define RFD_LAST 0x8000 /* last: last rfd in the list */
-#define RFD_SUSP 0x4000 /* last: suspend RU after */
-#define RFD_ERRMASK 0x0fe1 /* status: errormask */
-#define RFD_MATCHADD 0x0002 /* status: Destinationaddress !matches IA */
-#define RFD_RNR 0x0200 /* status: receiver out of resources */
-
-/*
- * Receive Buffer Descriptor (RBD)
- */
-struct rbd_struct
-{
- unsigned short status; /* status word,number of used bytes in buff */
- unsigned short next; /* pointeroffset to next RBD */
- char *buffer; /* receive buffer address pointer */
- unsigned short size; /* size of this buffer */
- unsigned short zero_dummy; /* dummy */
-};
-
-#define RBD_LAST 0x8000 /* last buffer */
-#define RBD_USED 0x4000 /* this buffer has data */
-#define RBD_MASK 0x3fff /* size-mask for length */
-
-/*
- * Statusvalues for Commands/RFD
- */
-#define STAT_COMPL 0x8000 /* status: frame/command is complete */
-#define STAT_BUSY 0x4000 /* status: frame/command is busy */
-#define STAT_OK 0x2000 /* status: frame/command is ok */
-
-/*
- * Action-Commands
- */
-#define CMD_NOP 0x0000 /* NOP */
-#define CMD_IASETUP 0x0001 /* initial address setup command */
-#define CMD_CONFIGURE 0x0002 /* configure command */
-#define CMD_MCSETUP 0x0003 /* MC setup command */
-#define CMD_XMIT 0x0004 /* transmit command */
-#define CMD_TDR 0x0005 /* time domain reflectometer (TDR) command */
-#define CMD_DUMP 0x0006 /* dump command */
-#define CMD_DIAGNOSE 0x0007 /* diagnose command */
-
-/*
- * Action command bits
- */
-#define CMD_LAST 0x8000 /* indicates last command in the CBL */
-#define CMD_SUSPEND 0x4000 /* suspend CU after this CB */
-#define CMD_INT 0x2000 /* generate interrupt after execution */
-
-/*
- * NOP - command
- */
-struct nop_cmd_struct
-{
- unsigned short cmd_status; /* status of this command */
- unsigned short cmd_cmd; /* the command itself (+bits) */
- unsigned short cmd_link; /* offsetpointer to next command */
-};
-
-/*
- * IA Setup command
- */
-struct iasetup_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned char iaddr[6];
-};
-
-/*
- * Configure command
- */
-struct configure_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned char byte_cnt; /* size of the config-cmd */
- unsigned char fifo; /* fifo/recv monitor */
- unsigned char sav_bf; /* save bad frames (bit7=1)*/
- unsigned char adr_len; /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/
- unsigned char priority; /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */
- unsigned char ifs; /* inter frame spacing */
- unsigned char time_low; /* slot time low */
- unsigned char time_high; /* slot time high(0-2) and max. retries(4-7) */
- unsigned char promisc; /* promisc-mode(0) , et al (1-7) */
- unsigned char carr_coll; /* carrier(0-3)/collision(4-7) stuff */
- unsigned char fram_len; /* minimal frame len */
- unsigned char dummy; /* dummy */
-};
-
-/*
- * Multicast Setup command
- */
-struct mcsetup_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short mc_cnt; /* number of bytes in the MC-List */
- unsigned char mc_list[0][6]; /* pointer to 6 bytes entries */
-};
-
-/*
- * transmit command
- */
-struct transmit_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short tbd_offset; /* pointeroffset to TBD */
- unsigned char dest[6]; /* destination address of the frame */
- unsigned short length; /* user defined: 802.3 length / Ether type */
-};
-
-#define TCMD_ERRMASK 0x0fa0
-#define TCMD_MAXCOLLMASK 0x000f
-#define TCMD_MAXCOLL 0x0020
-#define TCMD_HEARTBEAT 0x0040
-#define TCMD_DEFERRED 0x0080
-#define TCMD_UNDERRUN 0x0100
-#define TCMD_LOSTCTS 0x0200
-#define TCMD_NOCARRIER 0x0400
-#define TCMD_LATECOLL 0x0800
-
-struct tdr_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short status;
-};
-
-#define TDR_LNK_OK 0x8000 /* No link problem identified */
-#define TDR_XCVR_PRB 0x4000 /* indicates a transceiver problem */
-#define TDR_ET_OPN 0x2000 /* open, no correct termination */
-#define TDR_ET_SRT 0x1000 /* TDR detected a short circuit */
-#define TDR_TIMEMASK 0x07ff /* mask for the time field */
-
-/*
- * Transmit Buffer Descriptor (TBD)
- */
-struct tbd_struct
-{
- unsigned short size; /* size + EOF-Flag(15) */
- unsigned short next; /* pointeroffset to next TBD */
- char *buffer; /* pointer to buffer */
-};
-
-#define TBD_LAST 0x8000 /* EOF-Flag, indicates last buffer in list */
-
-/*************************************************************************/
-/*
-Verbatim from the Crynwyr stuff:
-
- The 3c523 responds with adapter code 0x6042 at slot
-registers xxx0 and xxx1. The setup register is at xxx2 and
-contains the following bits:
-
-0: card enable
-2,1: csr address select
- 00 = 0300
- 01 = 1300
- 10 = 2300
- 11 = 3300
-4,3: shared memory address select
- 00 = 0c0000
- 01 = 0c8000
- 10 = 0d0000
- 11 = 0d8000
-5: set to disable on-board thinnet
-7,6: (read-only) shows selected irq
- 00 = 12
- 01 = 7
- 10 = 3
- 11 = 9
-
-The interrupt-select register is at xxx3 and uses one bit per irq.
-
-0: int 12
-1: int 7
-2: int 3
-3: int 9
-
- Again, the documentation stresses that the setup register
-should never be written. The interrupt-select register may be
-written with the value corresponding to bits 7.6 in
-the setup register to insure corret setup.
-*/
-
-/* Offsets from the base I/O address. */
-#define ELMC_SA 0 /* first 6 bytes are IEEE network address */
-#define ELMC_CTRL 6 /* control & status register */
-#define ELMC_REVISION 7 /* revision register, first 4 bits only */
-#define ELMC_IO_EXTENT 8
-
-/* these are the bit selects for the port register 2 */
-#define ELMC_STATUS_ENABLED 0x01
-#define ELMC_STATUS_CSR_SELECT 0x06
-#define ELMC_STATUS_MEMORY_SELECT 0x18
-#define ELMC_STATUS_DISABLE_THIN 0x20
-#define ELMC_STATUS_IRQ_SELECT 0xc0
-
-/* this is the card id used in the detection code. You might recognize
-it from @6042.adf */
-#define ELMC_MCA_ID 0x6042
-
-/*
- The following define the bits for the control & status register
-
- The bank select registers can be used if more than 16K of memory is
- on the card. For some stupid reason, bank 3 is the one for the
- bottom 16K, and the card defaults to bank 0. So we have to set the
- bank to 3 before the card will even think of operating. To get bank
- 3, set BS0 and BS1 to high (of course...)
-*/
-#define ELMC_CTRL_BS0 0x01 /* RW bank select */
-#define ELMC_CTRL_BS1 0x02 /* RW bank select */
-#define ELMC_CTRL_INTE 0x04 /* RW interrupt enable, assert high */
-#define ELMC_CTRL_INT 0x08 /* R interrupt active, assert high */
-/*#define ELMC_CTRL_* 0x10*/ /* reserved */
-#define ELMC_CTRL_LBK 0x20 /* RW loopback enable, assert high */
-#define ELMC_CTRL_CA 0x40 /* RW channel attention, assert high */
-#define ELMC_CTRL_RST 0x80 /* RW 82586 reset, assert low */
-
-/* some handy compound bits */
-
-/* normal operation should have bank 3 and RST high, ints enabled */
-#define ELMC_NORMAL (ELMC_CTRL_INTE|ELMC_CTRL_RST|0x3)
-
-#endif /* _3c523_INCLUDE_ */
diff --git a/drivers/net/ethernet/i825xx/3c527.c b/drivers/net/ethernet/i825xx/3c527.c
deleted file mode 100644
index 278e791afe00..000000000000
--- a/drivers/net/ethernet/i825xx/3c527.c
+++ /dev/null
@@ -1,1660 +0,0 @@
-/* 3c527.c: 3Com Etherlink/MC32 driver for Linux 2.4 and 2.6.
- *
- * (c) Copyright 1998 Red Hat Software Inc
- * Written by Alan Cox.
- * Further debugging by Carl Drougge.
- * Initial SMP support by Felipe W Damasio <felipewd@terra.com.br>
- * Heavily modified by Richard Procter <rnp@paradise.net.nz>
- *
- * Based on skeleton.c written 1993-94 by Donald Becker and ne2.c
- * (for the MCA stuff) written by Wim Dumon.
- *
- * Thanks to 3Com for making this possible by providing me with the
- * documentation.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#define DRV_NAME "3c527"
-#define DRV_VERSION "0.7-SMP"
-#define DRV_RELDATE "2003/09/21"
-
-static const char *version =
-DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Procter <rnp@paradise.net.nz>\n";
-
-/**
- * DOC: Traps for the unwary
- *
- * The diagram (Figure 1-1) and the POS summary disagree with the
- * "Interrupt Level" section in the manual.
- *
- * The manual contradicts itself when describing the minimum number
- * buffers in the 'configure lists' command.
- * My card accepts a buffer config of 4/4.
- *
- * Setting the SAV BP bit does not save bad packets, but
- * only enables RX on-card stats collection.
- *
- * The documentation in places seems to miss things. In actual fact
- * I've always eventually found everything is documented, it just
- * requires careful study.
- *
- * DOC: Theory Of Operation
- *
- * The 3com 3c527 is a 32bit MCA bus mastering adapter with a large
- * amount of on board intelligence that housekeeps a somewhat dumber
- * Intel NIC. For performance we want to keep the transmit queue deep
- * as the card can transmit packets while fetching others from main
- * memory by bus master DMA. Transmission and reception are driven by
- * circular buffer queues.
- *
- * The mailboxes can be used for controlling how the card traverses
- * its buffer rings, but are used only for initial setup in this
- * implementation. The exec mailbox allows a variety of commands to
- * be executed. Each command must complete before the next is
- * executed. Primarily we use the exec mailbox for controlling the
- * multicast lists. We have to do a certain amount of interesting
- * hoop jumping as the multicast list changes can occur in interrupt
- * state when the card has an exec command pending. We defer such
- * events until the command completion interrupt.
- *
- * A copy break scheme (taken from 3c59x.c) is employed whereby
- * received frames exceeding a configurable length are passed
- * directly to the higher networking layers without incuring a copy,
- * in what amounts to a time/space trade-off.
- *
- * The card also keeps a large amount of statistical information
- * on-board. In a perfect world, these could be used safely at no
- * cost. However, lacking information to the contrary, processing
- * them without races would involve so much extra complexity as to
- * make it unworthwhile to do so. In the end, a hybrid SW/HW
- * implementation was made necessary --- see mc32_update_stats().
- *
- * DOC: Notes
- *
- * It should be possible to use two or more cards, but at this stage
- * only by loading two copies of the same module.
- *
- * The on-board 82586 NIC has trouble receiving multiple
- * back-to-back frames and so is likely to drop packets from fast
- * senders.
-**/
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_ether.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/mca-legacy.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/wait.h>
-#include <linux/ethtool.h>
-#include <linux/completion.h>
-#include <linux/bitops.h>
-#include <linux/semaphore.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include "3c527.h"
-
-MODULE_LICENSE("GPL");
-
-/*
- * The name of the card. Is used for messages and in the requests for
- * io regions, irqs and dma channels
- */
-static const char* cardname = DRV_NAME;
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 2
-#endif
-
-static unsigned int mc32_debug = NET_DEBUG;
-
-/* The number of low I/O ports used by the ethercard. */
-#define MC32_IO_EXTENT 8
-
-/* As implemented, values must be a power-of-2 -- 4/8/16/32 */
-#define TX_RING_LEN 32 /* Typically the card supports 37 */
-#define RX_RING_LEN 8 /* " " " */
-
-/* Copy break point, see above for details.
- * Setting to > 1512 effectively disables this feature. */
-#define RX_COPYBREAK 200 /* Value from 3c59x.c */
-
-/* Issue the 82586 workaround command - this is for "busy lans", but
- * basically means for all lans now days - has a performance (latency)
- * cost, but best set. */
-static const int WORKAROUND_82586=1;
-
-/* Pointers to buffers and their on-card records */
-struct mc32_ring_desc
-{
- volatile struct skb_header *p;
- struct sk_buff *skb;
-};
-
-/* Information that needs to be kept for each board. */
-struct mc32_local
-{
- int slot;
-
- u32 base;
- volatile struct mc32_mailbox *rx_box;
- volatile struct mc32_mailbox *tx_box;
- volatile struct mc32_mailbox *exec_box;
- volatile struct mc32_stats *stats; /* Start of on-card statistics */
- u16 tx_chain; /* Transmit list start offset */
- u16 rx_chain; /* Receive list start offset */
- u16 tx_len; /* Transmit list count */
- u16 rx_len; /* Receive list count */
-
- u16 xceiver_desired_state; /* HALTED or RUNNING */
- u16 cmd_nonblocking; /* Thread is uninterested in command result */
- u16 mc_reload_wait; /* A multicast load request is pending */
- u32 mc_list_valid; /* True when the mclist is set */
-
- struct mc32_ring_desc tx_ring[TX_RING_LEN]; /* Host Transmit ring */
- struct mc32_ring_desc rx_ring[RX_RING_LEN]; /* Host Receive ring */
-
- atomic_t tx_count; /* buffers left */
- atomic_t tx_ring_head; /* index to tx en-queue end */
- u16 tx_ring_tail; /* index to tx de-queue end */
-
- u16 rx_ring_tail; /* index to rx de-queue end */
-
- struct semaphore cmd_mutex; /* Serialises issuing of execute commands */
- struct completion execution_cmd; /* Card has completed an execute command */
- struct completion xceiver_cmd; /* Card has completed a tx or rx command */
-};
-
-/* The station (ethernet) address prefix, used for a sanity check. */
-#define SA_ADDR0 0x02
-#define SA_ADDR1 0x60
-#define SA_ADDR2 0xAC
-
-struct mca_adapters_t {
- unsigned int id;
- char *name;
-};
-
-static const struct mca_adapters_t mc32_adapters[] = {
- { 0x0041, "3COM EtherLink MC/32" },
- { 0x8EF5, "IBM High Performance Lan Adapter" },
- { 0x0000, NULL }
-};
-
-
-/* Macros for ring index manipulations */
-static inline u16 next_rx(u16 rx) { return (rx+1)&(RX_RING_LEN-1); };
-static inline u16 prev_rx(u16 rx) { return (rx-1)&(RX_RING_LEN-1); };
-
-static inline u16 next_tx(u16 tx) { return (tx+1)&(TX_RING_LEN-1); };
-
-
-/* Index to functions, as function prototypes. */
-static int mc32_probe1(struct net_device *dev, int ioaddr);
-static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len);
-static int mc32_open(struct net_device *dev);
-static void mc32_timeout(struct net_device *dev);
-static netdev_tx_t mc32_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-static irqreturn_t mc32_interrupt(int irq, void *dev_id);
-static int mc32_close(struct net_device *dev);
-static struct net_device_stats *mc32_get_stats(struct net_device *dev);
-static void mc32_set_multicast_list(struct net_device *dev);
-static void mc32_reset_multicast_list(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-
-static void cleanup_card(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- unsigned slot = lp->slot;
- mca_mark_as_unused(slot);
- mca_set_adapter_name(slot, NULL);
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, MC32_IO_EXTENT);
-}
-
-/**
- * mc32_probe - Search for supported boards
- * @unit: interface number to use
- *
- * Because MCA bus is a real bus and we can scan for cards we could do a
- * single scan for all boards here. Right now we use the passed in device
- * structure and scan for only one board. This needs fixing for modules
- * in particular.
- */
-
-struct net_device *__init mc32_probe(int unit)
-{
- struct net_device *dev = alloc_etherdev(sizeof(struct mc32_local));
- static int current_mca_slot = -1;
- int i;
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- if (unit >= 0)
- sprintf(dev->name, "eth%d", unit);
-
- /* Do not check any supplied i/o locations.
- POS registers usually don't fail :) */
-
- /* MCA cards have POS registers.
- Autodetecting MCA cards is extremely simple.
- Just search for the card. */
-
- for(i = 0; (mc32_adapters[i].name != NULL); i++) {
- current_mca_slot =
- mca_find_unused_adapter(mc32_adapters[i].id, 0);
-
- if(current_mca_slot != MCA_NOTFOUND) {
- if(!mc32_probe1(dev, current_mca_slot))
- {
- mca_set_adapter_name(current_mca_slot,
- mc32_adapters[i].name);
- mca_mark_as_used(current_mca_slot);
- err = register_netdev(dev);
- if (err) {
- cleanup_card(dev);
- free_netdev(dev);
- dev = ERR_PTR(err);
- }
- return dev;
- }
-
- }
- }
- free_netdev(dev);
- return ERR_PTR(-ENODEV);
-}
-
-static const struct net_device_ops netdev_ops = {
- .ndo_open = mc32_open,
- .ndo_stop = mc32_close,
- .ndo_start_xmit = mc32_send_packet,
- .ndo_get_stats = mc32_get_stats,
- .ndo_set_rx_mode = mc32_set_multicast_list,
- .ndo_tx_timeout = mc32_timeout,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-/**
- * mc32_probe1 - Check a given slot for a board and test the card
- * @dev: Device structure to fill in
- * @slot: The MCA bus slot being used by this card
- *
- * Decode the slot data and configure the card structures. Having done this we
- * can reset the card and configure it. The card does a full self test cycle
- * in firmware so we have to wait for it to return and post us either a
- * failure case or some addresses we use to find the board internals.
- */
-
-static int __init mc32_probe1(struct net_device *dev, int slot)
-{
- static unsigned version_printed;
- int i, err;
- u8 POS;
- u32 base;
- struct mc32_local *lp = netdev_priv(dev);
- static const u16 mca_io_bases[] = {
- 0x7280,0x7290,
- 0x7680,0x7690,
- 0x7A80,0x7A90,
- 0x7E80,0x7E90
- };
- static const u32 mca_mem_bases[] = {
- 0x00C0000,
- 0x00C4000,
- 0x00C8000,
- 0x00CC000,
- 0x00D0000,
- 0x00D4000,
- 0x00D8000,
- 0x00DC000
- };
- static const char * const failures[] = {
- "Processor instruction",
- "Processor data bus",
- "Processor data bus",
- "Processor data bus",
- "Adapter bus",
- "ROM checksum",
- "Base RAM",
- "Extended RAM",
- "82586 internal loopback",
- "82586 initialisation failure",
- "Adapter list configuration error"
- };
-
- /* Time to play MCA games */
-
- if (mc32_debug && version_printed++ == 0)
- pr_debug("%s", version);
-
- pr_info("%s: %s found in slot %d: ", dev->name, cardname, slot);
-
- POS = mca_read_stored_pos(slot, 2);
-
- if(!(POS&1))
- {
- pr_cont("disabled.\n");
- return -ENODEV;
- }
-
- /* Fill in the 'dev' fields. */
- dev->base_addr = mca_io_bases[(POS>>1)&7];
- dev->mem_start = mca_mem_bases[(POS>>4)&7];
-
- POS = mca_read_stored_pos(slot, 4);
- if(!(POS&1))
- {
- pr_cont("memory window disabled.\n");
- return -ENODEV;
- }
-
- POS = mca_read_stored_pos(slot, 5);
-
- i=(POS>>4)&3;
- if(i==3)
- {
- pr_cont("invalid memory window.\n");
- return -ENODEV;
- }
-
- i*=16384;
- i+=16384;
-
- dev->mem_end=dev->mem_start + i;
-
- dev->irq = ((POS>>2)&3)+9;
-
- if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname))
- {
- pr_cont("io 0x%3lX, which is busy.\n", dev->base_addr);
- return -EBUSY;
- }
-
- pr_cont("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
- dev->base_addr, dev->irq, dev->mem_start, i/1024);
-
-
- /* We ought to set the cache line size here.. */
-
-
- /*
- * Go PROM browsing
- */
-
- /* Retrieve and print the ethernet address. */
- for (i = 0; i < 6; i++)
- {
- mca_write_pos(slot, 6, i+12);
- mca_write_pos(slot, 7, 0);
-
- dev->dev_addr[i] = mca_read_pos(slot,3);
- }
-
- pr_info("%s: Address %pM ", dev->name, dev->dev_addr);
-
- mca_write_pos(slot, 6, 0);
- mca_write_pos(slot, 7, 0);
-
- POS = mca_read_stored_pos(slot, 4);
-
- if(POS&2)
- pr_cont(": BNC port selected.\n");
- else
- pr_cont(": AUI port selected.\n");
-
- POS=inb(dev->base_addr+HOST_CTRL);
- POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET;
- POS&=~HOST_CTRL_INTE;
- outb(POS, dev->base_addr+HOST_CTRL);
- /* Reset adapter */
- udelay(100);
- /* Reset off */
- POS&=~(HOST_CTRL_ATTN|HOST_CTRL_RESET);
- outb(POS, dev->base_addr+HOST_CTRL);
-
- udelay(300);
-
- /*
- * Grab the IRQ
- */
-
- err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED, DRV_NAME, dev);
- if (err) {
- release_region(dev->base_addr, MC32_IO_EXTENT);
- pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
- goto err_exit_ports;
- }
-
- memset(lp, 0, sizeof(struct mc32_local));
- lp->slot = slot;
-
- i=0;
-
- base = inb(dev->base_addr);
-
- while(base == 0xFF)
- {
- i++;
- if(i == 1000)
- {
- pr_err("%s: failed to boot adapter.\n", dev->name);
- err = -ENODEV;
- goto err_exit_irq;
- }
- udelay(1000);
- if(inb(dev->base_addr+2)&(1<<5))
- base = inb(dev->base_addr);
- }
-
- if(base>0)
- {
- if(base < 0x0C)
- pr_err("%s: %s%s.\n", dev->name, failures[base-1],
- base<0x0A?" test failure":"");
- else
- pr_err("%s: unknown failure %d.\n", dev->name, base);
- err = -ENODEV;
- goto err_exit_irq;
- }
-
- base=0;
- for(i=0;i<4;i++)
- {
- int n=0;
-
- while(!(inb(dev->base_addr+2)&(1<<5)))
- {
- n++;
- udelay(50);
- if(n>100)
- {
- pr_err("%s: mailbox read fail (%d).\n", dev->name, i);
- err = -ENODEV;
- goto err_exit_irq;
- }
- }
-
- base|=(inb(dev->base_addr)<<(8*i));
- }
-
- lp->exec_box=isa_bus_to_virt(dev->mem_start+base);
-
- base=lp->exec_box->data[1]<<16|lp->exec_box->data[0];
-
- lp->base = dev->mem_start+base;
-
- lp->rx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[2]);
- lp->tx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[3]);
-
- lp->stats = isa_bus_to_virt(lp->base + lp->exec_box->data[5]);
-
- /*
- * Descriptor chains (card relative)
- */
-
- lp->tx_chain = lp->exec_box->data[8]; /* Transmit list start offset */
- lp->rx_chain = lp->exec_box->data[10]; /* Receive list start offset */
- lp->tx_len = lp->exec_box->data[9]; /* Transmit list count */
- lp->rx_len = lp->exec_box->data[11]; /* Receive list count */
-
- sema_init(&lp->cmd_mutex, 0);
- init_completion(&lp->execution_cmd);
- init_completion(&lp->xceiver_cmd);
-
- pr_info("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
- dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
-
- dev->netdev_ops = &netdev_ops;
- dev->watchdog_timeo = HZ*5; /* Board does all the work */
- dev->ethtool_ops = &netdev_ethtool_ops;
-
- return 0;
-
-err_exit_irq:
- free_irq(dev->irq, dev);
-err_exit_ports:
- release_region(dev->base_addr, MC32_IO_EXTENT);
- return err;
-}
-
-
-/**
- * mc32_ready_poll - wait until we can feed it a command
- * @dev: The device to wait for
- *
- * Wait until the card becomes ready to accept a command via the
- * command register. This tells us nothing about the completion
- * status of any pending commands and takes very little time at all.
- */
-
-static inline void mc32_ready_poll(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
-}
-
-
-/**
- * mc32_command_nowait - send a command non blocking
- * @dev: The 3c527 to issue the command to
- * @cmd: The command word to write to the mailbox
- * @data: A data block if the command expects one
- * @len: Length of the data block
- *
- * Send a command from interrupt state. If there is a command
- * currently being executed then we return an error of -1. It
- * simply isn't viable to wait around as commands may be
- * slow. This can theoretically be starved on SMP, but it's hard
- * to see a realistic situation. We do not wait for the command
- * to complete --- we rely on the interrupt handler to tidy up
- * after us.
- */
-
-static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int len)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int ret = -1;
-
- if (down_trylock(&lp->cmd_mutex) == 0)
- {
- lp->cmd_nonblocking=1;
- lp->exec_box->mbox=0;
- lp->exec_box->mbox=cmd;
- memcpy((void *)lp->exec_box->data, data, len);
- barrier(); /* the memcpy forgot the volatile so be sure */
-
- /* Send the command */
- mc32_ready_poll(dev);
- outb(1<<6, ioaddr+HOST_CMD);
-
- ret = 0;
-
- /* Interrupt handler will signal mutex on completion */
- }
-
- return ret;
-}
-
-
-/**
- * mc32_command - send a command and sleep until completion
- * @dev: The 3c527 card to issue the command to
- * @cmd: The command word to write to the mailbox
- * @data: A data block if the command expects one
- * @len: Length of the data block
- *
- * Sends exec commands in a user context. This permits us to wait around
- * for the replies and also to wait for the command buffer to complete
- * from a previous command before we execute our command. After our
- * command completes we will attempt any pending multicast reload
- * we blocked off by hogging the exec buffer.
- *
- * You feed the card a command, you wait, it interrupts you get a
- * reply. All well and good. The complication arises because you use
- * commands for filter list changes which come in at bh level from things
- * like IPV6 group stuff.
- */
-
-static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- int ret = 0;
-
- down(&lp->cmd_mutex);
-
- /*
- * My Turn
- */
-
- lp->cmd_nonblocking=0;
- lp->exec_box->mbox=0;
- lp->exec_box->mbox=cmd;
- memcpy((void *)lp->exec_box->data, data, len);
- barrier(); /* the memcpy forgot the volatile so be sure */
-
- mc32_ready_poll(dev);
- outb(1<<6, ioaddr+HOST_CMD);
-
- wait_for_completion(&lp->execution_cmd);
-
- if(lp->exec_box->mbox&(1<<13))
- ret = -1;
-
- up(&lp->cmd_mutex);
-
- /*
- * A multicast set got blocked - try it now
- */
-
- if(lp->mc_reload_wait)
- {
- mc32_reset_multicast_list(dev);
- }
-
- return ret;
-}
-
-
-/**
- * mc32_start_transceiver - tell board to restart tx/rx
- * @dev: The 3c527 card to issue the command to
- *
- * This may be called from the interrupt state, where it is used
- * to restart the rx ring if the card runs out of rx buffers.
- *
- * We must first check if it's ok to (re)start the transceiver. See
- * mc32_close for details.
- */
-
-static void mc32_start_transceiver(struct net_device *dev) {
-
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* Ignore RX overflow on device closure */
- if (lp->xceiver_desired_state==HALTED)
- return;
-
- /* Give the card the offset to the post-EOL-bit RX descriptor */
- mc32_ready_poll(dev);
- lp->rx_box->mbox=0;
- lp->rx_box->data[0]=lp->rx_ring[prev_rx(lp->rx_ring_tail)].p->next;
- outb(HOST_CMD_START_RX, ioaddr+HOST_CMD);
-
- mc32_ready_poll(dev);
- lp->tx_box->mbox=0;
- outb(HOST_CMD_RESTRT_TX, ioaddr+HOST_CMD); /* card ignores this on RX restart */
-
- /* We are not interrupted on start completion */
-}
-
-
-/**
- * mc32_halt_transceiver - tell board to stop tx/rx
- * @dev: The 3c527 card to issue the command to
- *
- * We issue the commands to halt the card's transceiver. In fact,
- * after some experimenting we now simply tell the card to
- * suspend. When issuing aborts occasionally odd things happened.
- *
- * We then sleep until the card has notified us that both rx and
- * tx have been suspended.
- */
-
-static void mc32_halt_transceiver(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- mc32_ready_poll(dev);
- lp->rx_box->mbox=0;
- outb(HOST_CMD_SUSPND_RX, ioaddr+HOST_CMD);
- wait_for_completion(&lp->xceiver_cmd);
-
- mc32_ready_poll(dev);
- lp->tx_box->mbox=0;
- outb(HOST_CMD_SUSPND_TX, ioaddr+HOST_CMD);
- wait_for_completion(&lp->xceiver_cmd);
-}
-
-
-/**
- * mc32_load_rx_ring - load the ring of receive buffers
- * @dev: 3c527 to build the ring for
- *
- * This initialises the on-card and driver datastructures to
- * the point where mc32_start_transceiver() can be called.
- *
- * The card sets up the receive ring for us. We are required to use the
- * ring it provides, although the size of the ring is configurable.
- *
- * We allocate an sk_buff for each ring entry in turn and
- * initialise its house-keeping info. At the same time, we read
- * each 'next' pointer in our rx_ring array. This reduces slow
- * shared-memory reads and makes it easy to access predecessor
- * descriptors.
- *
- * We then set the end-of-list bit for the last entry so that the
- * card will know when it has run out of buffers.
- */
-
-static int mc32_load_rx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int i;
- u16 rx_base;
- volatile struct skb_header *p;
-
- rx_base=lp->rx_chain;
-
- for(i=0; i<RX_RING_LEN; i++) {
- lp->rx_ring[i].skb=alloc_skb(1532, GFP_KERNEL);
- if (lp->rx_ring[i].skb==NULL) {
- for (;i>=0;i--)
- kfree_skb(lp->rx_ring[i].skb);
- return -ENOBUFS;
- }
- skb_reserve(lp->rx_ring[i].skb, 18);
-
- p=isa_bus_to_virt(lp->base+rx_base);
-
- p->control=0;
- p->data=isa_virt_to_bus(lp->rx_ring[i].skb->data);
- p->status=0;
- p->length=1532;
-
- lp->rx_ring[i].p=p;
- rx_base=p->next;
- }
-
- lp->rx_ring[i-1].p->control |= CONTROL_EOL;
-
- lp->rx_ring_tail=0;
-
- return 0;
-}
-
-
-/**
- * mc32_flush_rx_ring - free the ring of receive buffers
- * @lp: Local data of 3c527 to flush the rx ring of
- *
- * Free the buffer for each ring slot. This may be called
- * before mc32_load_rx_ring(), eg. on error in mc32_open().
- * Requires rx skb pointers to point to a valid skb, or NULL.
- */
-
-static void mc32_flush_rx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int i;
-
- for(i=0; i < RX_RING_LEN; i++)
- {
- if (lp->rx_ring[i].skb) {
- dev_kfree_skb(lp->rx_ring[i].skb);
- lp->rx_ring[i].skb = NULL;
- }
- lp->rx_ring[i].p=NULL;
- }
-}
-
-
-/**
- * mc32_load_tx_ring - load transmit ring
- * @dev: The 3c527 card to issue the command to
- *
- * This sets up the host transmit data-structures.
- *
- * First, we obtain from the card it's current position in the tx
- * ring, so that we will know where to begin transmitting
- * packets.
- *
- * Then, we read the 'next' pointers from the on-card tx ring into
- * our tx_ring array to reduce slow shared-mem reads. Finally, we
- * intitalise the tx house keeping variables.
- *
- */
-
-static void mc32_load_tx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- volatile struct skb_header *p;
- int i;
- u16 tx_base;
-
- tx_base=lp->tx_box->data[0];
-
- for(i=0 ; i<TX_RING_LEN ; i++)
- {
- p=isa_bus_to_virt(lp->base+tx_base);
- lp->tx_ring[i].p=p;
- lp->tx_ring[i].skb=NULL;
-
- tx_base=p->next;
- }
-
- /* -1 so that tx_ring_head cannot "lap" tx_ring_tail */
- /* see mc32_tx_ring */
-
- atomic_set(&lp->tx_count, TX_RING_LEN-1);
- atomic_set(&lp->tx_ring_head, 0);
- lp->tx_ring_tail=0;
-}
-
-
-/**
- * mc32_flush_tx_ring - free transmit ring
- * @lp: Local data of 3c527 to flush the tx ring of
- *
- * If the ring is non-empty, zip over the it, freeing any
- * allocated skb_buffs. The tx ring house-keeping variables are
- * then reset. Requires rx skb pointers to point to a valid skb,
- * or NULL.
- */
-
-static void mc32_flush_tx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int i;
-
- for (i=0; i < TX_RING_LEN; i++)
- {
- if (lp->tx_ring[i].skb)
- {
- dev_kfree_skb(lp->tx_ring[i].skb);
- lp->tx_ring[i].skb = NULL;
- }
- }
-
- atomic_set(&lp->tx_count, 0);
- atomic_set(&lp->tx_ring_head, 0);
- lp->tx_ring_tail=0;
-}
-
-
-/**
- * mc32_open - handle 'up' of card
- * @dev: device to open
- *
- * The user is trying to bring the card into ready state. This requires
- * a brief dialogue with the card. Firstly we enable interrupts and then
- * 'indications'. Without these enabled the card doesn't bother telling
- * us what it has done. This had me puzzled for a week.
- *
- * We configure the number of card descriptors, then load the network
- * address and multicast filters. Turn on the workaround mode. This
- * works around a bug in the 82586 - it asks the firmware to do
- * so. It has a performance (latency) hit but is needed on busy
- * [read most] lans. We load the ring with buffers then we kick it
- * all off.
- */
-
-static int mc32_open(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- struct mc32_local *lp = netdev_priv(dev);
- u8 one=1;
- u8 regs;
- u16 descnumbuffs[2] = {TX_RING_LEN, RX_RING_LEN};
-
- /*
- * Interrupts enabled
- */
-
- regs=inb(ioaddr+HOST_CTRL);
- regs|=HOST_CTRL_INTE;
- outb(regs, ioaddr+HOST_CTRL);
-
- /*
- * Allow ourselves to issue commands
- */
-
- up(&lp->cmd_mutex);
-
-
- /*
- * Send the indications on command
- */
-
- mc32_command(dev, 4, &one, 2);
-
- /*
- * Poke it to make sure it's really dead.
- */
-
- mc32_halt_transceiver(dev);
- mc32_flush_tx_ring(dev);
-
- /*
- * Ask card to set up on-card descriptors to our spec
- */
-
- if(mc32_command(dev, 8, descnumbuffs, 4)) {
- pr_info("%s: %s rejected our buffer configuration!\n",
- dev->name, cardname);
- mc32_close(dev);
- return -ENOBUFS;
- }
-
- /* Report new configuration */
- mc32_command(dev, 6, NULL, 0);
-
- lp->tx_chain = lp->exec_box->data[8]; /* Transmit list start offset */
- lp->rx_chain = lp->exec_box->data[10]; /* Receive list start offset */
- lp->tx_len = lp->exec_box->data[9]; /* Transmit list count */
- lp->rx_len = lp->exec_box->data[11]; /* Receive list count */
-
- /* Set Network Address */
- mc32_command(dev, 1, dev->dev_addr, 6);
-
- /* Set the filters */
- mc32_set_multicast_list(dev);
-
- if (WORKAROUND_82586) {
- u16 zero_word=0;
- mc32_command(dev, 0x0D, &zero_word, 2); /* 82586 bug workaround on */
- }
-
- mc32_load_tx_ring(dev);
-
- if(mc32_load_rx_ring(dev))
- {
- mc32_close(dev);
- return -ENOBUFS;
- }
-
- lp->xceiver_desired_state = RUNNING;
-
- /* And finally, set the ball rolling... */
- mc32_start_transceiver(dev);
-
- netif_start_queue(dev);
-
- return 0;
-}
-
-
-/**
- * mc32_timeout - handle a timeout from the network layer
- * @dev: 3c527 that timed out
- *
- * Handle a timeout on transmit from the 3c527. This normally means
- * bad things as the hardware handles cable timeouts and mess for
- * us.
- *
- */
-
-static void mc32_timeout(struct net_device *dev)
-{
- pr_warning("%s: transmit timed out?\n", dev->name);
- /* Try to restart the adaptor. */
- netif_wake_queue(dev);
-}
-
-
-/**
- * mc32_send_packet - queue a frame for transmit
- * @skb: buffer to transmit
- * @dev: 3c527 to send it out of
- *
- * Transmit a buffer. This normally means throwing the buffer onto
- * the transmit queue as the queue is quite large. If the queue is
- * full then we set tx_busy and return. Once the interrupt handler
- * gets messages telling it to reclaim transmit queue entries, we will
- * clear tx_busy and the kernel will start calling this again.
- *
- * We do not disable interrupts or acquire any locks; this can
- * run concurrently with mc32_tx_ring(), and the function itself
- * is serialised at a higher layer. However, similarly for the
- * card itself, we must ensure that we update tx_ring_head only
- * after we've established a valid packet on the tx ring (and
- * before we let the card "see" it, to prevent it racing with the
- * irq handler).
- *
- */
-
-static netdev_tx_t mc32_send_packet(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- u32 head = atomic_read(&lp->tx_ring_head);
-
- volatile struct skb_header *p, *np;
-
- netif_stop_queue(dev);
-
- if(atomic_read(&lp->tx_count)==0) {
- return NETDEV_TX_BUSY;
- }
-
- if (skb_padto(skb, ETH_ZLEN)) {
- netif_wake_queue(dev);
- return NETDEV_TX_OK;
- }
-
- atomic_dec(&lp->tx_count);
-
- /* P is the last sending/sent buffer as a pointer */
- p=lp->tx_ring[head].p;
-
- head = next_tx(head);
-
- /* NP is the buffer we will be loading */
- np=lp->tx_ring[head].p;
-
- /* We will need this to flush the buffer out */
- lp->tx_ring[head].skb=skb;
-
- np->length = unlikely(skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
- np->data = isa_virt_to_bus(skb->data);
- np->status = 0;
- np->control = CONTROL_EOP | CONTROL_EOL;
- wmb();
-
- /*
- * The new frame has been setup; we can now
- * let the interrupt handler and card "see" it
- */
-
- atomic_set(&lp->tx_ring_head, head);
- p->control &= ~CONTROL_EOL;
-
- netif_wake_queue(dev);
- return NETDEV_TX_OK;
-}
-
-
-/**
- * mc32_update_stats - pull off the on board statistics
- * @dev: 3c527 to service
- *
- *
- * Query and reset the on-card stats. There's the small possibility
- * of a race here, which would result in an underestimation of
- * actual errors. As such, we'd prefer to keep all our stats
- * collection in software. As a rule, we do. However it can't be
- * used for rx errors and collisions as, by default, the card discards
- * bad rx packets.
- *
- * Setting the SAV BP in the rx filter command supposedly
- * stops this behaviour. However, testing shows that it only seems to
- * enable the collation of on-card rx statistics --- the driver
- * never sees an RX descriptor with an error status set.
- *
- */
-
-static void mc32_update_stats(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- volatile struct mc32_stats *st = lp->stats;
-
- u32 rx_errors=0;
-
- rx_errors+=dev->stats.rx_crc_errors +=st->rx_crc_errors;
- st->rx_crc_errors=0;
- rx_errors+=dev->stats.rx_fifo_errors +=st->rx_overrun_errors;
- st->rx_overrun_errors=0;
- rx_errors+=dev->stats.rx_frame_errors +=st->rx_alignment_errors;
- st->rx_alignment_errors=0;
- rx_errors+=dev->stats.rx_length_errors+=st->rx_tooshort_errors;
- st->rx_tooshort_errors=0;
- rx_errors+=dev->stats.rx_missed_errors+=st->rx_outofresource_errors;
- st->rx_outofresource_errors=0;
- dev->stats.rx_errors=rx_errors;
-
- /* Number of packets which saw one collision */
- dev->stats.collisions+=st->dataC[10];
- st->dataC[10]=0;
-
- /* Number of packets which saw 2--15 collisions */
- dev->stats.collisions+=st->dataC[11];
- st->dataC[11]=0;
-}
-
-
-/**
- * mc32_rx_ring - process the receive ring
- * @dev: 3c527 that needs its receive ring processing
- *
- *
- * We have received one or more indications from the card that a
- * receive has completed. The buffer ring thus contains dirty
- * entries. We walk the ring by iterating over the circular rx_ring
- * array, starting at the next dirty buffer (which happens to be the
- * one we finished up at last time around).
- *
- * For each completed packet, we will either copy it and pass it up
- * the stack or, if the packet is near MTU sized, we allocate
- * another buffer and flip the old one up the stack.
- *
- * We must succeed in keeping a buffer on the ring. If necessary we
- * will toss a received packet rather than lose a ring entry. Once
- * the first uncompleted descriptor is found, we move the
- * End-Of-List bit to include the buffers just processed.
- *
- */
-
-static void mc32_rx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- volatile struct skb_header *p;
- u16 rx_ring_tail;
- u16 rx_old_tail;
- int x=0;
-
- rx_old_tail = rx_ring_tail = lp->rx_ring_tail;
-
- do
- {
- p=lp->rx_ring[rx_ring_tail].p;
-
- if(!(p->status & (1<<7))) { /* Not COMPLETED */
- break;
- }
- if(p->status & (1<<6)) /* COMPLETED_OK */
- {
-
- u16 length=p->length;
- struct sk_buff *skb;
- struct sk_buff *newskb;
-
- /* Try to save time by avoiding a copy on big frames */
-
- if ((length > RX_COPYBREAK) &&
- ((newskb = netdev_alloc_skb(dev, 1532)) != NULL))
- {
- skb=lp->rx_ring[rx_ring_tail].skb;
- skb_put(skb, length);
-
- skb_reserve(newskb,18);
- lp->rx_ring[rx_ring_tail].skb=newskb;
- p->data=isa_virt_to_bus(newskb->data);
- }
- else
- {
- skb = netdev_alloc_skb(dev, length + 2);
-
- if(skb==NULL) {
- dev->stats.rx_dropped++;
- goto dropped;
- }
-
- skb_reserve(skb,2);
- memcpy(skb_put(skb, length),
- lp->rx_ring[rx_ring_tail].skb->data, length);
- }
-
- skb->protocol=eth_type_trans(skb,dev);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += length;
- netif_rx(skb);
- }
-
- dropped:
- p->length = 1532;
- p->status = 0;
-
- rx_ring_tail=next_rx(rx_ring_tail);
- }
- while(x++<48);
-
- /* If there was actually a frame to be processed, place the EOL bit */
- /* at the descriptor prior to the one to be filled next */
-
- if (rx_ring_tail != rx_old_tail)
- {
- lp->rx_ring[prev_rx(rx_ring_tail)].p->control |= CONTROL_EOL;
- lp->rx_ring[prev_rx(rx_old_tail)].p->control &= ~CONTROL_EOL;
-
- lp->rx_ring_tail=rx_ring_tail;
- }
-}
-
-
-/**
- * mc32_tx_ring - process completed transmits
- * @dev: 3c527 that needs its transmit ring processing
- *
- *
- * This operates in a similar fashion to mc32_rx_ring. We iterate
- * over the transmit ring. For each descriptor which has been
- * processed by the card, we free its associated buffer and note
- * any errors. This continues until the transmit ring is emptied
- * or we reach a descriptor that hasn't yet been processed by the
- * card.
- *
- */
-
-static void mc32_tx_ring(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- volatile struct skb_header *np;
-
- /*
- * We rely on head==tail to mean 'queue empty'.
- * This is why lp->tx_count=TX_RING_LEN-1: in order to prevent
- * tx_ring_head wrapping to tail and confusing a 'queue empty'
- * condition with 'queue full'
- */
-
- while (lp->tx_ring_tail != atomic_read(&lp->tx_ring_head))
- {
- u16 t;
-
- t=next_tx(lp->tx_ring_tail);
- np=lp->tx_ring[t].p;
-
- if(!(np->status & (1<<7)))
- {
- /* Not COMPLETED */
- break;
- }
- dev->stats.tx_packets++;
- if(!(np->status & (1<<6))) /* Not COMPLETED_OK */
- {
- dev->stats.tx_errors++;
-
- switch(np->status&0x0F)
- {
- case 1:
- dev->stats.tx_aborted_errors++;
- break; /* Max collisions */
- case 2:
- dev->stats.tx_fifo_errors++;
- break;
- case 3:
- dev->stats.tx_carrier_errors++;
- break;
- case 4:
- dev->stats.tx_window_errors++;
- break; /* CTS Lost */
- case 5:
- dev->stats.tx_aborted_errors++;
- break; /* Transmit timeout */
- }
- }
- /* Packets are sent in order - this is
- basically a FIFO queue of buffers matching
- the card ring */
- dev->stats.tx_bytes+=lp->tx_ring[t].skb->len;
- dev_kfree_skb_irq(lp->tx_ring[t].skb);
- lp->tx_ring[t].skb=NULL;
- atomic_inc(&lp->tx_count);
- netif_wake_queue(dev);
-
- lp->tx_ring_tail=t;
- }
-
-}
-
-
-/**
- * mc32_interrupt - handle an interrupt from a 3c527
- * @irq: Interrupt number
- * @dev_id: 3c527 that requires servicing
- * @regs: Registers (unused)
- *
- *
- * An interrupt is raised whenever the 3c527 writes to the command
- * register. This register contains the message it wishes to send us
- * packed into a single byte field. We keep reading status entries
- * until we have processed all the control items, but simply count
- * transmit and receive reports. When all reports are in we empty the
- * transceiver rings as appropriate. This saves the overhead of
- * multiple command requests.
- *
- * Because MCA is level-triggered, we shouldn't miss indications.
- * Therefore, we needn't ask the card to suspend interrupts within
- * this handler. The card receives an implicit acknowledgment of the
- * current interrupt when we read the command register.
- *
- */
-
-static irqreturn_t mc32_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct mc32_local *lp;
- int ioaddr, status, boguscount = 0;
- int rx_event = 0;
- int tx_event = 0;
-
- ioaddr = dev->base_addr;
- lp = netdev_priv(dev);
-
- /* See whats cooking */
-
- while((inb(ioaddr+HOST_STATUS)&HOST_STATUS_CWR) && boguscount++<2000)
- {
- status=inb(ioaddr+HOST_CMD);
-
- pr_debug("Status TX%d RX%d EX%d OV%d BC%d\n",
- (status&7), (status>>3)&7, (status>>6)&1,
- (status>>7)&1, boguscount);
-
- switch(status&7)
- {
- case 0:
- break;
- case 6: /* TX fail */
- case 2: /* TX ok */
- tx_event = 1;
- break;
- case 3: /* Halt */
- case 4: /* Abort */
- complete(&lp->xceiver_cmd);
- break;
- default:
- pr_notice("%s: strange tx ack %d\n", dev->name, status&7);
- }
- status>>=3;
- switch(status&7)
- {
- case 0:
- break;
- case 2: /* RX */
- rx_event=1;
- break;
- case 3: /* Halt */
- case 4: /* Abort */
- complete(&lp->xceiver_cmd);
- break;
- case 6:
- /* Out of RX buffers stat */
- /* Must restart rx */
- dev->stats.rx_dropped++;
- mc32_rx_ring(dev);
- mc32_start_transceiver(dev);
- break;
- default:
- pr_notice("%s: strange rx ack %d\n",
- dev->name, status&7);
- }
- status>>=3;
- if(status&1)
- {
- /*
- * No thread is waiting: we need to tidy
- * up ourself.
- */
-
- if (lp->cmd_nonblocking) {
- up(&lp->cmd_mutex);
- if (lp->mc_reload_wait)
- mc32_reset_multicast_list(dev);
- }
- else complete(&lp->execution_cmd);
- }
- if(status&2)
- {
- /*
- * We get interrupted once per
- * counter that is about to overflow.
- */
-
- mc32_update_stats(dev);
- }
- }
-
-
- /*
- * Process the transmit and receive rings
- */
-
- if(tx_event)
- mc32_tx_ring(dev);
-
- if(rx_event)
- mc32_rx_ring(dev);
-
- return IRQ_HANDLED;
-}
-
-
-/**
- * mc32_close - user configuring the 3c527 down
- * @dev: 3c527 card to shut down
- *
- * The 3c527 is a bus mastering device. We must be careful how we
- * shut it down. It may also be running shared interrupt so we have
- * to be sure to silence it properly
- *
- * We indicate that the card is closing to the rest of the
- * driver. Otherwise, it is possible that the card may run out
- * of receive buffers and restart the transceiver while we're
- * trying to close it.
- *
- * We abort any receive and transmits going on and then wait until
- * any pending exec commands have completed in other code threads.
- * In theory we can't get here while that is true, in practice I am
- * paranoid
- *
- * We turn off the interrupt enable for the board to be sure it can't
- * intefere with other devices.
- */
-
-static int mc32_close(struct net_device *dev)
-{
- struct mc32_local *lp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- u8 regs;
- u16 one=1;
-
- lp->xceiver_desired_state = HALTED;
- netif_stop_queue(dev);
-
- /*
- * Send the indications on command (handy debug check)
- */
-
- mc32_command(dev, 4, &one, 2);
-
- /* Shut down the transceiver */
-
- mc32_halt_transceiver(dev);
-
- /* Ensure we issue no more commands beyond this point */
-
- down(&lp->cmd_mutex);
-
- /* Ok the card is now stopping */
-
- regs=inb(ioaddr+HOST_CTRL);
- regs&=~HOST_CTRL_INTE;
- outb(regs, ioaddr+HOST_CTRL);
-
- mc32_flush_rx_ring(dev);
- mc32_flush_tx_ring(dev);
-
- mc32_update_stats(dev);
-
- return 0;
-}
-
-
-/**
- * mc32_get_stats - hand back stats to network layer
- * @dev: The 3c527 card to handle
- *
- * We've collected all the stats we can in software already. Now
- * it's time to update those kept on-card and return the lot.
- *
- */
-
-static struct net_device_stats *mc32_get_stats(struct net_device *dev)
-{
- mc32_update_stats(dev);
- return &dev->stats;
-}
-
-
-/**
- * do_mc32_set_multicast_list - attempt to update multicasts
- * @dev: 3c527 device to load the list on
- * @retry: indicates this is not the first call.
- *
- *
- * Actually set or clear the multicast filter for this adaptor. The
- * locking issues are handled by this routine. We have to track
- * state as it may take multiple calls to get the command sequence
- * completed. We just keep trying to schedule the loads until we
- * manage to process them all.
- *
- * num_addrs == -1 Promiscuous mode, receive all packets
- *
- * num_addrs == 0 Normal mode, clear multicast list
- *
- * num_addrs > 0 Multicast mode, receive normal and MC packets,
- * and do best-effort filtering.
- *
- * See mc32_update_stats() regards setting the SAV BP bit.
- *
- */
-
-static void do_mc32_set_multicast_list(struct net_device *dev, int retry)
-{
- struct mc32_local *lp = netdev_priv(dev);
- u16 filt = (1<<2); /* Save Bad Packets, for stats purposes */
-
- if ((dev->flags&IFF_PROMISC) ||
- (dev->flags&IFF_ALLMULTI) ||
- netdev_mc_count(dev) > 10)
- /* Enable promiscuous mode */
- filt |= 1;
- else if (!netdev_mc_empty(dev))
- {
- unsigned char block[62];
- unsigned char *bp;
- struct netdev_hw_addr *ha;
-
- if(retry==0)
- lp->mc_list_valid = 0;
- if(!lp->mc_list_valid)
- {
- block[1]=0;
- block[0]=netdev_mc_count(dev);
- bp=block+2;
-
- netdev_for_each_mc_addr(ha, dev) {
- memcpy(bp, ha->addr, 6);
- bp+=6;
- }
- if(mc32_command_nowait(dev, 2, block,
- 2+6*netdev_mc_count(dev))==-1)
- {
- lp->mc_reload_wait = 1;
- return;
- }
- lp->mc_list_valid=1;
- }
- }
-
- if(mc32_command_nowait(dev, 0, &filt, 2)==-1)
- {
- lp->mc_reload_wait = 1;
- }
- else {
- lp->mc_reload_wait = 0;
- }
-}
-
-
-/**
- * mc32_set_multicast_list - queue multicast list update
- * @dev: The 3c527 to use
- *
- * Commence loading the multicast list. This is called when the kernel
- * changes the lists. It will override any pending list we are trying to
- * load.
- */
-
-static void mc32_set_multicast_list(struct net_device *dev)
-{
- do_mc32_set_multicast_list(dev,0);
-}
-
-
-/**
- * mc32_reset_multicast_list - reset multicast list
- * @dev: The 3c527 to use
- *
- * Attempt the next step in loading the multicast lists. If this attempt
- * fails to complete then it will be scheduled and this function called
- * again later from elsewhere.
- */
-
-static void mc32_reset_multicast_list(struct net_device *dev)
-{
- do_mc32_set_multicast_list(dev,1);
-}
-
-static void netdev_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- strcpy(info->driver, DRV_NAME);
- strcpy(info->version, DRV_VERSION);
- sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
- return mc32_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
- mc32_debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
- .get_msglevel = netdev_get_msglevel,
- .set_msglevel = netdev_set_msglevel,
-};
-
-#ifdef MODULE
-
-static struct net_device *this_device;
-
-/**
- * init_module - entry point
- *
- * Probe and locate a 3c527 card. This really should probe and locate
- * all the 3c527 cards in the machine not just one of them. Yes you can
- * insmod multiple modules for now but it's a hack.
- */
-
-int __init init_module(void)
-{
- this_device = mc32_probe(-1);
- if (IS_ERR(this_device))
- return PTR_ERR(this_device);
- return 0;
-}
-
-/**
- * cleanup_module - free resources for an unload
- *
- * Unloading time. We release the MCA bus resources and the interrupt
- * at which point everything is ready to unload. The card must be stopped
- * at this point or we would not have been called. When we unload we
- * leave the card stopped but not totally shut down. When the card is
- * initialized it must be rebooted or the rings reloaded before any
- * transmit operations are allowed to start scribbling into memory.
- */
-
-void __exit cleanup_module(void)
-{
- unregister_netdev(this_device);
- cleanup_card(this_device);
- free_netdev(this_device);
-}
-
-#endif /* MODULE */
diff --git a/drivers/net/ethernet/i825xx/3c527.h b/drivers/net/ethernet/i825xx/3c527.h
deleted file mode 100644
index d693b8d15cde..000000000000
--- a/drivers/net/ethernet/i825xx/3c527.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 3COM "EtherLink MC/32" Descriptions
- */
-
-/*
- * Registers
- */
-
-#define HOST_CMD 0
-#define HOST_CMD_START_RX (1<<3)
-#define HOST_CMD_SUSPND_RX (3<<3)
-#define HOST_CMD_RESTRT_RX (5<<3)
-
-#define HOST_CMD_SUSPND_TX 3
-#define HOST_CMD_RESTRT_TX 5
-
-
-#define HOST_STATUS 2
-#define HOST_STATUS_CRR (1<<6)
-#define HOST_STATUS_CWR (1<<5)
-
-
-#define HOST_CTRL 6
-#define HOST_CTRL_ATTN (1<<7)
-#define HOST_CTRL_RESET (1<<6)
-#define HOST_CTRL_INTE (1<<2)
-
-#define HOST_RAMPAGE 8
-
-#define HALTED 0
-#define RUNNING 1
-
-struct mc32_mailbox
-{
- u16 mbox;
- u16 data[1];
-} __packed;
-
-struct skb_header
-{
- u8 status;
- u8 control;
- u16 next; /* Do not change! */
- u16 length;
- u32 data;
-} __packed;
-
-struct mc32_stats
-{
- /* RX Errors */
- u32 rx_crc_errors;
- u32 rx_alignment_errors;
- u32 rx_overrun_errors;
- u32 rx_tooshort_errors;
- u32 rx_toolong_errors;
- u32 rx_outofresource_errors;
-
- u32 rx_discarded; /* via card pattern match filter */
-
- /* TX Errors */
- u32 tx_max_collisions;
- u32 tx_carrier_errors;
- u32 tx_underrun_errors;
- u32 tx_cts_errors;
- u32 tx_timeout_errors;
-
- /* various cruft */
- u32 dataA[6];
- u16 dataB[5];
- u32 dataC[14];
-} __packed;
-
-#define STATUS_MASK 0x0F
-#define COMPLETED (1<<7)
-#define COMPLETED_OK (1<<6)
-#define BUFFER_BUSY (1<<5)
-
-#define CONTROL_EOP (1<<7) /* End Of Packet */
-#define CONTROL_EOL (1<<6) /* End of List */
-
-#define MCA_MC32_ID 0x0041 /* Our MCA ident */
diff --git a/drivers/net/ethernet/i825xx/Kconfig b/drivers/net/ethernet/i825xx/Kconfig
index ca1ae985c6df..fed5080a6b62 100644
--- a/drivers/net/ethernet/i825xx/Kconfig
+++ b/drivers/net/ethernet/i825xx/Kconfig
@@ -43,28 +43,6 @@ config EL16
To compile this driver as a module, choose M here. The module
will be called 3c507.
-config ELMC
- tristate "3c523 \"EtherLink/MC\" support"
- depends on MCA_LEGACY
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c523.
-
-config ELMC_II
- tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)"
- depends on MCA && MCA_LEGACY
- ---help---
- If you have a network (Ethernet) card of this type, say Y and read
- the Ethernet-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here. The module
- will be called 3c527.
-
config ARM_ETHER1
tristate "Acorn Ether1 support"
depends on ARM && ARCH_ACORN
diff --git a/drivers/net/ethernet/i825xx/Makefile b/drivers/net/ethernet/i825xx/Makefile
index f68a3694968a..6adff85e8ecc 100644
--- a/drivers/net/ethernet/i825xx/Makefile
+++ b/drivers/net/ethernet/i825xx/Makefile
@@ -7,8 +7,6 @@ obj-$(CONFIG_EEXPRESS) += eexpress.o
obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
obj-$(CONFIG_ELPLUS) += 3c505.o
obj-$(CONFIG_EL16) += 3c507.o
-obj-$(CONFIG_ELMC) += 3c523.o
-obj-$(CONFIG_ELMC_II) += 3c527.o
obj-$(CONFIG_LP486E) += lp486e.o
obj-$(CONFIG_NI52) += ni52.o
obj-$(CONFIG_SUN3_82586) += sun3_82586.o
diff --git a/drivers/net/ethernet/i825xx/eexpress.c b/drivers/net/ethernet/i825xx/eexpress.c
index cc2e66ad4436..7a6a2f04c5b1 100644
--- a/drivers/net/ethernet/i825xx/eexpress.c
+++ b/drivers/net/ethernet/i825xx/eexpress.c
@@ -9,7 +9,7 @@
* Many modifications, and currently maintained, by
* Philip Blundell <philb@gnu.org>
* Added the Compaq LTE Alan Cox <alan@lxorguk.ukuu.org.uk>
- * Added MCA support Adam Fritzler
+ * Added MCA support Adam Fritzler (now deleted)
*
* Note - this driver is experimental still - it has problems on faster
* machines. Someone needs to sit down and go through it line by line with
@@ -111,7 +111,6 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include <linux/mca-legacy.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
@@ -227,16 +226,6 @@ static unsigned short start_code[] = {
/* maps irq number to EtherExpress magic value */
static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 };
-#ifdef CONFIG_MCA_LEGACY
-/* mapping of the first four bits of the second POS register */
-static unsigned short mca_iomap[] = {
- 0x270, 0x260, 0x250, 0x240, 0x230, 0x220, 0x210, 0x200,
- 0x370, 0x360, 0x350, 0x340, 0x330, 0x320, 0x310, 0x300
-};
-/* bits 5-7 of the second POS register */
-static char mca_irqmap[] = { 12, 9, 3, 4, 5, 10, 11, 15 };
-#endif
-
/*
* Prototypes for Linux interface
*/
@@ -340,53 +329,6 @@ static int __init do_express_probe(struct net_device *dev)
dev->if_port = 0xff; /* not set */
-#ifdef CONFIG_MCA_LEGACY
- if (MCA_bus) {
- int slot = 0;
-
- /*
- * Only find one card at a time. Subsequent calls
- * will find others, however, proper multicard MCA
- * probing and setup can't be done with the
- * old-style Space.c init routines. -- ASF
- */
- while (slot != MCA_NOTFOUND) {
- int pos0, pos1;
-
- slot = mca_find_unused_adapter(0x628B, slot);
- if (slot == MCA_NOTFOUND)
- break;
-
- pos0 = mca_read_stored_pos(slot, 2);
- pos1 = mca_read_stored_pos(slot, 3);
- ioaddr = mca_iomap[pos1&0xf];
-
- dev->irq = mca_irqmap[(pos1>>4)&0x7];
-
- /*
- * XXX: Transceiver selection is done
- * differently on the MCA version.
- * How to get it to select something
- * other than external/AUI is currently
- * unknown. This code is just for looks. -- ASF
- */
- if ((pos0 & 0x7) == 0x1)
- dev->if_port = AUI;
- else if ((pos0 & 0x7) == 0x5) {
- if (pos1 & 0x80)
- dev->if_port = BNC;
- else
- dev->if_port = TPE;
- }
-
- mca_set_adapter_name(slot, "Intel EtherExpress 16 MCA");
- mca_set_adapter_procfn(slot, NULL, dev);
- mca_mark_as_used(slot);
-
- break;
- }
- }
-#endif
if (ioaddr&0xfe00) {
if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress"))
return -EBUSY;
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c
index c9069a28832b..f4d2da0db1b1 100644
--- a/drivers/net/ethernet/ibm/ehea/ehea_main.c
+++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c
@@ -3335,6 +3335,8 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev,
goto out_shutdown_ports;
}
+ /* Handle any events that might be pending. */
+ tasklet_hi_schedule(&adapter->neq_tasklet);
ret = 0;
goto out;
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
index 546efe30c9b8..79b07ec6726f 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -220,6 +220,17 @@ config IXGBE_DCB
If unsure, say N.
+config IXGBE_PTP
+ bool "PTP Clock Support"
+ default n
+ depends on IXGBE && PTP_1588_CLOCK
+ ---help---
+ Say Y here if you want support for 1588 Timestamping with a
+ PHC device, using the PTP 1588 Clock support. This is
+ required to enable timestamping support for the device.
+
+ If unsure, say N.
+
config IXGBEVF
tristate "Intel(R) 82599 Virtual Function Ethernet support"
depends on PCI_MSI
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c
index f1aef68e1e83..95731c841044 100644
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
@@ -493,7 +493,11 @@ out:
static void e1000_down_and_stop(struct e1000_adapter *adapter)
{
set_bit(__E1000_DOWN, &adapter->flags);
- cancel_work_sync(&adapter->reset_task);
+
+ /* Only kill reset task if adapter is not resetting */
+ if (!test_bit(__E1000_RESETTING, &adapter->flags))
+ cancel_work_sync(&adapter->reset_task);
+
cancel_delayed_work_sync(&adapter->watchdog_task);
cancel_delayed_work_sync(&adapter->phy_info_task);
cancel_delayed_work_sync(&adapter->fifo_stall_task);
@@ -4066,7 +4070,11 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
/* errors is only valid for DD + EOP descriptors */
if (unlikely((status & E1000_RXD_STAT_EOP) &&
(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
- u8 last_byte = *(skb->data + length - 1);
+ u8 *mapped;
+ u8 last_byte;
+
+ mapped = page_address(buffer_info->page);
+ last_byte = *(mapped + length - 1);
if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
last_byte)) {
spin_lock_irqsave(&adapter->stats_lock,
@@ -4391,30 +4399,6 @@ e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
break;
}
- /* Fix for errata 23, can't cross 64kB boundary */
- if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
- struct sk_buff *oldskb = skb;
- e_err(rx_err, "skb align check failed: %u bytes at "
- "%p\n", bufsz, skb->data);
- /* Try again, without freeing the previous */
- skb = netdev_alloc_skb_ip_align(netdev, bufsz);
- /* Failed allocation, critical failure */
- if (!skb) {
- dev_kfree_skb(oldskb);
- adapter->alloc_rx_buff_failed++;
- break;
- }
-
- if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
- /* give up */
- dev_kfree_skb(skb);
- dev_kfree_skb(oldskb);
- break; /* while (cleaned_count--) */
- }
-
- /* Use new allocation */
- dev_kfree_skb(oldskb);
- }
buffer_info->skb = skb;
buffer_info->length = adapter->rx_buffer_len;
check_page:
diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h
index 11c46661af09..351a4097b2ba 100644
--- a/drivers/net/ethernet/intel/e1000e/defines.h
+++ b/drivers/net/ethernet/intel/e1000e/defines.h
@@ -76,7 +76,7 @@
/* Extended Device Control */
#define E1000_CTRL_EXT_LPCD 0x00000004 /* LCD Power Cycle Done */
#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */
-#define E1000_CTRL_EXT_FORCE_SMBUS 0x00000004 /* Force SMBus mode*/
+#define E1000_CTRL_EXT_FORCE_SMBUS 0x00000800 /* Force SMBus mode */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c
index 42444d14aae6..55cc1565bc2f 100644
--- a/drivers/net/ethernet/intel/e1000e/param.c
+++ b/drivers/net/ethernet/intel/e1000e/param.c
@@ -344,50 +344,16 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
if (num_InterruptThrottleRate > bd) {
adapter->itr = InterruptThrottleRate[bd];
- switch (adapter->itr) {
- case 0:
- e_info("%s turned off\n", opt.name);
- break;
- case 1:
- e_info("%s set to dynamic mode\n", opt.name);
- adapter->itr_setting = adapter->itr;
- adapter->itr = 20000;
- break;
- case 3:
- e_info("%s set to dynamic conservative mode\n",
- opt.name);
- adapter->itr_setting = adapter->itr;
- adapter->itr = 20000;
- break;
- case 4:
- e_info("%s set to simplified (2000-8000 ints) mode\n",
- opt.name);
- adapter->itr_setting = 4;
- break;
- default:
- /*
- * Save the setting, because the dynamic bits
- * change itr.
- */
- if (e1000_validate_option(&adapter->itr, &opt,
- adapter) &&
- (adapter->itr == 3)) {
- /*
- * In case of invalid user value,
- * default to conservative mode.
- */
- adapter->itr_setting = adapter->itr;
- adapter->itr = 20000;
- } else {
- /*
- * Clear the lower two bits because
- * they are used as control.
- */
- adapter->itr_setting =
- adapter->itr & ~3;
- }
- break;
- }
+
+ /*
+ * Make sure a message is printed for non-special
+ * values. And in case of an invalid option, display
+ * warning, use default and go through itr/itr_setting
+ * adjustment logic below
+ */
+ if ((adapter->itr > 4) &&
+ e1000_validate_option(&adapter->itr, &opt, adapter))
+ adapter->itr = opt.def;
} else {
/*
* If no option specified, use default value and go
@@ -399,7 +365,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
* Make sure a message is printed for non-special
* default values
*/
- if (adapter->itr > 40)
+ if (adapter->itr > 4)
e_info("%s set to default %d\n", opt.name,
adapter->itr);
}
diff --git a/drivers/net/ethernet/intel/igb/Makefile b/drivers/net/ethernet/intel/igb/Makefile
index 4bd16e266414..97c197fd4a8e 100644
--- a/drivers/net/ethernet/intel/igb/Makefile
+++ b/drivers/net/ethernet/intel/igb/Makefile
@@ -33,6 +33,7 @@
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 e1000_mbx.o
+ e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o \
+ e1000_i210.o
igb-$(CONFIG_IGB_PTP) += igb_ptp.o
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index 08bdc33715ee..e65083958421 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -36,6 +36,7 @@
#include "e1000_mac.h"
#include "e1000_82575.h"
+#include "e1000_i210.h"
static s32 igb_get_invariants_82575(struct e1000_hw *);
static s32 igb_acquire_phy_82575(struct e1000_hw *);
@@ -52,6 +53,8 @@ static s32 igb_write_phy_reg_82580(struct e1000_hw *, u32, u16);
static s32 igb_reset_hw_82575(struct e1000_hw *);
static s32 igb_reset_hw_82580(struct e1000_hw *);
static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
+static s32 igb_set_d0_lplu_state_82580(struct e1000_hw *, bool);
+static s32 igb_set_d3_lplu_state_82580(struct e1000_hw *, bool);
static s32 igb_setup_copper_link_82575(struct e1000_hw *);
static s32 igb_setup_serdes_link_82575(struct e1000_hw *);
static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16);
@@ -96,6 +99,8 @@ static bool igb_sgmii_uses_mdio_82575(struct e1000_hw *hw)
break;
case e1000_82580:
case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
reg = rd32(E1000_MDICNFG);
ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
break;
@@ -150,6 +155,17 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
case E1000_DEV_ID_I350_SGMII:
mac->type = e1000_i350;
break;
+ case E1000_DEV_ID_I210_COPPER:
+ case E1000_DEV_ID_I210_COPPER_OEM1:
+ case E1000_DEV_ID_I210_COPPER_IT:
+ case E1000_DEV_ID_I210_FIBER:
+ case E1000_DEV_ID_I210_SERDES:
+ case E1000_DEV_ID_I210_SGMII:
+ mac->type = e1000_i210;
+ break;
+ case E1000_DEV_ID_I211_COPPER:
+ mac->type = e1000_i211;
+ break;
default:
return -E1000_ERR_MAC_INIT;
break;
@@ -182,26 +198,44 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
/* Set mta register count */
mac->mta_reg_count = 128;
/* Set rar entry count */
- mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
- if (mac->type == e1000_82576)
+ switch (mac->type) {
+ case e1000_82576:
mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
- if (mac->type == e1000_82580)
+ break;
+ case e1000_82580:
mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
- if (mac->type == e1000_i350)
+ break;
+ case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
+ break;
+ default:
+ mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
+ break;
+ }
/* reset */
if (mac->type >= e1000_82580)
mac->ops.reset_hw = igb_reset_hw_82580;
else
mac->ops.reset_hw = igb_reset_hw_82575;
+
+ if (mac->type >= e1000_i210) {
+ mac->ops.acquire_swfw_sync = igb_acquire_swfw_sync_i210;
+ mac->ops.release_swfw_sync = igb_release_swfw_sync_i210;
+ } else {
+ mac->ops.acquire_swfw_sync = igb_acquire_swfw_sync_82575;
+ mac->ops.release_swfw_sync = igb_release_swfw_sync_82575;
+ }
+
/* Set if part includes ASF firmware */
mac->asf_firmware_present = true;
/* Set if manageability features are enabled. */
mac->arc_subsystem_valid =
(rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK)
? true : false;
- /* enable EEE on i350 parts */
- if (mac->type == e1000_i350)
+ /* enable EEE on i350 parts and later parts */
+ if (mac->type >= e1000_i350)
dev_spec->eee_disable = false;
else
dev_spec->eee_disable = true;
@@ -213,26 +247,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
/* NVM initialization */
eecd = rd32(E1000_EECD);
-
- nvm->opcode_bits = 8;
- nvm->delay_usec = 1;
- switch (nvm->override) {
- case e1000_nvm_override_spi_large:
- nvm->page_size = 32;
- nvm->address_bits = 16;
- break;
- case e1000_nvm_override_spi_small:
- nvm->page_size = 8;
- nvm->address_bits = 8;
- break;
- default:
- nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
- nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8;
- break;
- }
-
- nvm->type = e1000_nvm_eeprom_spi;
-
size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
E1000_EECD_SIZE_EX_SHIFT);
@@ -242,6 +256,33 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
*/
size += NVM_WORD_SIZE_BASE_SHIFT;
+ nvm->word_size = 1 << size;
+ if (hw->mac.type < e1000_i210) {
+ nvm->opcode_bits = 8;
+ nvm->delay_usec = 1;
+ switch (nvm->override) {
+ case e1000_nvm_override_spi_large:
+ nvm->page_size = 32;
+ nvm->address_bits = 16;
+ break;
+ case e1000_nvm_override_spi_small:
+ nvm->page_size = 8;
+ nvm->address_bits = 8;
+ break;
+ default:
+ nvm->page_size = eecd
+ & E1000_EECD_ADDR_BITS ? 32 : 8;
+ nvm->address_bits = eecd
+ & E1000_EECD_ADDR_BITS ? 16 : 8;
+ break;
+ }
+ if (nvm->word_size == (1 << 15))
+ nvm->page_size = 128;
+
+ nvm->type = e1000_nvm_eeprom_spi;
+ } else
+ nvm->type = e1000_nvm_flash_hw;
+
/*
* Check for invalid size
*/
@@ -249,32 +290,60 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
pr_notice("The NVM size is not valid, defaulting to 32K\n");
size = 15;
}
- nvm->word_size = 1 << size;
- if (nvm->word_size == (1 << 15))
- nvm->page_size = 128;
/* NVM Function Pointers */
- nvm->ops.acquire = igb_acquire_nvm_82575;
- if (nvm->word_size < (1 << 15))
- nvm->ops.read = igb_read_nvm_eerd;
- else
- nvm->ops.read = igb_read_nvm_spi;
-
- nvm->ops.release = igb_release_nvm_82575;
switch (hw->mac.type) {
case e1000_82580:
nvm->ops.validate = igb_validate_nvm_checksum_82580;
nvm->ops.update = igb_update_nvm_checksum_82580;
+ nvm->ops.acquire = igb_acquire_nvm_82575;
+ nvm->ops.release = igb_release_nvm_82575;
+ if (nvm->word_size < (1 << 15))
+ nvm->ops.read = igb_read_nvm_eerd;
+ else
+ nvm->ops.read = igb_read_nvm_spi;
+ nvm->ops.write = igb_write_nvm_spi;
break;
case e1000_i350:
nvm->ops.validate = igb_validate_nvm_checksum_i350;
nvm->ops.update = igb_update_nvm_checksum_i350;
+ nvm->ops.acquire = igb_acquire_nvm_82575;
+ nvm->ops.release = igb_release_nvm_82575;
+ if (nvm->word_size < (1 << 15))
+ nvm->ops.read = igb_read_nvm_eerd;
+ else
+ nvm->ops.read = igb_read_nvm_spi;
+ nvm->ops.write = igb_write_nvm_spi;
+ break;
+ case e1000_i210:
+ nvm->ops.validate = igb_validate_nvm_checksum_i210;
+ nvm->ops.update = igb_update_nvm_checksum_i210;
+ nvm->ops.acquire = igb_acquire_nvm_i210;
+ nvm->ops.release = igb_release_nvm_i210;
+ nvm->ops.read = igb_read_nvm_srrd_i210;
+ nvm->ops.valid_led_default = igb_valid_led_default_i210;
+ break;
+ case e1000_i211:
+ nvm->ops.acquire = igb_acquire_nvm_i210;
+ nvm->ops.release = igb_release_nvm_i210;
+ nvm->ops.read = igb_read_nvm_i211;
+ nvm->ops.valid_led_default = igb_valid_led_default_i210;
+ nvm->ops.validate = NULL;
+ nvm->ops.update = NULL;
+ nvm->ops.write = NULL;
break;
default:
nvm->ops.validate = igb_validate_nvm_checksum;
nvm->ops.update = igb_update_nvm_checksum;
+ nvm->ops.acquire = igb_acquire_nvm_82575;
+ nvm->ops.release = igb_release_nvm_82575;
+ if (nvm->word_size < (1 << 15))
+ nvm->ops.read = igb_read_nvm_eerd;
+ else
+ nvm->ops.read = igb_read_nvm_spi;
+ nvm->ops.write = igb_write_nvm_spi;
+ break;
}
- nvm->ops.write = igb_write_nvm_spi;
/* if part supports SR-IOV then initialize mailbox parameters */
switch (mac->type) {
@@ -312,9 +381,13 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
if (igb_sgmii_active_82575(hw) && !igb_sgmii_uses_mdio_82575(hw)) {
phy->ops.read_reg = igb_read_phy_reg_sgmii_82575;
phy->ops.write_reg = igb_write_phy_reg_sgmii_82575;
- } else if (hw->mac.type >= e1000_82580) {
+ } else if ((hw->mac.type == e1000_82580)
+ || (hw->mac.type == e1000_i350)) {
phy->ops.read_reg = igb_read_phy_reg_82580;
phy->ops.write_reg = igb_write_phy_reg_82580;
+ } else if (hw->phy.type >= e1000_phy_i210) {
+ phy->ops.read_reg = igb_read_phy_reg_gs40g;
+ phy->ops.write_reg = igb_write_phy_reg_gs40g;
} else {
phy->ops.read_reg = igb_read_phy_reg_igp;
phy->ops.write_reg = igb_write_phy_reg_igp;
@@ -343,6 +416,14 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
else
phy->ops.get_cable_length = igb_get_cable_length_m88;
+ if (phy->id == I210_I_PHY_ID) {
+ phy->ops.get_cable_length =
+ igb_get_cable_length_m88_gen2;
+ phy->ops.set_d0_lplu_state =
+ igb_set_d0_lplu_state_82580;
+ phy->ops.set_d3_lplu_state =
+ igb_set_d3_lplu_state_82580;
+ }
phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88;
break;
case IGP03E1000_E_PHY_ID:
@@ -359,6 +440,17 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_82580;
phy->ops.get_cable_length = igb_get_cable_length_82580;
phy->ops.get_phy_info = igb_get_phy_info_82580;
+ phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82580;
+ phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580;
+ break;
+ case I210_I_PHY_ID:
+ phy->type = e1000_phy_i210;
+ phy->ops.get_phy_info = igb_get_phy_info_m88;
+ phy->ops.check_polarity = igb_check_polarity_m88;
+ phy->ops.get_cable_length = igb_get_cable_length_m88_gen2;
+ phy->ops.set_d0_lplu_state = igb_set_d0_lplu_state_82580;
+ phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580;
+ phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88;
break;
default:
return -E1000_ERR_PHY;
@@ -385,7 +477,7 @@ static s32 igb_acquire_phy_82575(struct e1000_hw *hw)
else if (hw->bus.func == E1000_FUNC_3)
mask = E1000_SWFW_PHY3_SM;
- return igb_acquire_swfw_sync_82575(hw, mask);
+ return hw->mac.ops.acquire_swfw_sync(hw, mask);
}
/**
@@ -406,7 +498,7 @@ static void igb_release_phy_82575(struct e1000_hw *hw)
else if (hw->bus.func == E1000_FUNC_3)
mask = E1000_SWFW_PHY3_SM;
- igb_release_swfw_sync_82575(hw, mask);
+ hw->mac.ops.release_swfw_sync(hw, mask);
}
/**
@@ -510,6 +602,8 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
break;
case e1000_82580:
case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
mdic = rd32(E1000_MDICNFG);
mdic &= E1000_MDICNFG_PHY_MASK;
phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
@@ -674,6 +768,96 @@ out:
}
/**
+ * igb_set_d0_lplu_state_82580 - Set Low Power Linkup D0 state
+ * @hw: pointer to the HW structure
+ * @active: true to enable LPLU, false to disable
+ *
+ * Sets the LPLU D0 state according to the active flag. When
+ * activating LPLU this function also disables smart speed
+ * and vice versa. LPLU will not be activated unless the
+ * device autonegotiation advertisement meets standards of
+ * either 10 or 10/100 or 10/100/1000 at all duplexes.
+ * This is a function pointer entry point only called by
+ * PHY setup routines.
+ **/
+static s32 igb_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val = 0;
+ u16 data;
+
+ data = rd32(E1000_82580_PHY_POWER_MGMT);
+
+ if (active) {
+ data |= E1000_82580_PM_D0_LPLU;
+
+ /* When LPLU is enabled, we should disable SmartSpeed */
+ data &= ~E1000_82580_PM_SPD;
+ } else {
+ data &= ~E1000_82580_PM_D0_LPLU;
+
+ /*
+ * LPLU and SmartSpeed are mutually exclusive. LPLU is used
+ * during Dx states where the power conservation is most
+ * important. During driver activity we should enable
+ * SmartSpeed, so performance is maintained.
+ */
+ if (phy->smart_speed == e1000_smart_speed_on)
+ data |= E1000_82580_PM_SPD;
+ else if (phy->smart_speed == e1000_smart_speed_off)
+ data &= ~E1000_82580_PM_SPD; }
+
+ wr32(E1000_82580_PHY_POWER_MGMT, data);
+ return ret_val;
+}
+
+/**
+ * igb_set_d3_lplu_state_82580 - Sets low power link up state for D3
+ * @hw: pointer to the HW structure
+ * @active: boolean used to enable/disable lplu
+ *
+ * Success returns 0, Failure returns 1
+ *
+ * The low power link up (lplu) state is set to the power management level D3
+ * and SmartSpeed is disabled when active is true, else clear lplu for D3
+ * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
+ * is used during Dx states where the power conservation is most important.
+ * During driver activity, SmartSpeed should be enabled so performance is
+ * maintained.
+ **/
+s32 igb_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val = 0;
+ u16 data;
+
+ data = rd32(E1000_82580_PHY_POWER_MGMT);
+
+ if (!active) {
+ data &= ~E1000_82580_PM_D3_LPLU;
+ /*
+ * LPLU and SmartSpeed are mutually exclusive. LPLU is used
+ * during Dx states where the power conservation is most
+ * important. During driver activity we should enable
+ * SmartSpeed, so performance is maintained.
+ */
+ if (phy->smart_speed == e1000_smart_speed_on)
+ data |= E1000_82580_PM_SPD;
+ else if (phy->smart_speed == e1000_smart_speed_off)
+ data &= ~E1000_82580_PM_SPD;
+ } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
+ (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
+ (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
+ data |= E1000_82580_PM_D3_LPLU;
+ /* When LPLU is enabled, we should disable SmartSpeed */
+ data &= ~E1000_82580_PM_SPD;
+ }
+
+ wr32(E1000_82580_PHY_POWER_MGMT, data);
+ return ret_val;
+}
+
+/**
* igb_acquire_nvm_82575 - Request for access to EEPROM
* @hw: pointer to the HW structure
*
@@ -686,14 +870,14 @@ static s32 igb_acquire_nvm_82575(struct e1000_hw *hw)
{
s32 ret_val;
- ret_val = igb_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw, E1000_SWFW_EEP_SM);
if (ret_val)
goto out;
ret_val = igb_acquire_nvm(hw);
if (ret_val)
- igb_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
+ hw->mac.ops.release_swfw_sync(hw, E1000_SWFW_EEP_SM);
out:
return ret_val;
@@ -709,7 +893,7 @@ out:
static void igb_release_nvm_82575(struct e1000_hw *hw)
{
igb_release_nvm(hw);
- igb_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
+ hw->mac.ops.release_swfw_sync(hw, E1000_SWFW_EEP_SM);
}
/**
@@ -1080,7 +1264,6 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
* is no link.
*/
igb_clear_hw_cntrs_82575(hw);
-
return ret_val;
}
@@ -1117,6 +1300,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
}
}
switch (hw->phy.type) {
+ case e1000_phy_i210:
case e1000_phy_m88:
if (hw->phy.id == I347AT4_E_PHY_ID ||
hw->phy.id == M88E1112_E_PHY_ID)
@@ -1757,7 +1941,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw)
/* Determine whether or not a global dev reset is requested */
if (global_device_reset &&
- igb_acquire_swfw_sync_82575(hw, swmbsw_mask))
+ hw->mac.ops.acquire_swfw_sync(hw, swmbsw_mask))
global_device_reset = false;
if (global_device_reset &&
@@ -1803,7 +1987,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw)
/* Release semaphore */
if (global_device_reset)
- igb_release_swfw_sync_82575(hw, swmbsw_mask);
+ hw->mac.ops.release_swfw_sync(hw, swmbsw_mask);
return ret_val;
}
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.h b/drivers/net/ethernet/intel/igb/e1000_82575.h
index b927d79ab536..e85c453f5428 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.h
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.h
@@ -55,10 +55,11 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
#define E1000_SRRCTL_DROP_EN 0x80000000
#define E1000_SRRCTL_TIMESTAMP 0x40000000
+
#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002
#define E1000_MRQC_ENABLE_VMDQ 0x00000003
-#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005
#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
+#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index 89eb1f85b9fa..ec7e4fe3e3ee 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -301,6 +301,8 @@
* transactions */
#define E1000_DMACR_DMAC_LX_SHIFT 28
#define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */
+/* DMA Coalescing BMC-to-OS Watchdog Enable */
+#define E1000_DMACR_DC_BMC2OSW_EN 0x00008000
#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit
* Threshold */
@@ -458,6 +460,7 @@
#define E1000_ERR_INVALID_ARGUMENT 16
#define E1000_ERR_NO_SPACE 17
#define E1000_ERR_NVM_PBA_SECTION 18
+#define E1000_ERR_INVM_VALUE_NOT_FOUND 19
/* Loop limit on how long we wait for auto-negotiation to complete */
#define COPPER_LINK_UP_LIMIT 10
@@ -595,6 +598,25 @@
#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
+#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */
+#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/
+#define E1000_FLUDONE_ATTEMPTS 20000
+#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */
+#define E1000_I210_FIFO_SEL_RX 0x00
+#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i))
+#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0)
+#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06
+#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01
+#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */
+#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done*/
+#define E1000_FLUDONE_ATTEMPTS 20000
+#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */
+#define E1000_I210_FIFO_SEL_RX 0x00
+#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i))
+#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0)
+#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06
+#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01
+
/* Offset to data in NVM read/write registers */
#define E1000_NVM_RW_REG_DATA 16
@@ -613,6 +635,16 @@
#define NVM_CHECKSUM_REG 0x003F
#define NVM_COMPATIBILITY_REG_3 0x0003
#define NVM_COMPATIBILITY_BIT_MASK 0x8000
+#define NVM_MAC_ADDR 0x0000
+#define NVM_SUB_DEV_ID 0x000B
+#define NVM_SUB_VEN_ID 0x000C
+#define NVM_DEV_ID 0x000D
+#define NVM_VEN_ID 0x000E
+#define NVM_INIT_CTRL_2 0x000F
+#define NVM_INIT_CTRL_4 0x0013
+#define NVM_LED_1_CFG 0x001C
+#define NVM_LED_0_2_CFG 0x001F
+
#define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */
#define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */
@@ -639,6 +671,7 @@
#define NVM_PBA_OFFSET_0 8
#define NVM_PBA_OFFSET_1 9
+#define NVM_RESERVED_WORD 0xFFFF
#define NVM_PBA_PTR_GUARD 0xFAFA
#define NVM_WORD_SIZE_BASE_SHIFT 6
@@ -696,6 +729,7 @@
#define I82580_I_PHY_ID 0x015403A0
#define I350_I_PHY_ID 0x015403B0
#define M88_VENDOR 0x0141
+#define I210_I_PHY_ID 0x01410C00
/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
@@ -815,6 +849,7 @@
#define E1000_IPCNFG_EEE_100M_AN 0x00000004 /* EEE Enable 100M AN */
#define E1000_EEER_TX_LPI_EN 0x00010000 /* EEE Tx LPI Enable */
#define E1000_EEER_RX_LPI_EN 0x00020000 /* EEE Rx LPI Enable */
+#define E1000_EEER_FRC_AN 0x10000000 /* Enable EEE in loopback */
#define E1000_EEER_LPI_FC 0x00040000 /* EEE Enable on FC */
/* SerDes Control */
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
index f67cbd3fa307..c2a51dcda550 100644
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -63,6 +63,13 @@ struct e1000_hw;
#define E1000_DEV_ID_I350_FIBER 0x1522
#define E1000_DEV_ID_I350_SERDES 0x1523
#define E1000_DEV_ID_I350_SGMII 0x1524
+#define E1000_DEV_ID_I210_COPPER 0x1533
+#define E1000_DEV_ID_I210_COPPER_OEM1 0x1534
+#define E1000_DEV_ID_I210_COPPER_IT 0x1535
+#define E1000_DEV_ID_I210_FIBER 0x1536
+#define E1000_DEV_ID_I210_SERDES 0x1537
+#define E1000_DEV_ID_I210_SGMII 0x1538
+#define E1000_DEV_ID_I211_COPPER 0x1539
#define E1000_REVISION_2 2
#define E1000_REVISION_4 4
@@ -83,6 +90,8 @@ enum e1000_mac_type {
e1000_82576,
e1000_82580,
e1000_i350,
+ e1000_i210,
+ e1000_i211,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
};
@@ -117,6 +126,7 @@ enum e1000_phy_type {
e1000_phy_igp_3,
e1000_phy_ife,
e1000_phy_82580,
+ e1000_phy_i210,
};
enum e1000_bus_type {
@@ -313,6 +323,9 @@ struct e1000_mac_operations {
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 *);
+ s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
+ void (*release_swfw_sync)(struct e1000_hw *, u16);
+
};
struct e1000_phy_operations {
@@ -338,6 +351,7 @@ struct e1000_nvm_operations {
s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
s32 (*update)(struct e1000_hw *);
s32 (*validate)(struct e1000_hw *);
+ s32 (*valid_led_default)(struct e1000_hw *, u16 *);
};
struct e1000_info {
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c
new file mode 100644
index 000000000000..77a5f939bc74
--- /dev/null
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -0,0 +1,603 @@
+/*******************************************************************************
+
+ Intel(R) Gigabit Ethernet Linux driver
+ Copyright(c) 2007-2012 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
+
+******************************************************************************/
+
+/* e1000_i210
+ * e1000_i211
+ */
+
+#include <linux/types.h>
+#include <linux/if_ether.h>
+
+#include "e1000_hw.h"
+#include "e1000_i210.h"
+
+static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw);
+static void igb_put_hw_semaphore_i210(struct e1000_hw *hw);
+static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data);
+static s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw);
+
+/**
+ * igb_acquire_nvm_i210 - Request for access to EEPROM
+ * @hw: pointer to the HW structure
+ *
+ * Acquire the necessary semaphores for exclusive access to the EEPROM.
+ * 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_i210(struct e1000_hw *hw)
+{
+ return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
+}
+
+/**
+ * igb_release_nvm_i210 - Release exclusive access to EEPROM
+ * @hw: pointer to the HW structure
+ *
+ * Stop any current commands to the EEPROM and clear the EEPROM request bit,
+ * then release the semaphores acquired.
+ **/
+void igb_release_nvm_i210(struct e1000_hw *hw)
+{
+ igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
+}
+
+/**
+ * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
+ * @hw: pointer to the HW structure
+ * @mask: specifies which semaphore to acquire
+ *
+ * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
+ * will also specify which port we're acquiring the lock for.
+ **/
+s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
+{
+ u32 swfw_sync;
+ u32 swmask = mask;
+ u32 fwmask = mask << 16;
+ s32 ret_val = E1000_SUCCESS;
+ s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
+
+ while (i < timeout) {
+ if (igb_get_hw_semaphore_i210(hw)) {
+ ret_val = -E1000_ERR_SWFW_SYNC;
+ goto out;
+ }
+
+ swfw_sync = rd32(E1000_SW_FW_SYNC);
+ if (!(swfw_sync & fwmask))
+ break;
+
+ /*
+ * Firmware currently using resource (fwmask)
+ */
+ igb_put_hw_semaphore_i210(hw);
+ mdelay(5);
+ i++;
+ }
+
+ if (i == timeout) {
+ hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n");
+ ret_val = -E1000_ERR_SWFW_SYNC;
+ goto out;
+ }
+
+ swfw_sync |= swmask;
+ wr32(E1000_SW_FW_SYNC, swfw_sync);
+
+ igb_put_hw_semaphore_i210(hw);
+out:
+ return ret_val;
+}
+
+/**
+ * igb_release_swfw_sync_i210 - Release SW/FW semaphore
+ * @hw: pointer to the HW structure
+ * @mask: specifies which semaphore to acquire
+ *
+ * Release the SW/FW semaphore used to access the PHY or NVM. The mask
+ * will also specify which port we're releasing the lock for.
+ **/
+void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
+{
+ u32 swfw_sync;
+
+ while (igb_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
+ ; /* Empty */
+
+ swfw_sync = rd32(E1000_SW_FW_SYNC);
+ swfw_sync &= ~mask;
+ wr32(E1000_SW_FW_SYNC, swfw_sync);
+
+ igb_put_hw_semaphore_i210(hw);
+}
+
+/**
+ * igb_get_hw_semaphore_i210 - Acquire hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Acquire the HW semaphore to access the PHY or NVM
+ **/
+static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
+{
+ u32 swsm;
+ s32 ret_val = E1000_SUCCESS;
+ s32 timeout = hw->nvm.word_size + 1;
+ s32 i = 0;
+
+ /* Get the FW semaphore. */
+ for (i = 0; i < timeout; i++) {
+ swsm = rd32(E1000_SWSM);
+ wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
+
+ /* Semaphore acquired if bit latched */
+ if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI)
+ break;
+
+ udelay(50);
+ }
+
+ if (i == timeout) {
+ /* Release semaphores */
+ igb_put_hw_semaphore(hw);
+ hw_dbg("Driver can't access the NVM\n");
+ ret_val = -E1000_ERR_NVM;
+ goto out;
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * igb_put_hw_semaphore_i210 - Release hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Release hardware semaphore used to access the PHY or NVM
+ **/
+static void igb_put_hw_semaphore_i210(struct e1000_hw *hw)
+{
+ u32 swsm;
+
+ swsm = rd32(E1000_SWSM);
+
+ swsm &= ~E1000_SWSM_SWESMBI;
+
+ wr32(E1000_SWSM, swsm);
+}
+
+/**
+ * igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
+ * @hw: pointer to the HW structure
+ * @offset: offset of word in the Shadow Ram to read
+ * @words: number of words to read
+ * @data: word read from the Shadow Ram
+ *
+ * Reads a 16 bit word from the Shadow Ram using the EERD register.
+ * Uses necessary synchronization semaphores.
+ **/
+s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data)
+{
+ s32 status = E1000_SUCCESS;
+ u16 i, count;
+
+ /* We cannot hold synchronization semaphores for too long,
+ * because of forceful takeover procedure. However it is more efficient
+ * to read in bursts than synchronizing access for each word. */
+ for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
+ count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
+ E1000_EERD_EEWR_MAX_COUNT : (words - i);
+ if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
+ status = igb_read_nvm_eerd(hw, offset, count,
+ data + i);
+ hw->nvm.ops.release(hw);
+ } else {
+ status = E1000_ERR_SWFW_SYNC;
+ }
+
+ if (status != E1000_SUCCESS)
+ break;
+ }
+
+ return status;
+}
+
+/**
+ * igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
+ * @hw: pointer to the HW structure
+ * @offset: offset within the Shadow RAM to be written to
+ * @words: number of words to write
+ * @data: 16 bit word(s) to be written to the Shadow RAM
+ *
+ * Writes data to Shadow RAM at offset using EEWR register.
+ *
+ * If e1000_update_nvm_checksum is not called after this function , the
+ * data will not be committed to FLASH and also Shadow RAM will most likely
+ * contain an invalid checksum.
+ *
+ * If error code is returned, data and Shadow RAM may be inconsistent - buffer
+ * partially written.
+ **/
+s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data)
+{
+ s32 status = E1000_SUCCESS;
+ u16 i, count;
+
+ /* We cannot hold synchronization semaphores for too long,
+ * because of forceful takeover procedure. However it is more efficient
+ * to write in bursts than synchronizing access for each word. */
+ for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
+ count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
+ E1000_EERD_EEWR_MAX_COUNT : (words - i);
+ if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
+ status = igb_write_nvm_srwr(hw, offset, count,
+ data + i);
+ hw->nvm.ops.release(hw);
+ } else {
+ status = E1000_ERR_SWFW_SYNC;
+ }
+
+ if (status != E1000_SUCCESS)
+ break;
+ }
+
+ return status;
+}
+
+/**
+ * igb_write_nvm_srwr - Write to Shadow Ram using EEWR
+ * @hw: pointer to the HW structure
+ * @offset: offset within the Shadow Ram to be written to
+ * @words: number of words to write
+ * @data: 16 bit word(s) to be written to the Shadow Ram
+ *
+ * Writes data to Shadow Ram at offset using EEWR register.
+ *
+ * If igb_update_nvm_checksum is not called after this function , the
+ * Shadow Ram will most likely contain an invalid checksum.
+ **/
+static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data)
+{
+ struct e1000_nvm_info *nvm = &hw->nvm;
+ u32 i, k, eewr = 0;
+ u32 attempts = 100000;
+ s32 ret_val = E1000_SUCCESS;
+
+ /*
+ * A check for invalid values: offset too large, too many words,
+ * too many words for the offset, and not enough words.
+ */
+ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
+ (words == 0)) {
+ hw_dbg("nvm parameter(s) out of bounds\n");
+ ret_val = -E1000_ERR_NVM;
+ goto out;
+ }
+
+ for (i = 0; i < words; i++) {
+ eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
+ (data[i] << E1000_NVM_RW_REG_DATA) |
+ E1000_NVM_RW_REG_START;
+
+ wr32(E1000_SRWR, eewr);
+
+ for (k = 0; k < attempts; k++) {
+ if (E1000_NVM_RW_REG_DONE &
+ rd32(E1000_SRWR)) {
+ ret_val = E1000_SUCCESS;
+ break;
+ }
+ udelay(5);
+ }
+
+ if (ret_val != E1000_SUCCESS) {
+ hw_dbg("Shadow RAM write EEWR timed out\n");
+ break;
+ }
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * igb_read_nvm_i211 - Read NVM wrapper function for I211
+ * @hw: pointer to the HW structure
+ * @address: the word address (aka eeprom offset) to read
+ * @data: pointer to the data read
+ *
+ * Wrapper function to return data formerly found in the NVM.
+ **/
+s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data)
+{
+ s32 ret_val = E1000_SUCCESS;
+
+ /* Only the MAC addr is required to be present in the iNVM */
+ switch (offset) {
+ case NVM_MAC_ADDR:
+ ret_val = igb_read_invm_i211(hw, offset, &data[0]);
+ ret_val |= igb_read_invm_i211(hw, offset+1, &data[1]);
+ ret_val |= igb_read_invm_i211(hw, offset+2, &data[2]);
+ if (ret_val != E1000_SUCCESS)
+ hw_dbg("MAC Addr not found in iNVM\n");
+ break;
+ case NVM_ID_LED_SETTINGS:
+ case NVM_INIT_CTRL_2:
+ case NVM_INIT_CTRL_4:
+ case NVM_LED_1_CFG:
+ case NVM_LED_0_2_CFG:
+ igb_read_invm_i211(hw, offset, data);
+ break;
+ case NVM_COMPAT:
+ *data = ID_LED_DEFAULT_I210;
+ break;
+ case NVM_SUB_DEV_ID:
+ *data = hw->subsystem_device_id;
+ break;
+ case NVM_SUB_VEN_ID:
+ *data = hw->subsystem_vendor_id;
+ break;
+ case NVM_DEV_ID:
+ *data = hw->device_id;
+ break;
+ case NVM_VEN_ID:
+ *data = hw->vendor_id;
+ break;
+ default:
+ hw_dbg("NVM word 0x%02x is not mapped.\n", offset);
+ *data = NVM_RESERVED_WORD;
+ break;
+ }
+ return ret_val;
+}
+
+/**
+ * igb_read_invm_i211 - Reads OTP
+ * @hw: pointer to the HW structure
+ * @address: the word address (aka eeprom offset) to read
+ * @data: pointer to the data read
+ *
+ * Reads 16-bit words from the OTP. Return error when the word is not
+ * stored in OTP.
+ **/
+s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data)
+{
+ s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
+ u32 invm_dword;
+ u16 i;
+ u8 record_type, word_address;
+
+ for (i = 0; i < E1000_INVM_SIZE; i++) {
+ invm_dword = rd32(E1000_INVM_DATA_REG(i));
+ /* Get record type */
+ record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
+ if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
+ break;
+ if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
+ i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
+ if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
+ i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
+ if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
+ word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
+ if (word_address == (u8)address) {
+ *data = INVM_DWORD_TO_WORD_DATA(invm_dword);
+ hw_dbg("Read INVM Word 0x%02x = %x",
+ address, *data);
+ status = E1000_SUCCESS;
+ break;
+ }
+ }
+ }
+ if (status != E1000_SUCCESS)
+ hw_dbg("Requested word 0x%02x not found in OTP\n", address);
+ return status;
+}
+
+/**
+ * igb_validate_nvm_checksum_i210 - 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_i210(struct e1000_hw *hw)
+{
+ s32 status = E1000_SUCCESS;
+ s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
+
+ if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
+
+ /*
+ * Replace the read function with semaphore grabbing with
+ * the one that skips this for a while.
+ * We have semaphore taken already here.
+ */
+ read_op_ptr = hw->nvm.ops.read;
+ hw->nvm.ops.read = igb_read_nvm_eerd;
+
+ status = igb_validate_nvm_checksum(hw);
+
+ /* Revert original read operation. */
+ hw->nvm.ops.read = read_op_ptr;
+
+ hw->nvm.ops.release(hw);
+ } else {
+ status = E1000_ERR_SWFW_SYNC;
+ }
+
+ return status;
+}
+
+
+/**
+ * igb_update_nvm_checksum_i210 - 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. Next commit EEPROM data onto the Flash.
+ **/
+s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw)
+{
+ s32 ret_val = E1000_SUCCESS;
+ u16 checksum = 0;
+ u16 i, nvm_data;
+
+ /*
+ * Read the first word from the EEPROM. If this times out or fails, do
+ * not continue or we could be in for a very long wait while every
+ * EEPROM read fails
+ */
+ ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data);
+ if (ret_val != E1000_SUCCESS) {
+ hw_dbg("EEPROM read failed\n");
+ goto out;
+ }
+
+ if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
+ /*
+ * Do not use hw->nvm.ops.write, hw->nvm.ops.read
+ * because we do not want to take the synchronization
+ * semaphores twice here.
+ */
+
+ for (i = 0; i < NVM_CHECKSUM_REG; i++) {
+ ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data);
+ if (ret_val) {
+ hw->nvm.ops.release(hw);
+ hw_dbg("NVM Read Error while updating checksum.\n");
+ goto out;
+ }
+ checksum += nvm_data;
+ }
+ checksum = (u16) NVM_SUM - checksum;
+ ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
+ &checksum);
+ if (ret_val != E1000_SUCCESS) {
+ hw->nvm.ops.release(hw);
+ hw_dbg("NVM Write Error while updating checksum.\n");
+ goto out;
+ }
+
+ hw->nvm.ops.release(hw);
+
+ ret_val = igb_update_flash_i210(hw);
+ } else {
+ ret_val = -E1000_ERR_SWFW_SYNC;
+ }
+out:
+ return ret_val;
+}
+
+/**
+ * igb_update_flash_i210 - Commit EEPROM to the flash
+ * @hw: pointer to the HW structure
+ *
+ **/
+s32 igb_update_flash_i210(struct e1000_hw *hw)
+{
+ s32 ret_val = E1000_SUCCESS;
+ u32 flup;
+
+ ret_val = igb_pool_flash_update_done_i210(hw);
+ if (ret_val == -E1000_ERR_NVM) {
+ hw_dbg("Flash update time out\n");
+ goto out;
+ }
+
+ flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210;
+ wr32(E1000_EECD, flup);
+
+ ret_val = igb_pool_flash_update_done_i210(hw);
+ if (ret_val == E1000_SUCCESS)
+ hw_dbg("Flash update complete\n");
+ else
+ hw_dbg("Flash update time out\n");
+
+out:
+ return ret_val;
+}
+
+/**
+ * igb_pool_flash_update_done_i210 - Pool FLUDONE status.
+ * @hw: pointer to the HW structure
+ *
+ **/
+s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw)
+{
+ s32 ret_val = -E1000_ERR_NVM;
+ u32 i, reg;
+
+ for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
+ reg = rd32(E1000_EECD);
+ if (reg & E1000_EECD_FLUDONE_I210) {
+ ret_val = E1000_SUCCESS;
+ break;
+ }
+ udelay(5);
+ }
+
+ return ret_val;
+}
+
+/**
+ * igb_valid_led_default_i210 - Verify a valid default LED config
+ * @hw: pointer to the HW structure
+ * @data: pointer to the NVM (EEPROM)
+ *
+ * Read the EEPROM for the current default LED configuration. If the
+ * LED configuration is not valid, set to a valid LED configuration.
+ **/
+s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
+{
+ s32 ret_val;
+
+ ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
+ if (ret_val) {
+ hw_dbg("NVM Read Error\n");
+ goto out;
+ }
+
+ if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
+ switch (hw->phy.media_type) {
+ case e1000_media_type_internal_serdes:
+ *data = ID_LED_DEFAULT_I210_SERDES;
+ break;
+ case e1000_media_type_copper:
+ default:
+ *data = ID_LED_DEFAULT_I210;
+ break;
+ }
+ }
+out:
+ return ret_val;
+}
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h
new file mode 100644
index 000000000000..5dc2bd3f50bc
--- /dev/null
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -0,0 +1,76 @@
+/*******************************************************************************
+
+ Intel(R) Gigabit Ethernet Linux driver
+ Copyright(c) 2007-2012 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_I210_H_
+#define _E1000_I210_H_
+
+extern s32 igb_update_flash_i210(struct e1000_hw *hw);
+extern s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw);
+extern s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw);
+extern s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset,
+ u16 words, u16 *data);
+extern s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
+ u16 words, u16 *data);
+extern s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data);
+extern s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
+extern void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
+extern s32 igb_acquire_nvm_i210(struct e1000_hw *hw);
+extern void igb_release_nvm_i210(struct e1000_hw *hw);
+extern s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
+extern s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data);
+
+#define E1000_STM_OPCODE 0xDB00
+#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
+
+#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \
+ (u8)((invm_dword) & 0x7)
+#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \
+ (u8)(((invm_dword) & 0x0000FE00) >> 9)
+#define INVM_DWORD_TO_WORD_DATA(invm_dword) \
+ (u16)(((invm_dword) & 0xFFFF0000) >> 16)
+
+enum E1000_INVM_STRUCTURE_TYPE {
+ E1000_INVM_UNINITIALIZED_STRUCTURE = 0x00,
+ E1000_INVM_WORD_AUTOLOAD_STRUCTURE = 0x01,
+ E1000_INVM_CSR_AUTOLOAD_STRUCTURE = 0x02,
+ E1000_INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE = 0x03,
+ E1000_INVM_RSA_KEY_SHA256_STRUCTURE = 0x04,
+ E1000_INVM_INVALIDATED_STRUCTURE = 0x0F,
+};
+
+#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
+#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
+
+#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
+ (ID_LED_OFF1_OFF2 << 4) | \
+ (ID_LED_DEF1_DEF2))
+#define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \
+ (ID_LED_DEF1_DEF2 << 4) | \
+ (ID_LED_DEF1_DEF2))
+
+#endif
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c
index f57338afd71f..819c145ac762 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -658,6 +658,7 @@ s32 igb_setup_link(struct e1000_hw *hw)
ret_val = igb_set_fc_watermarks(hw);
out:
+
return ret_val;
}
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c
index fa2c6ba62139..aa5fcdf3f357 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.c
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c
@@ -710,4 +710,3 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
out:
return ret_val;
}
-
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c
index 789de5b83aad..7be98b6f1052 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -35,6 +35,7 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw);
static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
u16 *phy_ctrl);
static s32 igb_wait_autoneg(struct e1000_hw *hw);
+static s32 igb_set_master_slave_mode(struct e1000_hw *hw);
/* Cable length tables */
static const u16 e1000_m88_cable_length_table[] =
@@ -570,6 +571,11 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
hw_dbg("Error committing the PHY changes\n");
goto out;
}
+ if (phy->type == e1000_phy_i210) {
+ ret_val = igb_set_master_slave_mode(hw);
+ if (ret_val)
+ return ret_val;
+ }
out:
return ret_val;
@@ -1213,12 +1219,22 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
goto out;
if (!link) {
- if (hw->phy.type != e1000_phy_m88 ||
- hw->phy.id == I347AT4_E_PHY_ID ||
- hw->phy.id == M88E1112_E_PHY_ID) {
+ bool reset_dsp = true;
+
+ switch (hw->phy.id) {
+ case I347AT4_E_PHY_ID:
+ case M88E1112_E_PHY_ID:
+ case I210_I_PHY_ID:
+ reset_dsp = false;
+ break;
+ default:
+ if (hw->phy.type != e1000_phy_m88)
+ reset_dsp = false;
+ break;
+ }
+ if (!reset_dsp)
hw_dbg("Link taking longer than expected.\n");
- } else {
-
+ else {
/*
* We didn't get link.
* Reset the DSP and cross our fingers.
@@ -1243,7 +1259,8 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
if (hw->phy.type != e1000_phy_m88 ||
hw->phy.id == I347AT4_E_PHY_ID ||
- hw->phy.id == M88E1112_E_PHY_ID)
+ hw->phy.id == M88E1112_E_PHY_ID ||
+ hw->phy.id == I210_I_PHY_ID)
goto out;
ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
@@ -1441,6 +1458,7 @@ s32 igb_check_downshift(struct e1000_hw *hw)
u16 phy_data, offset, mask;
switch (phy->type) {
+ case e1000_phy_i210:
case e1000_phy_m88:
case e1000_phy_gg82563:
offset = M88E1000_PHY_SPEC_STATUS;
@@ -1476,7 +1494,7 @@ out:
*
* Polarity is determined based on the PHY specific status register.
**/
-static s32 igb_check_polarity_m88(struct e1000_hw *hw)
+s32 igb_check_polarity_m88(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val;
@@ -1665,6 +1683,7 @@ s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw)
u16 phy_data, phy_data2, index, default_page, is_cm;
switch (hw->phy.id) {
+ case I210_I_PHY_ID:
case I347AT4_E_PHY_ID:
/* Remember the original page select and set it to 7 */
ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
@@ -2129,10 +2148,16 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
void igb_power_up_phy_copper(struct e1000_hw *hw)
{
u16 mii_reg = 0;
+ u16 power_reg = 0;
/* The PHY will retain its settings across a power down/up cycle */
hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
mii_reg &= ~MII_CR_POWER_DOWN;
+ if (hw->phy.type == e1000_phy_i210) {
+ hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg);
+ power_reg &= ~GS40G_CS_POWER_DOWN;
+ hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
+ }
hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
}
@@ -2146,10 +2171,18 @@ void igb_power_up_phy_copper(struct e1000_hw *hw)
void igb_power_down_phy_copper(struct e1000_hw *hw)
{
u16 mii_reg = 0;
+ u16 power_reg = 0;
/* The PHY will retain its settings across a power down/up cycle */
hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
mii_reg |= MII_CR_POWER_DOWN;
+
+ /* i210 Phy requires an additional bit for power up/down */
+ if (hw->phy.type == e1000_phy_i210) {
+ hw->phy.ops.read_reg(hw, GS40G_COPPER_SPEC, &power_reg);
+ power_reg |= GS40G_CS_POWER_DOWN;
+ hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
+ }
hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
msleep(1);
}
@@ -2345,3 +2378,103 @@ s32 igb_get_cable_length_82580(struct e1000_hw *hw)
out:
return ret_val;
}
+
+/**
+ * igb_write_phy_reg_gs40g - Write GS40G PHY register
+ * @hw: pointer to the HW structure
+ * @offset: lower half is register offset to write to
+ * upper half is page to use.
+ * @data: data to write at register offset
+ *
+ * Acquires semaphore, if necessary, then writes the data to PHY register
+ * at the offset. Release any acquired semaphores before exiting.
+ **/
+s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ s32 ret_val;
+ u16 page = offset >> GS40G_PAGE_SHIFT;
+
+ offset = offset & GS40G_OFFSET_MASK;
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return ret_val;
+
+ ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
+ if (ret_val)
+ goto release;
+ ret_val = igb_write_phy_reg_mdic(hw, offset, data);
+
+release:
+ hw->phy.ops.release(hw);
+ return ret_val;
+}
+
+/**
+ * igb_read_phy_reg_gs40g - Read GS40G PHY register
+ * @hw: pointer to the HW structure
+ * @offset: lower half is register offset to read to
+ * upper half is page to use.
+ * @data: data to read at register offset
+ *
+ * Acquires semaphore, if necessary, then reads the data in the PHY register
+ * at the offset. Release any acquired semaphores before exiting.
+ **/
+s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ s32 ret_val;
+ u16 page = offset >> GS40G_PAGE_SHIFT;
+
+ offset = offset & GS40G_OFFSET_MASK;
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return ret_val;
+
+ ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
+ if (ret_val)
+ goto release;
+ ret_val = igb_read_phy_reg_mdic(hw, offset, data);
+
+release:
+ hw->phy.ops.release(hw);
+ return ret_val;
+}
+
+/**
+ * igb_set_master_slave_mode - Setup PHY for Master/slave mode
+ * @hw: pointer to the HW structure
+ *
+ * Sets up Master/slave mode
+ **/
+static s32 igb_set_master_slave_mode(struct e1000_hw *hw)
+{
+ s32 ret_val;
+ u16 phy_data;
+
+ /* Resolve Master/Slave mode */
+ ret_val = hw->phy.ops.read_reg(hw, PHY_1000T_CTRL, &phy_data);
+ if (ret_val)
+ return ret_val;
+
+ /* load defaults for future use */
+ hw->phy.original_ms_type = (phy_data & CR_1000T_MS_ENABLE) ?
+ ((phy_data & CR_1000T_MS_VALUE) ?
+ e1000_ms_force_master :
+ e1000_ms_force_slave) : e1000_ms_auto;
+
+ switch (hw->phy.ms_type) {
+ case e1000_ms_force_master:
+ phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
+ break;
+ case e1000_ms_force_slave:
+ phy_data |= CR_1000T_MS_ENABLE;
+ phy_data &= ~(CR_1000T_MS_VALUE);
+ break;
+ case e1000_ms_auto:
+ phy_data &= ~CR_1000T_MS_ENABLE;
+ /* fall-through */
+ default:
+ break;
+ }
+
+ return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data);
+}
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.h b/drivers/net/ethernet/intel/igb/e1000_phy.h
index 4c32ac66ff39..34e40619f16b 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.h
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.h
@@ -73,6 +73,9 @@ s32 igb_copper_link_setup_82580(struct e1000_hw *hw);
s32 igb_get_phy_info_82580(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_82580(struct e1000_hw *hw);
s32 igb_get_cable_length_82580(struct e1000_hw *hw);
+s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
+s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
+s32 igb_check_polarity_m88(struct e1000_hw *hw);
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
@@ -114,6 +117,13 @@ s32 igb_get_cable_length_82580(struct e1000_hw *hw);
/* I82580 PHY Diagnostics Status */
#define I82580_DSTATUS_CABLE_LENGTH 0x03FC
#define I82580_DSTATUS_CABLE_LENGTH_SHIFT 2
+
+/* 82580 PHY Power Management */
+#define E1000_82580_PHY_POWER_MGMT 0xE14
+#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */
+#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */
+#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */
+
/* 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 */
@@ -133,4 +143,16 @@ s32 igb_get_cable_length_82580(struct e1000_hw *hw);
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
+/* GS40G - I210 PHY defines */
+#define GS40G_PAGE_SELECT 0x16
+#define GS40G_PAGE_SHIFT 16
+#define GS40G_OFFSET_MASK 0xFFFF
+#define GS40G_PAGE_2 0x20000
+#define GS40G_MAC_REG2 0x15
+#define GS40G_MAC_LB 0x4140
+#define GS40G_MAC_SPEED_1G 0X0006
+#define GS40G_COPPER_SPEC 0x0010
+#define GS40G_CS_POWER_DOWN 0x0002
+#define GS40G_LINE_LB 0x4000
+
#endif
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index ccdf36d503fd..35d1e4f2c92c 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -352,4 +352,18 @@
#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */
+#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */
+#define E1000_I210_FLMNGCTL 0x12038
+#define E1000_I210_FLMNGDATA 0x1203C
+#define E1000_I210_FLMNGCNT 0x12040
+
+#define E1000_I210_FLSWCTL 0x12048
+#define E1000_I210_FLSWDATA 0x1204C
+#define E1000_I210_FLSWCNT 0x12050
+
+#define E1000_I210_FLA 0x1201C
+
+#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n))
+#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */
+
#endif
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 3758ad246742..ae6d3f393a54 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -65,10 +65,13 @@ struct igb_adapter;
#define MAX_Q_VECTORS 8
/* Transmit and receive queues */
-#define IGB_MAX_RX_QUEUES (adapter->vfs_allocated_count ? 2 : \
- (hw->mac.type > e1000_82575 ? 8 : 4))
+#define IGB_MAX_RX_QUEUES ((adapter->vfs_allocated_count ? 2 : \
+ (hw->mac.type > e1000_82575 ? 8 : 4)))
+#define IGB_MAX_RX_QUEUES_I210 4
+#define IGB_MAX_RX_QUEUES_I211 2
#define IGB_MAX_TX_QUEUES 16
-
+#define IGB_MAX_TX_QUEUES_I210 4
+#define IGB_MAX_TX_QUEUES_I211 2
#define IGB_MAX_VF_MC_ENTRIES 30
#define IGB_MAX_VF_FUNCTIONS 8
#define IGB_MAX_VFTA_ENTRIES 128
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index e10821a0f249..812d4f963bd1 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -335,7 +335,7 @@ static void igb_set_msglevel(struct net_device *netdev, u32 data)
static int igb_get_regs_len(struct net_device *netdev)
{
-#define IGB_REGS_LEN 551
+#define IGB_REGS_LEN 739
return IGB_REGS_LEN * sizeof(u32);
}
@@ -552,10 +552,49 @@ static void igb_get_regs(struct net_device *netdev,
regs_buff[548] = rd32(E1000_TDFT);
regs_buff[549] = rd32(E1000_TDFHS);
regs_buff[550] = rd32(E1000_TDFPC);
- regs_buff[551] = adapter->stats.o2bgptc;
- regs_buff[552] = adapter->stats.b2ospc;
- regs_buff[553] = adapter->stats.o2bspc;
- regs_buff[554] = adapter->stats.b2ogprc;
+
+ if (hw->mac.type > e1000_82580) {
+ regs_buff[551] = adapter->stats.o2bgptc;
+ regs_buff[552] = adapter->stats.b2ospc;
+ regs_buff[553] = adapter->stats.o2bspc;
+ regs_buff[554] = adapter->stats.b2ogprc;
+ }
+
+ if (hw->mac.type != e1000_82576)
+ return;
+ for (i = 0; i < 12; i++)
+ regs_buff[555 + i] = rd32(E1000_SRRCTL(i + 4));
+ for (i = 0; i < 4; i++)
+ regs_buff[567 + i] = rd32(E1000_PSRTYPE(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[571 + i] = rd32(E1000_RDBAL(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[583 + i] = rd32(E1000_RDBAH(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[595 + i] = rd32(E1000_RDLEN(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[607 + i] = rd32(E1000_RDH(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[619 + i] = rd32(E1000_RDT(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[631 + i] = rd32(E1000_RXDCTL(i + 4));
+
+ for (i = 0; i < 12; i++)
+ regs_buff[643 + i] = rd32(E1000_TDBAL(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[655 + i] = rd32(E1000_TDBAH(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[667 + i] = rd32(E1000_TDLEN(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[679 + i] = rd32(E1000_TDH(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[691 + i] = rd32(E1000_TDT(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[703 + i] = rd32(E1000_TXDCTL(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[715 + i] = rd32(E1000_TDWBAL(i + 4));
+ for (i = 0; i < 12; i++)
+ regs_buff[727 + i] = rd32(E1000_TDWBAH(i + 4));
}
static int igb_get_eeprom_len(struct net_device *netdev)
@@ -624,6 +663,9 @@ static int igb_set_eeprom(struct net_device *netdev,
if (eeprom->len == 0)
return -EOPNOTSUPP;
+ if (hw->mac.type == e1000_i211)
+ return -EOPNOTSUPP;
+
if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
return -EFAULT;
@@ -851,6 +893,36 @@ struct igb_reg_test {
#define TABLE64_TEST_LO 5
#define TABLE64_TEST_HI 6
+/* i210 reg test */
+static struct igb_reg_test reg_test_i210[] = {
+ { E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+ { E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+ { E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+ /* RDH is read-only for i210, only test RDT. */
+ { E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
+ { E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
+ { E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+ { E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
+ { E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+ { E1000_RA, 0, 16, TABLE64_TEST_LO,
+ 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RA, 0, 16, TABLE64_TEST_HI,
+ 0x900FFFFF, 0xFFFFFFFF },
+ { E1000_MTA, 0, 128, TABLE32_TEST,
+ 0xFFFFFFFF, 0xFFFFFFFF },
+ { 0, 0, 0, 0, 0 }
+};
+
/* i350 reg test */
static struct igb_reg_test reg_test_i350[] = {
{ E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
@@ -1073,6 +1145,11 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
test = reg_test_i350;
toggle = 0x7FEFF3FF;
break;
+ case e1000_i210:
+ case e1000_i211:
+ test = reg_test_i210;
+ toggle = 0x7FEFF3FF;
+ break;
case e1000_82580:
test = reg_test_82580;
toggle = 0x7FEFF3FF;
@@ -1154,23 +1231,13 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
static int igb_eeprom_test(struct igb_adapter *adapter, u64 *data)
{
- u16 temp;
- u16 checksum = 0;
- u16 i;
-
*data = 0;
- /* Read and add up the contents of the EEPROM */
- for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
- if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp)) < 0) {
- *data = 1;
- break;
- }
- checksum += temp;
- }
- /* If Checksum is not Correct return error else test passed */
- if ((checksum != (u16) NVM_SUM) && !(*data))
- *data = 2;
+ /* Validate eeprom on all parts but i211 */
+ if (adapter->hw.mac.type != e1000_i211) {
+ if (adapter->hw.nvm.ops.validate(&adapter->hw) < 0)
+ *data = 2;
+ }
return *data;
}
@@ -1236,6 +1303,8 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
ics_mask = 0x77DCFED5;
break;
case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
ics_mask = 0x77DCFED5;
break;
default:
@@ -1402,23 +1471,35 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
u32 ctrl_reg = 0;
+ u16 phy_reg = 0;
hw->mac.autoneg = false;
- if (hw->phy.type == e1000_phy_m88) {
+ switch (hw->phy.type) {
+ case e1000_phy_m88:
/* Auto-MDI/MDIX Off */
igb_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
/* reset to update Auto-MDI/MDIX */
igb_write_phy_reg(hw, PHY_CONTROL, 0x9140);
/* autoneg off */
igb_write_phy_reg(hw, PHY_CONTROL, 0x8140);
- } else if (hw->phy.type == e1000_phy_82580) {
+ break;
+ case e1000_phy_82580:
/* enable MII loopback */
igb_write_phy_reg(hw, I82580_PHY_LBK_CTRL, 0x8041);
+ break;
+ case e1000_phy_i210:
+ /* set loopback speed in PHY */
+ igb_read_phy_reg(hw, (GS40G_PAGE_SELECT & GS40G_PAGE_2),
+ &phy_reg);
+ phy_reg |= GS40G_MAC_SPEED_1G;
+ igb_write_phy_reg(hw, (GS40G_PAGE_SELECT & GS40G_PAGE_2),
+ phy_reg);
+ ctrl_reg = rd32(E1000_CTRL_EXT);
+ default:
+ break;
}
- ctrl_reg = rd32(E1000_CTRL);
-
/* force 1000, set loopback */
igb_write_phy_reg(hw, PHY_CONTROL, 0x4140);
@@ -1431,7 +1512,7 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
E1000_CTRL_FD | /* Force Duplex to FULL */
E1000_CTRL_SLU); /* Set link up enable bit */
- if (hw->phy.type == e1000_phy_m88)
+ if ((hw->phy.type == e1000_phy_m88) || (hw->phy.type == e1000_phy_i210))
ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
wr32(E1000_CTRL, ctrl_reg);
@@ -1439,7 +1520,7 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
/* Disable the receiver on the PHY so when a cable is plugged in, the
* PHY does not begin to autoneg when a cable is reconnected to the NIC.
*/
- if (hw->phy.type == e1000_phy_m88)
+ if ((hw->phy.type == e1000_phy_m88) || (hw->phy.type == e1000_phy_i210))
igb_phy_disable_receiver(adapter);
udelay(500);
@@ -1704,6 +1785,14 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data)
*data = 0;
goto out;
}
+ if ((adapter->hw.mac.type == e1000_i210)
+ || (adapter->hw.mac.type == e1000_i210)) {
+ dev_err(&adapter->pdev->dev,
+ "Loopback test not supported "
+ "on this part at this time.\n");
+ *data = 0;
+ goto out;
+ }
*data = igb_setup_desc_rings(adapter);
if (*data)
goto out;
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 80d52d2dfea3..dd3bfe8cd36c 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -75,6 +75,11 @@ static const struct e1000_info *igb_info_tbl[] = {
};
static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_I211_COPPER), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_COPPER), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_FIBER), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SERDES), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_I210_SGMII), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_FIBER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I350_SERDES), board_82575 },
@@ -641,6 +646,8 @@ static void igb_cache_ring_register(struct igb_adapter *adapter)
case e1000_82575:
case e1000_82580:
case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
default:
for (; i < adapter->num_rx_queues; i++)
adapter->rx_ring[i]->reg_idx = rbase_offset + i;
@@ -727,8 +734,11 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
if (adapter->hw.mac.type >= e1000_82576)
set_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags);
- /* On i350, loopback VLAN packets have the tag byte-swapped. */
- if (adapter->hw.mac.type == e1000_i350)
+ /*
+ * On i350, i210, and i211, loopback VLAN packets
+ * have the tag byte-swapped.
+ * */
+ if (adapter->hw.mac.type >= e1000_i350)
set_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &ring->flags);
adapter->rx_ring[i] = ring;
@@ -822,6 +832,8 @@ static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector)
break;
case e1000_82580:
case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
/*
* On 82580 and newer adapters the scheme is similar to 82576
* however instead of ordering column-major we have things
@@ -888,6 +900,8 @@ static void igb_configure_msix(struct igb_adapter *adapter)
case e1000_82576:
case e1000_82580:
case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
/* Turn on MSI-X capability first, or our settings
* won't stick. And it will take days to debug. */
wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE |
@@ -1034,6 +1048,11 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter)
if (!(adapter->flags & IGB_FLAG_QUEUE_PAIRS))
numvecs += adapter->num_tx_queues;
+ /* i210 and i211 can only have 4 MSIX vectors for rx/tx queues. */
+ if ((adapter->hw.mac.type == e1000_i210)
+ || (adapter->hw.mac.type == e1000_i211))
+ numvecs = 4;
+
/* store the number of vectors reserved for queues */
adapter->num_q_vectors = numvecs;
@@ -1041,6 +1060,7 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter)
numvecs++;
adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry),
GFP_KERNEL);
+
if (!adapter->msix_entries)
goto msi_only;
@@ -1083,9 +1103,12 @@ msi_only:
adapter->flags |= IGB_FLAG_HAS_MSI;
out:
/* Notify the stack of the (possibly) reduced queue counts. */
+ rtnl_lock();
netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
- return netif_set_real_num_rx_queues(adapter->netdev,
- adapter->num_rx_queues);
+ err = netif_set_real_num_rx_queues(adapter->netdev,
+ adapter->num_rx_queues);
+ rtnl_unlock();
+ return err;
}
/**
@@ -1631,6 +1654,8 @@ void igb_reset(struct igb_adapter *adapter)
pba &= E1000_RXPBS_SIZE_MASK_82576;
break;
case e1000_82575:
+ case e1000_i210:
+ case e1000_i211:
default:
pba = E1000_PBA_34K;
break;
@@ -1826,7 +1851,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
*/
if (pdev->is_virtfn) {
WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n",
- pci_name(pdev), pdev->vendor, pdev->device);
+ pci_name(pdev), pdev->vendor, pdev->device);
return -EINVAL;
}
@@ -1980,11 +2005,16 @@ static int __devinit igb_probe(struct pci_dev *pdev,
* known good starting state */
hw->mac.ops.reset_hw(hw);
- /* make sure the NVM is good */
- if (hw->nvm.ops.validate(hw) < 0) {
- dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n");
- err = -EIO;
- goto err_eeprom;
+ /*
+ * make sure the NVM is good , i211 parts have special NVM that
+ * doesn't contain a checksum
+ */
+ if (hw->mac.type != e1000_i211) {
+ if (hw->nvm.ops.validate(hw) < 0) {
+ dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n");
+ err = -EIO;
+ goto err_eeprom;
+ }
}
/* copy the MAC address out of the NVM */
@@ -2118,6 +2148,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
adapter->num_rx_queues, adapter->num_tx_queues);
switch (hw->mac.type) {
case e1000_i350:
+ case e1000_i210:
+ case e1000_i211:
igb_set_eee_i350(hw);
break;
default:
@@ -2244,9 +2276,14 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter)
{
#ifdef CONFIG_PCI_IOV
struct pci_dev *pdev = adapter->pdev;
+ struct e1000_hw *hw = &adapter->hw;
int old_vfs = igb_find_enabled_vfs(adapter);
int i;
+ /* Virtualization features not supported on i210 family. */
+ if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211))
+ return;
+
if (old_vfs) {
dev_info(&pdev->dev, "%d pre-allocated VFs found - override "
"max_vfs setting of %d\n", old_vfs, max_vfs);
@@ -2258,6 +2295,7 @@ static void __devinit igb_probe_vfs(struct igb_adapter * adapter)
adapter->vf_data = kcalloc(adapter->vfs_allocated_count,
sizeof(struct vf_data_storage), GFP_KERNEL);
+
/* if allocation failed then we do not support SR-IOV */
if (!adapter->vf_data) {
adapter->vfs_allocated_count = 0;
@@ -2332,11 +2370,28 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
} else
adapter->vfs_allocated_count = max_vfs;
break;
+ case e1000_i210:
+ case e1000_i211:
+ adapter->vfs_allocated_count = 0;
+ break;
default:
break;
}
#endif /* CONFIG_PCI_IOV */
- adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
+ switch (hw->mac.type) {
+ case e1000_i210:
+ adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES_I210,
+ num_online_cpus());
+ break;
+ case e1000_i211:
+ adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES_I211,
+ num_online_cpus());
+ break;
+ default:
+ adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES,
+ num_online_cpus());
+ break;
+ }
/* i350 cannot do RSS and SR-IOV at the same time */
if (hw->mac.type == e1000_i350 && adapter->vfs_allocated_count)
adapter->rss_queues = 1;
@@ -2366,7 +2421,7 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
/* Explicitly disable IRQ since the NIC can be in any state. */
igb_irq_disable(adapter);
- if (hw->mac.type == e1000_i350)
+ if (hw->mac.type >= e1000_i350)
adapter->flags &= ~IGB_FLAG_DMAC;
set_bit(__IGB_DOWN, &adapter->state);
@@ -2819,6 +2874,17 @@ static void igb_setup_mrqc(struct igb_adapter *adapter)
/* Don't need to set TUOFL or IPOFL, they default to 1 */
wr32(E1000_RXCSUM, rxcsum);
+ /*
+ * Generate RSS hash based on TCP port numbers and/or
+ * IPv4/v6 src and dst addresses since UDP cannot be
+ * hashed reliably due to IP fragmentation
+ */
+
+ mrqc = E1000_MRQC_RSS_FIELD_IPV4 |
+ E1000_MRQC_RSS_FIELD_IPV4_TCP |
+ E1000_MRQC_RSS_FIELD_IPV6 |
+ E1000_MRQC_RSS_FIELD_IPV6_TCP |
+ E1000_MRQC_RSS_FIELD_IPV6_TCP_EX;
/* If VMDq is enabled then we set the appropriate mode for that, else
* we default to RSS so that an RSS hash is calculated per packet even
@@ -2834,25 +2900,15 @@ static void igb_setup_mrqc(struct igb_adapter *adapter)
wr32(E1000_VT_CTL, vtctl);
}
if (adapter->rss_queues > 1)
- mrqc = E1000_MRQC_ENABLE_VMDQ_RSS_2Q;
+ mrqc |= E1000_MRQC_ENABLE_VMDQ_RSS_2Q;
else
- mrqc = E1000_MRQC_ENABLE_VMDQ;
+ mrqc |= E1000_MRQC_ENABLE_VMDQ;
} else {
- mrqc = E1000_MRQC_ENABLE_RSS_4Q;
+ if (hw->mac.type != e1000_i211)
+ mrqc |= E1000_MRQC_ENABLE_RSS_4Q;
}
igb_vmm_control(adapter);
- /*
- * Generate RSS hash based on TCP port numbers and/or
- * IPv4/v6 src and dst addresses since UDP cannot be
- * hashed reliably due to IP fragmentation
- */
- mrqc |= E1000_MRQC_RSS_FIELD_IPV4 |
- E1000_MRQC_RSS_FIELD_IPV4_TCP |
- E1000_MRQC_RSS_FIELD_IPV6 |
- E1000_MRQC_RSS_FIELD_IPV6_TCP |
- E1000_MRQC_RSS_FIELD_IPV6_TCP_EX;
-
wr32(E1000_MRQC, mrqc);
}
@@ -3454,7 +3510,7 @@ static void igb_set_rx_mode(struct net_device *netdev)
* we will have issues with VLAN tag stripping not being done for frames
* that are only arriving because we are the default pool
*/
- if (hw->mac.type < e1000_82576)
+ if ((hw->mac.type < e1000_82576) || (hw->mac.type > e1000_i350))
return;
vmolr |= rd32(E1000_VMOLR(vfn)) &
@@ -3551,7 +3607,7 @@ static bool igb_thermal_sensor_event(struct e1000_hw *hw, u32 event)
bool ret = false;
u32 ctrl_ext, thstat;
- /* check for thermal sensor event on i350, copper only */
+ /* check for thermal sensor event on i350 copper only */
if (hw->mac.type == e1000_i350) {
thstat = rd32(E1000_THSTAT);
ctrl_ext = rd32(E1000_CTRL_EXT);
@@ -6653,18 +6709,7 @@ static int igb_resume(struct device *dev)
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
- if (!rtnl_is_locked()) {
- /*
- * shut up ASSERT_RTNL() warning in
- * netif_set_real_num_tx/rx_queues.
- */
- rtnl_lock();
- err = igb_init_interrupt_scheme(adapter);
- rtnl_unlock();
- } else {
- err = igb_init_interrupt_scheme(adapter);
- }
- if (err) {
+ if (igb_init_interrupt_scheme(adapter)) {
dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
return -ENOMEM;
}
@@ -7027,6 +7072,8 @@ static void igb_vmm_control(struct igb_adapter *adapter)
switch (hw->mac.type) {
case e1000_82575:
+ case e1000_i210:
+ case e1000_i211:
default:
/* replication is not supported for 82575 */
return;
@@ -7100,6 +7147,9 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)
/* watchdog timer= +-1000 usec in 32usec intervals */
reg |= (1000 >> 5);
+
+ /* Disable BMC-to-OS Watchdog Enable */
+ reg &= ~E1000_DMACR_DC_BMC2OSW_EN;
wr32(E1000_DMACR, reg);
/*
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index c9b71c5bc475..d5ee7fa50723 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -262,6 +262,8 @@ void igb_ptp_init(struct igb_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
switch (hw->mac.type) {
+ case e1000_i210:
+ case e1000_i211:
case e1000_i350:
case e1000_82580:
adapter->caps.owner = THIS_MODULE;
@@ -362,6 +364,8 @@ void igb_systim_to_hwtstamp(struct igb_adapter *adapter,
unsigned long flags;
switch (adapter->hw.mac.type) {
+ case e1000_i210:
+ case e1000_i211:
case e1000_i350:
case e1000_82580:
case e1000_82576:
diff --git a/drivers/net/ethernet/intel/ixgbe/Makefile b/drivers/net/ethernet/intel/ixgbe/Makefile
index 0708d7eb4668..0bdf06bc5c49 100644
--- a/drivers/net/ethernet/intel/ixgbe/Makefile
+++ b/drivers/net/ethernet/intel/ixgbe/Makefile
@@ -39,4 +39,6 @@ ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
ixgbe_dcb_82599.o ixgbe_dcb_nl.o
+ixgbe-$(CONFIG_IXGBE_PTP) += ixgbe_ptp.o
+
ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 425f86432f90..3ef3c5284e52 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -36,6 +36,12 @@
#include <linux/aer.h>
#include <linux/if_vlan.h>
+#ifdef CONFIG_IXGBE_PTP
+#include <linux/clocksource.h>
+#include <linux/net_tstamp.h>
+#include <linux/ptp_clock_kernel.h>
+#endif /* CONFIG_IXGBE_PTP */
+
#include "ixgbe_type.h"
#include "ixgbe_common.h"
#include "ixgbe_dcb.h"
@@ -96,6 +102,7 @@
#define IXGBE_TX_FLAGS_FCOE (u32)(1 << 5)
#define IXGBE_TX_FLAGS_FSO (u32)(1 << 6)
#define IXGBE_TX_FLAGS_TXSW (u32)(1 << 7)
+#define IXGBE_TX_FLAGS_TSTAMP (u32)(1 << 8)
#define IXGBE_TX_FLAGS_VLAN_MASK 0xffff0000
#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0xe0000000
#define IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT 29
@@ -458,6 +465,8 @@ struct ixgbe_adapter {
#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT (u32)(1 << 7)
#define IXGBE_FLAG2_RSS_FIELD_IPV4_UDP (u32)(1 << 8)
#define IXGBE_FLAG2_RSS_FIELD_IPV6_UDP (u32)(1 << 9)
+#define IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED (u32)(1 << 10)
+#define IXGBE_FLAG2_PTP_PPS_ENABLED (u32)(1 << 11)
/* Tx fast path data */
int num_tx_queues;
@@ -545,6 +554,17 @@ struct ixgbe_adapter {
u32 interrupt_event;
u32 led_reg;
+#ifdef CONFIG_IXGBE_PTP
+ struct ptp_clock *ptp_clock;
+ struct ptp_clock_info ptp_caps;
+ unsigned long last_overflow_check;
+ spinlock_t tmreg_lock;
+ struct cyclecounter cc;
+ struct timecounter tc;
+ u32 base_incval;
+ u32 cycle_speed;
+#endif /* CONFIG_IXGBE_PTP */
+
/* SR-IOV */
DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);
unsigned int num_vfs;
@@ -652,12 +672,15 @@ extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
union ixgbe_atr_input *mask);
extern void ixgbe_set_rx_mode(struct net_device *netdev);
#ifdef CONFIG_IXGBE_DCB
+extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter);
extern int ixgbe_setup_tc(struct net_device *dev, u8 tc);
#endif
extern void ixgbe_tx_ctxtdesc(struct ixgbe_ring *, u32, u32, u32, u32);
extern void ixgbe_do_reset(struct net_device *netdev);
+#ifdef CONFIG_IXGBE_HWMON
extern void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter);
extern int ixgbe_sysfs_init(struct ixgbe_adapter *adapter);
+#endif /* CONFIG_IXGBE_HWMON */
#ifdef IXGBE_FCOE
extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter);
extern int ixgbe_fso(struct ixgbe_ring *tx_ring,
@@ -688,4 +711,18 @@ static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring)
return netdev_get_tx_queue(ring->netdev, ring->queue_index);
}
+#ifdef CONFIG_IXGBE_PTP
+extern void ixgbe_ptp_init(struct ixgbe_adapter *adapter);
+extern void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);
+extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
+extern void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector,
+ struct sk_buff *skb);
+extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
+ struct sk_buff *skb);
+extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
+ struct ifreq *ifr, int cmd);
+extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
+extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr);
+#endif /* CONFIG_IXGBE_PTP */
+
#endif /* _IXGBE_H_ */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index c7e51b85b8b6..77ac41feb0fe 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -2561,7 +2561,7 @@ s32 ixgbe_disable_rx_buff_generic(struct ixgbe_hw *hw)
break;
else
/* Use interrupt-safe sleep just in case */
- udelay(10);
+ udelay(1000);
}
/* For informational purposes only */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
index d3695edfcb8b..87592b458c9c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
@@ -191,53 +191,46 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
*/
s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
{
- u32 reg;
+ u32 fcrtl, reg;
u8 i;
- if (pfc_en) {
- /* Enable Transmit Priority Flow Control */
- reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
- reg &= ~IXGBE_RMCS_TFCE_802_3X;
- /* correct the reporting of our flow control status */
- reg |= IXGBE_RMCS_TFCE_PRIORITY;
- IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
-
- /* Enable Receive Priority Flow Control */
- reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- reg &= ~IXGBE_FCTRL_RFCE;
- reg |= IXGBE_FCTRL_RPFCE;
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
-
- /* Configure pause time */
- for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++)
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800);
+ /* Enable Transmit Priority Flow Control */
+ reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
+ reg &= ~IXGBE_RMCS_TFCE_802_3X;
+ reg |= IXGBE_RMCS_TFCE_PRIORITY;
+ IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
- /* Configure flow control refresh threshold value */
- IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400);
- }
+ /* Enable Receive Priority Flow Control */
+ reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE);
- /*
- * Configure flow control thresholds and enable priority flow control
- * for each traffic class.
- */
- for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
- int enabled = pfc_en & (1 << i);
+ if (pfc_en)
+ reg |= IXGBE_FCTRL_RPFCE;
- reg = hw->fc.low_water << 10;
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
- if (enabled == pfc_enabled_tx ||
- enabled == pfc_enabled_full)
- reg |= IXGBE_FCRTL_XONE;
+ fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
+ /* Configure PFC Tx thresholds per TC */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ if (!(pfc_en & (1 << i))) {
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
+ continue;
+ }
+
+ reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
+ }
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg);
+ /* Configure pause time */
+ reg = hw->fc.pause_time * 0x00010001;
+ for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
- reg = hw->fc.high_water[i] << 10;
- if (enabled == pfc_enabled_tx ||
- enabled == pfc_enabled_full)
- reg |= IXGBE_FCRTH_FCEN;
+ /* Configure flow control refresh threshold value */
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
- }
return 0;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
index 65913c5a616e..4eac80d01857 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
@@ -211,24 +211,42 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
*/
s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
{
- u32 i, j, reg;
+ u32 i, j, fcrtl, reg;
u8 max_tc = 0;
- for (i = 0; i < MAX_USER_PRIORITY; i++)
+ /* Enable Transmit Priority Flow Control */
+ IXGBE_WRITE_REG(hw, IXGBE_FCCFG, IXGBE_FCCFG_TFCE_PRIORITY);
+
+ /* Enable Receive Priority Flow Control */
+ reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ reg |= IXGBE_MFLCN_DPF;
+
+ /*
+ * X540 supports per TC Rx priority flow control. So
+ * clear all TCs and only enable those that should be
+ * enabled.
+ */
+ reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
+
+ if (hw->mac.type == ixgbe_mac_X540)
+ reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
+
+ if (pfc_en)
+ reg |= IXGBE_MFLCN_RPFCE;
+
+ IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
+
+ for (i = 0; i < MAX_USER_PRIORITY; i++) {
if (prio_tc[i] > max_tc)
max_tc = prio_tc[i];
+ }
+
+ fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
/* Configure PFC Tx thresholds per TC */
- for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ for (i = 0; i <= max_tc; i++) {
int enabled = 0;
- if (i > max_tc) {
- reg = 0;
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
- IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
- continue;
- }
-
for (j = 0; j < MAX_USER_PRIORITY; j++) {
if ((prio_tc[j] == i) && (pfc_en & (1 << j))) {
enabled = 1;
@@ -236,50 +254,29 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
}
}
- reg = hw->fc.low_water << 10;
-
- if (enabled)
- reg |= IXGBE_FCRTL_XONE;
- IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
+ if (enabled) {
+ reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
+ } else {
+ reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
+ }
- reg = hw->fc.high_water[i] << 10;
- if (enabled)
- reg |= IXGBE_FCRTH_FCEN;
IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
}
- if (pfc_en) {
- /* Configure pause time (2 TCs per register) */
- reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
- for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
-
- /* Configure flow control refresh threshold value */
- IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
-
-
- reg = IXGBE_FCCFG_TFCE_PRIORITY;
- IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
- /*
- * Enable Receive PFC
- * 82599 will always honor XOFF frames we receive when
- * we are in PFC mode however X540 only honors enabled
- * traffic classes.
- */
- reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
- reg &= ~IXGBE_MFLCN_RFCE;
- reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF;
-
- if (hw->mac.type == ixgbe_mac_X540) {
- reg &= ~IXGBE_MFLCN_RPFCE_MASK;
- reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
- }
+ for (; i < MAX_TRAFFIC_CLASS; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0);
+ }
- IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
+ /* Configure pause time (2 TCs per register) */
+ reg = hw->fc.pause_time * 0x00010001;
+ for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
- } else {
- hw->mac.ops.fc_enable(hw);
- }
+ /* Configure flow control refresh threshold value */
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
return 0;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
index a09d6b4f0ab0..5164a21b13ca 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c
@@ -338,6 +338,8 @@ static void ixgbe_dcbnl_devreset(struct net_device *dev)
static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg;
+ struct ixgbe_hw *hw = &adapter->hw;
int ret = DCB_NO_HW_CHG;
int i;
@@ -350,32 +352,6 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
if (!adapter->dcb_set_bitmap)
return ret;
- if (adapter->dcb_cfg.pfc_mode_enable) {
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- if (adapter->hw.fc.current_mode != ixgbe_fc_pfc)
- adapter->last_lfc_mode =
- adapter->hw.fc.current_mode;
- break;
- default:
- break;
- }
- adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
- } else {
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- adapter->hw.fc.requested_mode = ixgbe_fc_none;
- break;
- case ixgbe_mac_82599EB:
- case ixgbe_mac_X540:
- adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
- break;
- default:
- break;
- }
- }
-
if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) {
u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS];
u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS];
@@ -388,23 +364,19 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
#endif
- ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg,
- max_frame, DCB_TX_CONFIG);
- ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg,
- max_frame, DCB_RX_CONFIG);
+ ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame,
+ DCB_TX_CONFIG);
+ ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame,
+ DCB_RX_CONFIG);
- ixgbe_dcb_unpack_refill(&adapter->dcb_cfg,
- DCB_TX_CONFIG, refill);
- ixgbe_dcb_unpack_max(&adapter->dcb_cfg, max);
- ixgbe_dcb_unpack_bwgid(&adapter->dcb_cfg,
- DCB_TX_CONFIG, bwg_id);
- ixgbe_dcb_unpack_prio(&adapter->dcb_cfg,
- DCB_TX_CONFIG, prio_type);
- ixgbe_dcb_unpack_map(&adapter->dcb_cfg,
- DCB_TX_CONFIG, prio_tc);
+ ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill);
+ ixgbe_dcb_unpack_max(dcb_cfg, max);
+ ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id);
+ ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type);
+ ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc);
- ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max,
- bwg_id, prio_type, prio_tc);
+ ixgbe_dcb_hw_ets_config(hw, refill, max, bwg_id,
+ prio_type, prio_tc);
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
netdev_set_prio_tc_map(netdev, i, prio_tc[i]);
@@ -413,19 +385,21 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
}
if (adapter->dcb_set_bitmap & BIT_PFC) {
- u8 pfc_en;
- u8 prio_tc[MAX_USER_PRIORITY];
+ if (dcb_cfg->pfc_mode_enable) {
+ u8 pfc_en;
+ u8 prio_tc[MAX_USER_PRIORITY];
+
+ ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc);
+ ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en);
+ ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc);
+ } else {
+ hw->mac.ops.fc_enable(hw);
+ }
- ixgbe_dcb_unpack_map(&adapter->dcb_cfg,
- DCB_TX_CONFIG, prio_tc);
- ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en);
- ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en, prio_tc);
- if (ret != DCB_HW_CHG_RST)
- ret = DCB_HW_CHG;
- }
+ ixgbe_set_rx_drop_en(adapter);
- if (adapter->dcb_cfg.pfc_mode_enable)
- adapter->hw.fc.current_mode = ixgbe_fc_pfc;
+ ret = DCB_HW_CHG;
+ }
#ifdef IXGBE_FCOE
/* Reprogam FCoE hardware offloads when the traffic class
@@ -647,7 +621,9 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
struct ieee_pfc *pfc)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
+ struct ixgbe_hw *hw = &adapter->hw;
u8 *prio_tc;
+ int err;
if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
return -EINVAL;
@@ -659,16 +635,18 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
return -ENOMEM;
}
- if (pfc->pfc_en) {
- adapter->last_lfc_mode = adapter->hw.fc.current_mode;
- adapter->hw.fc.current_mode = ixgbe_fc_pfc;
- } else {
- adapter->hw.fc.current_mode = adapter->last_lfc_mode;
- }
-
prio_tc = adapter->ixgbe_ieee_ets->prio_tc;
memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc));
- return ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en, prio_tc);
+
+ /* Enable link flow control parameters if PFC is disabled */
+ if (pfc->pfc_en)
+ err = ixgbe_dcb_hw_pfc_config(hw, pfc->pfc_en, prio_tc);
+ else
+ err = hw->mac.ops.fc_enable(hw);
+
+ ixgbe_set_rx_drop_en(adapter);
+
+ return err;
}
static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index cca3e9c4a08a..3178f1ec3711 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -391,11 +391,6 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
} else if (hw->fc.current_mode == ixgbe_fc_full) {
pause->rx_pause = 1;
pause->tx_pause = 1;
-#ifdef CONFIG_DCB
- } else if (hw->fc.current_mode == ixgbe_fc_pfc) {
- pause->rx_pause = 0;
- pause->tx_pause = 0;
-#endif
}
}
@@ -404,21 +399,14 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
- struct ixgbe_fc_info fc;
+ struct ixgbe_fc_info fc = hw->fc;
-#ifdef CONFIG_DCB
- if (adapter->dcb_cfg.pfc_mode_enable ||
- ((hw->mac.type == ixgbe_mac_82598EB) &&
- (adapter->flags & IXGBE_FLAG_DCB_ENABLED)))
+ /* 82598 does no support link flow control with DCB enabled */
+ if ((hw->mac.type == ixgbe_mac_82598EB) &&
+ (adapter->flags & IXGBE_FLAG_DCB_ENABLED))
return -EINVAL;
-#endif
- fc = hw->fc;
-
- if (pause->autoneg != AUTONEG_ENABLE)
- fc.disable_fc_autoneg = true;
- else
- fc.disable_fc_autoneg = false;
+ fc.disable_fc_autoneg = (pause->autoneg != AUTONEG_ENABLE);
if ((pause->rx_pause && pause->tx_pause) || pause->autoneg)
fc.requested_mode = ixgbe_fc_full;
@@ -426,14 +414,8 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
fc.requested_mode = ixgbe_fc_rx_pause;
else if (!pause->rx_pause && pause->tx_pause)
fc.requested_mode = ixgbe_fc_tx_pause;
- else if (!pause->rx_pause && !pause->tx_pause)
- fc.requested_mode = ixgbe_fc_none;
else
- return -EINVAL;
-
-#ifdef CONFIG_DCB
- adapter->last_lfc_mode = fc.requested_mode;
-#endif
+ fc.requested_mode = ixgbe_fc_none;
/* if the thing changed then we'll update and use new autoneg */
if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) {
@@ -2714,6 +2696,46 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
return ret;
}
+static int ixgbe_get_ts_info(struct net_device *dev,
+ struct ethtool_ts_info *info)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+
+ switch (adapter->hw.mac.type) {
+#ifdef CONFIG_IXGBE_PTP
+ case ixgbe_mac_X540:
+ case ixgbe_mac_82599EB:
+ info->so_timestamping =
+ SOF_TIMESTAMPING_TX_HARDWARE |
+ SOF_TIMESTAMPING_RX_HARDWARE |
+ SOF_TIMESTAMPING_RAW_HARDWARE;
+
+ if (adapter->ptp_clock)
+ info->phc_index = ptp_clock_index(adapter->ptp_clock);
+ else
+ info->phc_index = -1;
+
+ info->tx_types =
+ (1 << HWTSTAMP_TX_OFF) |
+ (1 << HWTSTAMP_TX_ON);
+
+ info->rx_filters =
+ (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
+ (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
+ (1 << HWTSTAMP_FILTER_SOME);
+ break;
+#endif /* CONFIG_IXGBE_PTP */
+ default:
+ return ethtool_op_get_ts_info(dev, info);
+ break;
+ }
+ return 0;
+}
+
static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_settings = ixgbe_get_settings,
.set_settings = ixgbe_set_settings,
@@ -2742,6 +2764,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.set_coalesce = ixgbe_set_coalesce,
.get_rxnfc = ixgbe_get_rxnfc,
.set_rxnfc = ixgbe_set_rxnfc,
+ .get_ts_info = ixgbe_get_ts_info,
};
void ixgbe_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index ea3cb710c2dd..bf20457ea23a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -63,8 +63,8 @@ static char ixgbe_default_device_descr[] =
"Intel(R) 10 Gigabit Network Connection";
#endif
#define MAJ 3
-#define MIN 8
-#define BUILD 21
+#define MIN 9
+#define BUILD 15
#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
__stringify(BUILD) "-k"
const char ixgbe_driver_version[] = DRV_VERSION;
@@ -610,39 +610,50 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *ring,
/* tx_buffer must be completely set up in the transmit path */
}
-static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter)
+static void ixgbe_update_xoff_rx_lfc(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
struct ixgbe_hw_stats *hwstats = &adapter->stats;
- u32 data = 0;
- u32 xoff[8] = {0};
int i;
+ u32 data;
- if ((hw->fc.current_mode == ixgbe_fc_full) ||
- (hw->fc.current_mode == ixgbe_fc_rx_pause)) {
- switch (hw->mac.type) {
- case ixgbe_mac_82598EB:
- data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
- break;
- default:
- data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
- }
- hwstats->lxoffrxc += data;
+ if ((hw->fc.current_mode != ixgbe_fc_full) &&
+ (hw->fc.current_mode != ixgbe_fc_rx_pause))
+ return;
- /* refill credits (no tx hang) if we received xoff */
- if (!data)
- return;
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
+ break;
+ default:
+ data = IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+ }
+ hwstats->lxoffrxc += data;
- for (i = 0; i < adapter->num_tx_queues; i++)
- clear_bit(__IXGBE_HANG_CHECK_ARMED,
- &adapter->tx_ring[i]->state);
+ /* refill credits (no tx hang) if we received xoff */
+ if (!data)
return;
- } else if (((adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE) &&
- !(adapter->dcb_cfg.pfc_mode_enable)) ||
- ((adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) &&
- adapter->ixgbe_ieee_pfc &&
- !(adapter->ixgbe_ieee_pfc->pfc_en)))
+
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ clear_bit(__IXGBE_HANG_CHECK_ARMED,
+ &adapter->tx_ring[i]->state);
+}
+
+static void ixgbe_update_xoff_received(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct ixgbe_hw_stats *hwstats = &adapter->stats;
+ u32 xoff[8] = {0};
+ int i;
+ bool pfc_en = adapter->dcb_cfg.pfc_mode_enable;
+
+ if (adapter->ixgbe_ieee_pfc)
+ pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en);
+
+ if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) || !pfc_en) {
+ ixgbe_update_xoff_rx_lfc(adapter);
return;
+ }
/* update stats for each tc, only valid with PFC enabled */
for (i = 0; i < MAX_TX_PACKET_BUFFERS; i++) {
@@ -778,6 +789,13 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
total_bytes += tx_buffer->bytecount;
total_packets += tx_buffer->gso_segs;
+#ifdef CONFIG_IXGBE_PTP
+ if (unlikely(tx_buffer->tx_flags &
+ IXGBE_TX_FLAGS_TSTAMP))
+ ixgbe_ptp_tx_hwtstamp(q_vector,
+ tx_buffer->skb);
+
+#endif
/* free the skb */
dev_kfree_skb_any(tx_buffer->skb);
@@ -1378,6 +1396,11 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
ixgbe_rx_checksum(rx_ring, rx_desc, skb);
+#ifdef CONFIG_IXGBE_PTP
+ if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS))
+ ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb);
+#endif
+
if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) {
u16 vid = le16_to_cpu(rx_desc->wb.upper.vlan);
__vlan_hwaccel_put_tag(skb, vid);
@@ -2299,6 +2322,9 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data)
}
ixgbe_check_fan_failure(adapter, eicr);
+#ifdef CONFIG_IXGBE_PTP
+ ixgbe_ptp_check_pps_event(adapter, eicr);
+#endif
/* re-enable the original interrupt state, no lsc, no queues */
if (!test_bit(__IXGBE_DOWN, &adapter->state))
@@ -2491,6 +2517,9 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
}
ixgbe_check_fan_failure(adapter, eicr);
+#ifdef CONFIG_IXGBE_PTP
+ ixgbe_ptp_check_pps_event(adapter, eicr);
+#endif
/* would disable interrupts here but EIAM disabled it */
napi_schedule(&q_vector->napi);
@@ -2760,6 +2789,61 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]);
}
+static void ixgbe_enable_rx_drop(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u8 reg_idx = ring->reg_idx;
+ u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(reg_idx));
+
+ srrctl |= IXGBE_SRRCTL_DROP_EN;
+
+ IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl);
+}
+
+static void ixgbe_disable_rx_drop(struct ixgbe_adapter *adapter,
+ struct ixgbe_ring *ring)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u8 reg_idx = ring->reg_idx;
+ u32 srrctl = IXGBE_READ_REG(hw, IXGBE_SRRCTL(reg_idx));
+
+ srrctl &= ~IXGBE_SRRCTL_DROP_EN;
+
+ IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(reg_idx), srrctl);
+}
+
+#ifdef CONFIG_IXGBE_DCB
+void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter)
+#else
+static void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter)
+#endif
+{
+ int i;
+ bool pfc_en = adapter->dcb_cfg.pfc_mode_enable;
+
+ if (adapter->ixgbe_ieee_pfc)
+ pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en);
+
+ /*
+ * We should set the drop enable bit if:
+ * SR-IOV is enabled
+ * or
+ * Number of Rx queues > 1 and flow control is disabled
+ *
+ * This allows us to avoid head of line blocking for security
+ * and performance reasons.
+ */
+ if (adapter->num_vfs || (adapter->num_rx_queues > 1 &&
+ !(adapter->hw.fc.current_mode & ixgbe_fc_tx_pause) && !pfc_en)) {
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ ixgbe_enable_rx_drop(adapter, adapter->rx_ring[i]);
+ } else {
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ ixgbe_disable_rx_drop(adapter, adapter->rx_ring[i]);
+ }
+}
+
#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
@@ -4403,9 +4487,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
/* default flow control settings */
hw->fc.requested_mode = ixgbe_fc_full;
hw->fc.current_mode = ixgbe_fc_full; /* init for ethtool output */
-#ifdef CONFIG_DCB
- adapter->last_lfc_mode = hw->fc.current_mode;
-#endif
ixgbe_pbthresh_setup(adapter);
hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
hw->fc.send_xon = true;
@@ -5268,8 +5349,10 @@ static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter)
if (adapter->ixgbe_ieee_pfc)
pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en);
- if (link_up && !((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && pfc_en))
+ if (link_up && !((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && pfc_en)) {
hw->mac.ops.fc_enable(hw);
+ ixgbe_set_rx_drop_en(adapter);
+ }
if (link_up ||
time_after(jiffies, (adapter->link_check_timeout +
@@ -5322,6 +5405,11 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
flow_rx = false;
break;
}
+
+#ifdef CONFIG_IXGBE_PTP
+ ixgbe_ptp_start_cyclecounter(adapter);
+#endif
+
e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
(link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
"10 Gbps" :
@@ -5359,6 +5447,10 @@ static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter *adapter)
if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB)
adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
+#ifdef CONFIG_IXGBE_PTP
+ ixgbe_ptp_start_cyclecounter(adapter);
+#endif
+
e_info(drv, "NIC Link is Down\n");
netif_carrier_off(netdev);
}
@@ -5658,6 +5750,9 @@ static void ixgbe_service_task(struct work_struct *work)
ixgbe_watchdog_subtask(adapter);
ixgbe_fdir_reinit_subtask(adapter);
ixgbe_check_hang_subtask(adapter);
+#ifdef CONFIG_IXGBE_PTP
+ ixgbe_ptp_overflow_check(adapter);
+#endif
ixgbe_service_event_complete(adapter);
}
@@ -5808,6 +5903,11 @@ static __le32 ixgbe_tx_cmd_type(u32 tx_flags)
if (tx_flags & IXGBE_TX_FLAGS_HW_VLAN)
cmd_type |= cpu_to_le32(IXGBE_ADVTXD_DCMD_VLE);
+#ifdef CONFIG_IXGBE_PTP
+ if (tx_flags & IXGBE_TX_FLAGS_TSTAMP)
+ cmd_type |= cpu_to_le32(IXGBE_ADVTXD_MAC_TSTAMP);
+#endif
+
/* set segmentation enable bits for TSO/FSO */
#ifdef IXGBE_FCOE
if (tx_flags & (IXGBE_TX_FLAGS_TSO | IXGBE_TX_FLAGS_FSO))
@@ -6198,6 +6298,15 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
tx_flags |= IXGBE_TX_FLAGS_SW_VLAN;
}
+ skb_tx_timestamp(skb);
+
+#ifdef CONFIG_IXGBE_PTP
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+ tx_flags |= IXGBE_TX_FLAGS_TSTAMP;
+ }
+#endif
+
#ifdef CONFIG_PCI_IOV
/*
* Use the l2switch_enable flag - would be false if the DMA
@@ -6350,7 +6459,14 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
+ switch (cmd) {
+#ifdef CONFIG_IXGBE_PTP
+ case SIOCSHWTSTAMP:
+ return ixgbe_ptp_hwtstamp_ioctl(adapter, req, cmd);
+#endif
+ default:
+ return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
+ }
}
/**
@@ -6542,15 +6658,17 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
if (tc) {
netdev_set_num_tc(dev, tc);
- adapter->last_lfc_mode = adapter->hw.fc.current_mode;
adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
- if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ adapter->last_lfc_mode = adapter->hw.fc.requested_mode;
adapter->hw.fc.requested_mode = ixgbe_fc_none;
+ }
} else {
netdev_reset_tc(dev);
- adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
@@ -7135,6 +7253,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+#ifdef CONFIG_IXGBE_PTP
+ ixgbe_ptp_init(adapter);
+#endif /* CONFIG_IXGBE_PTP*/
+
/* save off EEPROM version number */
hw->eeprom.ops.read(hw, 0x2e, &adapter->eeprom_verh);
hw->eeprom.ops.read(hw, 0x2d, &adapter->eeprom_verl);
@@ -7222,8 +7344,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
e_dev_info("%s\n", ixgbe_default_device_descr);
cards_found++;
+#ifdef CONFIG_IXGBE_HWMON
if (ixgbe_sysfs_init(adapter))
e_err(probe, "failed to allocate sysfs resources\n");
+#endif /* CONFIG_IXGBE_HWMON */
return 0;
@@ -7263,6 +7387,10 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
set_bit(__IXGBE_DOWN, &adapter->state);
cancel_work_sync(&adapter->service_task);
+#ifdef CONFIG_IXGBE_PTP
+ ixgbe_ptp_stop(adapter);
+#endif
+
#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
@@ -7271,7 +7399,9 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
}
#endif
+#ifdef CONFIG_IXGBE_HWMON
ixgbe_sysfs_exit(adapter);
+#endif /* CONFIG_IXGBE_HWMON */
#ifdef IXGBE_FCOE
if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
new file mode 100644
index 000000000000..ddc6a4d19302
--- /dev/null
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -0,0 +1,900 @@
+/*******************************************************************************
+
+ Intel 10 Gigabit PCI Express Linux driver
+ Copyright(c) 1999 - 2012 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 "ixgbe.h"
+#include <linux/export.h>
+
+/*
+ * The 82599 and the X540 do not have true 64bit nanosecond scale
+ * counter registers. Instead, SYSTIME is defined by a fixed point
+ * system which allows the user to define the scale counter increment
+ * value at every level change of the oscillator driving the SYSTIME
+ * value. For both devices the TIMINCA:IV field defines this
+ * increment. On the X540 device, 31 bits are provided. However on the
+ * 82599 only provides 24 bits. The time unit is determined by the
+ * clock frequency of the oscillator in combination with the TIMINCA
+ * register. When these devices link at 10Gb the oscillator has a
+ * period of 6.4ns. In order to convert the scale counter into
+ * nanoseconds the cyclecounter and timecounter structures are
+ * used. The SYSTIME registers need to be converted to ns values by use
+ * of only a right shift (division by power of 2). The following math
+ * determines the largest incvalue that will fit into the available
+ * bits in the TIMINCA register.
+ *
+ * PeriodWidth: Number of bits to store the clock period
+ * MaxWidth: The maximum width value of the TIMINCA register
+ * Period: The clock period for the oscillator
+ * round(): discard the fractional portion of the calculation
+ *
+ * Period * [ 2 ^ ( MaxWidth - PeriodWidth ) ]
+ *
+ * For the X540, MaxWidth is 31 bits, and the base period is 6.4 ns
+ * For the 82599, MaxWidth is 24 bits, and the base period is 6.4 ns
+ *
+ * The period also changes based on the link speed:
+ * At 10Gb link or no link, the period remains the same.
+ * At 1Gb link, the period is multiplied by 10. (64ns)
+ * At 100Mb link, the period is multiplied by 100. (640ns)
+ *
+ * The calculated value allows us to right shift the SYSTIME register
+ * value in order to quickly convert it into a nanosecond clock,
+ * while allowing for the maximum possible adjustment value.
+ *
+ * These diagrams are only for the 10Gb link period
+ *
+ * SYSTIMEH SYSTIMEL
+ * +--------------+ +--------------+
+ * X540 | 32 | | 1 | 3 | 28 |
+ * *--------------+ +--------------+
+ * \________ 36 bits ______/ fract
+ *
+ * +--------------+ +--------------+
+ * 82599 | 32 | | 8 | 3 | 21 |
+ * *--------------+ +--------------+
+ * \________ 43 bits ______/ fract
+ *
+ * The 36 bit X540 SYSTIME overflows every
+ * 2^36 * 10^-9 / 60 = 1.14 minutes or 69 seconds
+ *
+ * The 43 bit 82599 SYSTIME overflows every
+ * 2^43 * 10^-9 / 3600 = 2.4 hours
+ */
+#define IXGBE_INCVAL_10GB 0x66666666
+#define IXGBE_INCVAL_1GB 0x40000000
+#define IXGBE_INCVAL_100 0x50000000
+
+#define IXGBE_INCVAL_SHIFT_10GB 28
+#define IXGBE_INCVAL_SHIFT_1GB 24
+#define IXGBE_INCVAL_SHIFT_100 21
+
+#define IXGBE_INCVAL_SHIFT_82599 7
+#define IXGBE_INCPER_SHIFT_82599 24
+#define IXGBE_MAX_TIMEADJ_VALUE 0x7FFFFFFFFFFFFFFFULL
+
+#define IXGBE_OVERFLOW_PERIOD (HZ * 30)
+
+#ifndef NSECS_PER_SEC
+#define NSECS_PER_SEC 1000000000ULL
+#endif
+
+/**
+ * ixgbe_ptp_read - read raw cycle counter (to be used by time counter)
+ * @cc - the cyclecounter structure
+ *
+ * this function reads the cyclecounter registers and is called by the
+ * cyclecounter structure used to construct a ns counter from the
+ * arbitrary fixed point registers
+ */
+static cycle_t ixgbe_ptp_read(const struct cyclecounter *cc)
+{
+ struct ixgbe_adapter *adapter =
+ container_of(cc, struct ixgbe_adapter, cc);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u64 stamp = 0;
+
+ stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
+ stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
+
+ return stamp;
+}
+
+/**
+ * ixgbe_ptp_adjfreq
+ * @ptp - the ptp clock structure
+ * @ppb - parts per billion adjustment from base
+ *
+ * adjust the frequency of the ptp cycle counter by the
+ * indicated ppb from the base frequency.
+ */
+static int ixgbe_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+ struct ixgbe_adapter *adapter =
+ container_of(ptp, struct ixgbe_adapter, ptp_caps);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u64 freq;
+ u32 diff, incval;
+ int neg_adj = 0;
+
+ if (ppb < 0) {
+ neg_adj = 1;
+ ppb = -ppb;
+ }
+
+ smp_mb();
+ incval = ACCESS_ONCE(adapter->base_incval);
+
+ freq = incval;
+ freq *= ppb;
+ diff = div_u64(freq, 1000000000ULL);
+
+ incval = neg_adj ? (incval - diff) : (incval + diff);
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_X540:
+ IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval);
+ break;
+ case ixgbe_mac_82599EB:
+ IXGBE_WRITE_REG(hw, IXGBE_TIMINCA,
+ (1 << IXGBE_INCPER_SHIFT_82599) |
+ incval);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_ptp_adjtime
+ * @ptp - the ptp clock structure
+ * @delta - offset to adjust the cycle counter by
+ *
+ * adjust the timer by resetting the timecounter structure.
+ */
+static int ixgbe_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+ struct ixgbe_adapter *adapter =
+ container_of(ptp, struct ixgbe_adapter, ptp_caps);
+ unsigned long flags;
+ u64 now;
+
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+
+ now = timecounter_read(&adapter->tc);
+ now += delta;
+
+ /* reset the timecounter */
+ timecounter_init(&adapter->tc,
+ &adapter->cc,
+ now);
+
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+ return 0;
+}
+
+/**
+ * ixgbe_ptp_gettime
+ * @ptp - the ptp clock structure
+ * @ts - timespec structure to hold the current time value
+ *
+ * read the timecounter and return the correct value on ns,
+ * after converting it into a struct timespec.
+ */
+static int ixgbe_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+ struct ixgbe_adapter *adapter =
+ container_of(ptp, struct ixgbe_adapter, ptp_caps);
+ u64 ns;
+ u32 remainder;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+ ns = timecounter_read(&adapter->tc);
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+
+ ts->tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder);
+ ts->tv_nsec = remainder;
+
+ return 0;
+}
+
+/**
+ * ixgbe_ptp_settime
+ * @ptp - the ptp clock structure
+ * @ts - the timespec containing the new time for the cycle counter
+ *
+ * reset the timecounter to use a new base value instead of the kernel
+ * wall timer value.
+ */
+static int ixgbe_ptp_settime(struct ptp_clock_info *ptp,
+ const struct timespec *ts)
+{
+ struct ixgbe_adapter *adapter =
+ container_of(ptp, struct ixgbe_adapter, ptp_caps);
+ u64 ns;
+ unsigned long flags;
+
+ ns = ts->tv_sec * 1000000000ULL;
+ ns += ts->tv_nsec;
+
+ /* reset the timecounter */
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+ timecounter_init(&adapter->tc, &adapter->cc, ns);
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+
+ return 0;
+}
+
+/**
+ * ixgbe_ptp_enable
+ * @ptp - the ptp clock structure
+ * @rq - the requested feature to change
+ * @on - whether to enable or disable the feature
+ *
+ * enable (or disable) ancillary features of the phc subsystem.
+ * our driver only supports the PPS feature on the X540
+ */
+static int ixgbe_ptp_enable(struct ptp_clock_info *ptp,
+ struct ptp_clock_request *rq, int on)
+{
+ struct ixgbe_adapter *adapter =
+ container_of(ptp, struct ixgbe_adapter, ptp_caps);
+
+ /**
+ * When PPS is enabled, unmask the interrupt for the ClockOut
+ * feature, so that the interrupt handler can send the PPS
+ * event when the clock SDP triggers. Clear mask when PPS is
+ * disabled
+ */
+ if (rq->type == PTP_CLK_REQ_PPS) {
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_X540:
+ if (on)
+ adapter->flags2 |= IXGBE_FLAG2_PTP_PPS_ENABLED;
+ else
+ adapter->flags2 &=
+ ~IXGBE_FLAG2_PTP_PPS_ENABLED;
+ return 0;
+ default:
+ break;
+ }
+ }
+
+ return -ENOTSUPP;
+}
+
+/**
+ * ixgbe_ptp_check_pps_event
+ * @adapter - the private adapter structure
+ * @eicr - the interrupt cause register value
+ *
+ * This function is called by the interrupt routine when checking for
+ * interrupts. It will check and handle a pps event.
+ */
+void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct ptp_clock_event event;
+
+ event.type = PTP_CLOCK_PPS;
+
+ /* Make sure ptp clock is valid, and PPS event enabled */
+ if (!adapter->ptp_clock ||
+ !(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED))
+ return;
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_X540:
+ if (eicr & IXGBE_EICR_TIMESYNC)
+ ptp_clock_event(adapter->ptp_clock, &event);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * ixgbe_ptp_enable_sdp
+ * @hw - the hardware private structure
+ * @shift - the clock shift for calculating nanoseconds
+ *
+ * this function enables the clock out feature on the sdp0 for the
+ * X540 device. It will create a 1second periodic output that can be
+ * used as the PPS (via an interrupt).
+ *
+ * It calculates when the systime will be on an exact second, and then
+ * aligns the start of the PPS signal to that value. The shift is
+ * necessary because it can change based on the link speed.
+ */
+static void ixgbe_ptp_enable_sdp(struct ixgbe_hw *hw, int shift)
+{
+ u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh;
+ u64 clock_edge = 0;
+ u32 rem;
+
+ switch (hw->mac.type) {
+ case ixgbe_mac_X540:
+ esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+
+ /*
+ * enable the SDP0 pin as output, and connected to the native
+ * function for Timesync (ClockOut)
+ */
+ esdp |= (IXGBE_ESDP_SDP0_DIR |
+ IXGBE_ESDP_SDP0_NATIVE);
+
+ /*
+ * enable the Clock Out feature on SDP0, and allow interrupts
+ * to occur when the pin changes
+ */
+ tsauxc = (IXGBE_TSAUXC_EN_CLK |
+ IXGBE_TSAUXC_SYNCLK |
+ IXGBE_TSAUXC_SDP0_INT);
+
+ /* clock period (or pulse length) */
+ clktiml = (u32)(NSECS_PER_SEC << shift);
+ clktimh = (u32)((NSECS_PER_SEC << shift) >> 32);
+
+ clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
+ clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
+
+ /*
+ * account for the fact that we can't do u64 division
+ * with remainder, by converting the clock values into
+ * nanoseconds first
+ */
+ clock_edge >>= shift;
+ div_u64_rem(clock_edge, NSECS_PER_SEC, &rem);
+ clock_edge += (NSECS_PER_SEC - rem);
+ clock_edge <<= shift;
+
+ /* specify the initial clock start time */
+ trgttiml = (u32)clock_edge;
+ trgttimh = (u32)(clock_edge >> 32);
+
+ IXGBE_WRITE_REG(hw, IXGBE_CLKTIML, clktiml);
+ IXGBE_WRITE_REG(hw, IXGBE_CLKTIMH, clktimh);
+ IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml);
+ IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh);
+
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+ IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc);
+
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EICR_TIMESYNC);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * ixgbe_ptp_disable_sdp
+ * @hw - the private hardware structure
+ *
+ * this function disables the auxiliary SDP clock out feature
+ */
+static void ixgbe_ptp_disable_sdp(struct ixgbe_hw *hw)
+{
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_TIMESYNC);
+ IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0);
+}
+
+/**
+ * ixgbe_ptp_overflow_check - delayed work to detect SYSTIME overflow
+ * @work: structure containing information about this work task
+ *
+ * this work function is scheduled to continue reading the timecounter
+ * in order to prevent missing when the system time registers wrap
+ * around. This needs to be run approximately twice a minute when no
+ * PTP activity is occurring.
+ */
+void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter)
+{
+ unsigned long elapsed_jiffies = adapter->last_overflow_check - jiffies;
+ struct timespec ts;
+
+ if ((adapter->flags2 & IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED) &&
+ (elapsed_jiffies >= IXGBE_OVERFLOW_PERIOD)) {
+ ixgbe_ptp_gettime(&adapter->ptp_caps, &ts);
+ adapter->last_overflow_check = jiffies;
+ }
+}
+
+/**
+ * ixgbe_ptp_tx_hwtstamp - utility function which checks for TX time stamp
+ * @q_vector: structure containing interrupt and ring information
+ * @skb: particular skb to send timestamp with
+ *
+ * if the timestamp is valid, we convert it into the timecounter ns
+ * value, then store that result into the shhwtstamps structure which
+ * is passed up the network stack
+ */
+void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector,
+ struct sk_buff *skb)
+{
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_hw *hw;
+ struct skb_shared_hwtstamps shhwtstamps;
+ u64 regval = 0, ns;
+ u32 tsynctxctl;
+ unsigned long flags;
+
+ /* we cannot process timestamps on a ring without a q_vector */
+ if (!q_vector || !q_vector->adapter)
+ return;
+
+ adapter = q_vector->adapter;
+ hw = &adapter->hw;
+
+ tsynctxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPL);
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_TXSTMPH) << 32;
+
+ /*
+ * if TX timestamp is not valid, exit after clearing the
+ * timestamp registers
+ */
+ if (!(tsynctxctl & IXGBE_TSYNCTXCTL_VALID))
+ return;
+
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+ ns = timecounter_cyc2time(&adapter->tc, regval);
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+ shhwtstamps.hwtstamp = ns_to_ktime(ns);
+ skb_tstamp_tx(skb, &shhwtstamps);
+}
+
+/**
+ * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
+ * @q_vector: structure containing interrupt and ring information
+ * @skb: particular skb to send timestamp with
+ *
+ * if the timestamp is valid, we convert it into the timecounter ns
+ * value, then store that result into the shhwtstamps structure which
+ * is passed up the network stack
+ */
+void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
+ struct sk_buff *skb)
+{
+ struct ixgbe_adapter *adapter;
+ struct ixgbe_hw *hw;
+ struct skb_shared_hwtstamps *shhwtstamps;
+ u64 regval = 0, ns;
+ u32 tsyncrxctl;
+ unsigned long flags;
+
+ /* we cannot process timestamps on a ring without a q_vector */
+ if (!q_vector || !q_vector->adapter)
+ return;
+
+ adapter = q_vector->adapter;
+ hw = &adapter->hw;
+
+ tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
+ regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
+
+ /*
+ * If this bit is set, then the RX registers contain the time stamp. No
+ * other packet will be time stamped until we read these registers, so
+ * read the registers to make them available again. Because only one
+ * packet can be time stamped at a time, we know that the register
+ * values must belong to this one here and therefore we don't need to
+ * compare any of the additional attributes stored for it.
+ *
+ * If nothing went wrong, then it should have a skb_shared_tx that we
+ * can turn into a skb_shared_hwtstamps.
+ */
+ if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
+ return;
+
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+ ns = timecounter_cyc2time(&adapter->tc, regval);
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+
+ shhwtstamps = skb_hwtstamps(skb);
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+}
+
+/**
+ * ixgbe_ptp_hwtstamp_ioctl - control hardware time stamping
+ * @adapter: pointer to adapter struct
+ * @ifreq: ioctl data
+ * @cmd: particular ioctl requested
+ *
+ * Outgoing time stamping can be enabled and disabled. Play nice and
+ * disable it when requested, although it shouldn't case any overhead
+ * when no packet needs it. At most one packet in the queue may be
+ * marked for time stamping, otherwise it would be impossible to tell
+ * for sure to which packet the hardware time stamp belongs.
+ *
+ * Incoming time stamping has to be configured via the hardware
+ * filters. Not all combinations are supported, in particular event
+ * type has to be specified. Matching the kind of event packet is
+ * not supported, with the exception of "all V2 events regardless of
+ * level 2 or 4".
+ */
+int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
+ struct ifreq *ifr, int cmd)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ struct hwtstamp_config config;
+ u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED;
+ u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED;
+ u32 tsync_rx_mtrl = 0;
+ bool is_l4 = false;
+ bool is_l2 = false;
+ u32 regval;
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (config.flags)
+ return -EINVAL;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ tsync_tx_ctl = 0;
+ case HWTSTAMP_TX_ON:
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ tsync_rx_ctl = 0;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_mtrl = IXGBE_RXMTRL_V1_SYNC_MSG;
+ is_l4 = true;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_mtrl = IXGBE_RXMTRL_V1_DELAY_REQ_MSG;
+ is_l4 = true;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_mtrl = IXGBE_RXMTRL_V2_SYNC_MSG;
+ is_l2 = true;
+ is_l4 = true;
+ config.rx_filter = HWTSTAMP_FILTER_SOME;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_mtrl = IXGBE_RXMTRL_V2_DELAY_REQ_MSG;
+ is_l2 = true;
+ is_l4 = true;
+ config.rx_filter = HWTSTAMP_FILTER_SOME;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2;
+ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+ is_l2 = true;
+ is_l4 = true;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_ALL:
+ default:
+ /*
+ * register RXMTRL must be set, therefore it is not
+ * possible to time stamp both V1 Sync and Delay_Req messages
+ * and hardware does not support timestamping all packets
+ * => return error
+ */
+ return -ERANGE;
+ }
+
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ if (tsync_rx_ctl | tsync_tx_ctl)
+ return -ERANGE;
+ return 0;
+ }
+
+ /* define ethertype filter for timestamped packets */
+ if (is_l2)
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(3),
+ (IXGBE_ETQF_FILTER_EN | /* enable filter */
+ IXGBE_ETQF_1588 | /* enable timestamping */
+ ETH_P_1588)); /* 1588 eth protocol type */
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(3), 0);
+
+#define PTP_PORT 319
+ /* L4 Queue Filter[3]: filter by destination port and protocol */
+ if (is_l4) {
+ u32 ftqf = (IXGBE_FTQF_PROTOCOL_UDP /* UDP */
+ | IXGBE_FTQF_POOL_MASK_EN /* Pool not compared */
+ | IXGBE_FTQF_QUEUE_ENABLE);
+
+ ftqf |= ((IXGBE_FTQF_PROTOCOL_COMP_MASK /* protocol check */
+ & IXGBE_FTQF_DEST_PORT_MASK /* dest check */
+ & IXGBE_FTQF_SOURCE_PORT_MASK) /* source check */
+ << IXGBE_FTQF_5TUPLE_MASK_SHIFT);
+
+ IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(3),
+ (3 << IXGBE_IMIR_RX_QUEUE_SHIFT_82599 |
+ IXGBE_IMIR_SIZE_BP_82599));
+
+ /* enable port check */
+ IXGBE_WRITE_REG(hw, IXGBE_SDPQF(3),
+ (htons(PTP_PORT) |
+ htons(PTP_PORT) << 16));
+
+ IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), ftqf);
+
+ tsync_rx_mtrl |= PTP_PORT << 16;
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_FTQF(3), 0);
+ }
+
+ /* enable/disable TX */
+ regval = IXGBE_READ_REG(hw, IXGBE_TSYNCTXCTL);
+ regval &= ~IXGBE_TSYNCTXCTL_ENABLED;
+ regval |= tsync_tx_ctl;
+ IXGBE_WRITE_REG(hw, IXGBE_TSYNCTXCTL, regval);
+
+ /* enable/disable RX */
+ regval = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
+ regval &= ~(IXGBE_TSYNCRXCTL_ENABLED | IXGBE_TSYNCRXCTL_TYPE_MASK);
+ regval |= tsync_rx_ctl;
+ IXGBE_WRITE_REG(hw, IXGBE_TSYNCRXCTL, regval);
+
+ /* define which PTP packets are time stamped */
+ IXGBE_WRITE_REG(hw, IXGBE_RXMTRL, tsync_rx_mtrl);
+
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* clear TX/RX time stamp registers, just to be sure */
+ regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH);
+ regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
+/**
+ * ixgbe_ptp_start_cyclecounter - create the cycle counter from hw
+ * @adapter - pointer to the adapter structure
+ *
+ * this function initializes the timecounter and cyclecounter
+ * structures for use in generated a ns counter from the arbitrary
+ * fixed point cycles registers in the hardware.
+ *
+ * A change in link speed impacts the frequency of the DMA clock on
+ * the device, which is used to generate the cycle counter
+ * registers. Therefor this function is called whenever the link speed
+ * changes.
+ *
+ * This function also turns on the SDP pin for clock out feature (X540
+ * only), because this is where the shift is first calculated.
+ */
+void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 incval = 0;
+ u32 shift = 0;
+ u32 cycle_speed;
+ unsigned long flags;
+
+ /**
+ * Determine what speed we need to set the cyclecounter
+ * for. It should be different for 100Mb, 1Gb, and 10Gb. Treat
+ * unknown speeds as 10Gb. (Hence why we can't just copy the
+ * link_speed.
+ */
+ switch (adapter->link_speed) {
+ case IXGBE_LINK_SPEED_100_FULL:
+ case IXGBE_LINK_SPEED_1GB_FULL:
+ case IXGBE_LINK_SPEED_10GB_FULL:
+ cycle_speed = adapter->link_speed;
+ break;
+ default:
+ /* cycle speed should be 10Gb when there is no link */
+ cycle_speed = IXGBE_LINK_SPEED_10GB_FULL;
+ break;
+ }
+
+ /* Bail if the cycle speed didn't change */
+ if (adapter->cycle_speed == cycle_speed)
+ return;
+
+ /* disable the SDP clock out */
+ ixgbe_ptp_disable_sdp(hw);
+
+ /**
+ * Scale the NIC cycle counter by a large factor so that
+ * relatively small corrections to the frequency can be added
+ * or subtracted. The drawbacks of a large factor include
+ * (a) the clock register overflows more quickly, (b) the cycle
+ * counter structure must be able to convert the systime value
+ * to nanoseconds using only a multiplier and a right-shift,
+ * and (c) the value must fit within the timinca register space
+ * => math based on internal DMA clock rate and available bits
+ */
+ switch (cycle_speed) {
+ case IXGBE_LINK_SPEED_100_FULL:
+ incval = IXGBE_INCVAL_100;
+ shift = IXGBE_INCVAL_SHIFT_100;
+ break;
+ case IXGBE_LINK_SPEED_1GB_FULL:
+ incval = IXGBE_INCVAL_1GB;
+ shift = IXGBE_INCVAL_SHIFT_1GB;
+ break;
+ case IXGBE_LINK_SPEED_10GB_FULL:
+ incval = IXGBE_INCVAL_10GB;
+ shift = IXGBE_INCVAL_SHIFT_10GB;
+ break;
+ }
+
+ /**
+ * Modify the calculated values to fit within the correct
+ * number of bits specified by the hardware. The 82599 doesn't
+ * have the same space as the X540, so bitshift the calculated
+ * values to fit.
+ */
+ switch (hw->mac.type) {
+ case ixgbe_mac_X540:
+ IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, incval);
+ break;
+ case ixgbe_mac_82599EB:
+ incval >>= IXGBE_INCVAL_SHIFT_82599;
+ shift -= IXGBE_INCVAL_SHIFT_82599;
+ IXGBE_WRITE_REG(hw, IXGBE_TIMINCA,
+ (1 << IXGBE_INCPER_SHIFT_82599) |
+ incval);
+ break;
+ default:
+ /* other devices aren't supported */
+ return;
+ }
+
+ /* reset the system time registers */
+ IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0x00000000);
+ IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000);
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* now that the shift has been calculated and the systime
+ * registers reset, (re-)enable the Clock out feature*/
+ ixgbe_ptp_enable_sdp(hw, shift);
+
+ /* store the new cycle speed */
+ adapter->cycle_speed = cycle_speed;
+
+ ACCESS_ONCE(adapter->base_incval) = incval;
+ smp_mb();
+
+ /* grab the ptp lock */
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
+
+ memset(&adapter->cc, 0, sizeof(adapter->cc));
+ adapter->cc.read = ixgbe_ptp_read;
+ adapter->cc.mask = CLOCKSOURCE_MASK(64);
+ adapter->cc.shift = shift;
+ adapter->cc.mult = 1;
+
+ /* reset the ns time counter */
+ timecounter_init(&adapter->tc, &adapter->cc,
+ ktime_to_ns(ktime_get_real()));
+
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
+}
+
+/**
+ * ixgbe_ptp_init
+ * @adapter - the ixgbe private adapter structure
+ *
+ * This function performs the required steps for enabling ptp
+ * support. If ptp support has already been loaded it simply calls the
+ * cyclecounter init routine and exits.
+ */
+void ixgbe_ptp_init(struct ixgbe_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+
+ switch (adapter->hw.mac.type) {
+ case ixgbe_mac_X540:
+ snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
+ adapter->ptp_caps.owner = THIS_MODULE;
+ adapter->ptp_caps.max_adj = 250000000;
+ adapter->ptp_caps.n_alarm = 0;
+ adapter->ptp_caps.n_ext_ts = 0;
+ adapter->ptp_caps.n_per_out = 0;
+ adapter->ptp_caps.pps = 1;
+ adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq;
+ adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
+ adapter->ptp_caps.gettime = ixgbe_ptp_gettime;
+ adapter->ptp_caps.settime = ixgbe_ptp_settime;
+ adapter->ptp_caps.enable = ixgbe_ptp_enable;
+ break;
+ case ixgbe_mac_82599EB:
+ snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
+ adapter->ptp_caps.owner = THIS_MODULE;
+ adapter->ptp_caps.max_adj = 250000000;
+ adapter->ptp_caps.n_alarm = 0;
+ adapter->ptp_caps.n_ext_ts = 0;
+ adapter->ptp_caps.n_per_out = 0;
+ adapter->ptp_caps.pps = 0;
+ adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq;
+ adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
+ adapter->ptp_caps.gettime = ixgbe_ptp_gettime;
+ adapter->ptp_caps.settime = ixgbe_ptp_settime;
+ adapter->ptp_caps.enable = ixgbe_ptp_enable;
+ break;
+ default:
+ adapter->ptp_clock = NULL;
+ return;
+ }
+
+ spin_lock_init(&adapter->tmreg_lock);
+
+ ixgbe_ptp_start_cyclecounter(adapter);
+
+ /* (Re)start the overflow check */
+ adapter->flags2 |= IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED;
+
+ adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps);
+ if (IS_ERR(adapter->ptp_clock)) {
+ adapter->ptp_clock = NULL;
+ e_dev_err("ptp_clock_register failed\n");
+ } else
+ e_dev_info("registered PHC device on %s\n", netdev->name);
+
+ return;
+}
+
+/**
+ * ixgbe_ptp_stop - disable ptp device and stop the overflow check
+ * @adapter: pointer to adapter struct
+ *
+ * this function stops the ptp support, and cancels the delayed work.
+ */
+void ixgbe_ptp_stop(struct ixgbe_adapter *adapter)
+{
+ ixgbe_ptp_disable_sdp(&adapter->hw);
+
+ /* stop the overflow check task */
+ adapter->flags2 &= ~IXGBE_FLAG2_OVERFLOW_CHECK_ENABLED;
+
+ if (adapter->ptp_clock) {
+ ptp_clock_unregister(adapter->ptp_clock);
+ adapter->ptp_clock = NULL;
+ e_dev_info("removed PHC on %s\n",
+ adapter->netdev->name);
+ }
+}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index 39856371acb1..2d971d18696e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -544,13 +544,18 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
- if (retval)
+ if (retval) {
pr_err("Error receiving message from VF\n");
+ return retval;
+ }
/* this is a message we already processed, do nothing */
if (msgbuf[0] & (IXGBE_VT_MSGTYPE_ACK | IXGBE_VT_MSGTYPE_NACK))
return retval;
+ /* flush the ack before we write any messages back */
+ IXGBE_WRITE_FLUSH(hw);
+
/*
* until the vf completes a virtual function reset it should not be
* allowed to start any configuration.
@@ -635,14 +640,14 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
}
break;
case IXGBE_VF_SET_MACVLAN:
- if (adapter->vfinfo[vf].pf_set_mac) {
+ index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >>
+ IXGBE_VT_MSGINFO_SHIFT;
+ if (adapter->vfinfo[vf].pf_set_mac && index > 0) {
e_warn(drv, "VF %d requested MACVLAN filter but is "
"administratively denied\n", vf);
retval = -1;
break;
}
- index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >>
- IXGBE_VT_MSGINFO_SHIFT;
/*
* If the VF is allowed to set MAC filters then turn off
* anti-spoofing to avoid false positives. An index
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c
index f81c166dc5a8..1d80b1cefa6a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sysfs.c
@@ -37,12 +37,7 @@
#include <linux/netdevice.h>
#include <linux/hwmon.h>
-/*
- * This file provides a sysfs interface to export information from the
- * driver. The information presented is READ-ONLY.
- */
#ifdef CONFIG_IXGBE_HWMON
-
/* hwmon callback functions */
static ssize_t ixgbe_hwmon_show_location(struct device *dev,
struct device_attribute *attr,
@@ -162,17 +157,13 @@ static int ixgbe_add_hwmon_attr(struct ixgbe_adapter *adapter,
return rc;
}
-#endif /* CONFIG_IXGBE_HWMON */
static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter *adapter)
{
-#ifdef CONFIG_IXGBE_HWMON
int i;
-#endif /* CONFIG_IXGBE_HWMON */
if (adapter == NULL)
return;
-#ifdef CONFIG_IXGBE_HWMON
for (i = 0; i < adapter->ixgbe_hwmon_buff.n_hwmon; i++) {
device_remove_file(&adapter->pdev->dev,
@@ -183,12 +174,6 @@ static void ixgbe_sysfs_del_adapter(struct ixgbe_adapter *adapter)
if (adapter->ixgbe_hwmon_buff.device)
hwmon_device_unregister(adapter->ixgbe_hwmon_buff.device);
-#endif /* CONFIG_IXGBE_HWMON */
-
- if (adapter->info_kobj != NULL) {
- kobject_put(adapter->info_kobj);
- adapter->info_kobj = NULL;
- }
}
/* called from ixgbe_main.c */
@@ -200,32 +185,19 @@ void ixgbe_sysfs_exit(struct ixgbe_adapter *adapter)
/* called from ixgbe_main.c */
int ixgbe_sysfs_init(struct ixgbe_adapter *adapter)
{
-#ifdef CONFIG_IXGBE_HWMON
struct hwmon_buff *ixgbe_hwmon = &adapter->ixgbe_hwmon_buff;
unsigned int i;
int n_attrs;
-#endif /* CONFIG_IXGBE_HWMON */
- struct net_device *netdev = adapter->netdev;
int rc = 0;
- /* create info kobj and attribute listings in kobj */
- adapter->info_kobj = kobject_create_and_add("info", &netdev->dev.kobj);
- if (adapter->info_kobj == NULL) {
- rc = -ENOMEM;
- goto err;
- }
-
-#ifdef CONFIG_IXGBE_HWMON
/* If this method isn't defined we don't support thermals */
if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) {
- rc = -EPERM;
- goto err;
+ goto exit;
}
/* Don't create thermal hwmon interface if no sensors present */
- rc = adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw);
- if (rc)
- goto err;
+ if (adapter->hw.mac.ops.init_thermal_sensor_thresh(&adapter->hw))
+ goto exit;
/*
* Allocation space for max attributs
@@ -261,7 +233,6 @@ int ixgbe_sysfs_init(struct ixgbe_adapter *adapter)
if (rc)
goto err;
}
-#endif /* CONFIG_IXGBE_HWMON */
goto exit;
@@ -270,4 +241,5 @@ err:
exit:
return rc;
}
+#endif /* CONFIG_IXGBE_HWMON */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 5e64c77255e9..204848d2448c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -824,6 +824,8 @@ struct ixgbe_thermal_sensor_data {
#define IXGBE_TRGTTIMH0 0x08C28 /* Target Time Register 0 High - RW */
#define IXGBE_TRGTTIML1 0x08C2C /* Target Time Register 1 Low - RW */
#define IXGBE_TRGTTIMH1 0x08C30 /* Target Time Register 1 High - RW */
+#define IXGBE_CLKTIML 0x08C34 /* Clock Out Time Register Low - RW */
+#define IXGBE_CLKTIMH 0x08C38 /* Clock Out Time Register High - RW */
#define IXGBE_FREQOUT0 0x08C34 /* Frequency Out 0 Control register - RW */
#define IXGBE_FREQOUT1 0x08C38 /* Frequency Out 1 Control register - RW */
#define IXGBE_AUXSTMPL0 0x08C3C /* Auxiliary Time Stamp 0 register Low - RO */
@@ -1309,6 +1311,7 @@ enum {
#define IXGBE_EICR_LINKSEC 0x00200000 /* PN Threshold */
#define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */
#define IXGBE_EICR_TS 0x00800000 /* Thermal Sensor Event */
+#define IXGBE_EICR_TIMESYNC 0x01000000 /* Timesync Event */
#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */
#define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */
#define IXGBE_EICR_GPI_SDP2 0x04000000 /* Gen Purpose Interrupt on SDP2 */
@@ -1326,6 +1329,7 @@ enum {
#define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
+#define IXGBE_EICS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */
#define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
#define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
#define IXGBE_EICS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
@@ -1344,6 +1348,7 @@ enum {
#define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EIMS_TS IXGBE_EICR_TS /* Thermel Sensor Event */
+#define IXGBE_EIMS_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */
#define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
#define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
#define IXGBE_EIMS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
@@ -1361,6 +1366,7 @@ enum {
#define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
+#define IXGBE_EIMC_TIMESYNC IXGBE_EICR_TIMESYNC /* Timesync Event */
#define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
#define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
#define IXGBE_EIMC_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
@@ -1501,8 +1507,10 @@ enum {
#define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */
#define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */
#define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */
+#define IXGBE_ESDP_SDP0_DIR 0x00000100 /* SDP0 IO direction */
#define IXGBE_ESDP_SDP4_DIR 0x00000004 /* SDP4 IO direction */
#define IXGBE_ESDP_SDP5_DIR 0x00002000 /* SDP5 IO direction */
+#define IXGBE_ESDP_SDP0_NATIVE 0x00010000 /* SDP0 Native Function */
/* LEDCTL Bit Masks */
#define IXGBE_LED_IVRT_BASE 0x00000040
@@ -1879,6 +1887,40 @@ enum {
#define IXGBE_RXDCTL_RLPML_EN 0x00008000
#define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */
+#define IXGBE_TSAUXC_EN_CLK 0x00000004
+#define IXGBE_TSAUXC_SYNCLK 0x00000008
+#define IXGBE_TSAUXC_SDP0_INT 0x00000040
+
+#define IXGBE_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
+#define IXGBE_TSYNCTXCTL_ENABLED 0x00000010 /* Tx timestamping enabled */
+
+#define IXGBE_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
+#define IXGBE_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
+#define IXGBE_TSYNCRXCTL_TYPE_L2_V2 0x00
+#define IXGBE_TSYNCRXCTL_TYPE_L4_V1 0x02
+#define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
+#define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
+#define IXGBE_TSYNCRXCTL_ENABLED 0x00000010 /* Rx Timestamping enabled */
+
+#define IXGBE_RXMTRL_V1_CTRLT_MASK 0x000000FF
+#define IXGBE_RXMTRL_V1_SYNC_MSG 0x00
+#define IXGBE_RXMTRL_V1_DELAY_REQ_MSG 0x01
+#define IXGBE_RXMTRL_V1_FOLLOWUP_MSG 0x02
+#define IXGBE_RXMTRL_V1_DELAY_RESP_MSG 0x03
+#define IXGBE_RXMTRL_V1_MGMT_MSG 0x04
+
+#define IXGBE_RXMTRL_V2_MSGID_MASK 0x0000FF00
+#define IXGBE_RXMTRL_V2_SYNC_MSG 0x0000
+#define IXGBE_RXMTRL_V2_DELAY_REQ_MSG 0x0100
+#define IXGBE_RXMTRL_V2_PDELAY_REQ_MSG 0x0200
+#define IXGBE_RXMTRL_V2_PDELAY_RESP_MSG 0x0300
+#define IXGBE_RXMTRL_V2_FOLLOWUP_MSG 0x0800
+#define IXGBE_RXMTRL_V2_DELAY_RESP_MSG 0x0900
+#define IXGBE_RXMTRL_V2_PDELAY_FOLLOWUP_MSG 0x0A00
+#define IXGBE_RXMTRL_V2_ANNOUNCE_MSG 0x0B00
+#define IXGBE_RXMTRL_V2_SIGNALING_MSG 0x0C00
+#define IXGBE_RXMTRL_V2_MGMT_MSG 0x0D00
+
#define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
#define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/
#define IXGBE_FCTRL_UPE 0x00000200 /* Unicast Promiscuous Ena */
@@ -2008,6 +2050,7 @@ enum {
#define IXGBE_RXDADV_STAT_FCSTAT_NODDP 0x00000010 /* 01: Ctxt w/o DDP */
#define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */
#define IXGBE_RXDADV_STAT_FCSTAT_DDP 0x00000030 /* 11: Ctxt w/ DDP */
+#define IXGBE_RXDADV_STAT_TS 0x00010000 /* IEEE 1588 Time Stamp */
/* PSRTYPE bit definitions */
#define IXGBE_PSRTYPE_TCPHDR 0x00000010
@@ -2285,6 +2328,7 @@ struct ixgbe_adv_tx_context_desc {
/* Adv Transmit Descriptor Config Masks */
#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */
#define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */
+#define IXGBE_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE 1588 Time Stamp */
#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */
#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */
#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */
@@ -2573,9 +2617,6 @@ enum ixgbe_fc_mode {
ixgbe_fc_rx_pause,
ixgbe_fc_tx_pause,
ixgbe_fc_full,
-#ifdef CONFIG_DCB
- ixgbe_fc_pfc,
-#endif
ixgbe_fc_default
};
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 773c70ea3f62..1bcead1fa2f6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -1254,7 +1254,6 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_slave_state *slave_state = priv->mfunc.master.slave_state;
u32 reply;
- u32 slave_status = 0;
u8 is_going_down = 0;
int i;
@@ -1274,10 +1273,8 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
}
/*check if we are in the middle of FLR process,
if so return "retry" status to the slave*/
- if (MLX4_COMM_CMD_FLR == slave_state[slave].last_cmd) {
- slave_status = MLX4_DELAY_RESET_SLAVE;
+ if (MLX4_COMM_CMD_FLR == slave_state[slave].last_cmd)
goto inform_slave_state;
- }
/* write the version in the event field */
reply |= mlx4_comm_get_version();
@@ -1557,7 +1554,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
return 0;
err_resource:
- mlx4_free_resource_tracker(dev);
+ mlx4_free_resource_tracker(dev, RES_TR_FREE_ALL);
err_thread:
flush_workqueue(priv->mfunc.master.comm_wq);
destroy_workqueue(priv->mfunc.master.comm_wq);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index 346fdb2e92a6..988b2424e1c6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -101,6 +101,8 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
int i;
params->udp_rss = udp_rss;
+ params->num_tx_rings_p_up = min_t(int, num_online_cpus(),
+ MLX4_EN_MAX_TX_RING_P_UP);
if (params->udp_rss && !(mdev->dev->caps.flags
& MLX4_DEV_CAP_FLAG_UDP_RSS)) {
mlx4_warn(mdev, "UDP RSS is not supported on this device.\n");
@@ -113,8 +115,8 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
params->prof[i].tx_ppp = pfctx;
params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
- params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS +
- MLX4_EN_NUM_PPP_RINGS;
+ params->prof[i].tx_ring_num = params->num_tx_rings_p_up *
+ MLX4_EN_NUM_UP;
params->prof[i].rss_rings = 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index eaa8fadf19c0..926d8aac941c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -47,9 +47,22 @@
static int mlx4_en_setup_tc(struct net_device *dev, u8 up)
{
- if (up != MLX4_EN_NUM_UP)
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ int i;
+ unsigned int q, offset = 0;
+
+ if (up && up != MLX4_EN_NUM_UP)
return -EINVAL;
+ netdev_set_num_tc(dev, up);
+
+ /* Partition Tx queues evenly amongst UP's */
+ q = priv->tx_ring_num / up;
+ for (i = 0; i < up; i++) {
+ netdev_set_tc_queue(dev, i, q, offset);
+ offset += q;
+ }
+
return 0;
}
@@ -661,7 +674,7 @@ int mlx4_en_start_port(struct net_device *dev)
/* Configure ring */
tx_ring = &priv->tx_ring[i];
err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn,
- max(0, i - MLX4_EN_NUM_TX_RINGS));
+ i / priv->mdev->profile.num_tx_rings_p_up);
if (err) {
en_err(priv, "Failed allocating Tx ring\n");
mlx4_en_deactivate_cq(priv, cq);
@@ -986,6 +999,9 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
mlx4_en_free_resources(priv);
+ kfree(priv->tx_ring);
+ kfree(priv->tx_cq);
+
free_netdev(dev);
}
@@ -1091,6 +1107,18 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
priv->ctrl_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE |
MLX4_WQE_CTRL_SOLICITED);
priv->tx_ring_num = prof->tx_ring_num;
+ priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring) *
+ priv->tx_ring_num, GFP_KERNEL);
+ if (!priv->tx_ring) {
+ err = -ENOMEM;
+ goto out;
+ }
+ priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * priv->tx_ring_num,
+ GFP_KERNEL);
+ if (!priv->tx_cq) {
+ err = -ENOMEM;
+ goto out;
+ }
priv->rx_ring_num = prof->rx_ring_num;
priv->mac_index = -1;
priv->msg_enable = MLX4_EN_MSG_LEVEL;
@@ -1138,15 +1166,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
- netdev_set_num_tc(dev, MLX4_EN_NUM_UP);
-
- /* First 9 rings are for UP 0 */
- netdev_set_tc_queue(dev, 0, MLX4_EN_NUM_TX_RINGS + 1, 0);
-
- /* Partition Tx queues evenly amongst UP's 1-7 */
- for (i = 1; i < MLX4_EN_NUM_UP; i++)
- netdev_set_tc_queue(dev, i, 1, MLX4_EN_NUM_TX_RINGS + i);
-
SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
/* Set defualt MAC */
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 9a38483feb92..019d856b1334 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -525,14 +525,17 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk
u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
{
- u16 vlan_tag = 0;
+ struct mlx4_en_priv *priv = netdev_priv(dev);
+ u16 rings_p_up = priv->mdev->profile.num_tx_rings_p_up;
+ u8 up = 0;
- if (vlan_tx_tag_present(skb)) {
- vlan_tag = vlan_tx_tag_get(skb);
- return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13);
- }
+ if (dev->num_tc)
+ return skb_tx_hash(dev, skb);
+
+ if (vlan_tx_tag_present(skb))
+ up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT;
- return skb_tx_hash(dev, skb);
+ return __skb_tx_hash(dev, skb, rings_p_up) + up * rings_p_up;
}
static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt)
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 2a02ba522e60..24429a99190d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -1164,9 +1164,8 @@ int mlx4_INIT_PORT_wrapper(struct mlx4_dev *dev, int slave,
MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
if (err)
return err;
- priv->mfunc.master.slave_state[slave].init_port_mask |=
- (1 << port);
}
+ priv->mfunc.master.slave_state[slave].init_port_mask |= (1 << port);
++priv->mfunc.master.init_port_ref[port];
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 8bb05b46db86..984ace44104f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -1306,7 +1306,7 @@ static void mlx4_cleanup_counters_table(struct mlx4_dev *dev)
mlx4_bitmap_cleanup(&mlx4_priv(dev)->counters_bitmap);
}
-int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
+int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
{
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -1319,13 +1319,44 @@ int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
return 0;
}
+
+int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
+{
+ u64 out_param;
+ int err;
+
+ if (mlx4_is_mfunc(dev)) {
+ err = mlx4_cmd_imm(dev, 0, &out_param, RES_COUNTER,
+ RES_OP_RESERVE, MLX4_CMD_ALLOC_RES,
+ MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+ if (!err)
+ *idx = get_param_l(&out_param);
+
+ return err;
+ }
+ return __mlx4_counter_alloc(dev, idx);
+}
EXPORT_SYMBOL_GPL(mlx4_counter_alloc);
-void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
+void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
{
mlx4_bitmap_free(&mlx4_priv(dev)->counters_bitmap, idx);
return;
}
+
+void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
+{
+ u64 in_param;
+
+ if (mlx4_is_mfunc(dev)) {
+ set_param_l(&in_param, idx);
+ mlx4_cmd(dev, in_param, RES_COUNTER, RES_OP_RESERVE,
+ MLX4_CMD_FREE_RES, MLX4_CMD_TIME_CLASS_A,
+ MLX4_CMD_WRAPPED);
+ return;
+ }
+ __mlx4_counter_free(dev, idx);
+}
EXPORT_SYMBOL_GPL(mlx4_counter_free);
static int mlx4_setup_hca(struct mlx4_dev *dev)
@@ -1865,7 +1896,6 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
mlx4_err(dev, "Failed to enable sriov,"
"continuing without sriov enabled"
" (err = %d).\n", err);
- num_vfs = 0;
err = 0;
} else {
mlx4_warn(dev, "Running in master mode\n");
@@ -2022,7 +2052,7 @@ err_cmd:
mlx4_cmd_cleanup(dev);
err_sriov:
- if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV))
+ if (dev->flags & MLX4_FLAG_SRIOV)
pci_disable_sriov(pdev);
err_rel_own:
@@ -2070,6 +2100,10 @@ static void mlx4_remove_one(struct pci_dev *pdev)
mlx4_CLOSE_PORT(dev, p);
}
+ if (mlx4_is_master(dev))
+ mlx4_free_resource_tracker(dev,
+ RES_TR_FREE_SLAVES_ONLY);
+
mlx4_cleanup_counters_table(dev);
mlx4_cleanup_mcg_table(dev);
mlx4_cleanup_qp_table(dev);
@@ -2082,7 +2116,8 @@ static void mlx4_remove_one(struct pci_dev *pdev)
mlx4_cleanup_pd_table(dev);
if (mlx4_is_master(dev))
- mlx4_free_resource_tracker(dev);
+ mlx4_free_resource_tracker(dev,
+ RES_TR_FREE_STRUCTS_ONLY);
iounmap(priv->kar);
mlx4_uar_free(dev, &priv->driver_uar);
@@ -2099,7 +2134,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
if (dev->flags & MLX4_FLAG_MSI_X)
pci_disable_msix(pdev);
- if (num_vfs && (dev->flags & MLX4_FLAG_SRIOV)) {
+ if (dev->flags & MLX4_FLAG_SRIOV) {
mlx4_warn(dev, "Disabling sriov\n");
pci_disable_sriov(pdev);
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 4799e824052f..f4a8f98e402a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -357,7 +357,6 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
u32 prot;
int i;
bool found;
- int last_index;
int err;
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -419,7 +418,6 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
if (err)
goto out_mailbox;
}
- last_index = entry->index;
}
/* add the new qpn to list of promisc qps */
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index cd56f1aea4b5..86b6e5a2fabf 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -146,6 +146,11 @@ enum mlx4_alloc_mode {
RES_OP_MAP_ICM,
};
+enum mlx4_res_tracker_free_type {
+ RES_TR_FREE_ALL,
+ RES_TR_FREE_SLAVES_ONLY,
+ RES_TR_FREE_STRUCTS_ONLY,
+};
/*
*Virtual HCR structures.
@@ -871,6 +876,10 @@ void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac);
int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac);
int __mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
int start_index, int npages, u64 *page_list);
+int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx);
+void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx);
+int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn);
+void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn);
void mlx4_start_catas_poll(struct mlx4_dev *dev);
void mlx4_stop_catas_poll(struct mlx4_dev *dev);
@@ -1027,7 +1036,8 @@ int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev,
void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id);
int mlx4_init_resource_tracker(struct mlx4_dev *dev);
-void mlx4_free_resource_tracker(struct mlx4_dev *dev);
+void mlx4_free_resource_tracker(struct mlx4_dev *dev,
+ enum mlx4_res_tracker_free_type type);
int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_vhcr *vhcr,
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 5d876375a132..6ae350921b1a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -111,9 +111,7 @@ enum {
#define MLX4_EN_MIN_TX_SIZE (4096 / TXBB_SIZE)
#define MLX4_EN_SMALL_PKT_SIZE 64
-#define MLX4_EN_NUM_TX_RINGS 8
-#define MLX4_EN_NUM_PPP_RINGS 8
-#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS)
+#define MLX4_EN_MAX_TX_RING_P_UP 32
#define MLX4_EN_NUM_UP 8
#define MLX4_EN_DEF_TX_RING_SIZE 512
#define MLX4_EN_DEF_RX_RING_SIZE 1024
@@ -339,6 +337,7 @@ struct mlx4_en_profile {
u32 active_ports;
u32 small_pkt_int;
u8 no_reset;
+ u8 num_tx_rings_p_up;
struct mlx4_en_port_profile prof[MLX4_MAX_PORTS + 1];
};
@@ -477,9 +476,9 @@ struct mlx4_en_priv {
u16 num_frags;
u16 log_rx_info;
- struct mlx4_en_tx_ring tx_ring[MAX_TX_RINGS];
+ struct mlx4_en_tx_ring *tx_ring;
struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS];
- struct mlx4_en_cq tx_cq[MAX_TX_RINGS];
+ struct mlx4_en_cq *tx_cq;
struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
struct work_struct mcast_task;
struct work_struct mac_task;
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index fe2ac8449c19..af55b7ce5341 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -788,7 +788,6 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages,
int max_maps, u8 page_shift, struct mlx4_fmr *fmr)
{
struct mlx4_priv *priv = mlx4_priv(dev);
- u64 mtt_offset;
int err = -ENOMEM;
if (max_maps > dev->caps.max_fmr_maps)
@@ -811,8 +810,6 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages,
if (err)
return err;
- mtt_offset = fmr->mr.mtt.offset * dev->caps.mtt_entry_sz;
-
fmr->mtts = mlx4_table_find(&priv->mr_table.mtt_table,
fmr->mr.mtt.offset,
&fmr->dma_handle);
@@ -895,6 +892,6 @@ EXPORT_SYMBOL_GPL(mlx4_fmr_free);
int mlx4_SYNC_TPT(struct mlx4_dev *dev)
{
return mlx4_cmd(dev, 0, 0, 0, MLX4_CMD_SYNC_TPT, 1000,
- MLX4_CMD_WRAPPED);
+ MLX4_CMD_NATIVE);
}
EXPORT_SYMBOL_GPL(mlx4_SYNC_TPT);
diff --git a/drivers/net/ethernet/mellanox/mlx4/pd.c b/drivers/net/ethernet/mellanox/mlx4/pd.c
index db4746d0dca7..1ac88637ad9d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/pd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/pd.c
@@ -63,7 +63,7 @@ void mlx4_pd_free(struct mlx4_dev *dev, u32 pdn)
}
EXPORT_SYMBOL_GPL(mlx4_pd_free);
-int mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn)
+int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn)
{
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -73,12 +73,47 @@ int mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn)
return 0;
}
+
+int mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn)
+{
+ u64 out_param;
+ int err;
+
+ if (mlx4_is_mfunc(dev)) {
+ err = mlx4_cmd_imm(dev, 0, &out_param,
+ RES_XRCD, RES_OP_RESERVE,
+ MLX4_CMD_ALLOC_RES,
+ MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+ if (err)
+ return err;
+
+ *xrcdn = get_param_l(&out_param);
+ return 0;
+ }
+ return __mlx4_xrcd_alloc(dev, xrcdn);
+}
EXPORT_SYMBOL_GPL(mlx4_xrcd_alloc);
-void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
+void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
{
mlx4_bitmap_free(&mlx4_priv(dev)->xrcd_bitmap, xrcdn);
}
+
+void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
+{
+ u64 in_param;
+ int err;
+
+ if (mlx4_is_mfunc(dev)) {
+ set_param_l(&in_param, xrcdn);
+ err = mlx4_cmd(dev, in_param, RES_XRCD,
+ RES_OP_RESERVE, MLX4_CMD_FREE_RES,
+ MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+ if (err)
+ mlx4_warn(dev, "Failed to release xrcdn %d\n", xrcdn);
+ } else
+ __mlx4_xrcd_free(dev, xrcdn);
+}
EXPORT_SYMBOL_GPL(mlx4_xrcd_free);
int mlx4_init_pd_table(struct mlx4_dev *dev)
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index 55b12e6bed87..1fe2c7a8b40c 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -338,13 +338,12 @@ EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);
void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
{
u64 out_param;
- int err;
if (mlx4_is_mfunc(dev)) {
set_param_l(&out_param, port);
- err = mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
- RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
- MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
+ (void) mlx4_cmd_imm(dev, mac, &out_param, RES_MAC,
+ RES_OP_RESERVE_AND_MAP, MLX4_CMD_FREE_RES,
+ MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
return;
}
__mlx4_unregister_mac(dev, port, mac);
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 8752e6e08169..b45d0e7f6ab0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -89,17 +89,6 @@ enum res_qp_states {
RES_QP_HW
};
-static inline const char *qp_states_str(enum res_qp_states state)
-{
- switch (state) {
- case RES_QP_BUSY: return "RES_QP_BUSY";
- case RES_QP_RESERVED: return "RES_QP_RESERVED";
- case RES_QP_MAPPED: return "RES_QP_MAPPED";
- case RES_QP_HW: return "RES_QP_HW";
- default: return "Unknown";
- }
-}
-
struct res_qp {
struct res_common com;
struct res_mtt *mtt;
@@ -173,16 +162,6 @@ enum res_srq_states {
RES_SRQ_HW,
};
-static inline const char *srq_states_str(enum res_srq_states state)
-{
- switch (state) {
- case RES_SRQ_BUSY: return "RES_SRQ_BUSY";
- case RES_SRQ_ALLOCATED: return "RES_SRQ_ALLOCATED";
- case RES_SRQ_HW: return "RES_SRQ_HW";
- default: return "Unknown";
- }
-}
-
struct res_srq {
struct res_common com;
struct res_mtt *mtt;
@@ -195,20 +174,21 @@ enum res_counter_states {
RES_COUNTER_ALLOCATED,
};
-static inline const char *counter_states_str(enum res_counter_states state)
-{
- switch (state) {
- case RES_COUNTER_BUSY: return "RES_COUNTER_BUSY";
- case RES_COUNTER_ALLOCATED: return "RES_COUNTER_ALLOCATED";
- default: return "Unknown";
- }
-}
-
struct res_counter {
struct res_common com;
int port;
};
+enum res_xrcdn_states {
+ RES_XRCD_BUSY = RES_ANY_BUSY,
+ RES_XRCD_ALLOCATED,
+};
+
+struct res_xrcdn {
+ struct res_common com;
+ int port;
+};
+
/* For Debug uses */
static const char *ResourceType(enum mlx4_resource rt)
{
@@ -221,6 +201,7 @@ static const char *ResourceType(enum mlx4_resource rt)
case RES_MAC: return "RES_MAC";
case RES_EQ: return "RES_EQ";
case RES_COUNTER: return "RES_COUNTER";
+ case RES_XRCD: return "RES_XRCD";
default: return "Unknown resource type !!!";
};
}
@@ -254,16 +235,23 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev)
return 0 ;
}
-void mlx4_free_resource_tracker(struct mlx4_dev *dev)
+void mlx4_free_resource_tracker(struct mlx4_dev *dev,
+ enum mlx4_res_tracker_free_type type)
{
struct mlx4_priv *priv = mlx4_priv(dev);
int i;
if (priv->mfunc.master.res_tracker.slave_list) {
- for (i = 0 ; i < dev->num_slaves; i++)
- mlx4_delete_all_resources_for_slave(dev, i);
-
- kfree(priv->mfunc.master.res_tracker.slave_list);
+ if (type != RES_TR_FREE_STRUCTS_ONLY)
+ for (i = 0 ; i < dev->num_slaves; i++)
+ if (type == RES_TR_FREE_ALL ||
+ dev->caps.function != i)
+ mlx4_delete_all_resources_for_slave(dev, i);
+
+ if (type != RES_TR_FREE_SLAVES_ONLY) {
+ kfree(priv->mfunc.master.res_tracker.slave_list);
+ priv->mfunc.master.res_tracker.slave_list = NULL;
+ }
}
}
@@ -471,6 +459,20 @@ static struct res_common *alloc_counter_tr(int id)
return &ret->com;
}
+static struct res_common *alloc_xrcdn_tr(int id)
+{
+ struct res_xrcdn *ret;
+
+ ret = kzalloc(sizeof *ret, GFP_KERNEL);
+ if (!ret)
+ return NULL;
+
+ ret->com.res_id = id;
+ ret->com.state = RES_XRCD_ALLOCATED;
+
+ return &ret->com;
+}
+
static struct res_common *alloc_tr(int id, enum mlx4_resource type, int slave,
int extra)
{
@@ -501,7 +503,9 @@ static struct res_common *alloc_tr(int id, enum mlx4_resource type, int slave,
case RES_COUNTER:
ret = alloc_counter_tr(id);
break;
-
+ case RES_XRCD:
+ ret = alloc_xrcdn_tr(id);
+ break;
default:
return NULL;
}
@@ -624,6 +628,16 @@ static int remove_counter_ok(struct res_counter *res)
return 0;
}
+static int remove_xrcdn_ok(struct res_xrcdn *res)
+{
+ if (res->com.state == RES_XRCD_BUSY)
+ return -EBUSY;
+ else if (res->com.state != RES_XRCD_ALLOCATED)
+ return -EPERM;
+
+ return 0;
+}
+
static int remove_cq_ok(struct res_cq *res)
{
if (res->com.state == RES_CQ_BUSY)
@@ -663,6 +677,8 @@ static int remove_ok(struct res_common *res, enum mlx4_resource type, int extra)
return remove_eq_ok((struct res_eq *)res);
case RES_COUNTER:
return remove_counter_ok((struct res_counter *)res);
+ case RES_XRCD:
+ return remove_xrcdn_ok((struct res_xrcdn *)res);
default:
return -EINVAL;
}
@@ -1269,6 +1285,50 @@ static int vlan_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
return 0;
}
+static int counter_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
+ u64 in_param, u64 *out_param)
+{
+ u32 index;
+ int err;
+
+ if (op != RES_OP_RESERVE)
+ return -EINVAL;
+
+ err = __mlx4_counter_alloc(dev, &index);
+ if (err)
+ return err;
+
+ err = add_res_range(dev, slave, index, 1, RES_COUNTER, 0);
+ if (err)
+ __mlx4_counter_free(dev, index);
+ else
+ set_param_l(out_param, index);
+
+ return err;
+}
+
+static int xrcdn_alloc_res(struct mlx4_dev *dev, int slave, int op, int cmd,
+ u64 in_param, u64 *out_param)
+{
+ u32 xrcdn;
+ int err;
+
+ if (op != RES_OP_RESERVE)
+ return -EINVAL;
+
+ err = __mlx4_xrcd_alloc(dev, &xrcdn);
+ if (err)
+ return err;
+
+ err = add_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0);
+ if (err)
+ __mlx4_xrcd_free(dev, xrcdn);
+ else
+ set_param_l(out_param, xrcdn);
+
+ return err;
+}
+
int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_vhcr *vhcr,
struct mlx4_cmd_mailbox *inbox,
@@ -1314,6 +1374,16 @@ int mlx4_ALLOC_RES_wrapper(struct mlx4_dev *dev, int slave,
vhcr->in_param, &vhcr->out_param);
break;
+ case RES_COUNTER:
+ err = counter_alloc_res(dev, slave, vhcr->op_modifier, alop,
+ vhcr->in_param, &vhcr->out_param);
+ break;
+
+ case RES_XRCD:
+ err = xrcdn_alloc_res(dev, slave, vhcr->op_modifier, alop,
+ vhcr->in_param, &vhcr->out_param);
+ break;
+
default:
err = -EINVAL;
break;
@@ -1496,6 +1566,44 @@ static int vlan_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
return 0;
}
+static int counter_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
+ u64 in_param, u64 *out_param)
+{
+ int index;
+ int err;
+
+ if (op != RES_OP_RESERVE)
+ return -EINVAL;
+
+ index = get_param_l(&in_param);
+ err = rem_res_range(dev, slave, index, 1, RES_COUNTER, 0);
+ if (err)
+ return err;
+
+ __mlx4_counter_free(dev, index);
+
+ return err;
+}
+
+static int xrcdn_free_res(struct mlx4_dev *dev, int slave, int op, int cmd,
+ u64 in_param, u64 *out_param)
+{
+ int xrcdn;
+ int err;
+
+ if (op != RES_OP_RESERVE)
+ return -EINVAL;
+
+ xrcdn = get_param_l(&in_param);
+ err = rem_res_range(dev, slave, xrcdn, 1, RES_XRCD, 0);
+ if (err)
+ return err;
+
+ __mlx4_xrcd_free(dev, xrcdn);
+
+ return err;
+}
+
int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_vhcr *vhcr,
struct mlx4_cmd_mailbox *inbox,
@@ -1541,6 +1649,15 @@ int mlx4_FREE_RES_wrapper(struct mlx4_dev *dev, int slave,
vhcr->in_param, &vhcr->out_param);
break;
+ case RES_COUNTER:
+ err = counter_free_res(dev, slave, vhcr->op_modifier, alop,
+ vhcr->in_param, &vhcr->out_param);
+ break;
+
+ case RES_XRCD:
+ err = xrcdn_free_res(dev, slave, vhcr->op_modifier, alop,
+ vhcr->in_param, &vhcr->out_param);
+
default:
break;
}
@@ -2536,7 +2653,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_qp qp; /* dummy for calling attach/detach */
u8 *gid = inbox->buf;
enum mlx4_protocol prot = (vhcr->in_modifier >> 28) & 0x7;
- int err, err1;
+ int err;
int qpn;
struct res_qp *rqp;
int attach = vhcr->op_modifier;
@@ -2571,7 +2688,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
ex_rem:
/* ignore error return below, already in error */
- err1 = rem_mcg_res(dev, slave, rqp, gid, prot, type);
+ (void) rem_mcg_res(dev, slave, rqp, gid, prot, type);
ex_put:
put_res(dev, slave, qpn, RES_QP);
@@ -2604,13 +2721,12 @@ static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp)
{
struct res_gid *rgid;
struct res_gid *tmp;
- int err;
struct mlx4_qp qp; /* dummy for calling attach/detach */
list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) {
qp.qpn = rqp->local_qpn;
- err = mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot,
- rgid->steer);
+ (void) mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot,
+ rgid->steer);
list_del(&rgid->list);
kfree(rgid);
}
@@ -3036,14 +3152,13 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave)
MLX4_CMD_HW2SW_EQ,
MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_NATIVE);
- mlx4_dbg(dev, "rem_slave_eqs: failed"
- " to move slave %d eqs %d to"
- " SW ownership\n", slave, eqn);
+ if (err)
+ mlx4_dbg(dev, "rem_slave_eqs: failed"
+ " to move slave %d eqs %d to"
+ " SW ownership\n", slave, eqn);
mlx4_free_cmd_mailbox(dev, mailbox);
- if (!err) {
- atomic_dec(&eq->mtt->ref_count);
- state = RES_EQ_RESERVED;
- }
+ atomic_dec(&eq->mtt->ref_count);
+ state = RES_EQ_RESERVED;
break;
default:
@@ -3056,6 +3171,64 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave)
spin_unlock_irq(mlx4_tlock(dev));
}
+static void rem_slave_counters(struct mlx4_dev *dev, int slave)
+{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
+ struct list_head *counter_list =
+ &tracker->slave_list[slave].res_list[RES_COUNTER];
+ struct res_counter *counter;
+ struct res_counter *tmp;
+ int err;
+ int index;
+
+ err = move_all_busy(dev, slave, RES_COUNTER);
+ if (err)
+ mlx4_warn(dev, "rem_slave_counters: Could not move all counters to "
+ "busy for slave %d\n", slave);
+
+ spin_lock_irq(mlx4_tlock(dev));
+ list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
+ if (counter->com.owner == slave) {
+ index = counter->com.res_id;
+ radix_tree_delete(&tracker->res_tree[RES_COUNTER], index);
+ list_del(&counter->com.list);
+ kfree(counter);
+ __mlx4_counter_free(dev, index);
+ }
+ }
+ spin_unlock_irq(mlx4_tlock(dev));
+}
+
+static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave)
+{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker;
+ struct list_head *xrcdn_list =
+ &tracker->slave_list[slave].res_list[RES_XRCD];
+ struct res_xrcdn *xrcd;
+ struct res_xrcdn *tmp;
+ int err;
+ int xrcdn;
+
+ err = move_all_busy(dev, slave, RES_XRCD);
+ if (err)
+ mlx4_warn(dev, "rem_slave_xrcdns: Could not move all xrcdns to "
+ "busy for slave %d\n", slave);
+
+ spin_lock_irq(mlx4_tlock(dev));
+ list_for_each_entry_safe(xrcd, tmp, xrcdn_list, com.list) {
+ if (xrcd->com.owner == slave) {
+ xrcdn = xrcd->com.res_id;
+ radix_tree_delete(&tracker->res_tree[RES_XRCD], xrcdn);
+ list_del(&xrcd->com.list);
+ kfree(xrcd);
+ __mlx4_xrcd_free(dev, xrcdn);
+ }
+ }
+ spin_unlock_irq(mlx4_tlock(dev));
+}
+
void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
{
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -3069,5 +3242,7 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
rem_slave_mrs(dev, slave);
rem_slave_eqs(dev, slave);
rem_slave_mtts(dev, slave);
+ rem_slave_counters(dev, slave);
+ rem_slave_xrcdns(dev, slave);
mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
}
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c
index f8dda009d3c0..5e313e9a252f 100644
--- a/drivers/net/ethernet/micrel/ks8851.c
+++ b/drivers/net/ethernet/micrel/ks8851.c
@@ -618,10 +618,8 @@ static void ks8851_irq_work(struct work_struct *work)
netif_dbg(ks, intr, ks->netdev,
"%s: status 0x%04x\n", __func__, status);
- if (status & IRQ_LCI) {
- /* should do something about checking link status */
+ if (status & IRQ_LCI)
handled |= IRQ_LCI;
- }
if (status & IRQ_LDI) {
u16 pmecr = ks8851_rdreg16(ks, KS_PMECR);
@@ -684,6 +682,9 @@ static void ks8851_irq_work(struct work_struct *work)
mutex_unlock(&ks->lock);
+ if (status & IRQ_LCI)
+ mii_check_link(&ks->mii);
+
if (status & IRQ_TXI)
netif_wake_queue(ks->netdev);
diff --git a/drivers/net/ethernet/natsemi/Kconfig b/drivers/net/ethernet/natsemi/Kconfig
index eb836f770f50..f157334579fd 100644
--- a/drivers/net/ethernet/natsemi/Kconfig
+++ b/drivers/net/ethernet/natsemi/Kconfig
@@ -6,9 +6,8 @@ config NET_VENDOR_NATSEMI
bool "National Semi-conductor devices"
default y
depends on AMIGA_PCMCIA || ARM || EISA || EXPERIMENTAL || H8300 || \
- ISA || M32R || MAC || MACH_JAZZ || MACH_TX49XX || MCA || \
- MCA_LEGACY || MIPS || PCI || PCMCIA || SUPERH || \
- XTENSA_PLATFORM_XT2000 || ZORRO
+ ISA || M32R || MAC || MACH_JAZZ || MACH_TX49XX || MIPS || \
+ PCI || PCMCIA || SUPERH || XTENSA_PLATFORM_XT2000 || ZORRO
---help---
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
@@ -21,21 +20,6 @@ config NET_VENDOR_NATSEMI
if NET_VENDOR_NATSEMI
-config IBMLANA
- tristate "IBM LAN Adapter/A support"
- depends on MCA
- ---help---
- This is a Micro Channel Ethernet adapter. You need to set
- CONFIG_MCA to use this driver. It is both available as an in-kernel
- driver and as a module.
-
- To compile this driver as a module, choose M here. The only
- currently supported card is the IBM LAN Adapter/A for Ethernet. It
- will both support 16K and 32K memory windows, however a 32K window
- gives a better security against packet losses. Usage of multiple
- boards with this driver should be possible, but has not been tested
- up to now due to lack of hardware.
-
config MACSONIC
tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
depends on MAC
diff --git a/drivers/net/ethernet/natsemi/Makefile b/drivers/net/ethernet/natsemi/Makefile
index 9aa5dea52b3e..764c532a96d1 100644
--- a/drivers/net/ethernet/natsemi/Makefile
+++ b/drivers/net/ethernet/natsemi/Makefile
@@ -2,7 +2,6 @@
# Makefile for the National Semi-conductor Sonic devices.
#
-obj-$(CONFIG_IBMLANA) += ibmlana.o
obj-$(CONFIG_MACSONIC) += macsonic.o
obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o
obj-$(CONFIG_NATSEMI) += natsemi.o
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
index 9f3dbc4feadc..b07311eaa693 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe.h
@@ -584,7 +584,6 @@ struct pch_gbe_hw_stats {
/**
* struct pch_gbe_adapter - board specific private data structure
* @stats_lock: Spinlock structure for status
- * @tx_queue_lock: Spinlock structure for transmit
* @ethtool_lock: Spinlock structure for ethtool
* @irq_sem: Semaphore for interrupt
* @netdev: Pointer of network device structure
@@ -609,7 +608,6 @@ struct pch_gbe_hw_stats {
struct pch_gbe_adapter {
spinlock_t stats_lock;
- spinlock_t tx_queue_lock;
spinlock_t ethtool_lock;
atomic_t irq_sem;
struct net_device *netdev;
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 9dc7e5023671..3787c64ee71c 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -645,14 +645,11 @@ static void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw)
*/
static int pch_gbe_alloc_queues(struct pch_gbe_adapter *adapter)
{
- int size;
-
- size = (int)sizeof(struct pch_gbe_tx_ring);
- adapter->tx_ring = kzalloc(size, GFP_KERNEL);
+ adapter->tx_ring = kzalloc(sizeof(*adapter->tx_ring), GFP_KERNEL);
if (!adapter->tx_ring)
return -ENOMEM;
- size = (int)sizeof(struct pch_gbe_rx_ring);
- adapter->rx_ring = kzalloc(size, GFP_KERNEL);
+
+ adapter->rx_ring = kzalloc(sizeof(*adapter->rx_ring), GFP_KERNEL);
if (!adapter->rx_ring) {
kfree(adapter->tx_ring);
return -ENOMEM;
@@ -1169,7 +1166,6 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
struct sk_buff *tmp_skb;
unsigned int frame_ctrl;
unsigned int ring_num;
- unsigned long flags;
/*-- Set frame control --*/
frame_ctrl = 0;
@@ -1216,14 +1212,14 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
}
}
}
- spin_lock_irqsave(&tx_ring->tx_lock, flags);
+
ring_num = tx_ring->next_to_use;
if (unlikely((ring_num + 1) == tx_ring->count))
tx_ring->next_to_use = 0;
else
tx_ring->next_to_use = ring_num + 1;
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+
buffer_info = &tx_ring->buffer_info[ring_num];
tmp_skb = buffer_info->skb;
@@ -1525,7 +1521,7 @@ pch_gbe_alloc_rx_buffers_pool(struct pch_gbe_adapter *adapter,
&rx_ring->rx_buff_pool_logic,
GFP_KERNEL);
if (!rx_ring->rx_buff_pool) {
- pr_err("Unable to allocate memory for the receive poll buffer\n");
+ pr_err("Unable to allocate memory for the receive pool buffer\n");
return -ENOMEM;
}
memset(rx_ring->rx_buff_pool, 0, size);
@@ -1644,15 +1640,17 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n",
cleaned_count);
/* Recover from running out of Tx resources in xmit_frame */
+ spin_lock(&tx_ring->tx_lock);
if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) {
netif_wake_queue(adapter->netdev);
adapter->stats.tx_restart_count++;
pr_debug("Tx wake queue\n");
}
- spin_lock(&adapter->tx_queue_lock);
+
tx_ring->next_to_clean = i;
- spin_unlock(&adapter->tx_queue_lock);
+
pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
+ spin_unlock(&tx_ring->tx_lock);
return cleaned;
}
@@ -2043,7 +2041,6 @@ static int pch_gbe_sw_init(struct pch_gbe_adapter *adapter)
return -ENOMEM;
}
spin_lock_init(&adapter->hw.miim_lock);
- spin_lock_init(&adapter->tx_queue_lock);
spin_lock_init(&adapter->stats_lock);
spin_lock_init(&adapter->ethtool_lock);
atomic_set(&adapter->irq_sem, 0);
@@ -2148,10 +2145,10 @@ static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tx_ring->next_to_use, tx_ring->next_to_clean);
return NETDEV_TX_BUSY;
}
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
/* CRC,ITAG no support */
pch_gbe_tx_queue(adapter, tx_ring, skb);
+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
index b5de8a7b90f1..37ccbe54e62d 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic.h
@@ -53,8 +53,8 @@
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 78
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.78"
+#define _NETXEN_NIC_LINUX_SUBVERSION 79
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.79"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
@@ -419,6 +419,8 @@ struct rcv_desc {
(((sts_data) >> 52) & 0x1)
#define netxen_get_lro_sts_seq_number(sts_data) \
((sts_data) & 0x0FFFFFFFF)
+#define netxen_get_lro_sts_mss(sts_data1) \
+ ((sts_data1 >> 32) & 0x0FFFF)
struct status_desc {
@@ -794,6 +796,7 @@ struct netxen_cmd_args {
#define NX_CAP0_JUMBO_CONTIGUOUS NX_CAP_BIT(0, 7)
#define NX_CAP0_LRO_CONTIGUOUS NX_CAP_BIT(0, 8)
#define NX_CAP0_HW_LRO NX_CAP_BIT(0, 10)
+#define NX_CAP0_HW_LRO_MSS NX_CAP_BIT(0, 21)
/*
* Context state
@@ -1073,6 +1076,8 @@ typedef struct {
#define NX_FW_CAPABILITY_FVLANTX (1 << 9)
#define NX_FW_CAPABILITY_HW_LRO (1 << 10)
#define NX_FW_CAPABILITY_GBE_LINK_CFG (1 << 11)
+#define NX_FW_CAPABILITY_MORE_CAPS (1 << 31)
+#define NX_FW_CAPABILITY_2_LRO_MAX_TCP_SEG (1 << 2)
/* module types */
#define LINKEVENT_MODULE_NOT_PRESENT 1
@@ -1155,6 +1160,7 @@ typedef struct {
#define NETXEN_NIC_BRIDGE_ENABLED 0X10
#define NETXEN_NIC_DIAG_ENABLED 0x20
#define NETXEN_FW_RESET_OWNER 0x40
+#define NETXEN_FW_MSS_CAP 0x80
#define NETXEN_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
@@ -1201,6 +1207,9 @@ typedef struct {
#define NX_FORCE_FW_RESET 0xdeaddead
+/* Fw dump levels */
+static const u32 FW_DUMP_LEVELS[] = { 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff };
+
/* Flash read/write address */
#define NX_FW_DUMP_REG1 0x00130060
#define NX_FW_DUMP_REG2 0x001e0000
@@ -1814,6 +1823,13 @@ struct netxen_brdinfo {
char short_name[NETXEN_MAX_SHORT_NAME];
};
+struct netxen_dimm_cfg {
+ u8 presence;
+ u8 mem_type;
+ u8 dimm_type;
+ u32 size;
+};
+
static const struct netxen_brdinfo netxen_boards[] = {
{NETXEN_BRDTYPE_P2_SB31_10G_CX4, 1, "XGb CX4"},
{NETXEN_BRDTYPE_P2_SB31_10G_HMEZ, 1, "XGb HMEZ"},
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
index f3c0057a802b..7f556a84925d 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
@@ -229,7 +229,7 @@ netxen_setup_minidump(struct netxen_adapter *adapter)
adapter->mdump.md_template;
adapter->mdump.md_capture_buff = NULL;
adapter->mdump.fw_supports_md = 1;
- adapter->mdump.md_enabled = 1;
+ adapter->mdump.md_enabled = 0;
return err;
@@ -328,6 +328,9 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
cap = (NX_CAP0_LEGACY_CONTEXT | NX_CAP0_LEGACY_MN);
cap |= (NX_CAP0_JUMBO_CONTIGUOUS | NX_CAP0_LRO_CONTIGUOUS);
+ if (adapter->flags & NETXEN_FW_MSS_CAP)
+ cap |= NX_CAP0_HW_LRO_MSS;
+
prq->capabilities[0] = cpu_to_le32(cap);
prq->host_int_crb_mode =
cpu_to_le32(NX_HOST_INT_CRB_MODE_SHARED);
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
index 8c39299331a2..39730403782f 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_ethtool.c
@@ -834,7 +834,7 @@ netxen_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
static int
netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val)
{
- int ret = 0;
+ int i;
struct netxen_adapter *adapter = netdev_priv(netdev);
struct netxen_minidump *mdump = &adapter->mdump;
@@ -844,7 +844,7 @@ netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val)
mdump->md_enabled = 1;
if (adapter->fw_mdump_rdy) {
netdev_info(netdev, "Previous dump not cleared, not forcing dump\n");
- return ret;
+ return 0;
}
netdev_info(netdev, "Forcing a fw dump\n");
nx_dev_request_reset(adapter);
@@ -867,19 +867,21 @@ netxen_set_dump(struct net_device *netdev, struct ethtool_dump *val)
adapter->flags &= ~NETXEN_FW_RESET_OWNER;
break;
default:
- if (val->flag <= NX_DUMP_MASK_MAX &&
- val->flag >= NX_DUMP_MASK_MIN) {
- mdump->md_capture_mask = val->flag & 0xff;
- netdev_info(netdev, "Driver mask changed to: 0x%x\n",
+ for (i = 0; i < ARRAY_SIZE(FW_DUMP_LEVELS); i++) {
+ if (val->flag == FW_DUMP_LEVELS[i]) {
+ mdump->md_capture_mask = val->flag;
+ netdev_info(netdev,
+ "Driver mask changed to: 0x%x\n",
mdump->md_capture_mask);
- break;
+ return 0;
+ }
}
netdev_info(netdev,
"Invalid dump level: 0x%x\n", val->flag);
return -EINVAL;
}
- return ret;
+ return 0;
}
static int
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
index b1a897cd9a8d..28e076960bcb 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hdr.h
@@ -776,6 +776,7 @@ enum {
#define CRB_SW_INT_MASK_3 (NETXEN_NIC_REG(0x1e8))
#define CRB_FW_CAPABILITIES_1 (NETXEN_CAM_RAM(0x128))
+#define CRB_FW_CAPABILITIES_2 (NETXEN_CAM_RAM(0x12c))
#define CRB_MAC_BLOCK_START (NETXEN_CAM_RAM(0x1c0))
/*
@@ -955,6 +956,31 @@ enum {
#define NX_CRB_DEV_REF_COUNT (NETXEN_CAM_RAM(0x138))
#define NX_CRB_DEV_STATE (NETXEN_CAM_RAM(0x140))
+/* MiniDIMM related macros */
+#define NETXEN_DIMM_CAPABILITY (NETXEN_CAM_RAM(0x258))
+#define NETXEN_DIMM_PRESENT 0x1
+#define NETXEN_DIMM_MEMTYPE_DDR2_SDRAM 0x2
+#define NETXEN_DIMM_SIZE 0x4
+#define NETXEN_DIMM_MEMTYPE(VAL) ((VAL >> 3) & 0xf)
+#define NETXEN_DIMM_NUMROWS(VAL) ((VAL >> 7) & 0xf)
+#define NETXEN_DIMM_NUMCOLS(VAL) ((VAL >> 11) & 0xf)
+#define NETXEN_DIMM_NUMRANKS(VAL) ((VAL >> 15) & 0x3)
+#define NETXEN_DIMM_DATAWIDTH(VAL) ((VAL >> 18) & 0x3)
+#define NETXEN_DIMM_NUMBANKS(VAL) ((VAL >> 21) & 0xf)
+#define NETXEN_DIMM_TYPE(VAL) ((VAL >> 25) & 0x3f)
+#define NETXEN_DIMM_VALID_FLAG 0x80000000
+
+#define NETXEN_DIMM_MEM_DDR2_SDRAM 0x8
+
+#define NETXEN_DIMM_STD_MEM_SIZE 512
+
+#define NETXEN_DIMM_TYPE_RDIMM 0x1
+#define NETXEN_DIMM_TYPE_UDIMM 0x2
+#define NETXEN_DIMM_TYPE_SO_DIMM 0x4
+#define NETXEN_DIMM_TYPE_Micro_DIMM 0x8
+#define NETXEN_DIMM_TYPE_Mini_RDIMM 0x10
+#define NETXEN_DIMM_TYPE_Mini_UDIMM 0x20
+
/* Device State */
#define NX_DEV_COLD 1
#define NX_DEV_INITALIZING 2
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
index 718b27440351..0d725dc91bcb 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
@@ -1131,7 +1131,6 @@ netxen_validate_firmware(struct netxen_adapter *adapter)
_build(file_fw_ver));
return -EINVAL;
}
-
val = nx_get_bios_version(adapter);
netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
if ((__force u32)val != bios) {
@@ -1661,6 +1660,9 @@ netxen_process_lro(struct netxen_adapter *adapter,
length = skb->len;
+ if (adapter->flags & NETXEN_FW_MSS_CAP)
+ skb_shinfo(skb)->gso_size = netxen_get_lro_sts_mss(sts_data1);
+
netif_receive_skb(skb);
adapter->stats.lro_pkts++;
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
index 65a718f9ccd3..342b3a79bd0f 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
@@ -1184,6 +1184,7 @@ netxen_nic_attach(struct netxen_adapter *adapter)
int err, ring;
struct nx_host_rds_ring *rds_ring;
struct nx_host_tx_ring *tx_ring;
+ u32 capab2;
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
return 0;
@@ -1192,6 +1193,13 @@ netxen_nic_attach(struct netxen_adapter *adapter)
if (err)
return err;
+ adapter->flags &= ~NETXEN_FW_MSS_CAP;
+ if (adapter->capabilities & NX_FW_CAPABILITY_MORE_CAPS) {
+ capab2 = NXRD32(adapter, CRB_FW_CAPABILITIES_2);
+ if (capab2 & NX_FW_CAPABILITY_2_LRO_MAX_TCP_SEG)
+ adapter->flags |= NETXEN_FW_MSS_CAP;
+ }
+
err = netxen_napi_add(adapter, netdev);
if (err)
return err;
@@ -1810,7 +1818,6 @@ netxen_tso_check(struct net_device *netdev,
flags = FLAGS_VLAN_TAGGED;
} else if (vlan_tx_tag_present(skb)) {
-
flags = FLAGS_VLAN_OOB;
vid = vlan_tx_tag_get(skb);
netxen_set_tx_vlan_tci(first_desc, vid);
@@ -2926,6 +2933,134 @@ static struct bin_attribute bin_attr_mem = {
.write = netxen_sysfs_write_mem,
};
+static ssize_t
+netxen_sysfs_read_dimm(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *attr,
+ char *buf, loff_t offset, size_t size)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct netxen_adapter *adapter = dev_get_drvdata(dev);
+ struct net_device *netdev = adapter->netdev;
+ struct netxen_dimm_cfg dimm;
+ u8 dw, rows, cols, banks, ranks;
+ u32 val;
+
+ if (size != sizeof(struct netxen_dimm_cfg)) {
+ netdev_err(netdev, "Invalid size\n");
+ return -1;
+ }
+
+ memset(&dimm, 0, sizeof(struct netxen_dimm_cfg));
+ val = NXRD32(adapter, NETXEN_DIMM_CAPABILITY);
+
+ /* Checks if DIMM info is valid. */
+ if (val & NETXEN_DIMM_VALID_FLAG) {
+ netdev_err(netdev, "Invalid DIMM flag\n");
+ dimm.presence = 0xff;
+ goto out;
+ }
+
+ rows = NETXEN_DIMM_NUMROWS(val);
+ cols = NETXEN_DIMM_NUMCOLS(val);
+ ranks = NETXEN_DIMM_NUMRANKS(val);
+ banks = NETXEN_DIMM_NUMBANKS(val);
+ dw = NETXEN_DIMM_DATAWIDTH(val);
+
+ dimm.presence = (val & NETXEN_DIMM_PRESENT);
+
+ /* Checks if DIMM info is present. */
+ if (!dimm.presence) {
+ netdev_err(netdev, "DIMM not present\n");
+ goto out;
+ }
+
+ dimm.dimm_type = NETXEN_DIMM_TYPE(val);
+
+ switch (dimm.dimm_type) {
+ case NETXEN_DIMM_TYPE_RDIMM:
+ case NETXEN_DIMM_TYPE_UDIMM:
+ case NETXEN_DIMM_TYPE_SO_DIMM:
+ case NETXEN_DIMM_TYPE_Micro_DIMM:
+ case NETXEN_DIMM_TYPE_Mini_RDIMM:
+ case NETXEN_DIMM_TYPE_Mini_UDIMM:
+ break;
+ default:
+ netdev_err(netdev, "Invalid DIMM type %x\n", dimm.dimm_type);
+ goto out;
+ }
+
+ if (val & NETXEN_DIMM_MEMTYPE_DDR2_SDRAM)
+ dimm.mem_type = NETXEN_DIMM_MEM_DDR2_SDRAM;
+ else
+ dimm.mem_type = NETXEN_DIMM_MEMTYPE(val);
+
+ if (val & NETXEN_DIMM_SIZE) {
+ dimm.size = NETXEN_DIMM_STD_MEM_SIZE;
+ goto out;
+ }
+
+ if (!rows) {
+ netdev_err(netdev, "Invalid no of rows %x\n", rows);
+ goto out;
+ }
+
+ if (!cols) {
+ netdev_err(netdev, "Invalid no of columns %x\n", cols);
+ goto out;
+ }
+
+ if (!banks) {
+ netdev_err(netdev, "Invalid no of banks %x\n", banks);
+ goto out;
+ }
+
+ ranks += 1;
+
+ switch (dw) {
+ case 0x0:
+ dw = 32;
+ break;
+ case 0x1:
+ dw = 33;
+ break;
+ case 0x2:
+ dw = 36;
+ break;
+ case 0x3:
+ dw = 64;
+ break;
+ case 0x4:
+ dw = 72;
+ break;
+ case 0x5:
+ dw = 80;
+ break;
+ case 0x6:
+ dw = 128;
+ break;
+ case 0x7:
+ dw = 144;
+ break;
+ default:
+ netdev_err(netdev, "Invalid data-width %x\n", dw);
+ goto out;
+ }
+
+ dimm.size = ((1 << rows) * (1 << cols) * dw * banks * ranks) / 8;
+ /* Size returned in MB. */
+ dimm.size = (dimm.size) / 0x100000;
+out:
+ memcpy(buf, &dimm, sizeof(struct netxen_dimm_cfg));
+ return sizeof(struct netxen_dimm_cfg);
+
+}
+
+static struct bin_attribute bin_attr_dimm = {
+ .attr = { .name = "dimm", .mode = (S_IRUGO | S_IWUSR) },
+ .size = 0,
+ .read = netxen_sysfs_read_dimm,
+};
+
static void
netxen_create_sysfs_entries(struct netxen_adapter *adapter)
@@ -2963,6 +3098,8 @@ netxen_create_diag_entries(struct netxen_adapter *adapter)
dev_info(dev, "failed to create crb sysfs entry\n");
if (device_create_bin_file(dev, &bin_attr_mem))
dev_info(dev, "failed to create mem sysfs entry\n");
+ if (device_create_bin_file(dev, &bin_attr_dimm))
+ dev_info(dev, "failed to create dimm sysfs entry\n");
}
@@ -2975,6 +3112,7 @@ netxen_remove_diag_entries(struct netxen_adapter *adapter)
device_remove_file(dev, &dev_attr_diag_mode);
device_remove_bin_file(dev, &bin_attr_crb);
device_remove_bin_file(dev, &bin_attr_mem);
+ device_remove_bin_file(dev, &bin_attr_dimm);
}
#ifdef CONFIG_INET
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 735423f7273f..9e9e78a5c4d7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -1232,7 +1232,12 @@ qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
else
dump->len = 0;
- dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
+
+ if (!fw_dump->enable)
+ dump->flag = ETH_FW_DUMP_DISABLE;
+ else
+ dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
+
dump->version = adapter->fw_version;
return 0;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 5c4713521d4c..46e77a2c5121 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1965,7 +1965,7 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter,
__le16 vlan_id = 0;
u8 hindex;
- if (!compare_ether_addr(phdr->h_source, adapter->mac_addr))
+ if (ether_addr_equal(phdr->h_source, adapter->mac_addr))
return;
if (adapter->fhash.fnum >= adapter->fhash.fmax)
@@ -2235,8 +2235,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (adapter->flags & QLCNIC_MACSPOOF) {
phdr = (struct ethhdr *)skb->data;
- if (compare_ether_addr(phdr->h_source,
- adapter->mac_addr))
+ if (!ether_addr_equal(phdr->h_source, adapter->mac_addr))
goto drop_packet;
}
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 00628d84342f..4f74b9762c29 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -63,8 +63,12 @@
#define R8169_MSG_DEFAULT \
(NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN)
-#define TX_BUFFS_AVAIL(tp) \
- (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
+#define TX_SLOTS_AVAIL(tp) \
+ (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx)
+
+/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */
+#define TX_FRAGS_READY_FOR(tp,nr_frags) \
+ (TX_SLOTS_AVAIL(tp) >= (nr_frags + 1))
/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
The RTL chips use a 64 element hash table based on the Ethernet CRC. */
@@ -5494,7 +5498,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
u32 opts[2];
int frags;
- if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
+ if (unlikely(!TX_FRAGS_READY_FOR(tp, skb_shinfo(skb)->nr_frags))) {
netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n");
goto err_stop_0;
}
@@ -5548,7 +5552,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
mmiowb();
- if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
+ if (!TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
/* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
* not miss a ring update when it notices a stopped queue.
*/
@@ -5562,7 +5566,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
* can't.
*/
smp_mb();
- if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)
+ if (TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS))
netif_wake_queue(dev);
}
@@ -5685,7 +5689,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
*/
smp_mb();
if (netif_queue_stopped(dev) &&
- (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) {
+ TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
netif_wake_queue(dev);
}
/*
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 3cbfbffe3f00..b95f2e1b33f0 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -656,25 +656,30 @@ static void efx_stop_datapath(struct efx_nic *efx)
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
+ struct pci_dev *dev = efx->pci_dev;
int rc;
EFX_ASSERT_RESET_SERIALISED(efx);
BUG_ON(efx->port_enabled);
- rc = efx_nic_flush_queues(efx);
- if (rc && EFX_WORKAROUND_7803(efx)) {
- /* Schedule a reset to recover from the flush failure. The
- * descriptor caches reference memory we're about to free,
- * but falcon_reconfigure_mac_wrapper() won't reconnect
- * the MACs because of the pending reset. */
- netif_err(efx, drv, efx->net_dev,
- "Resetting to recover from flush failure\n");
- efx_schedule_reset(efx, RESET_TYPE_ALL);
- } else if (rc) {
- netif_err(efx, drv, efx->net_dev, "failed to flush queues\n");
- } else {
- netif_dbg(efx, drv, efx->net_dev,
- "successfully flushed all queues\n");
+ /* Only perform flush if dma is enabled */
+ if (dev->is_busmaster) {
+ rc = efx_nic_flush_queues(efx);
+
+ if (rc && EFX_WORKAROUND_7803(efx)) {
+ /* Schedule a reset to recover from the flush failure. The
+ * descriptor caches reference memory we're about to free,
+ * but falcon_reconfigure_mac_wrapper() won't reconnect
+ * the MACs because of the pending reset. */
+ netif_err(efx, drv, efx->net_dev,
+ "Resetting to recover from flush failure\n");
+ efx_schedule_reset(efx, RESET_TYPE_ALL);
+ } else if (rc) {
+ netif_err(efx, drv, efx->net_dev, "failed to flush queues\n");
+ } else {
+ netif_dbg(efx, drv, efx->net_dev,
+ "successfully flushed all queues\n");
+ }
}
efx_for_each_channel(channel, efx) {
@@ -1349,7 +1354,7 @@ static int efx_probe_interrupts(struct efx_nic *efx)
}
/* RSS might be usable on VFs even if it is disabled on the PF */
- efx->rss_spread = (efx->n_rx_channels > 1 ?
+ efx->rss_spread = ((efx->n_rx_channels > 1 || !efx_sriov_wanted(efx)) ?
efx->n_rx_channels : efx_vf_size(efx));
return 0;
@@ -2492,8 +2497,8 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
efx_fini_io(efx);
netif_dbg(efx, drv, efx->net_dev, "shutdown successful\n");
- pci_set_drvdata(pci_dev, NULL);
efx_fini_struct(efx);
+ pci_set_drvdata(pci_dev, NULL);
free_netdev(efx->net_dev);
};
@@ -2695,6 +2700,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
fail2:
efx_fini_struct(efx);
fail1:
+ pci_set_drvdata(pci_dev, NULL);
WARN_ON(rc > 0);
netif_dbg(efx, drv, efx->net_dev, "initialisation failed. rc=%d\n", rc);
free_netdev(net_dev);
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index f22f45f515a8..03ded364c8da 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -1023,7 +1023,7 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx,
return -EINVAL;
/* Is it a default UC or MC filter? */
- if (!compare_ether_addr(mac_mask->h_dest, mac_addr_mc_mask) &&
+ if (ether_addr_equal(mac_mask->h_dest, mac_addr_mc_mask) &&
vlan_tag_mask == 0) {
if (is_multicast_ether_addr(mac_entry->h_dest))
rc = efx_filter_set_mc_def(&spec);
@@ -1108,6 +1108,39 @@ static int efx_ethtool_set_rxfh_indir(struct net_device *net_dev,
return 0;
}
+static int efx_ethtool_get_module_eeprom(struct net_device *net_dev,
+ struct ethtool_eeprom *ee,
+ u8 *data)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int ret;
+
+ if (!efx->phy_op || !efx->phy_op->get_module_eeprom)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&efx->mac_lock);
+ ret = efx->phy_op->get_module_eeprom(efx, ee, data);
+ mutex_unlock(&efx->mac_lock);
+
+ return ret;
+}
+
+static int efx_ethtool_get_module_info(struct net_device *net_dev,
+ struct ethtool_modinfo *modinfo)
+{
+ struct efx_nic *efx = netdev_priv(net_dev);
+ int ret;
+
+ if (!efx->phy_op || !efx->phy_op->get_module_info)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&efx->mac_lock);
+ ret = efx->phy_op->get_module_info(efx, modinfo);
+ mutex_unlock(&efx->mac_lock);
+
+ return ret;
+}
+
const struct ethtool_ops efx_ethtool_ops = {
.get_settings = efx_ethtool_get_settings,
.set_settings = efx_ethtool_set_settings,
@@ -1137,4 +1170,6 @@ const struct ethtool_ops efx_ethtool_ops = {
.get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
.get_rxfh_indir = efx_ethtool_get_rxfh_indir,
.set_rxfh_indir = efx_ethtool_set_rxfh_indir,
+ .get_module_info = efx_ethtool_get_module_info,
+ .get_module_eeprom = efx_ethtool_get_module_eeprom,
};
diff --git a/drivers/net/ethernet/sfc/mcdi_phy.c b/drivers/net/ethernet/sfc/mcdi_phy.c
index 7bcad899a936..13cb40fe90c1 100644
--- a/drivers/net/ethernet/sfc/mcdi_phy.c
+++ b/drivers/net/ethernet/sfc/mcdi_phy.c
@@ -739,6 +739,80 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx,
return NULL;
}
+#define SFP_PAGE_SIZE 128
+#define SFP_NUM_PAGES 2
+static int efx_mcdi_phy_get_module_eeprom(struct efx_nic *efx,
+ struct ethtool_eeprom *ee, u8 *data)
+{
+ u8 outbuf[MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX];
+ u8 inbuf[MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN];
+ size_t outlen;
+ int rc;
+ unsigned int payload_len;
+ unsigned int space_remaining = ee->len;
+ unsigned int page;
+ unsigned int page_off;
+ unsigned int to_copy;
+ u8 *user_data = data;
+
+ BUILD_BUG_ON(SFP_PAGE_SIZE * SFP_NUM_PAGES != ETH_MODULE_SFF_8079_LEN);
+
+ page_off = ee->offset % SFP_PAGE_SIZE;
+ page = ee->offset / SFP_PAGE_SIZE;
+
+ while (space_remaining && (page < SFP_NUM_PAGES)) {
+ MCDI_SET_DWORD(inbuf, GET_PHY_MEDIA_INFO_IN_PAGE, page);
+
+ rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_MEDIA_INFO,
+ inbuf, sizeof(inbuf),
+ outbuf, sizeof(outbuf),
+ &outlen);
+ if (rc)
+ return rc;
+
+ if (outlen < (MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST +
+ SFP_PAGE_SIZE))
+ return -EIO;
+
+ payload_len = MCDI_DWORD(outbuf,
+ GET_PHY_MEDIA_INFO_OUT_DATALEN);
+ if (payload_len != SFP_PAGE_SIZE)
+ return -EIO;
+
+ /* Copy as much as we can into data */
+ payload_len -= page_off;
+ to_copy = (space_remaining < payload_len) ?
+ space_remaining : payload_len;
+
+ memcpy(user_data,
+ outbuf + page_off +
+ MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST,
+ to_copy);
+
+ space_remaining -= to_copy;
+ user_data += to_copy;
+ page_off = 0;
+ page++;
+ }
+
+ return 0;
+}
+
+static int efx_mcdi_phy_get_module_info(struct efx_nic *efx,
+ struct ethtool_modinfo *modinfo)
+{
+ struct efx_mcdi_phy_data *phy_cfg = efx->phy_data;
+
+ switch (phy_cfg->media) {
+ case MC_CMD_MEDIA_SFP_PLUS:
+ modinfo->type = ETH_MODULE_SFF_8079;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
const struct efx_phy_operations efx_mcdi_phy_ops = {
.probe = efx_mcdi_phy_probe,
.init = efx_port_dummy_op_int,
@@ -751,4 +825,6 @@ const struct efx_phy_operations efx_mcdi_phy_ops = {
.test_alive = efx_mcdi_phy_test_alive,
.run_tests = efx_mcdi_phy_run_tests,
.test_name = efx_mcdi_phy_test_name,
+ .get_module_eeprom = efx_mcdi_phy_get_module_eeprom,
+ .get_module_info = efx_mcdi_phy_get_module_info,
};
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index f0385e1fb2d8..0e575359af17 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -252,8 +252,6 @@ struct efx_rx_page_state {
* @max_fill: RX descriptor maximum fill level (<= ring size)
* @fast_fill_trigger: RX descriptor fill level that will trigger a fast fill
* (<= @max_fill)
- * @fast_fill_limit: The level to which a fast fill will fill
- * (@fast_fill_trigger <= @fast_fill_limit <= @max_fill)
* @min_fill: RX descriptor minimum non-zero fill level.
* This records the minimum fill level observed when a ring
* refill was triggered.
@@ -274,7 +272,6 @@ struct efx_rx_queue {
int removed_count;
unsigned int max_fill;
unsigned int fast_fill_trigger;
- unsigned int fast_fill_limit;
unsigned int min_fill;
unsigned int min_overfill;
unsigned int alloc_page_count;
@@ -522,6 +519,11 @@ struct efx_phy_operations {
int (*test_alive) (struct efx_nic *efx);
const char *(*test_name) (struct efx_nic *efx, unsigned int index);
int (*run_tests) (struct efx_nic *efx, int *results, unsigned flags);
+ int (*get_module_eeprom) (struct efx_nic *efx,
+ struct ethtool_eeprom *ee,
+ u8 *data);
+ int (*get_module_info) (struct efx_nic *efx,
+ struct ethtool_modinfo *modinfo);
};
/**
diff --git a/drivers/net/ethernet/sfc/qt202x_phy.c b/drivers/net/ethernet/sfc/qt202x_phy.c
index 8a7caf88ffb6..326a28637f3c 100644
--- a/drivers/net/ethernet/sfc/qt202x_phy.c
+++ b/drivers/net/ethernet/sfc/qt202x_phy.c
@@ -449,6 +449,37 @@ static void qt202x_phy_remove(struct efx_nic *efx)
efx->phy_data = NULL;
}
+static int qt202x_phy_get_module_info(struct efx_nic *efx,
+ struct ethtool_modinfo *modinfo)
+{
+ modinfo->type = ETH_MODULE_SFF_8079;
+ modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
+ return 0;
+}
+
+static int qt202x_phy_get_module_eeprom(struct efx_nic *efx,
+ struct ethtool_eeprom *ee, u8 *data)
+{
+ int mmd, reg_base, rc, i;
+
+ if (efx->phy_type == PHY_TYPE_QT2025C) {
+ mmd = MDIO_MMD_PCS;
+ reg_base = 0xd000;
+ } else {
+ mmd = MDIO_MMD_PMAPMD;
+ reg_base = 0x8007;
+ }
+
+ for (i = 0; i < ee->len; i++) {
+ rc = efx_mdio_read(efx, mmd, reg_base + ee->offset + i);
+ if (rc < 0)
+ return rc;
+ data[i] = rc;
+ }
+
+ return 0;
+}
+
const struct efx_phy_operations falcon_qt202x_phy_ops = {
.probe = qt202x_phy_probe,
.init = qt202x_phy_init,
@@ -459,4 +490,6 @@ const struct efx_phy_operations falcon_qt202x_phy_ops = {
.get_settings = qt202x_phy_get_settings,
.set_settings = efx_mdio_set_settings,
.test_alive = efx_mdio_test_alive,
+ .get_module_eeprom = qt202x_phy_get_module_eeprom,
+ .get_module_info = qt202x_phy_get_module_info,
};
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index 763fa2fe1a38..243e91f3dff9 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -76,12 +76,7 @@ static int rx_alloc_method = RX_ALLOC_METHOD_AUTO;
/* This is the percentage fill level below which new RX descriptors
* will be added to the RX descriptor ring.
*/
-static unsigned int rx_refill_threshold = 90;
-
-/* This is the percentage fill level to which an RX queue will be refilled
- * when the "RX refill threshold" is reached.
- */
-static unsigned int rx_refill_limit = 95;
+static unsigned int rx_refill_threshold;
/*
* RX maximum head room required.
@@ -342,7 +337,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel,
* efx_fast_push_rx_descriptors - push new RX descriptors quickly
* @rx_queue: RX descriptor queue
* This will aim to fill the RX descriptor queue up to
- * @rx_queue->@fast_fill_limit. If there is insufficient atomic
+ * @rx_queue->@max_fill. If there is insufficient atomic
* memory to do so, a slow fill will be scheduled.
*
* The caller must provide serialisation (none is used here). In practise,
@@ -367,15 +362,14 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue)
rx_queue->min_fill = fill_level;
}
- space = rx_queue->fast_fill_limit - fill_level;
- if (space < EFX_RX_BATCH)
- goto out;
+ space = rx_queue->max_fill - fill_level;
+ EFX_BUG_ON_PARANOID(space < EFX_RX_BATCH);
netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev,
"RX queue %d fast-filling descriptor ring from"
" level %d to level %d using %s allocation\n",
efx_rx_queue_index(rx_queue), fill_level,
- rx_queue->fast_fill_limit,
+ rx_queue->max_fill,
channel->rx_alloc_push_pages ? "page" : "skb");
do {
@@ -681,7 +675,7 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue)
void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
{
struct efx_nic *efx = rx_queue->efx;
- unsigned int max_fill, trigger, limit;
+ unsigned int max_fill, trigger, max_trigger;
netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev,
"initialising RX queue %d\n", efx_rx_queue_index(rx_queue));
@@ -694,12 +688,17 @@ void efx_init_rx_queue(struct efx_rx_queue *rx_queue)
/* Initialise limit fields */
max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM;
- trigger = max_fill * min(rx_refill_threshold, 100U) / 100U;
- limit = max_fill * min(rx_refill_limit, 100U) / 100U;
+ max_trigger = max_fill - EFX_RX_BATCH;
+ if (rx_refill_threshold != 0) {
+ trigger = max_fill * min(rx_refill_threshold, 100U) / 100U;
+ if (trigger > max_trigger)
+ trigger = max_trigger;
+ } else {
+ trigger = max_trigger;
+ }
rx_queue->max_fill = max_fill;
rx_queue->fast_fill_trigger = trigger;
- rx_queue->fast_fill_limit = limit;
/* Set up RX descriptor ring */
rx_queue->enabled = true;
@@ -746,5 +745,5 @@ MODULE_PARM_DESC(rx_alloc_method, "Allocation method used for RX buffers");
module_param(rx_refill_threshold, uint, 0444);
MODULE_PARM_DESC(rx_refill_threshold,
- "RX descriptor ring fast/slow fill threshold (%)");
+ "RX descriptor ring refill threshold (%)");
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index f5dedcbf4651..bcd54d6e94fd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -247,8 +247,8 @@ struct stmmac_desc_ops {
struct stmmac_dma_ops {
/* DMA core initialization */
- int (*init) (void __iomem *ioaddr, int pbl, int fb, int burst_len,
- u32 dma_tx, u32 dma_rx);
+ int (*init) (void __iomem *ioaddr, int pbl, int fb, int mb,
+ int burst_len, u32 dma_tx, u32 dma_rx);
/* Dump DMA registers */
void (*dump_regs) (void __iomem *ioaddr);
/* Set tx/rx threshold in the csr6 register
@@ -280,7 +280,7 @@ struct stmmac_ops {
/* Handle extra events on specific interrupts hw dependent */
void (*host_irq_status) (void __iomem *ioaddr);
/* Multicast filter setting */
- void (*set_filter) (struct net_device *dev);
+ void (*set_filter) (struct net_device *dev, int id);
/* Flow control setting */
void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex,
unsigned int fc, unsigned int pause_time);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index 54339a78e358..23478bf4ed7a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -61,9 +61,11 @@ enum power_event {
};
/* GMAC HW ADDR regs */
-#define GMAC_ADDR_HIGH(reg) (0x00000040+(reg * 8))
-#define GMAC_ADDR_LOW(reg) (0x00000044+(reg * 8))
-#define GMAC_MAX_UNICAST_ADDRESSES 16
+#define GMAC_ADDR_HIGH(reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \
+ (reg * 8))
+#define GMAC_ADDR_LOW(reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \
+ (reg * 8))
+#define GMAC_MAX_PERFECT_ADDRESSES 32
#define GMAC_AN_CTRL 0x000000c0 /* AN control */
#define GMAC_AN_STATUS 0x000000c4 /* AN status */
@@ -139,6 +141,7 @@ enum rx_tx_priority_ratio {
};
#define DMA_BUS_MODE_FB 0x00010000 /* Fixed burst */
+#define DMA_BUS_MODE_MB 0x04000000 /* Mixed burst */
#define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */
#define DMA_BUS_MODE_RPBL_SHIFT 17
#define DMA_BUS_MODE_USP 0x00800000
@@ -205,4 +208,7 @@ enum rtc_control {
#define GMAC_MMC_TX_INTR 0x108
#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
+/* Synopsys Core versions */
+#define DWMAC_CORE_3_40 34
+
extern const struct stmmac_dma_ops dwmac1000_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index e7cbcd99c2cb..b5e4d02f15c9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -84,10 +84,11 @@ static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
GMAC_ADDR_LOW(reg_n));
}
-static void dwmac1000_set_filter(struct net_device *dev)
+static void dwmac1000_set_filter(struct net_device *dev, int id)
{
void __iomem *ioaddr = (void __iomem *) dev->base_addr;
unsigned int value = 0;
+ unsigned int perfect_addr_number;
CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
__func__, netdev_mc_count(dev), netdev_uc_count(dev));
@@ -121,8 +122,14 @@ static void dwmac1000_set_filter(struct net_device *dev)
writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
}
+ /* Extra 16 regs are available in cores newer than the 3.40. */
+ if (id > DWMAC_CORE_3_40)
+ perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES;
+ else
+ perfect_addr_number = GMAC_MAX_PERFECT_ADDRESSES / 2;
+
/* Handle multiple unicast addresses (perfect filtering)*/
- if (netdev_uc_count(dev) > GMAC_MAX_UNICAST_ADDRESSES)
+ if (netdev_uc_count(dev) > perfect_addr_number)
/* Switch to promiscuous mode is more than 16 addrs
are required */
value |= GMAC_FRAME_FILTER_PR;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 3675c5731565..033500090f55 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -31,7 +31,7 @@
#include "dwmac_dma.h"
static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb,
- int burst_len, u32 dma_tx, u32 dma_rx)
+ int mb, int burst_len, u32 dma_tx, u32 dma_rx)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
int limit;
@@ -66,6 +66,10 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb,
if (fb)
value |= DMA_BUS_MODE_FB;
+ /* Mixed Burst has no effect when fb is set */
+ if (mb)
+ value |= DMA_BUS_MODE_MB;
+
#ifdef CONFIG_STMMAC_DA
value |= DMA_BUS_MODE_DA; /* Rx has priority over tx */
#endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
index efde50ff03f8..19e0f4eed2bc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -89,7 +89,7 @@ static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
}
-static void dwmac100_set_filter(struct net_device *dev)
+static void dwmac100_set_filter(struct net_device *dev, int id)
{
void __iomem *ioaddr = (void __iomem *) dev->base_addr;
u32 value = readl(ioaddr + MAC_CONTROL);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
index 92ed2e07609e..c2b4d55a79b6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
@@ -33,7 +33,7 @@
#include "dwmac_dma.h"
static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb,
- int burst_len, u32 dma_tx, u32 dma_rx)
+ int mb, int burst_len, u32 dma_tx, u32 dma_rx)
{
u32 value = readl(ioaddr + DMA_BUS_MODE);
int limit;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
index f20aa12931d0..4e0e18a44fcc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
@@ -31,6 +31,8 @@
#define DWMAC_LIB_DBG(fmt, args...) do { } while (0)
#endif
+#define GMAC_HI_REG_AE 0x80000000
+
/* CSR1 enables the transmit DMA to check for new descriptor */
void dwmac_enable_dma_transmission(void __iomem *ioaddr)
{
@@ -233,7 +235,11 @@ void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6],
unsigned long data;
data = (addr[5] << 8) | addr[4];
- writel(data, ioaddr + high);
+ /* For MAC Addr registers se have to set the Address Enable (AE)
+ * bit that has no effect on the High Reg 0 where the bit 31 (MO)
+ * is RO.
+ */
+ writel(data | GMAC_HI_REG_AE, ioaddr + high);
data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
writel(data, ioaddr + low);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index db2de9a49952..6b5d060ee9de 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -85,6 +85,7 @@ struct stmmac_priv {
struct clk *stmmac_clk;
#endif
int clk_csr;
+ int synopsys_id;
};
extern int phyaddr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1a4cf8128f91..70966330f44e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -925,6 +925,7 @@ static void stmmac_check_ether_addr(struct stmmac_priv *priv)
static int stmmac_init_dma_engine(struct stmmac_priv *priv)
{
int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, burst_len = 0;
+ int mixed_burst = 0;
/* Some DMA parameters can be passed from the platform;
* in case of these are not passed we keep a default
@@ -932,10 +933,11 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
if (priv->plat->dma_cfg) {
pbl = priv->plat->dma_cfg->pbl;
fixed_burst = priv->plat->dma_cfg->fixed_burst;
+ mixed_burst = priv->plat->dma_cfg->mixed_burst;
burst_len = priv->plat->dma_cfg->burst_len;
}
- return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst,
+ return priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst,
burst_len, priv->dma_tx_phy,
priv->dma_rx_phy);
}
@@ -1465,7 +1467,7 @@ static void stmmac_set_rx_mode(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev);
spin_lock(&priv->lock);
- priv->hw->mac->set_filter(dev);
+ priv->hw->mac->set_filter(dev, priv->synopsys_id);
spin_unlock(&priv->lock);
}
@@ -1638,7 +1640,7 @@ static const struct file_operations stmmac_rings_status_fops = {
.open = stmmac_sysfs_ring_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = single_release,
};
static int stmmac_sysfs_dma_cap_read(struct seq_file *seq, void *v)
@@ -1710,7 +1712,7 @@ static const struct file_operations stmmac_dma_cap_fops = {
.open = stmmac_sysfs_dma_cap_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = single_release,
};
static int stmmac_init_fs(struct net_device *dev)
@@ -1806,7 +1808,7 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
priv->hw->ring = &ring_mode_ops;
/* Get and dump the chip ID */
- stmmac_get_synopsys_id(priv);
+ priv->synopsys_id = stmmac_get_synopsys_id(priv);
/* Get the HW capability (new GMAC newer than 3.50a) */
priv->hw_cap_support = stmmac_get_hw_features(priv);
@@ -1987,6 +1989,7 @@ int stmmac_suspend(struct net_device *ndev)
{
struct stmmac_priv *priv = netdev_priv(ndev);
int dis_ic = 0;
+ unsigned long flags;
if (!ndev || !netif_running(ndev))
return 0;
@@ -1994,7 +1997,7 @@ int stmmac_suspend(struct net_device *ndev)
if (priv->phydev)
phy_stop(priv->phydev);
- spin_lock(&priv->lock);
+ spin_lock_irqsave(&priv->lock, flags);
netif_device_detach(ndev);
netif_stop_queue(ndev);
@@ -2022,18 +2025,19 @@ int stmmac_suspend(struct net_device *ndev)
/* Disable clock in case of PWM is off */
stmmac_clk_disable(priv);
}
- spin_unlock(&priv->lock);
+ spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
int stmmac_resume(struct net_device *ndev)
{
struct stmmac_priv *priv = netdev_priv(ndev);
+ unsigned long flags;
if (!netif_running(ndev))
return 0;
- spin_lock(&priv->lock);
+ spin_lock_irqsave(&priv->lock, flags);
/* Power Down bit, into the PM register, is cleared
* automatically as soon as a magic packet or a Wake-up frame
@@ -2061,7 +2065,7 @@ int stmmac_resume(struct net_device *ndev)
netif_start_queue(ndev);
- spin_unlock(&priv->lock);
+ spin_unlock_irqrestore(&priv->lock, flags);
if (priv->phydev)
phy_start(priv->phydev);
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c
index 38e3ae9155b7..a108db35924e 100644
--- a/drivers/net/ethernet/sun/sunvnet.c
+++ b/drivers/net/ethernet/sun/sunvnet.c
@@ -618,7 +618,7 @@ struct vnet_port *__tx_port_find(struct vnet *vp, struct sk_buff *skb)
struct vnet_port *port;
hlist_for_each_entry(port, n, hp, hash) {
- if (!compare_ether_addr(port->raddr, skb->data))
+ if (ether_addr_equal(port->raddr, skb->data))
return port;
}
port = NULL;
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c
index 3d501ec7fad7..96070e9b50dc 100644
--- a/drivers/net/ethernet/tile/tilepro.c
+++ b/drivers/net/ethernet/tile/tilepro.c
@@ -843,7 +843,7 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)
if (!is_multicast_ether_addr(buf)) {
/* Filter packets not for our address. */
const u8 *mine = dev->dev_addr;
- filter = compare_ether_addr(mine, buf);
+ filter = !ether_addr_equal(mine, buf);
}
}
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
index 5c14f82c4954..961c8321451f 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c
@@ -1590,8 +1590,8 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
found = 0;
oldest = NULL;
list_for_each_entry(target, &wl->network_list, list) {
- if (!compare_ether_addr(&target->hwinfo->bssid[2],
- &scan_info->bssid[2])) {
+ if (ether_addr_equal(&target->hwinfo->bssid[2],
+ &scan_info->bssid[2])) {
found = 1;
pr_debug("%s: same BBS found scanned list\n",
__func__);
@@ -1691,8 +1691,8 @@ struct gelic_wl_scan_info *gelic_wl_find_best_bss(struct gelic_wl_info *wl)
/* If bss specified, check it only */
if (test_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat)) {
- if (!compare_ether_addr(&scan_info->hwinfo->bssid[2],
- wl->bssid)) {
+ if (ether_addr_equal(&scan_info->hwinfo->bssid[2],
+ wl->bssid)) {
best_bss = scan_info;
pr_debug("%s: bssid matched\n", __func__);
break;
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index c35824552792..4ffcd57b011b 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -27,6 +27,7 @@
#include <linux/list.h>
#include <linux/hyperv.h>
+#include <linux/rndis.h>
/* Fwd declaration */
struct hv_netvsc_packet;
@@ -506,295 +507,6 @@ struct netvsc_device {
void *extension;
};
-
-/* Status codes */
-
-
-#ifndef STATUS_SUCCESS
-#define STATUS_SUCCESS (0x00000000L)
-#endif
-
-#ifndef STATUS_UNSUCCESSFUL
-#define STATUS_UNSUCCESSFUL (0xC0000001L)
-#endif
-
-#ifndef STATUS_PENDING
-#define STATUS_PENDING (0x00000103L)
-#endif
-
-#ifndef STATUS_INSUFFICIENT_RESOURCES
-#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL)
-#endif
-
-#ifndef STATUS_BUFFER_OVERFLOW
-#define STATUS_BUFFER_OVERFLOW (0x80000005L)
-#endif
-
-#ifndef STATUS_NOT_SUPPORTED
-#define STATUS_NOT_SUPPORTED (0xC00000BBL)
-#endif
-
-#define RNDIS_STATUS_SUCCESS (STATUS_SUCCESS)
-#define RNDIS_STATUS_PENDING (STATUS_PENDING)
-#define RNDIS_STATUS_NOT_RECOGNIZED (0x00010001L)
-#define RNDIS_STATUS_NOT_COPIED (0x00010002L)
-#define RNDIS_STATUS_NOT_ACCEPTED (0x00010003L)
-#define RNDIS_STATUS_CALL_ACTIVE (0x00010007L)
-
-#define RNDIS_STATUS_ONLINE (0x40010003L)
-#define RNDIS_STATUS_RESET_START (0x40010004L)
-#define RNDIS_STATUS_RESET_END (0x40010005L)
-#define RNDIS_STATUS_RING_STATUS (0x40010006L)
-#define RNDIS_STATUS_CLOSED (0x40010007L)
-#define RNDIS_STATUS_WAN_LINE_UP (0x40010008L)
-#define RNDIS_STATUS_WAN_LINE_DOWN (0x40010009L)
-#define RNDIS_STATUS_WAN_FRAGMENT (0x4001000AL)
-#define RNDIS_STATUS_MEDIA_CONNECT (0x4001000BL)
-#define RNDIS_STATUS_MEDIA_DISCONNECT (0x4001000CL)
-#define RNDIS_STATUS_HARDWARE_LINE_UP (0x4001000DL)
-#define RNDIS_STATUS_HARDWARE_LINE_DOWN (0x4001000EL)
-#define RNDIS_STATUS_INTERFACE_UP (0x4001000FL)
-#define RNDIS_STATUS_INTERFACE_DOWN (0x40010010L)
-#define RNDIS_STATUS_MEDIA_BUSY (0x40010011L)
-#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION (0x40010012L)
-#define RNDIS_STATUS_WW_INDICATION RDIA_SPECIFIC_INDICATION
-#define RNDIS_STATUS_LINK_SPEED_CHANGE (0x40010013L)
-
-#define RNDIS_STATUS_NOT_RESETTABLE (0x80010001L)
-#define RNDIS_STATUS_SOFT_ERRORS (0x80010003L)
-#define RNDIS_STATUS_HARD_ERRORS (0x80010004L)
-#define RNDIS_STATUS_BUFFER_OVERFLOW (STATUS_BUFFER_OVERFLOW)
-
-#define RNDIS_STATUS_FAILURE (STATUS_UNSUCCESSFUL)
-#define RNDIS_STATUS_RESOURCES (STATUS_INSUFFICIENT_RESOURCES)
-#define RNDIS_STATUS_CLOSING (0xC0010002L)
-#define RNDIS_STATUS_BAD_VERSION (0xC0010004L)
-#define RNDIS_STATUS_BAD_CHARACTERISTICS (0xC0010005L)
-#define RNDIS_STATUS_ADAPTER_NOT_FOUND (0xC0010006L)
-#define RNDIS_STATUS_OPEN_FAILED (0xC0010007L)
-#define RNDIS_STATUS_DEVICE_FAILED (0xC0010008L)
-#define RNDIS_STATUS_MULTICAST_FULL (0xC0010009L)
-#define RNDIS_STATUS_MULTICAST_EXISTS (0xC001000AL)
-#define RNDIS_STATUS_MULTICAST_NOT_FOUND (0xC001000BL)
-#define RNDIS_STATUS_REQUEST_ABORTED (0xC001000CL)
-#define RNDIS_STATUS_RESET_IN_PROGRESS (0xC001000DL)
-#define RNDIS_STATUS_CLOSING_INDICATING (0xC001000EL)
-#define RNDIS_STATUS_NOT_SUPPORTED (STATUS_NOT_SUPPORTED)
-#define RNDIS_STATUS_INVALID_PACKET (0xC001000FL)
-#define RNDIS_STATUS_OPEN_LIST_FULL (0xC0010010L)
-#define RNDIS_STATUS_ADAPTER_NOT_READY (0xC0010011L)
-#define RNDIS_STATUS_ADAPTER_NOT_OPEN (0xC0010012L)
-#define RNDIS_STATUS_NOT_INDICATING (0xC0010013L)
-#define RNDIS_STATUS_INVALID_LENGTH (0xC0010014L)
-#define RNDIS_STATUS_INVALID_DATA (0xC0010015L)
-#define RNDIS_STATUS_BUFFER_TOO_SHORT (0xC0010016L)
-#define RNDIS_STATUS_INVALID_OID (0xC0010017L)
-#define RNDIS_STATUS_ADAPTER_REMOVED (0xC0010018L)
-#define RNDIS_STATUS_UNSUPPORTED_MEDIA (0xC0010019L)
-#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE (0xC001001AL)
-#define RNDIS_STATUS_FILE_NOT_FOUND (0xC001001BL)
-#define RNDIS_STATUS_ERROR_READING_FILE (0xC001001CL)
-#define RNDIS_STATUS_ALREADY_MAPPED (0xC001001DL)
-#define RNDIS_STATUS_RESOURCE_CONFLICT (0xC001001EL)
-#define RNDIS_STATUS_NO_CABLE (0xC001001FL)
-
-#define RNDIS_STATUS_INVALID_SAP (0xC0010020L)
-#define RNDIS_STATUS_SAP_IN_USE (0xC0010021L)
-#define RNDIS_STATUS_INVALID_ADDRESS (0xC0010022L)
-#define RNDIS_STATUS_VC_NOT_ACTIVATED (0xC0010023L)
-#define RNDIS_STATUS_DEST_OUT_OF_ORDER (0xC0010024L)
-#define RNDIS_STATUS_VC_NOT_AVAILABLE (0xC0010025L)
-#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE (0xC0010026L)
-#define RNDIS_STATUS_INCOMPATABLE_QOS (0xC0010027L)
-#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED (0xC0010028L)
-#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION (0xC0010029L)
-
-#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR (0xC0011000L)
-
-/* Object Identifiers used by NdisRequest Query/Set Information */
-/* General Objects */
-#define RNDIS_OID_GEN_SUPPORTED_LIST 0x00010101
-#define RNDIS_OID_GEN_HARDWARE_STATUS 0x00010102
-#define RNDIS_OID_GEN_MEDIA_SUPPORTED 0x00010103
-#define RNDIS_OID_GEN_MEDIA_IN_USE 0x00010104
-#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105
-#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106
-#define RNDIS_OID_GEN_LINK_SPEED 0x00010107
-#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108
-#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109
-#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A
-#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B
-#define RNDIS_OID_GEN_VENDOR_ID 0x0001010C
-#define RNDIS_OID_GEN_VENDOR_DESCRIPTION 0x0001010D
-#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER 0x0001010E
-#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD 0x0001010F
-#define RNDIS_OID_GEN_DRIVER_VERSION 0x00010110
-#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111
-#define RNDIS_OID_GEN_PROTOCOL_OPTIONS 0x00010112
-#define RNDIS_OID_GEN_MAC_OPTIONS 0x00010113
-#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
-#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115
-#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION 0x00010116
-#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118
-#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119
-#define RNDIS_OID_GEN_MACHINE_NAME 0x0001021A
-#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B
-
-#define RNDIS_OID_GEN_XMIT_OK 0x00020101
-#define RNDIS_OID_GEN_RCV_OK 0x00020102
-#define RNDIS_OID_GEN_XMIT_ERROR 0x00020103
-#define RNDIS_OID_GEN_RCV_ERROR 0x00020104
-#define RNDIS_OID_GEN_RCV_NO_BUFFER 0x00020105
-
-#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT 0x00020201
-#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
-#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT 0x00020203
-#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
-#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT 0x00020205
-#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
-#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV 0x00020207
-#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
-#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV 0x00020209
-#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
-#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV 0x0002020B
-#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
-
-#define RNDIS_OID_GEN_RCV_CRC_ERROR 0x0002020D
-#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
-
-#define RNDIS_OID_GEN_GET_TIME_CAPS 0x0002020F
-#define RNDIS_OID_GEN_GET_NETCARD_TIME 0x00020210
-
-/* These are connection-oriented general OIDs. */
-/* These replace the above OIDs for connection-oriented media. */
-#define RNDIS_OID_GEN_CO_SUPPORTED_LIST 0x00010101
-#define RNDIS_OID_GEN_CO_HARDWARE_STATUS 0x00010102
-#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED 0x00010103
-#define RNDIS_OID_GEN_CO_MEDIA_IN_USE 0x00010104
-#define RNDIS_OID_GEN_CO_LINK_SPEED 0x00010105
-#define RNDIS_OID_GEN_CO_VENDOR_ID 0x00010106
-#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION 0x00010107
-#define RNDIS_OID_GEN_CO_DRIVER_VERSION 0x00010108
-#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS 0x00010109
-#define RNDIS_OID_GEN_CO_MAC_OPTIONS 0x0001010A
-#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS 0x0001010B
-#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION 0x0001010C
-#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED 0x0001010D
-
-#define RNDIS_OID_GEN_CO_GET_TIME_CAPS 0x00010201
-#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME 0x00010202
-
-/* These are connection-oriented statistics OIDs. */
-#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK 0x00020101
-#define RNDIS_OID_GEN_CO_RCV_PDUS_OK 0x00020102
-#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103
-#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR 0x00020104
-#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER 0x00020105
-
-
-#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR 0x00020201
-#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH 0x00020202
-#define RNDIS_OID_GEN_CO_BYTES_XMIT 0x00020203
-#define RNDIS_OID_GEN_CO_BYTES_RCV 0x00020204
-#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205
-#define RNDIS_OID_GEN_CO_NETCARD_LOAD 0x00020206
-
-/* These are objects for Connection-oriented media call-managers. */
-#define RNDIS_OID_CO_ADD_PVC 0xFF000001
-#define RNDIS_OID_CO_DELETE_PVC 0xFF000002
-#define RNDIS_OID_CO_GET_CALL_INFORMATION 0xFF000003
-#define RNDIS_OID_CO_ADD_ADDRESS 0xFF000004
-#define RNDIS_OID_CO_DELETE_ADDRESS 0xFF000005
-#define RNDIS_OID_CO_GET_ADDRESSES 0xFF000006
-#define RNDIS_OID_CO_ADDRESS_CHANGE 0xFF000007
-#define RNDIS_OID_CO_SIGNALING_ENABLED 0xFF000008
-#define RNDIS_OID_CO_SIGNALING_DISABLED 0xFF000009
-
-/* 802.3 Objects (Ethernet) */
-#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101
-#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102
-#define RNDIS_OID_802_3_MULTICAST_LIST 0x01010103
-#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE 0x01010104
-#define RNDIS_OID_802_3_MAC_OPTIONS 0x01010105
-
-#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001
-
-#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
-#define RNDIS_OID_802_3_XMIT_ONE_COLLISION 0x01020102
-#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
-
-#define RNDIS_OID_802_3_XMIT_DEFERRED 0x01020201
-#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
-#define RNDIS_OID_802_3_RCV_OVERRUN 0x01020203
-#define RNDIS_OID_802_3_XMIT_UNDERRUN 0x01020204
-#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205
-#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
-#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
-
-/* Remote NDIS message types */
-#define REMOTE_NDIS_PACKET_MSG 0x00000001
-#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002
-#define REMOTE_NDIS_HALT_MSG 0x00000003
-#define REMOTE_NDIS_QUERY_MSG 0x00000004
-#define REMOTE_NDIS_SET_MSG 0x00000005
-#define REMOTE_NDIS_RESET_MSG 0x00000006
-#define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007
-#define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008
-
-#define REMOTE_CONDIS_MP_CREATE_VC_MSG 0x00008001
-#define REMOTE_CONDIS_MP_DELETE_VC_MSG 0x00008002
-#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG 0x00008005
-#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG 0x00008006
-#define REMOTE_CONDIS_INDICATE_STATUS_MSG 0x00008007
-
-/* Remote NDIS message completion types */
-#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002
-#define REMOTE_NDIS_QUERY_CMPLT 0x80000004
-#define REMOTE_NDIS_SET_CMPLT 0x80000005
-#define REMOTE_NDIS_RESET_CMPLT 0x80000006
-#define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008
-
-#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT 0x80008001
-#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT 0x80008002
-#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT 0x80008005
-#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT 0x80008006
-
-/*
- * Reserved message type for private communication between lower-layer host
- * driver and remote device, if necessary.
- */
-#define REMOTE_NDIS_BUS_MSG 0xff000001
-
-/* Defines for DeviceFlags in struct rndis_initialize_complete */
-#define RNDIS_DF_CONNECTIONLESS 0x00000001
-#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002
-#define RNDIS_DF_RAW_DATA 0x00000004
-
-/* Remote NDIS medium types. */
-#define RNDIS_MEDIUM_802_3 0x00000000
-#define RNDIS_MEDIUM_802_5 0x00000001
-#define RNDIS_MEDIUM_FDDI 0x00000002
-#define RNDIS_MEDIUM_WAN 0x00000003
-#define RNDIS_MEDIUM_LOCAL_TALK 0x00000004
-#define RNDIS_MEDIUM_ARCNET_RAW 0x00000006
-#define RNDIS_MEDIUM_ARCNET_878_2 0x00000007
-#define RNDIS_MEDIUM_ATM 0x00000008
-#define RNDIS_MEDIUM_WIRELESS_WAN 0x00000009
-#define RNDIS_MEDIUM_IRDA 0x0000000a
-#define RNDIS_MEDIUM_CO_WAN 0x0000000b
-/* Not a real medium, defined as an upper-bound */
-#define RNDIS_MEDIUM_MAX 0x0000000d
-
-
-/* Remote NDIS medium connection states. */
-#define RNDIS_MEDIA_STATE_CONNECTED 0x00000000
-#define RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001
-
-/* Remote NDIS version numbers */
-#define RNDIS_MAJOR_VERSION 0x00000001
-#define RNDIS_MINOR_VERSION 0x00000000
-
-
/* NdisInitialize message */
struct rndis_initialize_request {
u32 req_id;
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index d6be64bcefd4..981ebb115637 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -129,8 +129,8 @@ static void dump_rndis_message(struct hv_device *hv_dev,
netdev = net_device->ndev;
switch (rndis_msg->ndis_msg_type) {
- case REMOTE_NDIS_PACKET_MSG:
- netdev_dbg(netdev, "REMOTE_NDIS_PACKET_MSG (len %u, "
+ case RNDIS_MSG_PACKET:
+ netdev_dbg(netdev, "RNDIS_MSG_PACKET (len %u, "
"data offset %u data len %u, # oob %u, "
"oob offset %u, oob len %u, pkt offset %u, "
"pkt len %u\n",
@@ -144,8 +144,8 @@ static void dump_rndis_message(struct hv_device *hv_dev,
rndis_msg->msg.pkt.per_pkt_info_len);
break;
- case REMOTE_NDIS_INITIALIZE_CMPLT:
- netdev_dbg(netdev, "REMOTE_NDIS_INITIALIZE_CMPLT "
+ case RNDIS_MSG_INIT_C:
+ netdev_dbg(netdev, "RNDIS_MSG_INIT_C "
"(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
"device flags %d, max xfer size 0x%x, max pkts %u, "
"pkt aligned %u)\n",
@@ -162,8 +162,8 @@ static void dump_rndis_message(struct hv_device *hv_dev,
pkt_alignment_factor);
break;
- case REMOTE_NDIS_QUERY_CMPLT:
- netdev_dbg(netdev, "REMOTE_NDIS_QUERY_CMPLT "
+ case RNDIS_MSG_QUERY_C:
+ netdev_dbg(netdev, "RNDIS_MSG_QUERY_C "
"(len %u, id 0x%x, status 0x%x, buf len %u, "
"buf offset %u)\n",
rndis_msg->msg_len,
@@ -175,16 +175,16 @@ static void dump_rndis_message(struct hv_device *hv_dev,
info_buf_offset);
break;
- case REMOTE_NDIS_SET_CMPLT:
+ case RNDIS_MSG_SET_C:
netdev_dbg(netdev,
- "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)\n",
+ "RNDIS_MSG_SET_C (len %u, id 0x%x, status 0x%x)\n",
rndis_msg->msg_len,
rndis_msg->msg.set_complete.req_id,
rndis_msg->msg.set_complete.status);
break;
- case REMOTE_NDIS_INDICATE_STATUS_MSG:
- netdev_dbg(netdev, "REMOTE_NDIS_INDICATE_STATUS_MSG "
+ case RNDIS_MSG_INDICATE:
+ netdev_dbg(netdev, "RNDIS_MSG_INDICATE "
"(len %u, status 0x%x, buf len %u, buf offset %u)\n",
rndis_msg->msg_len,
rndis_msg->msg.indicate_status.status,
@@ -264,14 +264,14 @@ static void rndis_filter_receive_response(struct rndis_device *dev,
sizeof(struct rndis_filter_packet));
if (resp->ndis_msg_type ==
- REMOTE_NDIS_RESET_CMPLT) {
+ RNDIS_MSG_RESET_C) {
/* does not have a request id field */
request->response_msg.msg.reset_complete.
- status = STATUS_BUFFER_OVERFLOW;
+ status = RNDIS_STATUS_BUFFER_OVERFLOW;
} else {
request->response_msg.msg.
init_complete.status =
- STATUS_BUFFER_OVERFLOW;
+ RNDIS_STATUS_BUFFER_OVERFLOW;
}
}
@@ -415,19 +415,19 @@ int rndis_filter_receive(struct hv_device *dev,
dump_rndis_message(dev, rndis_msg);
switch (rndis_msg->ndis_msg_type) {
- case REMOTE_NDIS_PACKET_MSG:
+ case RNDIS_MSG_PACKET:
/* data msg */
rndis_filter_receive_data(rndis_dev, rndis_msg, pkt);
break;
- case REMOTE_NDIS_INITIALIZE_CMPLT:
- case REMOTE_NDIS_QUERY_CMPLT:
- case REMOTE_NDIS_SET_CMPLT:
+ case RNDIS_MSG_INIT_C:
+ case RNDIS_MSG_QUERY_C:
+ case RNDIS_MSG_SET_C:
/* completion msgs */
rndis_filter_receive_response(rndis_dev, rndis_msg);
break;
- case REMOTE_NDIS_INDICATE_STATUS_MSG:
+ case RNDIS_MSG_INDICATE:
/* notification msgs */
rndis_filter_receive_indicate_status(rndis_dev, rndis_msg);
break;
@@ -456,7 +456,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
return -EINVAL;
*result_size = 0;
- request = get_rndis_request(dev, REMOTE_NDIS_QUERY_MSG,
+ request = get_rndis_request(dev, RNDIS_MSG_QUERY,
RNDIS_MESSAGE_SIZE(struct rndis_query_request));
if (!request) {
ret = -ENOMEM;
@@ -536,7 +536,7 @@ int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
ndev = dev->net_dev->ndev;
- request = get_rndis_request(dev, REMOTE_NDIS_SET_MSG,
+ request = get_rndis_request(dev, RNDIS_MSG_SET,
RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
sizeof(u32));
if (!request) {
@@ -588,7 +588,7 @@ static int rndis_filter_init_device(struct rndis_device *dev)
u32 status;
int ret, t;
- request = get_rndis_request(dev, REMOTE_NDIS_INITIALIZE_MSG,
+ request = get_rndis_request(dev, RNDIS_MSG_INIT,
RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
if (!request) {
ret = -ENOMEM;
@@ -641,7 +641,7 @@ static void rndis_filter_halt_device(struct rndis_device *dev)
struct rndis_halt_request *halt;
/* Attempt to do a rndis device halt */
- request = get_rndis_request(dev, REMOTE_NDIS_HALT_MSG,
+ request = get_rndis_request(dev, RNDIS_MSG_HALT,
RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
if (!request)
goto cleanup;
@@ -805,7 +805,7 @@ int rndis_filter_send(struct hv_device *dev,
if (isvlan)
rndis_msg_size += NDIS_VLAN_PPI_SIZE;
- rndis_msg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG;
+ rndis_msg->ndis_msg_type = RNDIS_MSG_PACKET;
rndis_msg->msg_len = pkt->total_data_buflen +
rndis_msg_size;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 9653ed6998fe..66a9bfe7b1c8 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -57,7 +57,7 @@ static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
struct hlist_node *n;
hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[addr[5]], hlist) {
- if (!compare_ether_addr_64bits(vlan->dev->dev_addr, addr))
+ if (ether_addr_equal_64bits(vlan->dev->dev_addr, addr))
return vlan;
}
return NULL;
@@ -96,7 +96,7 @@ static int macvlan_addr_busy(const struct macvlan_port *port,
* currently in use by the underlying device or
* another macvlan.
*/
- if (!compare_ether_addr_64bits(port->dev->dev_addr, addr))
+ if (ether_addr_equal_64bits(port->dev->dev_addr, addr))
return 1;
if (macvlan_hash_lookup(port, addr))
@@ -118,8 +118,7 @@ static int macvlan_broadcast_one(struct sk_buff *skb,
return vlan->forward(dev, skb);
skb->dev = dev;
- if (!compare_ether_addr_64bits(eth->h_dest,
- dev->broadcast))
+ if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast))
skb->pkt_type = PACKET_BROADCAST;
else
skb->pkt_type = PACKET_MULTICAST;
@@ -259,7 +258,7 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
xmit_world:
skb->ip_summed = ip_summed;
- skb_set_dev(skb, vlan->lowerdev);
+ skb->dev = vlan->lowerdev;
return dev_queue_xmit(skb);
}
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 163559c16988..2ee56de7b0ca 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -1,5 +1,6 @@
#include <linux/etherdevice.h>
#include <linux/if_macvlan.h>
+#include <linux/if_vlan.h>
#include <linux/interrupt.h>
#include <linux/nsproxy.h>
#include <linux/compat.h>
@@ -782,6 +783,8 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
struct macvlan_dev *vlan;
int ret;
int vnet_hdr_len = 0;
+ int vlan_offset = 0;
+ int copied;
if (q->flags & IFF_VNET_HDR) {
struct virtio_net_hdr vnet_hdr;
@@ -796,18 +799,48 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr)))
return -EFAULT;
}
+ copied = vnet_hdr_len;
+
+ if (!vlan_tx_tag_present(skb))
+ len = min_t(int, skb->len, len);
+ else {
+ int copy;
+ struct {
+ __be16 h_vlan_proto;
+ __be16 h_vlan_TCI;
+ } veth;
+ veth.h_vlan_proto = htons(ETH_P_8021Q);
+ veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb));
+
+ vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto);
+ len = min_t(int, skb->len + VLAN_HLEN, len);
+
+ copy = min_t(int, vlan_offset, len);
+ ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy);
+ len -= copy;
+ copied += copy;
+ if (ret || !len)
+ goto done;
+
+ copy = min_t(int, sizeof(veth), len);
+ ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy);
+ len -= copy;
+ copied += copy;
+ if (ret || !len)
+ goto done;
+ }
- len = min_t(int, skb->len, len);
-
- ret = skb_copy_datagram_const_iovec(skb, 0, iv, vnet_hdr_len, len);
+ ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len);
+ copied += len;
+done:
rcu_read_lock_bh();
vlan = rcu_dereference_bh(q->vlan);
if (vlan)
- macvlan_count_rx(vlan, len, ret == 0, 0);
+ macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0);
rcu_read_unlock_bh();
- return ret ? ret : (len + vnet_hdr_len);
+ return ret ? ret : copied;
}
static ssize_t macvtap_do_read(struct macvtap_queue *q, struct kiocb *iocb,
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 83d5c9f55686..683ef1ce5519 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -88,7 +88,7 @@ static struct class mdio_bus_class = {
.dev_release = mdiobus_release,
};
-#ifdef CONFIG_OF_MDIO
+#if IS_ENABLED(CONFIG_OF_MDIO)
/* Helper function for of_mdio_find_bus */
static int of_mdio_bus_match(struct device *dev, void *mdio_bus_np)
{
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index e8c42d6a7d1c..de86a5582224 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -207,7 +207,7 @@ static struct phy_device* phy_device_create(struct mii_bus *bus,
* Description: Reads the ID registers of the PHY at @addr on the
* @bus, stores it in @phy_id and returns zero on success.
*/
-int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id)
+static int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id)
{
int phy_reg;
@@ -230,7 +230,6 @@ int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id)
return 0;
}
-EXPORT_SYMBOL(get_phy_id);
/**
* get_phy_device - reads the specified PHY device and returns its @phy_device struct
diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c
index af95a98fd86f..a031f6b456b4 100644
--- a/drivers/net/ppp/ppp_async.c
+++ b/drivers/net/ppp/ppp_async.c
@@ -613,7 +613,7 @@ ppp_async_encode(struct asyncppp *ap)
*buf++ = PPP_FLAG;
ap->olim = buf;
- kfree_skb(ap->tpkt);
+ consume_skb(ap->tpkt);
ap->tpkt = NULL;
return 1;
}
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 21d7151fb0ab..5c0557222f20 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1092,13 +1092,13 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
new_skb->data, skb->len + 2,
compressor_skb_size);
if (len > 0 && (ppp->flags & SC_CCP_UP)) {
- kfree_skb(skb);
+ consume_skb(skb);
skb = new_skb;
skb_put(skb, len);
skb_pull(skb, 2); /* pull off A/C bytes */
} else if (len == 0) {
/* didn't compress, or CCP not up yet */
- kfree_skb(new_skb);
+ consume_skb(new_skb);
new_skb = skb;
} else {
/*
@@ -1112,7 +1112,7 @@ pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
if (net_ratelimit())
netdev_err(ppp->dev, "ppp: compressor dropped pkt\n");
kfree_skb(skb);
- kfree_skb(new_skb);
+ consume_skb(new_skb);
new_skb = NULL;
}
return new_skb;
@@ -1178,7 +1178,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
!(ppp->flags & SC_NO_TCP_CCID));
if (cp == skb->data + 2) {
/* didn't compress */
- kfree_skb(new_skb);
+ consume_skb(new_skb);
} else {
if (cp[0] & SL_TYPE_COMPRESSED_TCP) {
proto = PPP_VJC_COMP;
@@ -1187,7 +1187,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
proto = PPP_VJC_UNCOMP;
cp[0] = skb->data[2];
}
- kfree_skb(skb);
+ consume_skb(skb);
skb = new_skb;
cp = skb_put(skb, len + 2);
cp[0] = 0;
@@ -1703,7 +1703,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
}
skb_reserve(ns, 2);
skb_copy_bits(skb, 0, skb_put(ns, skb->len), skb->len);
- kfree_skb(skb);
+ consume_skb(skb);
skb = ns;
}
else
@@ -1851,7 +1851,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb)
goto err;
}
- kfree_skb(skb);
+ consume_skb(skb);
skb = ns;
skb_put(skb, len);
skb_pull(skb, 2); /* pull off the A/C bytes */
diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c
index 55e466c511d5..1a12033d2efa 100644
--- a/drivers/net/ppp/ppp_synctty.c
+++ b/drivers/net/ppp/ppp_synctty.c
@@ -588,7 +588,7 @@ ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *skb)
skb_reserve(npkt,2);
skb_copy_from_linear_data(skb,
skb_put(npkt, skb->len), skb->len);
- kfree_skb(skb);
+ consume_skb(skb);
skb = npkt;
}
skb_push(skb,2);
@@ -656,7 +656,7 @@ ppp_sync_push(struct syncppp *ap)
if (sent < ap->tpkt->len) {
tty_stuffed = 1;
} else {
- kfree_skb(ap->tpkt);
+ consume_skb(ap->tpkt);
ap->tpkt = NULL;
clear_bit(XMIT_FULL, &ap->xmit_flags);
done = 1;
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 2fa1a9b6f498..cbf7047decc0 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -201,7 +201,7 @@ static int __set_item(struct pppoe_net *pn, struct pppox_sock *po)
return 0;
}
-static struct pppox_sock *__delete_item(struct pppoe_net *pn, __be16 sid,
+static void __delete_item(struct pppoe_net *pn, __be16 sid,
char *addr, int ifindex)
{
int hash = hash_item(sid, addr);
@@ -220,8 +220,6 @@ static struct pppox_sock *__delete_item(struct pppoe_net *pn, __be16 sid,
src = &ret->next;
ret = ret->next;
}
-
- return ret;
}
/**********************************************************************
@@ -264,16 +262,12 @@ static inline struct pppox_sock *get_item_by_addr(struct net *net,
return pppox_sock;
}
-static inline struct pppox_sock *delete_item(struct pppoe_net *pn, __be16 sid,
+static inline void delete_item(struct pppoe_net *pn, __be16 sid,
char *addr, int ifindex)
{
- struct pppox_sock *ret;
-
write_lock_bh(&pn->hash_lock);
- ret = __delete_item(pn, sid, addr, ifindex);
+ __delete_item(pn, sid, addr, ifindex);
write_unlock_bh(&pn->hash_lock);
-
- return ret;
}
/***************************************************************************
@@ -990,8 +984,10 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
if (skb) {
total_len = min_t(size_t, total_len, skb->len);
error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
- if (error == 0)
- error = total_len;
+ if (error == 0) {
+ consume_skb(skb);
+ return total_len;
+ }
}
kfree_skb(skb);
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index 72b50f57e7b2..1c98321b56cc 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -209,7 +209,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
}
if (skb->sk)
skb_set_owner_w(new_skb, skb->sk);
- kfree_skb(skb);
+ consume_skb(skb);
skb = new_skb;
}
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
deleted file mode 100644
index 0924f572f59b..000000000000
--- a/drivers/net/tokenring/3c359.c
+++ /dev/null
@@ -1,1831 +0,0 @@
-/*
- * 3c359.c (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved
- *
- * Linux driver for 3Com 3c359 Tokenlink Velocity XL PCI NIC
- *
- * Base Driver Olympic:
- * Written 1999 Peter De Schrijver & Mike Phillips
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * 7/17/00 - Clean up, version number 0.9.0. Ready to release to the world.
- *
- * 2/16/01 - Port up to kernel 2.4.2 ready for submission into the kernel.
- * 3/05/01 - Last clean up stuff before submission.
- * 2/15/01 - Finally, update to new pci api.
- *
- * To Do:
- */
-
-/*
- * Technical Card Details
- *
- * All access to data is done with 16/8 bit transfers. The transfer
- * method really sucks. You can only read or write one location at a time.
- *
- * Also, the microcode for the card must be uploaded if the card does not have
- * the flashrom on board. This is a 28K bloat in the driver when compiled
- * as a module.
- *
- * Rx is very simple, status into a ring of descriptors, dma data transfer,
- * interrupts to tell us when a packet is received.
- *
- * Tx is a little more interesting. Similar scenario, descriptor and dma data
- * transfers, but we don't have to interrupt the card to tell it another packet
- * is ready for transmission, we are just doing simple memory writes, not io or mmio
- * writes. The card can be set up to simply poll on the next
- * descriptor pointer and when this value is non-zero will automatically download
- * the next packet. The card then interrupts us when the packet is done.
- *
- */
-
-#define XL_DEBUG 0
-
-#include <linux/jiffies.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/proc_fs.h>
-#include <linux/ptrace.h>
-#include <linux/skbuff.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/bitops.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-
-#include <net/checksum.h>
-
-#include <asm/io.h>
-
-#include "3c359.h"
-
-static char version[] __devinitdata =
-"3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ;
-
-#define FW_NAME "3com/3C359.bin"
-MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ;
-MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver\n") ;
-MODULE_FIRMWARE(FW_NAME);
-
-/* Module parameters */
-
-/* Ring Speed 0,4,16
- * 0 = Autosense
- * 4,16 = Selected speed only, no autosense
- * This allows the card to be the first on the ring
- * and become the active monitor.
- *
- * WARNING: Some hubs will allow you to insert
- * at the wrong speed.
- *
- * The adapter will _not_ fail to open if there are no
- * active monitors on the ring, it will simply open up in
- * its last known ringspeed if no ringspeed is specified.
- */
-
-static int ringspeed[XL_MAX_ADAPTERS] = {0,} ;
-
-module_param_array(ringspeed, int, NULL, 0);
-MODULE_PARM_DESC(ringspeed,"3c359: Ringspeed selection - 4,16 or 0") ;
-
-/* Packet buffer size */
-
-static int pkt_buf_sz[XL_MAX_ADAPTERS] = {0,} ;
-
-module_param_array(pkt_buf_sz, int, NULL, 0) ;
-MODULE_PARM_DESC(pkt_buf_sz,"3c359: Initial buffer size") ;
-/* Message Level */
-
-static int message_level[XL_MAX_ADAPTERS] = {0,} ;
-
-module_param_array(message_level, int, NULL, 0) ;
-MODULE_PARM_DESC(message_level, "3c359: Level of reported messages") ;
-/*
- * This is a real nasty way of doing this, but otherwise you
- * will be stuck with 1555 lines of hex #'s in the code.
- */
-
-static DEFINE_PCI_DEVICE_TABLE(xl_pci_tbl) =
-{
- {PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, },
- { } /* terminate list */
-};
-MODULE_DEVICE_TABLE(pci,xl_pci_tbl) ;
-
-static int xl_init(struct net_device *dev);
-static int xl_open(struct net_device *dev);
-static int xl_open_hw(struct net_device *dev) ;
-static int xl_hw_reset(struct net_device *dev);
-static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev);
-static void xl_dn_comp(struct net_device *dev);
-static int xl_close(struct net_device *dev);
-static void xl_set_rx_mode(struct net_device *dev);
-static irqreturn_t xl_interrupt(int irq, void *dev_id);
-static int xl_set_mac_address(struct net_device *dev, void *addr) ;
-static void xl_arb_cmd(struct net_device *dev);
-static void xl_asb_cmd(struct net_device *dev) ;
-static void xl_srb_cmd(struct net_device *dev, int srb_cmd) ;
-static void xl_wait_misr_flags(struct net_device *dev) ;
-static int xl_change_mtu(struct net_device *dev, int mtu);
-static void xl_srb_bh(struct net_device *dev) ;
-static void xl_asb_bh(struct net_device *dev) ;
-static void xl_reset(struct net_device *dev) ;
-static void xl_freemem(struct net_device *dev) ;
-
-
-/* EEProm Access Functions */
-static u16 xl_ee_read(struct net_device *dev, int ee_addr) ;
-static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value) ;
-
-/* Debugging functions */
-#if XL_DEBUG
-static void print_tx_state(struct net_device *dev) ;
-static void print_rx_state(struct net_device *dev) ;
-
-static void print_tx_state(struct net_device *dev)
-{
-
- struct xl_private *xl_priv = netdev_priv(dev);
- struct xl_tx_desc *txd ;
- u8 __iomem *xl_mmio = xl_priv->xl_mmio ;
- int i ;
-
- printk("tx_ring_head: %d, tx_ring_tail: %d, free_ent: %d\n",xl_priv->tx_ring_head,
- xl_priv->tx_ring_tail, xl_priv->free_ring_entries) ;
- printk("Ring , Address , FSH , DnNextPtr, Buffer, Buffer_Len\n");
- for (i = 0; i < 16; i++) {
- txd = &(xl_priv->xl_tx_ring[i]) ;
- printk("%d, %08lx, %08x, %08x, %08x, %08x\n", i, virt_to_bus(txd),
- txd->framestartheader, txd->dnnextptr, txd->buffer, txd->buffer_length ) ;
- }
-
- printk("DNLISTPTR = %04x\n", readl(xl_mmio + MMIO_DNLISTPTR) );
-
- printk("DmaCtl = %04x\n", readl(xl_mmio + MMIO_DMA_CTRL) );
- printk("Queue status = %0x\n",netif_running(dev) ) ;
-}
-
-static void print_rx_state(struct net_device *dev)
-{
-
- struct xl_private *xl_priv = netdev_priv(dev);
- struct xl_rx_desc *rxd ;
- u8 __iomem *xl_mmio = xl_priv->xl_mmio ;
- int i ;
-
- printk("rx_ring_tail: %d\n", xl_priv->rx_ring_tail);
- printk("Ring , Address , FrameState , UPNextPtr, FragAddr, Frag_Len\n");
- for (i = 0; i < 16; i++) {
- /* rxd = (struct xl_rx_desc *)xl_priv->rx_ring_dma_addr + (i * sizeof(struct xl_rx_desc)) ; */
- rxd = &(xl_priv->xl_rx_ring[i]) ;
- printk("%d, %08lx, %08x, %08x, %08x, %08x\n", i, virt_to_bus(rxd),
- rxd->framestatus, rxd->upnextptr, rxd->upfragaddr, rxd->upfraglen ) ;
- }
-
- printk("UPLISTPTR = %04x\n", readl(xl_mmio + MMIO_UPLISTPTR));
-
- printk("DmaCtl = %04x\n", readl(xl_mmio + MMIO_DMA_CTRL));
- printk("Queue status = %0x\n",netif_running(dev));
-}
-#endif
-
-/*
- * Read values from the on-board EEProm. This looks very strange
- * but you have to wait for the EEProm to get/set the value before
- * passing/getting the next value from the nic. As with all requests
- * on this nic it has to be done in two stages, a) tell the nic which
- * memory address you want to access and b) pass/get the value from the nic.
- * With the EEProm, you have to wait before and between access a) and b).
- * As this is only read at initialization time and the wait period is very
- * small we shouldn't have to worry about scheduling issues.
- */
-
-static u16 xl_ee_read(struct net_device *dev, int ee_addr)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem *xl_mmio = xl_priv->xl_mmio ;
-
- /* Wait for EEProm to not be busy */
- writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
-
- /* Tell EEProm what we want to do and where */
- writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ;
-
- /* Wait for EEProm to not be busy */
- writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
-
- /* Tell EEProm what we want to do and where */
- writel(IO_WORD_WRITE | EECONTROL , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(EEREAD + ee_addr, xl_mmio + MMIO_MACDATA) ;
-
- /* Finally read the value from the EEProm */
- writel(IO_WORD_READ | EEDATA , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- return readw(xl_mmio + MMIO_MACDATA) ;
-}
-
-/*
- * Write values to the onboard eeprom. As with eeprom read you need to
- * set which location to write, wait, value to write, wait, with the
- * added twist of having to enable eeprom writes as well.
- */
-
-static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem *xl_mmio = xl_priv->xl_mmio ;
-
- /* Wait for EEProm to not be busy */
- writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
-
- /* Enable write/erase */
- writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(EE_ENABLE_WRITE, xl_mmio + MMIO_MACDATA) ;
-
- /* Wait for EEProm to not be busy */
- writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
-
- /* Put the value we want to write into EEDATA */
- writel(IO_WORD_WRITE | EEDATA, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(ee_value, xl_mmio + MMIO_MACDATA) ;
-
- /* Tell EEProm to write eevalue into ee_addr */
- writel(IO_WORD_WRITE | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(EEWRITE + ee_addr, xl_mmio + MMIO_MACDATA) ;
-
- /* Wait for EEProm to not be busy, to ensure write gets done */
- writel(IO_WORD_READ | EECONTROL, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- while ( readw(xl_mmio + MMIO_MACDATA) & EEBUSY ) ;
-
- return ;
-}
-
-static const struct net_device_ops xl_netdev_ops = {
- .ndo_open = xl_open,
- .ndo_stop = xl_close,
- .ndo_start_xmit = xl_xmit,
- .ndo_change_mtu = xl_change_mtu,
- .ndo_set_rx_mode = xl_set_rx_mode,
- .ndo_set_mac_address = xl_set_mac_address,
-};
-
-static int __devinit xl_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct net_device *dev ;
- struct xl_private *xl_priv ;
- static int card_no = -1 ;
- int i ;
-
- card_no++ ;
-
- if (pci_enable_device(pdev)) {
- return -ENODEV ;
- }
-
- pci_set_master(pdev);
-
- if ((i = pci_request_regions(pdev,"3c359"))) {
- return i ;
- }
-
- /*
- * Allowing init_trdev to allocate the private data will align
- * xl_private on a 32 bytes boundary which we need for the rx/tx
- * descriptors
- */
-
- dev = alloc_trdev(sizeof(struct xl_private)) ;
- if (!dev) {
- pci_release_regions(pdev) ;
- return -ENOMEM ;
- }
- xl_priv = netdev_priv(dev);
-
-#if XL_DEBUG
- printk("pci_device: %p, dev:%p, dev->priv: %p, ba[0]: %10x, ba[1]:%10x\n",
- pdev, dev, netdev_priv(dev), (unsigned int)pdev->resource[0].start, (unsigned int)pdev->resource[1].start);
-#endif
-
- dev->irq=pdev->irq;
- dev->base_addr=pci_resource_start(pdev,0) ;
- xl_priv->xl_card_name = pci_name(pdev);
- xl_priv->xl_mmio=ioremap(pci_resource_start(pdev,1), XL_IO_SPACE);
- xl_priv->pdev = pdev ;
-
- if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
- xl_priv->pkt_buf_sz = PKT_BUF_SZ ;
- else
- xl_priv->pkt_buf_sz = pkt_buf_sz[card_no] ;
-
- dev->mtu = xl_priv->pkt_buf_sz - TR_HLEN ;
- xl_priv->xl_ring_speed = ringspeed[card_no] ;
- xl_priv->xl_message_level = message_level[card_no] ;
- xl_priv->xl_functional_addr[0] = xl_priv->xl_functional_addr[1] = xl_priv->xl_functional_addr[2] = xl_priv->xl_functional_addr[3] = 0 ;
- xl_priv->xl_copy_all_options = 0 ;
-
- if((i = xl_init(dev))) {
- iounmap(xl_priv->xl_mmio) ;
- free_netdev(dev) ;
- pci_release_regions(pdev) ;
- return i ;
- }
-
- dev->netdev_ops = &xl_netdev_ops;
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- pci_set_drvdata(pdev,dev) ;
- if ((i = register_netdev(dev))) {
- printk(KERN_ERR "3C359, register netdev failed\n") ;
- pci_set_drvdata(pdev,NULL) ;
- iounmap(xl_priv->xl_mmio) ;
- free_netdev(dev) ;
- pci_release_regions(pdev) ;
- return i ;
- }
-
- printk(KERN_INFO "3C359: %s registered as: %s\n",xl_priv->xl_card_name,dev->name) ;
-
- return 0;
-}
-
-static int xl_init_firmware(struct xl_private *xl_priv)
-{
- int err;
-
- err = request_firmware(&xl_priv->fw, FW_NAME, &xl_priv->pdev->dev);
- if (err) {
- printk(KERN_ERR "Failed to load firmware \"%s\"\n", FW_NAME);
- return err;
- }
-
- if (xl_priv->fw->size < 16) {
- printk(KERN_ERR "Bogus length %zu in \"%s\"\n",
- xl_priv->fw->size, FW_NAME);
- release_firmware(xl_priv->fw);
- err = -EINVAL;
- }
-
- return err;
-}
-
-static int __devinit xl_init(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- int err;
-
- printk(KERN_INFO "%s\n", version);
- printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n",
- xl_priv->xl_card_name, (unsigned int)dev->base_addr ,xl_priv->xl_mmio, dev->irq);
-
- spin_lock_init(&xl_priv->xl_lock) ;
-
- err = xl_init_firmware(xl_priv);
- if (err == 0)
- err = xl_hw_reset(dev);
-
- return err;
-}
-
-
-/*
- * Hardware reset. This needs to be a separate entity as we need to reset the card
- * when we change the EEProm settings.
- */
-
-static int xl_hw_reset(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem *xl_mmio = xl_priv->xl_mmio ;
- unsigned long t ;
- u16 i ;
- u16 result_16 ;
- u8 result_8 ;
- u16 start ;
- int j ;
-
- if (xl_priv->fw == NULL)
- return -EINVAL;
-
- /*
- * Reset the card. If the card has got the microcode on board, we have
- * missed the initialization interrupt, so we must always do this.
- */
-
- writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ;
-
- /*
- * Must wait for cmdInProgress bit (12) to clear before continuing with
- * card configuration.
- */
-
- t=jiffies;
- while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
- schedule();
- if (time_after(jiffies, t + 40 * HZ)) {
- printk(KERN_ERR "%s: 3COM 3C359 Velocity XL card not responding to global reset.\n", dev->name);
- return -ENODEV;
- }
- }
-
- /*
- * Enable pmbar by setting bit in CPAttention
- */
-
- writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- result_8 = readb(xl_mmio + MMIO_MACDATA) ;
- result_8 = result_8 | CPA_PMBARVIS ;
- writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(result_8, xl_mmio + MMIO_MACDATA) ;
-
- /*
- * Read cpHold bit in pmbar, if cleared we have got Flashrom on board.
- * If not, we need to upload the microcode to the card
- */
-
- writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD);
-
-#if XL_DEBUG
- printk(KERN_INFO "Read from PMBAR = %04x\n", readw(xl_mmio + MMIO_MACDATA));
-#endif
-
- if ( readw( (xl_mmio + MMIO_MACDATA)) & PMB_CPHOLD ) {
-
- /* Set PmBar, privateMemoryBase bits (8:2) to 0 */
-
- writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD);
- result_16 = readw(xl_mmio + MMIO_MACDATA) ;
- result_16 = result_16 & ~((0x7F) << 2) ;
- writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(result_16,xl_mmio + MMIO_MACDATA) ;
-
- /* Set CPAttention, memWrEn bit */
-
- writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- result_8 = readb(xl_mmio + MMIO_MACDATA) ;
- result_8 = result_8 | CPA_MEMWREN ;
- writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(result_8, xl_mmio + MMIO_MACDATA) ;
-
- /*
- * Now to write the microcode into the shared ram
- * The microcode must finish at position 0xFFFF,
- * so we must subtract to get the start position for the code
- *
- * Looks strange but ensures compiler only uses
- * 16 bit unsigned int
- */
- start = (0xFFFF - (xl_priv->fw->size) + 1) ;
-
- printk(KERN_INFO "3C359: Uploading Microcode: ");
-
- for (i = start, j = 0; j < xl_priv->fw->size; i++, j++) {
- writel(MEM_BYTE_WRITE | 0XD0000 | i,
- xl_mmio + MMIO_MAC_ACCESS_CMD);
- writeb(xl_priv->fw->data[j], xl_mmio + MMIO_MACDATA);
- if (j % 1024 == 0)
- printk(".");
- }
- printk("\n") ;
-
- for (i = 0; i < 16; i++) {
- writel((MEM_BYTE_WRITE | 0xDFFF0) + i,
- xl_mmio + MMIO_MAC_ACCESS_CMD);
- writeb(xl_priv->fw->data[xl_priv->fw->size - 16 + i],
- xl_mmio + MMIO_MACDATA);
- }
-
- /*
- * Have to write the start address of the upload to FFF4, but
- * the address must be >> 4. You do not want to know how long
- * it took me to discover this.
- */
-
- writel(MEM_WORD_WRITE | 0xDFFF4, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(start >> 4, xl_mmio + MMIO_MACDATA);
-
- /* Clear the CPAttention, memWrEn Bit */
-
- writel( (IO_BYTE_READ | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- result_8 = readb(xl_mmio + MMIO_MACDATA) ;
- result_8 = result_8 & ~CPA_MEMWREN ;
- writel( (IO_BYTE_WRITE | CPATTENTION), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(result_8, xl_mmio + MMIO_MACDATA) ;
-
- /* Clear the cpHold bit in pmbar */
-
- writel( (IO_WORD_READ | PMBAR),xl_mmio + MMIO_MAC_ACCESS_CMD);
- result_16 = readw(xl_mmio + MMIO_MACDATA) ;
- result_16 = result_16 & ~PMB_CPHOLD ;
- writel( (IO_WORD_WRITE | PMBAR), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(result_16,xl_mmio + MMIO_MACDATA) ;
-
-
- } /* If microcode upload required */
-
- /*
- * The card should now go though a self test procedure and get itself ready
- * to be opened, we must wait for an srb response with the initialization
- * information.
- */
-
-#if XL_DEBUG
- printk(KERN_INFO "%s: Microcode uploaded, must wait for the self test to complete\n", dev->name);
-#endif
-
- writew(SETINDENABLE | 0xFFF, xl_mmio + MMIO_COMMAND) ;
-
- t=jiffies;
- while ( !(readw(xl_mmio + MMIO_INTSTATUS_AUTO) & INTSTAT_SRB) ) {
- schedule();
- if (time_after(jiffies, t + 15 * HZ)) {
- printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n");
- return -ENODEV;
- }
- }
-
- /*
- * Write the RxBufArea with D000, RxEarlyThresh, TxStartThresh,
- * DnPriReqThresh, read the tech docs if you want to know what
- * values they need to be.
- */
-
- writel(MMIO_WORD_WRITE | RXBUFAREA, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(0xD000, xl_mmio + MMIO_MACDATA) ;
-
- writel(MMIO_WORD_WRITE | RXEARLYTHRESH, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(0X0020, xl_mmio + MMIO_MACDATA) ;
-
- writew( SETTXSTARTTHRESH | 0x40 , xl_mmio + MMIO_COMMAND) ;
-
- writeb(0x04, xl_mmio + MMIO_DNBURSTTHRESH) ;
- writeb(0x04, xl_mmio + DNPRIREQTHRESH) ;
-
- /*
- * Read WRBR to provide the location of the srb block, have to use byte reads not word reads.
- * Tech docs have this wrong !!!!
- */
-
- writel(MMIO_BYTE_READ | WRBR, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- xl_priv->srb = readb(xl_mmio + MMIO_MACDATA) << 8 ;
- writel( (MMIO_BYTE_READ | WRBR) + 1, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- xl_priv->srb = xl_priv->srb | readb(xl_mmio + MMIO_MACDATA) ;
-
-#if XL_DEBUG
- writel(IO_WORD_READ | SWITCHSETTINGS, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- if ( readw(xl_mmio + MMIO_MACDATA) & 2) {
- printk(KERN_INFO "Default ring speed 4 mbps\n");
- } else {
- printk(KERN_INFO "Default ring speed 16 mbps\n");
- }
- printk(KERN_INFO "%s: xl_priv->srb = %04x\n",xl_priv->xl_card_name, xl_priv->srb);
-#endif
-
- return 0;
-}
-
-static int xl_open(struct net_device *dev)
-{
- struct xl_private *xl_priv=netdev_priv(dev);
- u8 __iomem *xl_mmio = xl_priv->xl_mmio ;
- u8 i ;
- __le16 hwaddr[3] ; /* Should be u8[6] but we get word return values */
- int open_err ;
-
- u16 switchsettings, switchsettings_eeprom ;
-
- if (request_irq(dev->irq, xl_interrupt, IRQF_SHARED , "3c359", dev))
- return -EAGAIN;
-
- /*
- * Read the information from the EEPROM that we need.
- */
-
- hwaddr[0] = cpu_to_le16(xl_ee_read(dev,0x10));
- hwaddr[1] = cpu_to_le16(xl_ee_read(dev,0x11));
- hwaddr[2] = cpu_to_le16(xl_ee_read(dev,0x12));
-
- /* Ring speed */
-
- switchsettings_eeprom = xl_ee_read(dev,0x08) ;
- switchsettings = switchsettings_eeprom ;
-
- if (xl_priv->xl_ring_speed != 0) {
- if (xl_priv->xl_ring_speed == 4)
- switchsettings = switchsettings | 0x02 ;
- else
- switchsettings = switchsettings & ~0x02 ;
- }
-
- /* Only write EEProm if there has been a change */
- if (switchsettings != switchsettings_eeprom) {
- xl_ee_write(dev,0x08,switchsettings) ;
- /* Hardware reset after changing EEProm */
- xl_hw_reset(dev) ;
- }
-
- memcpy(dev->dev_addr,hwaddr,dev->addr_len) ;
-
- open_err = xl_open_hw(dev) ;
-
- /*
- * This really needs to be cleaned up with better error reporting.
- */
-
- if (open_err != 0) { /* Something went wrong with the open command */
- if (open_err & 0x07) { /* Wrong speed, retry at different speed */
- printk(KERN_WARNING "%s: Open Error, retrying at different ringspeed\n", dev->name);
- switchsettings = switchsettings ^ 2 ;
- xl_ee_write(dev,0x08,switchsettings) ;
- xl_hw_reset(dev) ;
- open_err = xl_open_hw(dev) ;
- if (open_err != 0) {
- printk(KERN_WARNING "%s: Open error returned a second time, we're bombing out now\n", dev->name);
- free_irq(dev->irq,dev) ;
- return -ENODEV ;
- }
- } else {
- printk(KERN_WARNING "%s: Open Error = %04x\n", dev->name, open_err) ;
- free_irq(dev->irq,dev) ;
- return -ENODEV ;
- }
- }
-
- /*
- * Now to set up the Rx and Tx buffer structures
- */
- /* These MUST be on 8 byte boundaries */
- xl_priv->xl_tx_ring = kzalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL);
- if (xl_priv->xl_tx_ring == NULL) {
- free_irq(dev->irq,dev);
- return -ENOMEM;
- }
- xl_priv->xl_rx_ring = kzalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL);
- if (xl_priv->xl_rx_ring == NULL) {
- free_irq(dev->irq,dev);
- kfree(xl_priv->xl_tx_ring);
- return -ENOMEM;
- }
-
- /* Setup Rx Ring */
- for (i=0 ; i < XL_RX_RING_SIZE ; i++) {
- struct sk_buff *skb ;
-
- skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ;
- if (skb==NULL)
- break ;
-
- skb->dev = dev ;
- xl_priv->xl_rx_ring[i].upfragaddr = cpu_to_le32(pci_map_single(xl_priv->pdev, skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
- xl_priv->xl_rx_ring[i].upfraglen = cpu_to_le32(xl_priv->pkt_buf_sz) | RXUPLASTFRAG;
- xl_priv->rx_ring_skb[i] = skb ;
- }
-
- if (i==0) {
- printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name);
- free_irq(dev->irq,dev) ;
- kfree(xl_priv->xl_tx_ring);
- kfree(xl_priv->xl_rx_ring);
- return -EIO ;
- }
-
- xl_priv->rx_ring_no = i ;
- xl_priv->rx_ring_tail = 0 ;
- xl_priv->rx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_rx_ring, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_TODEVICE) ;
- for (i=0;i<(xl_priv->rx_ring_no-1);i++) {
- xl_priv->xl_rx_ring[i].upnextptr = cpu_to_le32(xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * (i+1)));
- }
- xl_priv->xl_rx_ring[i].upnextptr = 0 ;
-
- writel(xl_priv->rx_ring_dma_addr, xl_mmio + MMIO_UPLISTPTR) ;
-
- /* Setup Tx Ring */
-
- xl_priv->tx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_tx_ring, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,PCI_DMA_TODEVICE) ;
-
- xl_priv->tx_ring_head = 1 ;
- xl_priv->tx_ring_tail = 255 ; /* Special marker for first packet */
- xl_priv->free_ring_entries = XL_TX_RING_SIZE ;
-
- /*
- * Setup the first dummy DPD entry for polling to start working.
- */
-
- xl_priv->xl_tx_ring[0].framestartheader = TXDPDEMPTY;
- xl_priv->xl_tx_ring[0].buffer = 0 ;
- xl_priv->xl_tx_ring[0].buffer_length = 0 ;
- xl_priv->xl_tx_ring[0].dnnextptr = 0 ;
-
- writel(xl_priv->tx_ring_dma_addr, xl_mmio + MMIO_DNLISTPTR) ;
- writel(DNUNSTALL, xl_mmio + MMIO_COMMAND) ;
- writel(UPUNSTALL, xl_mmio + MMIO_COMMAND) ;
- writel(DNENABLE, xl_mmio + MMIO_COMMAND) ;
- writeb(0x40, xl_mmio + MMIO_DNPOLL) ;
-
- /*
- * Enable interrupts on the card
- */
-
- writel(SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ;
- writel(SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ;
-
- netif_start_queue(dev) ;
- return 0;
-
-}
-
-static int xl_open_hw(struct net_device *dev)
-{
- struct xl_private *xl_priv=netdev_priv(dev);
- u8 __iomem *xl_mmio = xl_priv->xl_mmio ;
- u16 vsoff ;
- char ver_str[33];
- int open_err ;
- int i ;
- unsigned long t ;
-
- /*
- * Okay, let's build up the Open.NIC srb command
- *
- */
-
- writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(OPEN_NIC, xl_mmio + MMIO_MACDATA) ;
-
- /*
- * Use this as a test byte, if it comes back with the same value, the command didn't work
- */
-
- writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb)+ 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(0xff,xl_mmio + MMIO_MACDATA) ;
-
- /* Open options */
- writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(0x00, xl_mmio + MMIO_MACDATA) ;
- writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + 9, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(0x00, xl_mmio + MMIO_MACDATA) ;
-
- /*
- * Node address, be careful here, the docs say you can just put zeros here and it will use
- * the hardware address, it doesn't, you must include the node address in the open command.
- */
-
- if (xl_priv->xl_laa[0]) { /* If using a LAA address */
- for (i=10;i<16;i++) {
- writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(xl_priv->xl_laa[i-10],xl_mmio + MMIO_MACDATA) ;
- }
- memcpy(dev->dev_addr,xl_priv->xl_laa,dev->addr_len) ;
- } else { /* Regular hardware address */
- for (i=10;i<16;i++) {
- writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(dev->dev_addr[i-10], xl_mmio + MMIO_MACDATA) ;
- }
- }
-
- /* Default everything else to 0 */
- for (i = 16; i < 34; i++) {
- writel( (MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(0x00,xl_mmio + MMIO_MACDATA) ;
- }
-
- /*
- * Set the csrb bit in the MISR register
- */
-
- xl_wait_misr_flags(dev) ;
- writel(MEM_BYTE_WRITE | MF_CSRB, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(0xFF, xl_mmio + MMIO_MACDATA) ;
- writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(MISR_CSRB , xl_mmio + MMIO_MACDATA) ;
-
- /*
- * Now wait for the command to run
- */
-
- t=jiffies;
- while (! (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) {
- schedule();
- if (time_after(jiffies, t + 40 * HZ)) {
- printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n");
- break ;
- }
- }
-
- /*
- * Let's interpret the open response
- */
-
- writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb)+2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- if (readb(xl_mmio + MMIO_MACDATA)!=0) {
- open_err = readb(xl_mmio + MMIO_MACDATA) << 8 ;
- writel( (MEM_BYTE_READ | 0xD0000 | xl_priv->srb) + 7, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- open_err |= readb(xl_mmio + MMIO_MACDATA) ;
- return open_err ;
- } else {
- writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 8, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- xl_priv->asb = swab16(readw(xl_mmio + MMIO_MACDATA)) ;
- printk(KERN_INFO "%s: Adapter Opened Details: ",dev->name) ;
- printk("ASB: %04x",xl_priv->asb ) ;
- writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 10, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- printk(", SRB: %04x",swab16(readw(xl_mmio + MMIO_MACDATA)) ) ;
-
- writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 12, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- xl_priv->arb = swab16(readw(xl_mmio + MMIO_MACDATA)) ;
- printk(", ARB: %04x\n",xl_priv->arb );
- writel( (MEM_WORD_READ | 0xD0000 | xl_priv->srb) + 14, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- vsoff = swab16(readw(xl_mmio + MMIO_MACDATA)) ;
-
- /*
- * Interesting, sending the individual characters directly to printk was causing klogd to use
- * use 100% of processor time, so we build up the string and print that instead.
- */
-
- for (i=0;i<0x20;i++) {
- writel( (MEM_BYTE_READ | 0xD0000 | vsoff) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- ver_str[i] = readb(xl_mmio + MMIO_MACDATA) ;
- }
- ver_str[i] = '\0' ;
- printk(KERN_INFO "%s: Microcode version String: %s\n",dev->name,ver_str);
- }
-
- /*
- * Issue the AckInterrupt
- */
- writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
-
- return 0 ;
-}
-
-/*
- * There are two ways of implementing rx on the 359 NIC, either
- * interrupt driven or polling. We are going to uses interrupts,
- * it is the easier way of doing things.
- *
- * The Rx works with a ring of Rx descriptors. At initialise time the ring
- * entries point to the next entry except for the last entry in the ring
- * which points to 0. The card is programmed with the location of the first
- * available descriptor and keeps reading the next_ptr until next_ptr is set
- * to 0. Hopefully with a ring size of 16 the card will never get to read a next_ptr
- * of 0. As the Rx interrupt is received we copy the frame up to the protocol layers
- * and then point the end of the ring to our current position and point our current
- * position to 0, therefore making the current position the last position on the ring.
- * The last position on the ring therefore loops continually loops around the rx ring.
- *
- * rx_ring_tail is the position on the ring to process next. (Think of a snake, the head
- * expands as the card adds new packets and we go around eating the tail processing the
- * packets.)
- *
- * Undoubtably it could be streamlined and improved upon, but at the moment it works
- * and the fast path through the routine is fine.
- *
- * adv_rx_ring could be inlined to increase performance, but its called a *lot* of times
- * in xl_rx so would increase the size of the function significantly.
- */
-
-static void adv_rx_ring(struct net_device *dev) /* Advance rx_ring, cut down on bloat in xl_rx */
-{
- struct xl_private *xl_priv=netdev_priv(dev);
- int n = xl_priv->rx_ring_tail;
- int prev_ring_loc;
-
- prev_ring_loc = (n + XL_RX_RING_SIZE - 1) & (XL_RX_RING_SIZE - 1);
- xl_priv->xl_rx_ring[prev_ring_loc].upnextptr = cpu_to_le32(xl_priv->rx_ring_dma_addr + (sizeof (struct xl_rx_desc) * n));
- xl_priv->xl_rx_ring[n].framestatus = 0;
- xl_priv->xl_rx_ring[n].upnextptr = 0;
- xl_priv->rx_ring_tail++;
- xl_priv->rx_ring_tail &= (XL_RX_RING_SIZE-1);
-}
-
-static void xl_rx(struct net_device *dev)
-{
- struct xl_private *xl_priv=netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
- struct sk_buff *skb, *skb2 ;
- int frame_length = 0, copy_len = 0 ;
- int temp_ring_loc ;
-
- /*
- * Receive the next frame, loop around the ring until all frames
- * have been received.
- */
-
- while (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & (RXUPDCOMPLETE | RXUPDFULL) ) { /* Descriptor to process */
-
- if (xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus & RXUPDFULL ) { /* UpdFull, Multiple Descriptors used for the frame */
-
- /*
- * This is a pain, you need to go through all the descriptors until the last one
- * for this frame to find the framelength
- */
-
- temp_ring_loc = xl_priv->rx_ring_tail ;
-
- while (xl_priv->xl_rx_ring[temp_ring_loc].framestatus & RXUPDFULL ) {
- temp_ring_loc++ ;
- temp_ring_loc &= (XL_RX_RING_SIZE-1) ;
- }
-
- frame_length = le32_to_cpu(xl_priv->xl_rx_ring[temp_ring_loc].framestatus) & 0x7FFF;
-
- skb = dev_alloc_skb(frame_length) ;
-
- if (skb==NULL) { /* No memory for frame, still need to roll forward the rx ring */
- printk(KERN_WARNING "%s: dev_alloc_skb failed - multi buffer !\n", dev->name) ;
- while (xl_priv->rx_ring_tail != temp_ring_loc)
- adv_rx_ring(dev) ;
-
- adv_rx_ring(dev) ; /* One more time just for luck :) */
- dev->stats.rx_dropped++ ;
-
- writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
- return ;
- }
-
- while (xl_priv->rx_ring_tail != temp_ring_loc) {
- copy_len = le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen) & 0x7FFF;
- frame_length -= copy_len ;
- pci_dma_sync_single_for_cpu(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE);
- skb_copy_from_linear_data(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail],
- skb_put(skb, copy_len),
- copy_len);
- pci_dma_sync_single_for_device(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE);
- adv_rx_ring(dev) ;
- }
-
- /* Now we have found the last fragment */
- pci_dma_sync_single_for_cpu(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE);
- skb_copy_from_linear_data(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail],
- skb_put(skb,copy_len), frame_length);
-/* memcpy(skb_put(skb,frame_length), bus_to_virt(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), frame_length) ; */
- pci_dma_sync_single_for_device(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE);
- adv_rx_ring(dev) ;
- skb->protocol = tr_type_trans(skb,dev) ;
- netif_rx(skb) ;
-
- } else { /* Single Descriptor Used, simply swap buffers over, fast path */
-
- frame_length = le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].framestatus) & 0x7FFF;
-
- skb = dev_alloc_skb(xl_priv->pkt_buf_sz) ;
-
- if (skb==NULL) { /* Still need to fix the rx ring */
- printk(KERN_WARNING "%s: dev_alloc_skb failed in rx, single buffer\n",dev->name);
- adv_rx_ring(dev) ;
- dev->stats.rx_dropped++ ;
- writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
- return ;
- }
-
- skb2 = xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] ;
- pci_unmap_single(xl_priv->pdev, le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr), xl_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
- skb_put(skb2, frame_length) ;
- skb2->protocol = tr_type_trans(skb2,dev) ;
-
- xl_priv->rx_ring_skb[xl_priv->rx_ring_tail] = skb ;
- xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr = cpu_to_le32(pci_map_single(xl_priv->pdev,skb->data,xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
- xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfraglen = cpu_to_le32(xl_priv->pkt_buf_sz) | RXUPLASTFRAG;
- adv_rx_ring(dev) ;
- dev->stats.rx_packets++ ;
- dev->stats.rx_bytes += frame_length ;
-
- netif_rx(skb2) ;
- } /* if multiple buffers */
- } /* while packet to do */
-
- /* Clear the updComplete interrupt */
- writel(ACK_INTERRUPT | UPCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
- return ;
-}
-
-/*
- * This is ruthless, it doesn't care what state the card is in it will
- * completely reset the adapter.
- */
-
-static void xl_reset(struct net_device *dev)
-{
- struct xl_private *xl_priv=netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
- unsigned long t;
-
- writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ;
-
- /*
- * Must wait for cmdInProgress bit (12) to clear before continuing with
- * card configuration.
- */
-
- t=jiffies;
- while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
- if (time_after(jiffies, t + 40 * HZ)) {
- printk(KERN_ERR "3COM 3C359 Velocity XL card not responding.\n");
- break ;
- }
- }
-
-}
-
-static void xl_freemem(struct net_device *dev)
-{
- struct xl_private *xl_priv=netdev_priv(dev);
- int i ;
-
- for (i=0;i<XL_RX_RING_SIZE;i++) {
- dev_kfree_skb_irq(xl_priv->rx_ring_skb[xl_priv->rx_ring_tail]) ;
- pci_unmap_single(xl_priv->pdev,le32_to_cpu(xl_priv->xl_rx_ring[xl_priv->rx_ring_tail].upfragaddr),xl_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
- xl_priv->rx_ring_tail++ ;
- xl_priv->rx_ring_tail &= XL_RX_RING_SIZE-1;
- }
-
- /* unmap ring */
- pci_unmap_single(xl_priv->pdev,xl_priv->rx_ring_dma_addr, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_FROMDEVICE) ;
-
- pci_unmap_single(xl_priv->pdev,xl_priv->tx_ring_dma_addr, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, PCI_DMA_TODEVICE) ;
-
- kfree(xl_priv->xl_rx_ring) ;
- kfree(xl_priv->xl_tx_ring) ;
-
- return ;
-}
-
-static irqreturn_t xl_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct xl_private *xl_priv =netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
- u16 intstatus, macstatus ;
-
- intstatus = readw(xl_mmio + MMIO_INTSTATUS) ;
-
- if (!(intstatus & 1)) /* We didn't generate the interrupt */
- return IRQ_NONE;
-
- spin_lock(&xl_priv->xl_lock) ;
-
- /*
- * Process the interrupt
- */
- /*
- * Something fishy going on here, we shouldn't get 0001 ints, not fatal though.
- */
- if (intstatus == 0x0001) {
- writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
- printk(KERN_INFO "%s: 00001 int received\n",dev->name);
- } else {
- if (intstatus & (HOSTERRINT | SRBRINT | ARBCINT | UPCOMPINT | DNCOMPINT | HARDERRINT | (1<<8) | TXUNDERRUN | ASBFINT)) {
-
- /*
- * Host Error.
- * It may be possible to recover from this, but usually it means something
- * is seriously fubar, so we just close the adapter.
- */
-
- if (intstatus & HOSTERRINT) {
- printk(KERN_WARNING "%s: Host Error, performing global reset, intstatus = %04x\n",dev->name,intstatus);
- writew( GLOBAL_RESET, xl_mmio + MMIO_COMMAND ) ;
- printk(KERN_WARNING "%s: Resetting hardware:\n", dev->name);
- netif_stop_queue(dev) ;
- xl_freemem(dev) ;
- free_irq(dev->irq,dev);
- xl_reset(dev) ;
- writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
- spin_unlock(&xl_priv->xl_lock) ;
- return IRQ_HANDLED;
- } /* Host Error */
-
- if (intstatus & SRBRINT ) { /* Srbc interrupt */
- writel(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
- if (xl_priv->srb_queued)
- xl_srb_bh(dev) ;
- } /* SRBR Interrupt */
-
- if (intstatus & TXUNDERRUN) { /* Issue DnReset command */
- writel(DNRESET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { /* Wait for command to run */
- /* !!! FIX-ME !!!!
- Must put a timeout check here ! */
- /* Empty Loop */
- }
- printk(KERN_WARNING "%s: TX Underrun received\n",dev->name);
- writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
- } /* TxUnderRun */
-
- if (intstatus & ARBCINT ) { /* Arbc interrupt */
- xl_arb_cmd(dev) ;
- } /* Arbc */
-
- if (intstatus & ASBFINT) {
- if (xl_priv->asb_queued == 1) {
- xl_asb_cmd(dev) ;
- } else if (xl_priv->asb_queued == 2) {
- xl_asb_bh(dev) ;
- } else {
- writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ;
- }
- } /* Asbf */
-
- if (intstatus & UPCOMPINT ) /* UpComplete */
- xl_rx(dev) ;
-
- if (intstatus & DNCOMPINT ) /* DnComplete */
- xl_dn_comp(dev) ;
-
- if (intstatus & HARDERRINT ) { /* Hardware error */
- writel(MMIO_WORD_READ | MACSTATUS, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- macstatus = readw(xl_mmio + MMIO_MACDATA) ;
- printk(KERN_WARNING "%s: MacStatusError, details: ", dev->name);
- if (macstatus & (1<<14))
- printk(KERN_WARNING "tchk error: Unrecoverable error\n");
- if (macstatus & (1<<3))
- printk(KERN_WARNING "eint error: Internal watchdog timer expired\n");
- if (macstatus & (1<<2))
- printk(KERN_WARNING "aint error: Host tried to perform invalid operation\n");
- printk(KERN_WARNING "Instatus = %02x, macstatus = %02x\n",intstatus,macstatus) ;
- printk(KERN_WARNING "%s: Resetting hardware:\n", dev->name);
- netif_stop_queue(dev) ;
- xl_freemem(dev) ;
- free_irq(dev->irq,dev);
- unregister_netdev(dev) ;
- free_netdev(dev) ;
- xl_reset(dev) ;
- writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
- spin_unlock(&xl_priv->xl_lock) ;
- return IRQ_HANDLED;
- }
- } else {
- printk(KERN_WARNING "%s: Received Unknown interrupt : %04x\n", dev->name, intstatus);
- writel(ACK_INTERRUPT | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
- }
- }
-
- /* Turn interrupts back on */
-
- writel( SETINDENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ;
- writel( SETINTENABLE | INT_MASK, xl_mmio + MMIO_COMMAND) ;
-
- spin_unlock(&xl_priv->xl_lock) ;
- return IRQ_HANDLED;
-}
-
-/*
- * Tx - Polling configuration
- */
-
-static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct xl_private *xl_priv=netdev_priv(dev);
- struct xl_tx_desc *txd ;
- int tx_head, tx_tail, tx_prev ;
- unsigned long flags ;
-
- spin_lock_irqsave(&xl_priv->xl_lock,flags) ;
-
- netif_stop_queue(dev) ;
-
- if (xl_priv->free_ring_entries > 1 ) {
- /*
- * Set up the descriptor for the packet
- */
- tx_head = xl_priv->tx_ring_head ;
- tx_tail = xl_priv->tx_ring_tail ;
-
- txd = &(xl_priv->xl_tx_ring[tx_head]) ;
- txd->dnnextptr = 0 ;
- txd->framestartheader = cpu_to_le32(skb->len) | TXDNINDICATE;
- txd->buffer = cpu_to_le32(pci_map_single(xl_priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE));
- txd->buffer_length = cpu_to_le32(skb->len) | TXDNFRAGLAST;
- xl_priv->tx_ring_skb[tx_head] = skb ;
- dev->stats.tx_packets++ ;
- dev->stats.tx_bytes += skb->len ;
-
- /*
- * Set the nextptr of the previous descriptor equal to this descriptor, add XL_TX_RING_SIZE -1
- * to ensure no negative numbers in unsigned locations.
- */
-
- tx_prev = (xl_priv->tx_ring_head + XL_TX_RING_SIZE - 1) & (XL_TX_RING_SIZE - 1) ;
-
- xl_priv->tx_ring_head++ ;
- xl_priv->tx_ring_head &= (XL_TX_RING_SIZE - 1) ;
- xl_priv->free_ring_entries-- ;
-
- xl_priv->xl_tx_ring[tx_prev].dnnextptr = cpu_to_le32(xl_priv->tx_ring_dma_addr + (sizeof (struct xl_tx_desc) * tx_head));
-
- /* Sneaky, by doing a read on DnListPtr we can force the card to poll on the DnNextPtr */
- /* readl(xl_mmio + MMIO_DNLISTPTR) ; */
-
- netif_wake_queue(dev) ;
-
- spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ;
-
- return NETDEV_TX_OK;
- } else {
- spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ;
- return NETDEV_TX_BUSY;
- }
-
-}
-
-/*
- * The NIC has told us that a packet has been downloaded onto the card, we must
- * find out which packet it has done, clear the skb and information for the packet
- * then advance around the ring for all transmitted packets
- */
-
-static void xl_dn_comp(struct net_device *dev)
-{
- struct xl_private *xl_priv=netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
- struct xl_tx_desc *txd ;
-
-
- if (xl_priv->tx_ring_tail == 255) {/* First time */
- xl_priv->xl_tx_ring[0].framestartheader = 0 ;
- xl_priv->xl_tx_ring[0].dnnextptr = 0 ;
- xl_priv->tx_ring_tail = 1 ;
- }
-
- while (xl_priv->xl_tx_ring[xl_priv->tx_ring_tail].framestartheader & TXDNCOMPLETE ) {
- txd = &(xl_priv->xl_tx_ring[xl_priv->tx_ring_tail]) ;
- pci_unmap_single(xl_priv->pdev, le32_to_cpu(txd->buffer), xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]->len, PCI_DMA_TODEVICE);
- txd->framestartheader = 0 ;
- txd->buffer = cpu_to_le32(0xdeadbeef);
- txd->buffer_length = 0 ;
- dev_kfree_skb_irq(xl_priv->tx_ring_skb[xl_priv->tx_ring_tail]) ;
- xl_priv->tx_ring_tail++ ;
- xl_priv->tx_ring_tail &= (XL_TX_RING_SIZE - 1) ;
- xl_priv->free_ring_entries++ ;
- }
-
- netif_wake_queue(dev) ;
-
- writel(ACK_INTERRUPT | DNCOMPACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
-}
-
-/*
- * Close the adapter properly.
- * This srb reply cannot be handled from interrupt context as we have
- * to free the interrupt from the driver.
- */
-
-static int xl_close(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
- unsigned long t ;
-
- netif_stop_queue(dev) ;
-
- /*
- * Close the adapter, need to stall the rx and tx queues.
- */
-
- writew(DNSTALL, xl_mmio + MMIO_COMMAND) ;
- t=jiffies;
- while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
- schedule();
- if (time_after(jiffies, t + 10 * HZ)) {
- printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNSTALL not responding.\n", dev->name);
- break ;
- }
- }
- writew(DNDISABLE, xl_mmio + MMIO_COMMAND) ;
- t=jiffies;
- while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
- schedule();
- if (time_after(jiffies, t + 10 * HZ)) {
- printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNDISABLE not responding.\n", dev->name);
- break ;
- }
- }
- writew(UPSTALL, xl_mmio + MMIO_COMMAND) ;
- t=jiffies;
- while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
- schedule();
- if (time_after(jiffies, t + 10 * HZ)) {
- printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPSTALL not responding.\n", dev->name);
- break ;
- }
- }
-
- /* Turn off interrupts, we will still get the indication though
- * so we can trap it
- */
-
- writel(SETINTENABLE, xl_mmio + MMIO_COMMAND) ;
-
- xl_srb_cmd(dev,CLOSE_NIC) ;
-
- t=jiffies;
- while (!(readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) {
- schedule();
- if (time_after(jiffies, t + 10 * HZ)) {
- printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-CLOSENIC not responding.\n", dev->name);
- break ;
- }
- }
- /* Read the srb response from the adapter */
-
- writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD);
- if (readb(xl_mmio + MMIO_MACDATA) != CLOSE_NIC) {
- printk(KERN_INFO "%s: CLOSE_NIC did not get a CLOSE_NIC response\n",dev->name);
- } else {
- writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- if (readb(xl_mmio + MMIO_MACDATA)==0) {
- printk(KERN_INFO "%s: Adapter has been closed\n",dev->name);
- writew(ACK_INTERRUPT | SRBRACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
-
- xl_freemem(dev) ;
- free_irq(dev->irq,dev) ;
- } else {
- printk(KERN_INFO "%s: Close nic command returned error code %02x\n",dev->name, readb(xl_mmio + MMIO_MACDATA)) ;
- }
- }
-
- /* Reset the upload and download logic */
-
- writew(UPRESET, xl_mmio + MMIO_COMMAND) ;
- t=jiffies;
- while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
- schedule();
- if (time_after(jiffies, t + 10 * HZ)) {
- printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPRESET not responding.\n", dev->name);
- break ;
- }
- }
- writew(DNRESET, xl_mmio + MMIO_COMMAND) ;
- t=jiffies;
- while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) {
- schedule();
- if (time_after(jiffies, t + 10 * HZ)) {
- printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNRESET not responding.\n", dev->name);
- break ;
- }
- }
- xl_hw_reset(dev) ;
- return 0 ;
-}
-
-static void xl_set_rx_mode(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- struct netdev_hw_addr *ha;
- unsigned char dev_mc_address[4] ;
- u16 options ;
-
- if (dev->flags & IFF_PROMISC)
- options = 0x0004 ;
- else
- options = 0x0000 ;
-
- if (options ^ xl_priv->xl_copy_all_options) { /* Changed, must send command */
- xl_priv->xl_copy_all_options = options ;
- xl_srb_cmd(dev, SET_RECEIVE_MODE) ;
- return ;
- }
-
- dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ;
-
- netdev_for_each_mc_addr(ha, dev) {
- dev_mc_address[0] |= ha->addr[2];
- dev_mc_address[1] |= ha->addr[3];
- dev_mc_address[2] |= ha->addr[4];
- dev_mc_address[3] |= ha->addr[5];
- }
-
- if (memcmp(xl_priv->xl_functional_addr,dev_mc_address,4) != 0) { /* Options have changed, run the command */
- memcpy(xl_priv->xl_functional_addr, dev_mc_address,4) ;
- xl_srb_cmd(dev, SET_FUNC_ADDRESS) ;
- }
- return ;
-}
-
-
-/*
- * We issued an srb command and now we must read
- * the response from the completed command.
- */
-
-static void xl_srb_bh(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
- u8 srb_cmd, ret_code ;
- int i ;
-
- writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- srb_cmd = readb(xl_mmio + MMIO_MACDATA) ;
- writel((MEM_BYTE_READ | 0xd0000 | xl_priv->srb) +2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- ret_code = readb(xl_mmio + MMIO_MACDATA) ;
-
- /* Ret_code is standard across all commands */
-
- switch (ret_code) {
- case 1:
- printk(KERN_INFO "%s: Command: %d - Invalid Command code\n",dev->name,srb_cmd) ;
- break ;
- case 4:
- printk(KERN_INFO "%s: Command: %d - Adapter is closed, must be open for this command\n",dev->name,srb_cmd);
- break ;
-
- case 6:
- printk(KERN_INFO "%s: Command: %d - Options Invalid for command\n",dev->name,srb_cmd);
- break ;
-
- case 0: /* Successful command execution */
- switch (srb_cmd) {
- case READ_LOG: /* Returns 14 bytes of data from the NIC */
- if(xl_priv->xl_message_level)
- printk(KERN_INFO "%s: READ.LOG 14 bytes of data ",dev->name) ;
- /*
- * We still have to read the log even if message_level = 0 and we don't want
- * to see it
- */
- for (i=0;i<14;i++) {
- writel(MEM_BYTE_READ | 0xd0000 | xl_priv->srb | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- if(xl_priv->xl_message_level)
- printk("%02x:",readb(xl_mmio + MMIO_MACDATA)) ;
- }
- printk("\n") ;
- break ;
- case SET_FUNC_ADDRESS:
- if(xl_priv->xl_message_level)
- printk(KERN_INFO "%s: Functional Address Set\n",dev->name);
- break ;
- case CLOSE_NIC:
- if(xl_priv->xl_message_level)
- printk(KERN_INFO "%s: Received CLOSE_NIC interrupt in interrupt handler\n",dev->name);
- break ;
- case SET_MULTICAST_MODE:
- if(xl_priv->xl_message_level)
- printk(KERN_INFO "%s: Multicast options successfully changed\n",dev->name) ;
- break ;
- case SET_RECEIVE_MODE:
- if(xl_priv->xl_message_level) {
- if (xl_priv->xl_copy_all_options == 0x0004)
- printk(KERN_INFO "%s: Entering promiscuous mode\n", dev->name);
- else
- printk(KERN_INFO "%s: Entering normal receive mode\n",dev->name);
- }
- break ;
-
- } /* switch */
- break ;
- } /* switch */
- return ;
-}
-
-static int xl_set_mac_address (struct net_device *dev, void *addr)
-{
- struct sockaddr *saddr = addr ;
- struct xl_private *xl_priv = netdev_priv(dev);
-
- if (netif_running(dev)) {
- printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ;
- return -EIO ;
- }
-
- memcpy(xl_priv->xl_laa, saddr->sa_data,dev->addr_len) ;
-
- if (xl_priv->xl_message_level) {
- printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev->name, xl_priv->xl_laa[0],
- xl_priv->xl_laa[1], xl_priv->xl_laa[2],
- xl_priv->xl_laa[3], xl_priv->xl_laa[4],
- xl_priv->xl_laa[5]);
- }
-
- return 0 ;
-}
-
-static void xl_arb_cmd(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
- u8 arb_cmd ;
- u16 lan_status, lan_status_diff ;
-
- writel( ( MEM_BYTE_READ | 0xD0000 | xl_priv->arb), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- arb_cmd = readb(xl_mmio + MMIO_MACDATA) ;
-
- if (arb_cmd == RING_STATUS_CHANGE) { /* Ring.Status.Change */
- writel( ( (MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
-
- printk(KERN_INFO "%s: Ring Status Change: New Status = %04x\n", dev->name, swab16(readw(xl_mmio + MMIO_MACDATA) )) ;
-
- lan_status = swab16(readw(xl_mmio + MMIO_MACDATA));
-
- /* Acknowledge interrupt, this tells nic we are done with the arb */
- writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
-
- lan_status_diff = xl_priv->xl_lan_status ^ lan_status ;
-
- if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) {
- if (lan_status_diff & LSC_LWF)
- printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name);
- if (lan_status_diff & LSC_ARW)
- printk(KERN_WARNING "%s: Auto removal error\n",dev->name);
- if (lan_status_diff & LSC_FPE)
- printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name);
- if (lan_status_diff & LSC_RR)
- printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name);
-
- /* Adapter has been closed by the hardware */
-
- netif_stop_queue(dev);
- xl_freemem(dev) ;
- free_irq(dev->irq,dev);
-
- printk(KERN_WARNING "%s: Adapter has been closed\n", dev->name);
- } /* If serious error */
-
- if (xl_priv->xl_message_level) {
- if (lan_status_diff & LSC_SIG_LOSS)
- printk(KERN_WARNING "%s: No receive signal detected\n", dev->name);
- if (lan_status_diff & LSC_HARD_ERR)
- printk(KERN_INFO "%s: Beaconing\n",dev->name);
- if (lan_status_diff & LSC_SOFT_ERR)
- printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n",dev->name);
- if (lan_status_diff & LSC_TRAN_BCN)
- printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n",dev->name);
- if (lan_status_diff & LSC_SS)
- printk(KERN_INFO "%s: Single Station on the ring\n", dev->name);
- if (lan_status_diff & LSC_RING_REC)
- printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name);
- if (lan_status_diff & LSC_FDX_MODE)
- printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name);
- }
-
- if (lan_status_diff & LSC_CO) {
- if (xl_priv->xl_message_level)
- printk(KERN_INFO "%s: Counter Overflow\n", dev->name);
- /* Issue READ.LOG command */
- xl_srb_cmd(dev, READ_LOG) ;
- }
-
- /* There is no command in the tech docs to issue the read_sr_counters */
- if (lan_status_diff & LSC_SR_CO) {
- if (xl_priv->xl_message_level)
- printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name);
- }
-
- xl_priv->xl_lan_status = lan_status ;
-
- } /* Lan.change.status */
- else if ( arb_cmd == RECEIVE_DATA) { /* Received.Data */
-#if XL_DEBUG
- printk(KERN_INFO "Received.Data\n");
-#endif
- writel( ((MEM_WORD_READ | 0xD0000 | xl_priv->arb) + 6), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- xl_priv->mac_buffer = swab16(readw(xl_mmio + MMIO_MACDATA)) ;
-
- /* Now we are going to be really basic here and not do anything
- * with the data at all. The tech docs do not give me enough
- * information to calculate the buffers properly so we're
- * just going to tell the nic that we've dealt with the frame
- * anyway.
- */
-
- /* Acknowledge interrupt, this tells nic we are done with the arb */
- writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK, xl_mmio + MMIO_COMMAND) ;
-
- /* Is the ASB free ? */
-
- xl_priv->asb_queued = 0 ;
- writel( ((MEM_BYTE_READ | 0xD0000 | xl_priv->asb) + 2), xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- if (readb(xl_mmio + MMIO_MACDATA) != 0xff) {
- xl_priv->asb_queued = 1 ;
-
- xl_wait_misr_flags(dev) ;
-
- writel(MEM_BYTE_WRITE | MF_ASBFR, xl_mmio + MMIO_MAC_ACCESS_CMD);
- writeb(0xff, xl_mmio + MMIO_MACDATA) ;
- writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(MISR_ASBFR, xl_mmio + MMIO_MACDATA) ;
- return ;
- /* Drop out and wait for the bottom half to be run */
- }
-
- xl_asb_cmd(dev) ;
-
- } else {
- printk(KERN_WARNING "%s: Received unknown arb (xl_priv) command: %02x\n",dev->name,arb_cmd);
- }
-
- /* Acknowledge the arb interrupt */
-
- writel(ACK_INTERRUPT | ARBCACK | LATCH_ACK , xl_mmio + MMIO_COMMAND) ;
-
- return ;
-}
-
-
-/*
- * There is only one asb command, but we can get called from different
- * places.
- */
-
-static void xl_asb_cmd(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
-
- if (xl_priv->asb_queued == 1)
- writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ;
-
- writel(MEM_BYTE_WRITE | 0xd0000 | xl_priv->asb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(0x81, xl_mmio + MMIO_MACDATA) ;
-
- writel(MEM_WORD_WRITE | 0xd0000 | xl_priv->asb | 6, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(swab16(xl_priv->mac_buffer), xl_mmio + MMIO_MACDATA) ;
-
- xl_wait_misr_flags(dev) ;
-
- writel(MEM_BYTE_WRITE | MF_RASB, xl_mmio + MMIO_MAC_ACCESS_CMD);
- writeb(0xff, xl_mmio + MMIO_MACDATA) ;
-
- writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(MISR_RASB, xl_mmio + MMIO_MACDATA) ;
-
- xl_priv->asb_queued = 2 ;
-
- return ;
-}
-
-/*
- * This will only get called if there was an error
- * from the asb cmd.
- */
-static void xl_asb_bh(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
- u8 ret_code ;
-
- writel(MMIO_BYTE_READ | 0xd0000 | xl_priv->asb | 2, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- ret_code = readb(xl_mmio + MMIO_MACDATA) ;
- switch (ret_code) {
- case 0x01:
- printk(KERN_INFO "%s: ASB Command, unrecognized command code\n",dev->name);
- break ;
- case 0x26:
- printk(KERN_INFO "%s: ASB Command, unexpected receive buffer\n", dev->name);
- break ;
- case 0x40:
- printk(KERN_INFO "%s: ASB Command, Invalid Station ID\n", dev->name);
- break ;
- }
- xl_priv->asb_queued = 0 ;
- writel(ACK_INTERRUPT | LATCH_ACK | ASBFACK, xl_mmio + MMIO_COMMAND) ;
- return ;
-}
-
-/*
- * Issue srb commands to the nic
- */
-
-static void xl_srb_cmd(struct net_device *dev, int srb_cmd)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
-
- switch (srb_cmd) {
- case READ_LOG:
- writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(READ_LOG, xl_mmio + MMIO_MACDATA) ;
- break;
-
- case CLOSE_NIC:
- writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(CLOSE_NIC, xl_mmio + MMIO_MACDATA) ;
- break ;
-
- case SET_RECEIVE_MODE:
- writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(SET_RECEIVE_MODE, xl_mmio + MMIO_MACDATA) ;
- writel(MEM_WORD_WRITE | 0xD0000 | xl_priv->srb | 4, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writew(xl_priv->xl_copy_all_options, xl_mmio + MMIO_MACDATA) ;
- break ;
-
- case SET_FUNC_ADDRESS:
- writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(SET_FUNC_ADDRESS, xl_mmio + MMIO_MACDATA) ;
- writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 6 , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(xl_priv->xl_functional_addr[0], xl_mmio + MMIO_MACDATA) ;
- writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 7 , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(xl_priv->xl_functional_addr[1], xl_mmio + MMIO_MACDATA) ;
- writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 8 , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(xl_priv->xl_functional_addr[2], xl_mmio + MMIO_MACDATA) ;
- writel(MEM_BYTE_WRITE | 0xD0000 | xl_priv->srb | 9 , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(xl_priv->xl_functional_addr[3], xl_mmio + MMIO_MACDATA) ;
- break ;
- } /* switch */
-
-
- xl_wait_misr_flags(dev) ;
-
- /* Write 0xff to the CSRB flag */
- writel(MEM_BYTE_WRITE | MF_CSRB , xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(0xFF, xl_mmio + MMIO_MACDATA) ;
- /* Set csrb bit in MISR register to process command */
- writel(MMIO_BYTE_WRITE | MISR_SET, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(MISR_CSRB, xl_mmio + MMIO_MACDATA) ;
- xl_priv->srb_queued = 1 ;
-
- return ;
-}
-
-/*
- * This is nasty, to use the MISR command you have to wait for 6 memory locations
- * to be zero. This is the way the driver does on other OS'es so we should be ok with
- * the empty loop.
- */
-
-static void xl_wait_misr_flags(struct net_device *dev)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u8 __iomem * xl_mmio = xl_priv->xl_mmio ;
-
- int i ;
-
- writel(MMIO_BYTE_READ | MISR_RW, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- if (readb(xl_mmio + MMIO_MACDATA) != 0) { /* Misr not clear */
- for (i=0; i<6; i++) {
- writel(MEM_BYTE_READ | 0xDFFE0 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- while (readb(xl_mmio + MMIO_MACDATA) != 0) {
- ; /* Empty Loop */
- }
- }
- }
-
- writel(MMIO_BYTE_WRITE | MISR_AND, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(0x80, xl_mmio + MMIO_MACDATA) ;
-
- return ;
-}
-
-/*
- * Change mtu size, this should work the same as olympic
- */
-
-static int xl_change_mtu(struct net_device *dev, int mtu)
-{
- struct xl_private *xl_priv = netdev_priv(dev);
- u16 max_mtu ;
-
- if (xl_priv->xl_ring_speed == 4)
- max_mtu = 4500 ;
- else
- max_mtu = 18000 ;
-
- if (mtu > max_mtu)
- return -EINVAL ;
- if (mtu < 100)
- return -EINVAL ;
-
- dev->mtu = mtu ;
- xl_priv->pkt_buf_sz = mtu + TR_HLEN ;
-
- return 0 ;
-}
-
-static void __devexit xl_remove_one (struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct xl_private *xl_priv=netdev_priv(dev);
-
- release_firmware(xl_priv->fw);
- unregister_netdev(dev);
- iounmap(xl_priv->xl_mmio) ;
- pci_release_regions(pdev) ;
- pci_set_drvdata(pdev,NULL) ;
- free_netdev(dev);
- return ;
-}
-
-static struct pci_driver xl_3c359_driver = {
- .name = "3c359",
- .id_table = xl_pci_tbl,
- .probe = xl_probe,
- .remove = __devexit_p(xl_remove_one),
-};
-
-module_pci_driver(xl_3c359_driver);
-
-MODULE_LICENSE("GPL") ;
diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h
deleted file mode 100644
index bcb1a6b4a4c7..000000000000
--- a/drivers/net/tokenring/3c359.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * 3c359.h (c) 2000 Mike Phillips (mikep@linuxtr.net) All Rights Reserved
- *
- * Linux driver for 3Com 3C359 Token Link PCI XL cards.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License Version 2 or (at your option)
- * any later verion, incorporated herein by reference.
- */
-
-/* Memory Access Commands */
-#define IO_BYTE_READ 0x28 << 24
-#define IO_BYTE_WRITE 0x18 << 24
-#define IO_WORD_READ 0x20 << 24
-#define IO_WORD_WRITE 0x10 << 24
-#define MMIO_BYTE_READ 0x88 << 24
-#define MMIO_BYTE_WRITE 0x48 << 24
-#define MMIO_WORD_READ 0x80 << 24
-#define MMIO_WORD_WRITE 0x40 << 24
-#define MEM_BYTE_READ 0x8C << 24
-#define MEM_BYTE_WRITE 0x4C << 24
-#define MEM_WORD_READ 0x84 << 24
-#define MEM_WORD_WRITE 0x44 << 24
-
-#define PMBAR 0x1C80
-#define PMB_CPHOLD (1<<10)
-
-#define CPATTENTION 0x180D
-#define CPA_PMBARVIS (1<<7)
-#define CPA_MEMWREN (1<<6)
-
-#define SWITCHSETTINGS 0x1C88
-#define EECONTROL 0x1C8A
-#define EEDATA 0x1C8C
-#define EEREAD 0x0080
-#define EEWRITE 0x0040
-#define EEERASE 0x0060
-#define EE_ENABLE_WRITE 0x0030
-#define EEBUSY (1<<15)
-
-#define WRBR 0xCDE02
-#define WWOR 0xCDE04
-#define WWCR 0xCDE06
-#define MACSTATUS 0xCDE08
-#define MISR_RW 0xCDE0B
-#define MISR_AND 0xCDE2B
-#define MISR_SET 0xCDE4B
-#define RXBUFAREA 0xCDE10
-#define RXEARLYTHRESH 0xCDE12
-#define TXSTARTTHRESH 0x58
-#define DNPRIREQTHRESH 0x2C
-
-#define MISR_CSRB (1<<5)
-#define MISR_RASB (1<<4)
-#define MISR_SRBFR (1<<3)
-#define MISR_ASBFR (1<<2)
-#define MISR_ARBF (1<<1)
-
-/* MISR Flags memory locations */
-#define MF_SSBF 0xDFFE0
-#define MF_ARBF 0xDFFE1
-#define MF_ASBFR 0xDFFE2
-#define MF_SRBFR 0xDFFE3
-#define MF_RASB 0xDFFE4
-#define MF_CSRB 0xDFFE5
-
-#define MMIO_MACDATA 0x10
-#define MMIO_MAC_ACCESS_CMD 0x14
-#define MMIO_TIMER 0x1A
-#define MMIO_DMA_CTRL 0x20
-#define MMIO_DNLISTPTR 0x24
-#define MMIO_HASHFILTER 0x28
-#define MMIO_CONFIG 0x29
-#define MMIO_DNPRIREQTHRESH 0x2C
-#define MMIO_DNPOLL 0x2D
-#define MMIO_UPPKTSTATUS 0x30
-#define MMIO_FREETIMER 0x34
-#define MMIO_COUNTDOWN 0x36
-#define MMIO_UPLISTPTR 0x38
-#define MMIO_UPPOLL 0x3C
-#define MMIO_UPBURSTTHRESH 0x40
-#define MMIO_DNBURSTTHRESH 0x41
-#define MMIO_INTSTATUS_AUTO 0x56
-#define MMIO_TXSTARTTHRESH 0x58
-#define MMIO_INTERRUPTENABLE 0x5A
-#define MMIO_INDICATIONENABLE 0x5C
-#define MMIO_COMMAND 0x5E /* These two are meant to be the same */
-#define MMIO_INTSTATUS 0x5E /* Makes the code more readable this way */
-#define INTSTAT_CMD_IN_PROGRESS (1<<12)
-#define INTSTAT_SRB (1<<14)
-#define INTSTAT_INTLATCH (1<<0)
-
-/* Indication / Interrupt Mask
- * Annoyingly the bits to be set in the indication and interrupt enable
- * do not match with the actual bits received in the interrupt, although
- * they are in the same order.
- * The mapping for the indication / interrupt are:
- * Bit Indication / Interrupt
- * 0 HostError
- * 1 txcomplete
- * 2 updneeded
- * 3 rxcomplete
- * 4 intrequested
- * 5 macerror
- * 6 dncomplete
- * 7 upcomplete
- * 8 txunderrun
- * 9 asbf
- * 10 srbr
- * 11 arbc
- *
- * The only ones we don't want to receive are txcomplete and rxcomplete
- * we use dncomplete and upcomplete instead.
- */
-
-#define INT_MASK 0xFF5
-
-/* Note the subtle difference here, IND and INT */
-
-#define SETINDENABLE (8<<12)
-#define SETINTENABLE (7<<12)
-#define SRBBIT (1<<10)
-#define ASBBIT (1<<9)
-#define ARBBIT (1<<11)
-
-#define SRB 0xDFE90
-#define ASB 0xDFED0
-#define ARB 0xD0000
-#define SCRATCH 0xDFEF0
-
-#define INT_REQUEST 0x6000 /* (6 << 12) */
-#define ACK_INTERRUPT 0x6800 /* (13 <<11) */
-#define GLOBAL_RESET 0x00
-#define DNDISABLE 0x5000
-#define DNENABLE 0x4800
-#define DNSTALL 0x3002
-#define DNRESET 0x5800
-#define DNUNSTALL 0x3003
-#define UPRESET 0x2800
-#define UPSTALL 0x3000
-#define UPUNSTALL 0x3001
-#define SETCONFIG 0x4000
-#define SETTXSTARTTHRESH 0x9800
-
-/* Received Interrupts */
-#define ASBFINT (1<<13)
-#define SRBRINT (1<<14)
-#define ARBCINT (1<<15)
-#define TXUNDERRUN (1<<11)
-
-#define UPCOMPINT (1<<10)
-#define DNCOMPINT (1<<9)
-#define HARDERRINT (1<<7)
-#define RXCOMPLETE (1<<4)
-#define TXCOMPINT (1<<2)
-#define HOSTERRINT (1<<1)
-
-/* Receive descriptor bits */
-#define RXOVERRUN cpu_to_le32(1<<19)
-#define RXFC cpu_to_le32(1<<21)
-#define RXAR cpu_to_le32(1<<22)
-#define RXUPDCOMPLETE cpu_to_le32(1<<23)
-#define RXUPDFULL cpu_to_le32(1<<24)
-#define RXUPLASTFRAG cpu_to_le32(1<<31)
-
-/* Transmit descriptor bits */
-#define TXDNCOMPLETE cpu_to_le32(1<<16)
-#define TXTXINDICATE cpu_to_le32(1<<27)
-#define TXDPDEMPTY cpu_to_le32(1<<29)
-#define TXDNINDICATE cpu_to_le32(1<<31)
-#define TXDNFRAGLAST cpu_to_le32(1<<31)
-
-/* Interrupts to Acknowledge */
-#define LATCH_ACK 1
-#define TXCOMPACK (1<<1)
-#define INTREQACK (1<<2)
-#define DNCOMPACK (1<<3)
-#define UPCOMPACK (1<<4)
-#define ASBFACK (1<<5)
-#define SRBRACK (1<<6)
-#define ARBCACK (1<<7)
-
-#define XL_IO_SPACE 128
-#define SRB_COMMAND_SIZE 50
-
-/* Adapter Commands */
-#define REQUEST_INT 0x00
-#define MODIFY_OPEN_PARMS 0x01
-#define RESTORE_OPEN_PARMS 0x02
-#define OPEN_NIC 0x03
-#define CLOSE_NIC 0x04
-#define SET_SLEEP_MODE 0x05
-#define SET_GROUP_ADDRESS 0x06
-#define SET_FUNC_ADDRESS 0x07
-#define READ_LOG 0x08
-#define SET_MULTICAST_MODE 0x0C
-#define CHANGE_WAKEUP_PATTERN 0x0D
-#define GET_STATISTICS 0x13
-#define SET_RECEIVE_MODE 0x1F
-
-/* ARB Commands */
-#define RECEIVE_DATA 0x81
-#define RING_STATUS_CHANGE 0x84
-
-/* ASB Commands */
-#define ASB_RECEIVE_DATE 0x81
-
-/* Defines for LAN STATUS CHANGE reports */
-#define LSC_SIG_LOSS 0x8000
-#define LSC_HARD_ERR 0x4000
-#define LSC_SOFT_ERR 0x2000
-#define LSC_TRAN_BCN 0x1000
-#define LSC_LWF 0x0800
-#define LSC_ARW 0x0400
-#define LSC_FPE 0x0200
-#define LSC_RR 0x0100
-#define LSC_CO 0x0080
-#define LSC_SS 0x0040
-#define LSC_RING_REC 0x0020
-#define LSC_SR_CO 0x0010
-#define LSC_FDX_MODE 0x0004
-
-#define XL_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */
-
-/* 3c359 defaults for buffers */
-
-#define XL_RX_RING_SIZE 16 /* must be a power of 2 */
-#define XL_TX_RING_SIZE 16 /* must be a power of 2 */
-
-#define PKT_BUF_SZ 4096 /* Default packet size */
-
-/* 3c359 data structures */
-
-struct xl_tx_desc {
- __le32 dnnextptr;
- __le32 framestartheader;
- __le32 buffer;
- __le32 buffer_length;
-};
-
-struct xl_rx_desc {
- __le32 upnextptr;
- __le32 framestatus;
- __le32 upfragaddr;
- __le32 upfraglen;
-};
-
-struct xl_private {
-
-
- /* These two structures must be aligned on 8 byte boundaries */
-
- /* struct xl_rx_desc xl_rx_ring[XL_RX_RING_SIZE]; */
- /* struct xl_tx_desc xl_tx_ring[XL_TX_RING_SIZE]; */
- struct xl_rx_desc *xl_rx_ring ;
- struct xl_tx_desc *xl_tx_ring ;
- struct sk_buff *tx_ring_skb[XL_TX_RING_SIZE], *rx_ring_skb[XL_RX_RING_SIZE];
- int tx_ring_head, tx_ring_tail ;
- int rx_ring_tail, rx_ring_no ;
- int free_ring_entries ;
-
- u16 srb;
- u16 arb;
- u16 asb;
-
- u8 __iomem *xl_mmio;
- const char *xl_card_name;
- struct pci_dev *pdev ;
-
- spinlock_t xl_lock ;
-
- volatile int srb_queued;
- struct wait_queue *srb_wait;
- volatile int asb_queued;
-
- u16 mac_buffer ;
- u16 xl_lan_status ;
- u8 xl_ring_speed ;
- u16 pkt_buf_sz ;
- u8 xl_message_level;
- u16 xl_copy_all_options ;
- unsigned char xl_functional_addr[4] ;
- u16 xl_addr_table_addr, xl_parms_addr ;
- u8 xl_laa[6] ;
- u32 rx_ring_dma_addr ;
- u32 tx_ring_dma_addr ;
-
- /* firmware section */
- const struct firmware *fw;
-};
-
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
deleted file mode 100644
index ef3bb1326e4f..000000000000
--- a/drivers/net/tokenring/Kconfig
+++ /dev/null
@@ -1,199 +0,0 @@
-#
-# Token Ring driver configuration
-#
-
-# So far, we only have PCI, ISA, and MCA token ring devices
-menuconfig TR
- bool "Token Ring driver support"
- depends on NETDEVICES && !UML
- depends on (PCI || ISA || MCA || CCW || PCMCIA)
- help
- Token Ring is IBM's way of communication on a local network; the
- rest of the world uses Ethernet. To participate on a Token Ring
- network, you need a special Token ring network card. If you are
- connected to such a Token Ring network and want to use your Token
- Ring card under Linux, say Y here and to the driver for your
- particular card below and read the Token-Ring mini-HOWTO, available
- from <http://www.tldp.org/docs.html#howto>. Most people can
- say N here.
-
-if TR
-
-config WANT_LLC
- def_bool y
- select LLC
-
-config PCMCIA_IBMTR
- tristate "IBM PCMCIA tokenring adapter support"
- depends on IBMTR!=y && PCMCIA
- ---help---
- Say Y here if you intend to attach this type of Token Ring PCMCIA
- card to your computer. You then also need to say Y to "Token Ring
- driver support".
-
- To compile this driver as a module, choose M here: the module will be
- called ibmtr_cs.
-
-config IBMTR
- tristate "IBM Tropic chipset based adapter support"
- depends on ISA || MCA
- ---help---
- This is support for all IBM Token Ring cards that don't use DMA. If
- you have such a beast, say Y and read the Token-Ring mini-HOWTO,
- available from <http://www.tldp.org/docs.html#howto>.
-
- Warning: this driver will almost definitely fail if more than one
- active Token Ring card is present.
-
- To compile this driver as a module, choose M here: the module will be
- called ibmtr.
-
-config IBMOL
- tristate "IBM Olympic chipset PCI adapter support"
- depends on PCI
- ---help---
- This is support for all non-Lanstreamer IBM PCI Token Ring Cards.
- Specifically this is all IBM PCI, PCI Wake On Lan, PCI II, PCI II
- Wake On Lan, and PCI 100/16/4 adapters.
-
- If you have such an adapter, say Y and read the Token-Ring
- mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here: the module will be
- called olympic.
-
- Also read <file:Documentation/networking/olympic.txt> or check the
- Linux Token Ring Project site for the latest information at
- <http://www.linuxtr.net/>.
-
-config IBMLS
- tristate "IBM Lanstreamer chipset PCI adapter support"
- depends on PCI && !64BIT
- help
- This is support for IBM Lanstreamer PCI Token Ring Cards.
-
- If you have such an adapter, say Y and read the Token-Ring
- mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here: the module will be
- called lanstreamer.
-
-config 3C359
- tristate "3Com 3C359 Token Link Velocity XL adapter support"
- depends on PCI
- ---help---
- This is support for the 3Com PCI Velocity XL cards, specifically
- the 3Com 3C359, please note this is not for the 3C339 cards, you
- should use the tms380 driver instead.
-
- If you have such an adapter, say Y and read the Token-Ring
- mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>.
-
- To compile this driver as a module, choose M here: the module will be
- called 3c359.
-
- Also read the file <file:Documentation/networking/3c359.txt> or check the
- Linux Token Ring Project site for the latest information at
- <http://www.linuxtr.net>
-
-config TMS380TR
- tristate "Generic TMS380 Token Ring ISA/PCI adapter support"
- depends on PCI || ISA || MCA
- select FW_LOADER
- ---help---
- This driver provides generic support for token ring adapters
- based on the Texas Instruments TMS380 series chipsets. This
- includes the SysKonnect TR4/16(+) ISA (SK-4190), SysKonnect
- TR4/16(+) PCI (SK-4590), SysKonnect TR4/16 PCI (SK-4591),
- Compaq 4/16 PCI, Thomas-Conrad TC4048 4/16 PCI, and several
- Madge adapters. If you say Y here, you will be asked to select
- which cards to support below. If you're using modules, each
- class of card will be supported by a separate module.
-
- If you have such an adapter and would like to use it, say Y and
- read the Token-Ring mini-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>.
-
- Also read the file <file:Documentation/networking/tms380tr.txt> or
- check <http://www.auk.cx/tms380tr/>.
-
- To compile this driver as a module, choose M here: the module will be
- called tms380tr.
-
-config TMSPCI
- tristate "Generic TMS380 PCI support"
- depends on TMS380TR && PCI
- ---help---
- This tms380 module supports generic TMS380-based PCI cards.
-
- These cards are known to work:
- - Compaq 4/16 TR PCI
- - SysKonnect TR4/16 PCI (SK-4590/SK-4591)
- - Thomas-Conrad TC4048 PCI 4/16
- - 3Com Token Link Velocity
-
- To compile this driver as a module, choose M here: the module will be
- called tmspci.
-
-config SKISA
- tristate "SysKonnect TR4/16 ISA support"
- depends on TMS380TR && ISA && ISA_DMA_API
- help
- This tms380 module supports SysKonnect TR4/16 ISA cards.
-
- These cards are known to work:
- - SysKonnect TR4/16 ISA (SK-4190)
-
- To compile this driver as a module, choose M here: the module will be
- called skisa.
-
-config PROTEON
- tristate "Proteon ISA support"
- depends on TMS380TR && ISA && ISA_DMA_API
- help
- This tms380 module supports Proteon ISA cards.
-
- These cards are known to work:
- - Proteon 1392
- - Proteon 1392 plus
-
- To compile this driver as a module, choose M here: the module will be
- called proteon.
-
-config ABYSS
- tristate "Madge Smart 16/4 PCI Mk2 support"
- depends on TMS380TR && PCI
- help
- This tms380 module supports the Madge Smart 16/4 PCI Mk2
- cards (51-02).
-
- To compile this driver as a module, choose M here: the module will be
- called abyss.
-
-config MADGEMC
- tristate "Madge Smart 16/4 Ringnode MicroChannel"
- depends on TMS380TR && MCA
- help
- This tms380 module supports the Madge Smart 16/4 MC16 and MC32
- MicroChannel adapters.
-
- To compile this driver as a module, choose M here: the module will be
- called madgemc.
-
-config SMCTR
- tristate "SMC ISA/MCA adapter support"
- depends on (ISA || MCA_LEGACY) && (BROKEN || !64BIT)
- ---help---
- This is support for the ISA and MCA SMC Token Ring cards,
- specifically SMC TokenCard Elite (8115T) and SMC TokenCard Elite/A
- (8115T/A) adapters.
-
- If you have such an adapter and would like to use it, say Y or M and
- read the Token-Ring mini-HOWTO, available from
- <http://www.tldp.org/docs.html#howto> and the file
- <file:Documentation/networking/smctr.txt>.
-
- To compile this driver as a module, choose M here: the module will be
- called smctr.
-
-endif # TR
diff --git a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile
deleted file mode 100644
index f1be8d97b7a8..000000000000
--- a/drivers/net/tokenring/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Makefile for drivers/net/tokenring
-#
-
-obj-$(CONFIG_PCMCIA_IBMTR) += ibmtr_cs.o
-obj-$(CONFIG_IBMTR) += ibmtr.o
-obj-$(CONFIG_IBMOL) += olympic.o
-obj-$(CONFIG_IBMLS) += lanstreamer.o
-obj-$(CONFIG_TMS380TR) += tms380tr.o
-obj-$(CONFIG_ABYSS) += abyss.o
-obj-$(CONFIG_MADGEMC) += madgemc.o
-obj-$(CONFIG_PROTEON) += proteon.o
-obj-$(CONFIG_TMSPCI) += tmspci.o
-obj-$(CONFIG_SKISA) += skisa.o
-obj-$(CONFIG_SMCTR) += smctr.o
-obj-$(CONFIG_3C359) += 3c359.o
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
deleted file mode 100644
index b715e6b444da..000000000000
--- a/drivers/net/tokenring/abyss.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * abyss.c: Network driver for the Madge Smart 16/4 PCI Mk2 token ring card.
- *
- * Written 1999-2000 by Adam Fritzler
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * This driver module supports the following cards:
- * - Madge Smart 16/4 PCI Mk2
- *
- * Maintainer(s):
- * AF Adam Fritzler
- *
- * Modification History:
- * 30-Dec-99 AF Split off from the tms380tr driver.
- * 22-Jan-00 AF Updated to use indirect read/writes
- * 23-Nov-00 JG New PCI API, cleanups
- *
- *
- * TODO:
- * 1. See if we can use MMIO instead of inb/outb/inw/outw
- * 2. Add support for Mk1 (has AT24 attached to the PCI
- * config registers)
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "tms380tr.h"
-#include "abyss.h" /* Madge-specific constants */
-
-static char version[] __devinitdata =
-"abyss.c: v1.02 23/11/2000 by Adam Fritzler\n";
-
-#define ABYSS_IO_EXTENT 64
-
-static DEFINE_PCI_DEVICE_TABLE(abyss_pci_tbl) = {
- { PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_MK2,
- PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_TOKEN_RING << 8, 0x00ffffff, },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, abyss_pci_tbl);
-
-MODULE_LICENSE("GPL");
-
-static int abyss_open(struct net_device *dev);
-static int abyss_close(struct net_device *dev);
-static void abyss_enable(struct net_device *dev);
-static int abyss_chipset_init(struct net_device *dev);
-static void abyss_read_eeprom(struct net_device *dev);
-static unsigned short abyss_setnselout_pins(struct net_device *dev);
-
-static void at24_writedatabyte(unsigned long regaddr, unsigned char byte);
-static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr);
-static int at24_sendcmd(unsigned long regaddr, unsigned char cmd);
-static unsigned char at24_readdatabit(unsigned long regaddr);
-static unsigned char at24_readdatabyte(unsigned long regaddr);
-static int at24_waitforack(unsigned long regaddr);
-static int at24_waitfornack(unsigned long regaddr);
-static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data);
-static void at24_start(unsigned long regaddr);
-static unsigned char at24_readb(unsigned long regaddr, unsigned char addr);
-
-static unsigned short abyss_sifreadb(struct net_device *dev, unsigned short reg)
-{
- return inb(dev->base_addr + reg);
-}
-
-static unsigned short abyss_sifreadw(struct net_device *dev, unsigned short reg)
-{
- return inw(dev->base_addr + reg);
-}
-
-static void abyss_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- outb(val, dev->base_addr + reg);
-}
-
-static void abyss_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- outw(val, dev->base_addr + reg);
-}
-
-static struct net_device_ops abyss_netdev_ops;
-
-static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- static int versionprinted;
- struct net_device *dev;
- struct net_local *tp;
- int ret, pci_irq_line;
- unsigned long pci_ioaddr;
-
- if (versionprinted++ == 0)
- printk("%s", version);
-
- if (pci_enable_device(pdev))
- return -EIO;
-
- /* Remove I/O space marker in bit 0. */
- pci_irq_line = pdev->irq;
- pci_ioaddr = pci_resource_start (pdev, 0);
-
- /* At this point we have found a valid card. */
-
- dev = alloc_trdev(sizeof(struct net_local));
- if (!dev)
- return -ENOMEM;
-
- if (!request_region(pci_ioaddr, ABYSS_IO_EXTENT, dev->name)) {
- ret = -EBUSY;
- goto err_out_trdev;
- }
-
- ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED,
- dev->name, dev);
- if (ret)
- goto err_out_region;
-
- dev->base_addr = pci_ioaddr;
- dev->irq = pci_irq_line;
-
- printk("%s: Madge Smart 16/4 PCI Mk2 (Abyss)\n", dev->name);
- printk("%s: IO: %#4lx IRQ: %d\n",
- dev->name, pci_ioaddr, dev->irq);
- /*
- * The TMS SIF registers lay 0x10 above the card base address.
- */
- dev->base_addr += 0x10;
-
- ret = tmsdev_init(dev, &pdev->dev);
- if (ret) {
- printk("%s: unable to get memory for dev->priv.\n",
- dev->name);
- goto err_out_irq;
- }
-
- abyss_read_eeprom(dev);
-
- printk("%s: Ring Station Address: %pM\n", dev->name, dev->dev_addr);
-
- tp = netdev_priv(dev);
- tp->setnselout = abyss_setnselout_pins;
- tp->sifreadb = abyss_sifreadb;
- tp->sifreadw = abyss_sifreadw;
- tp->sifwriteb = abyss_sifwriteb;
- tp->sifwritew = abyss_sifwritew;
-
- memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1);
-
- dev->netdev_ops = &abyss_netdev_ops;
-
- pci_set_drvdata(pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- ret = register_netdev(dev);
- if (ret)
- goto err_out_tmsdev;
- return 0;
-
-err_out_tmsdev:
- pci_set_drvdata(pdev, NULL);
- tmsdev_term(dev);
-err_out_irq:
- free_irq(pdev->irq, dev);
-err_out_region:
- release_region(pci_ioaddr, ABYSS_IO_EXTENT);
-err_out_trdev:
- free_netdev(dev);
- return ret;
-}
-
-static unsigned short abyss_setnselout_pins(struct net_device *dev)
-{
- unsigned short val = 0;
- struct net_local *tp = netdev_priv(dev);
-
- if(tp->DataRate == SPEED_4)
- val |= 0x01; /* Set 4Mbps */
- else
- val |= 0x00; /* Set 16Mbps */
-
- return val;
-}
-
-/*
- * The following Madge boards should use this code:
- * - Smart 16/4 PCI Mk2 (Abyss)
- * - Smart 16/4 PCI Mk1 (PCI T)
- * - Smart 16/4 Client Plus PnP (Big Apple)
- * - Smart 16/4 Cardbus Mk2
- *
- * These access an Atmel AT24 SEEPROM using their glue chip registers.
- *
- */
-static void at24_writedatabyte(unsigned long regaddr, unsigned char byte)
-{
- int i;
-
- for (i = 0; i < 8; i++) {
- at24_setlines(regaddr, 0, (byte >> (7-i))&0x01);
- at24_setlines(regaddr, 1, (byte >> (7-i))&0x01);
- at24_setlines(regaddr, 0, (byte >> (7-i))&0x01);
- }
-}
-
-static int at24_sendfullcmd(unsigned long regaddr, unsigned char cmd, unsigned char addr)
-{
- if (at24_sendcmd(regaddr, cmd)) {
- at24_writedatabyte(regaddr, addr);
- return at24_waitforack(regaddr);
- }
- return 0;
-}
-
-static int at24_sendcmd(unsigned long regaddr, unsigned char cmd)
-{
- int i;
-
- for (i = 0; i < 10; i++) {
- at24_start(regaddr);
- at24_writedatabyte(regaddr, cmd);
- if (at24_waitforack(regaddr))
- return 1;
- }
- return 0;
-}
-
-static unsigned char at24_readdatabit(unsigned long regaddr)
-{
- unsigned char val;
-
- at24_setlines(regaddr, 0, 1);
- at24_setlines(regaddr, 1, 1);
- val = (inb(regaddr) & AT24_DATA)?1:0;
- at24_setlines(regaddr, 1, 1);
- at24_setlines(regaddr, 0, 1);
- return val;
-}
-
-static unsigned char at24_readdatabyte(unsigned long regaddr)
-{
- unsigned char data = 0;
- int i;
-
- for (i = 0; i < 8; i++) {
- data <<= 1;
- data |= at24_readdatabit(regaddr);
- }
-
- return data;
-}
-
-static int at24_waitforack(unsigned long regaddr)
-{
- int i;
-
- for (i = 0; i < 10; i++) {
- if ((at24_readdatabit(regaddr) & 0x01) == 0x00)
- return 1;
- }
- return 0;
-}
-
-static int at24_waitfornack(unsigned long regaddr)
-{
- int i;
- for (i = 0; i < 10; i++) {
- if ((at24_readdatabit(regaddr) & 0x01) == 0x01)
- return 1;
- }
- return 0;
-}
-
-static void at24_setlines(unsigned long regaddr, unsigned char clock, unsigned char data)
-{
- unsigned char val = AT24_ENABLE;
- if (clock)
- val |= AT24_CLOCK;
- if (data)
- val |= AT24_DATA;
-
- outb(val, regaddr);
- tms380tr_wait(20); /* Very necessary. */
-}
-
-static void at24_start(unsigned long regaddr)
-{
- at24_setlines(regaddr, 0, 1);
- at24_setlines(regaddr, 1, 1);
- at24_setlines(regaddr, 1, 0);
- at24_setlines(regaddr, 0, 1);
-}
-
-static unsigned char at24_readb(unsigned long regaddr, unsigned char addr)
-{
- unsigned char data = 0xff;
-
- if (at24_sendfullcmd(regaddr, AT24_WRITE, addr)) {
- if (at24_sendcmd(regaddr, AT24_READ)) {
- data = at24_readdatabyte(regaddr);
- if (!at24_waitfornack(regaddr))
- data = 0xff;
- }
- }
- return data;
-}
-
-
-/*
- * Enable basic functions of the Madge chipset needed
- * for initialization.
- */
-static void abyss_enable(struct net_device *dev)
-{
- unsigned char reset_reg;
- unsigned long ioaddr;
-
- ioaddr = dev->base_addr;
- reset_reg = inb(ioaddr + PCIBM2_RESET_REG);
- reset_reg |= PCIBM2_RESET_REG_CHIP_NRES;
- outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
- tms380tr_wait(100);
-}
-
-/*
- * Enable the functions of the Madge chipset needed for
- * full working order.
- */
-static int abyss_chipset_init(struct net_device *dev)
-{
- unsigned char reset_reg;
- unsigned long ioaddr;
-
- ioaddr = dev->base_addr;
-
- reset_reg = inb(ioaddr + PCIBM2_RESET_REG);
-
- reset_reg |= PCIBM2_RESET_REG_CHIP_NRES;
- outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
-
- reset_reg &= ~(PCIBM2_RESET_REG_CHIP_NRES |
- PCIBM2_RESET_REG_FIFO_NRES |
- PCIBM2_RESET_REG_SIF_NRES);
- outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
-
- tms380tr_wait(100);
-
- reset_reg |= PCIBM2_RESET_REG_CHIP_NRES;
- outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
-
- reset_reg |= PCIBM2_RESET_REG_SIF_NRES;
- outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
-
- reset_reg |= PCIBM2_RESET_REG_FIFO_NRES;
- outb(reset_reg, ioaddr + PCIBM2_RESET_REG);
-
- outb(PCIBM2_INT_CONTROL_REG_SINTEN |
- PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE,
- ioaddr + PCIBM2_INT_CONTROL_REG);
-
- outb(30, ioaddr + PCIBM2_FIFO_THRESHOLD);
-
- return 0;
-}
-
-static inline void abyss_chipset_close(struct net_device *dev)
-{
- unsigned long ioaddr;
-
- ioaddr = dev->base_addr;
- outb(0, ioaddr + PCIBM2_RESET_REG);
-}
-
-/*
- * Read configuration data from the AT24 SEEPROM on Madge cards.
- *
- */
-static void abyss_read_eeprom(struct net_device *dev)
-{
- struct net_local *tp;
- unsigned long ioaddr;
- unsigned short val;
- int i;
-
- tp = netdev_priv(dev);
- ioaddr = dev->base_addr;
-
- /* Must enable glue chip first */
- abyss_enable(dev);
-
- val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG,
- PCIBM2_SEEPROM_RING_SPEED);
- tp->DataRate = val?SPEED_4:SPEED_16; /* set open speed */
- printk("%s: SEEPROM: ring speed: %dMb/sec\n", dev->name, tp->DataRate);
-
- val = at24_readb(ioaddr + PCIBM2_SEEPROM_REG,
- PCIBM2_SEEPROM_RAM_SIZE) * 128;
- printk("%s: SEEPROM: adapter RAM: %dkb\n", dev->name, val);
-
- dev->addr_len = 6;
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = at24_readb(ioaddr + PCIBM2_SEEPROM_REG,
- PCIBM2_SEEPROM_BIA+i);
-}
-
-static int abyss_open(struct net_device *dev)
-{
- abyss_chipset_init(dev);
- tms380tr_open(dev);
- return 0;
-}
-
-static int abyss_close(struct net_device *dev)
-{
- tms380tr_close(dev);
- abyss_chipset_close(dev);
- return 0;
-}
-
-static void __devexit abyss_detach (struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- BUG_ON(!dev);
- unregister_netdev(dev);
- release_region(dev->base_addr-0x10, ABYSS_IO_EXTENT);
- free_irq(dev->irq, dev);
- tmsdev_term(dev);
- free_netdev(dev);
- pci_set_drvdata(pdev, NULL);
-}
-
-static struct pci_driver abyss_driver = {
- .name = "abyss",
- .id_table = abyss_pci_tbl,
- .probe = abyss_attach,
- .remove = __devexit_p(abyss_detach),
-};
-
-static int __init abyss_init (void)
-{
- abyss_netdev_ops = tms380tr_netdev_ops;
-
- abyss_netdev_ops.ndo_open = abyss_open;
- abyss_netdev_ops.ndo_stop = abyss_close;
-
- return pci_register_driver(&abyss_driver);
-}
-
-static void __exit abyss_rmmod (void)
-{
- pci_unregister_driver (&abyss_driver);
-}
-
-module_init(abyss_init);
-module_exit(abyss_rmmod);
-
diff --git a/drivers/net/tokenring/abyss.h b/drivers/net/tokenring/abyss.h
deleted file mode 100644
index b0a473b89133..000000000000
--- a/drivers/net/tokenring/abyss.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * abyss.h: Header for the abyss tms380tr module
- *
- * Authors:
- * - Adam Fritzler
- */
-
-#ifndef __LINUX_MADGETR_H
-#define __LINUX_MADGETR_H
-
-#ifdef __KERNEL__
-
-/*
- * For Madge Smart 16/4 PCI Mk2. Since we increment the base address
- * to get everything correct for the TMS SIF, we do these as negatives
- * as they fall below the SIF in addressing.
- */
-#define PCIBM2_INT_STATUS_REG ((short)-15)/* 0x01 */
-#define PCIBM2_INT_CONTROL_REG ((short)-14)/* 0x02 */
-#define PCIBM2_RESET_REG ((short)-12)/* 0x04 */
-#define PCIBM2_SEEPROM_REG ((short)-9) /* 0x07 */
-
-#define PCIBM2_INT_CONTROL_REG_SINTEN 0x02
-#define PCIBM2_INT_CONTROL_REG_PCI_ERR_ENABLE 0x80
-#define PCIBM2_INT_STATUS_REG_PCI_ERR 0x80
-
-#define PCIBM2_RESET_REG_CHIP_NRES 0x01
-#define PCIBM2_RESET_REG_FIFO_NRES 0x02
-#define PCIBM2_RESET_REG_SIF_NRES 0x04
-
-#define PCIBM2_FIFO_THRESHOLD 0x21
-#define PCIBM2_BURST_LENGTH 0x22
-
-/*
- * Bits in PCIBM2_SEEPROM_REG.
- */
-#define AT24_ENABLE 0x04
-#define AT24_DATA 0x02
-#define AT24_CLOCK 0x01
-
-/*
- * AT24 Commands.
- */
-#define AT24_WRITE 0xA0
-#define AT24_READ 0xA1
-
-/*
- * Addresses in AT24 SEEPROM.
- */
-#define PCIBM2_SEEPROM_BIA 0x12
-#define PCIBM2_SEEPROM_RING_SPEED 0x18
-#define PCIBM2_SEEPROM_RAM_SIZE 0x1A
-#define PCIBM2_SEEPROM_HWF1 0x1C
-#define PCIBM2_SEEPROM_HWF2 0x1E
-
-
-#endif /* __KERNEL__ */
-#endif /* __LINUX_MADGETR_H */
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
deleted file mode 100644
index b5c8c18f5046..000000000000
--- a/drivers/net/tokenring/ibmtr.c
+++ /dev/null
@@ -1,1964 +0,0 @@
-/* ibmtr.c: A shared-memory IBM Token Ring 16/4 driver for linux
- *
- * Written 1993 by Mark Swanson and Peter De Schrijver.
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * This device driver should work with Any IBM Token Ring Card that does
- * not use DMA.
- *
- * I used Donald Becker's (becker@scyld.com) device driver work
- * as a base for most of my initial work.
- *
- * Changes by Peter De Schrijver
- * (Peter.Deschrijver@linux.cc.kuleuven.ac.be) :
- *
- * + changed name to ibmtr.c in anticipation of other tr boards.
- * + changed reset code and adapter open code.
- * + added SAP open code.
- * + a first attempt to write interrupt, transmit and receive routines.
- *
- * Changes by David W. Morris (dwm@shell.portal.com) :
- * 941003 dwm: - Restructure tok_probe for multiple adapters, devices.
- * + Add comments, misc reorg for clarity.
- * + Flatten interrupt handler levels.
- *
- * Changes by Farzad Farid (farzy@zen.via.ecp.fr)
- * and Pascal Andre (andre@chimay.via.ecp.fr) (March 9 1995) :
- * + multi ring support clean up.
- * + RFC1042 compliance enhanced.
- *
- * Changes by Pascal Andre (andre@chimay.via.ecp.fr) (September 7 1995) :
- * + bug correction in tr_tx
- * + removed redundant information display
- * + some code reworking
- *
- * Changes by Michel Lespinasse (walken@via.ecp.fr),
- * Yann Doussot (doussot@via.ecp.fr) and Pascal Andre (andre@via.ecp.fr)
- * (February 18, 1996) :
- * + modified shared memory and mmio access port the driver to
- * alpha platform (structure access -> readb/writeb)
- *
- * Changes by Steve Kipisz (bungy@ibm.net or kipisz@vnet.ibm.com)
- * (January 18 1996):
- * + swapped WWOR and WWCR in ibmtr.h
- * + moved some init code from tok_probe into trdev_init. The
- * PCMCIA code can call trdev_init to complete initializing
- * the driver.
- * + added -DPCMCIA to support PCMCIA
- * + detecting PCMCIA Card Removal in interrupt handler. If
- * ISRP is FF, then a PCMCIA card has been removed
- * 10/2000 Burt needed a new method to avoid crashing the OS
- *
- * Changes by Paul Norton (pnorton@cts.com) :
- * + restructured the READ.LOG logic to prevent the transmit SRB
- * from being rudely overwritten before the transmit cycle is
- * complete. (August 15 1996)
- * + completed multiple adapter support. (November 20 1996)
- * + implemented csum_partial_copy in tr_rx and increased receive
- * buffer size and count. Minor fixes. (March 15, 1997)
- *
- * Changes by Christopher Turcksin <wabbit@rtfc.demon.co.uk>
- * + Now compiles ok as a module again.
- *
- * Changes by Paul Norton (pnorton@ieee.org) :
- * + moved the header manipulation code in tr_tx and tr_rx to
- * net/802/tr.c. (July 12 1997)
- * + add retry and timeout on open if cable disconnected. (May 5 1998)
- * + lifted 2000 byte mtu limit. now depends on shared-RAM size.
- * May 25 1998)
- * + can't allocate 2k recv buff at 8k shared-RAM. (20 October 1998)
- *
- * Changes by Joel Sloan (jjs@c-me.com) :
- * + disable verbose debug messages by default - to enable verbose
- * debugging, edit the IBMTR_DEBUG_MESSAGES define below
- *
- * Changes by Mike Phillips <phillim@amtrak.com> :
- * + Added extra #ifdef's to work with new PCMCIA Token Ring Code.
- * The PCMCIA code now just sets up the card so it can be recognized
- * by ibmtr_probe. Also checks allocated memory vs. on-board memory
- * for correct figure to use.
- *
- * Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) :
- * + added spinlocks for SMP sanity (10 March 1999)
- *
- * Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting
- * i.e. using functional address C0 00 00 04 00 00 to transmit and
- * receive multicast packets.
- *
- * Changes by Mike Sullivan (based on original sram patch by Dave Grothe
- * to support windowing into on adapter shared ram.
- * i.e. Use LANAID to setup a PnP configuration with 16K RAM. Paging
- * will shift this 16K window over the entire available shared RAM.
- *
- * Changes by Peter De Schrijver (p2@mind.be) :
- * + fixed a problem with PCMCIA card removal
- *
- * Change by Mike Sullivan et al.:
- * + added turbo card support. No need to use lanaid to configure
- * the adapter into isa compatibility mode.
- *
- * Changes by Burt Silverman to allow the computer to behave nicely when
- * a cable is pulled or not in place, or a PCMCIA card is removed hot.
- */
-
-/* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value
-in the event that chatty debug messages are desired - jjs 12/30/98 */
-
-#define IBMTR_DEBUG_MESSAGES 0
-
-#include <linux/module.h>
-#include <linux/sched.h>
-
-#ifdef PCMCIA /* required for ibmtr_cs.c to build */
-#undef MODULE /* yes, really */
-#undef ENABLE_PAGING
-#else
-#define ENABLE_PAGING 1
-#endif
-
-/* changes the output format of driver initialization */
-#define TR_VERBOSE 0
-
-/* some 95 OS send many non UI frame; this allow removing the warning */
-#define TR_FILTERNONUI 1
-
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/ip.h>
-#include <linux/trdevice.h>
-#include <linux/ibmtr.h>
-
-#include <net/checksum.h>
-
-#include <asm/io.h>
-
-#define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args)
-#define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args)
-
-/* version and credits */
-#ifndef PCMCIA
-static char version[] __devinitdata =
- "\nibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n"
- " v2.1.125 10/20/98 Paul Norton <pnorton@ieee.org>\n"
- " v2.2.0 12/30/98 Joel Sloan <jjs@c-me.com>\n"
- " v2.2.1 02/08/00 Mike Sullivan <sullivam@us.ibm.com>\n"
- " v2.2.2 07/27/00 Burt Silverman <burts@us.ibm.com>\n"
- " v2.4.0 03/01/01 Mike Sullivan <sullivan@us.ibm.com>\n";
-#endif
-
-/* this allows displaying full adapter information */
-
-static char *channel_def[] __devinitdata = { "ISA", "MCA", "ISA P&P" };
-
-static char pcchannelid[] __devinitdata = {
- 0x05, 0x00, 0x04, 0x09,
- 0x04, 0x03, 0x04, 0x0f,
- 0x03, 0x06, 0x03, 0x01,
- 0x03, 0x01, 0x03, 0x00,
- 0x03, 0x09, 0x03, 0x09,
- 0x03, 0x00, 0x02, 0x00
-};
-
-static char mcchannelid[] __devinitdata = {
- 0x04, 0x0d, 0x04, 0x01,
- 0x05, 0x02, 0x05, 0x03,
- 0x03, 0x06, 0x03, 0x03,
- 0x05, 0x08, 0x03, 0x04,
- 0x03, 0x05, 0x03, 0x01,
- 0x03, 0x08, 0x02, 0x00
-};
-
-static char __devinit *adapter_def(char type)
-{
- switch (type) {
- case 0xF: return "PC Adapter | PC Adapter II | Adapter/A";
- case 0xE: return "16/4 Adapter | 16/4 Adapter/A (long)";
- case 0xD: return "16/4 Adapter/A (short) | 16/4 ISA-16 Adapter";
- case 0xC: return "Auto 16/4 Adapter";
- default: return "adapter (unknown type)";
- }
-};
-
-#define TRC_INIT 0x01 /* Trace initialization & PROBEs */
-#define TRC_INITV 0x02 /* verbose init trace points */
-static unsigned char ibmtr_debug_trace = 0;
-
-static int ibmtr_probe1(struct net_device *dev, int ioaddr);
-static unsigned char get_sram_size(struct tok_info *adapt_info);
-static int trdev_init(struct net_device *dev);
-static int tok_open(struct net_device *dev);
-static int tok_init_card(struct net_device *dev);
-static void tok_open_adapter(unsigned long dev_addr);
-static void open_sap(unsigned char type, struct net_device *dev);
-static void tok_set_multicast_list(struct net_device *dev);
-static netdev_tx_t tok_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-static int tok_close(struct net_device *dev);
-static irqreturn_t tok_interrupt(int irq, void *dev_id);
-static void initial_tok_int(struct net_device *dev);
-static void tr_tx(struct net_device *dev);
-static void tr_rx(struct net_device *dev);
-static void ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev);
-static void tok_rerun(unsigned long dev_addr);
-static void ibmtr_readlog(struct net_device *dev);
-static int ibmtr_change_mtu(struct net_device *dev, int mtu);
-static void find_turbo_adapters(int *iolist);
-
-static int ibmtr_portlist[IBMTR_MAX_ADAPTERS+1] __devinitdata = {
- 0xa20, 0xa24, 0, 0, 0
-};
-static int __devinitdata turbo_io[IBMTR_MAX_ADAPTERS] = {0};
-static int __devinitdata turbo_irq[IBMTR_MAX_ADAPTERS] = {0};
-static int __devinitdata turbo_searched = 0;
-
-#ifndef PCMCIA
-static __u32 ibmtr_mem_base __devinitdata = 0xd0000;
-#endif
-
-static void __devinit PrtChanID(char *pcid, short stride)
-{
- short i, j;
- for (i = 0, j = 0; i < 24; i++, j += stride)
- printk("%1x", ((int) pcid[j]) & 0x0f);
- printk("\n");
-}
-
-static void __devinit HWPrtChanID(void __iomem *pcid, short stride)
-{
- short i, j;
- for (i = 0, j = 0; i < 24; i++, j += stride)
- printk("%1x", ((int) readb(pcid + j)) & 0x0f);
- printk("\n");
-}
-
-/* We have to ioremap every checked address, because isa_readb is
- * going away.
- */
-
-static void __devinit find_turbo_adapters(int *iolist)
-{
- int ram_addr;
- int index=0;
- void __iomem *chanid;
- int found_turbo=0;
- unsigned char *tchanid, ctemp;
- int i, j;
- unsigned long jif;
- void __iomem *ram_mapped ;
-
- if (turbo_searched == 1) return;
- turbo_searched=1;
- for (ram_addr=0xC0000; ram_addr < 0xE0000; ram_addr+=0x2000) {
-
- __u32 intf_tbl=0;
-
- found_turbo=1;
- ram_mapped = ioremap((u32)ram_addr,0x1fff) ;
- if (ram_mapped==NULL)
- continue ;
- chanid=(CHANNEL_ID + ram_mapped);
- tchanid=pcchannelid;
- ctemp=readb(chanid) & 0x0f;
- if (ctemp != *tchanid) continue;
- for (i=2,j=1; i<=46; i=i+2,j++) {
- if ((readb(chanid+i) & 0x0f) != tchanid[j]){
- found_turbo=0;
- break;
- }
- }
- if (!found_turbo) continue;
-
- writeb(0x90, ram_mapped+0x1E01);
- for(i=2; i<0x0f; i++) {
- writeb(0x00, ram_mapped+0x1E01+i);
- }
- writeb(0x00, ram_mapped+0x1E01);
- for(jif=jiffies+TR_BUSY_INTERVAL; time_before_eq(jiffies,jif););
- intf_tbl=ntohs(readw(ram_mapped+ACA_OFFSET+ACA_RW+WRBR_EVEN));
- if (intf_tbl) {
-#if IBMTR_DEBUG_MESSAGES
- printk("ibmtr::find_turbo_adapters, Turbo found at "
- "ram_addr %x\n",ram_addr);
- printk("ibmtr::find_turbo_adapters, interface_table ");
- for(i=0; i<6; i++) {
- printk("%x:",readb(ram_addr+intf_tbl+i));
- }
- printk("\n");
-#endif
- turbo_io[index]=ntohs(readw(ram_mapped+intf_tbl+4));
- turbo_irq[index]=readb(ram_mapped+intf_tbl+3);
- outb(0, turbo_io[index] + ADAPTRESET);
- for(jif=jiffies+TR_RST_TIME;time_before_eq(jiffies,jif););
- outb(0, turbo_io[index] + ADAPTRESETREL);
- index++;
- continue;
- }
-#if IBMTR_DEBUG_MESSAGES
- printk("ibmtr::find_turbo_adapters, ibmtr card found at"
- " %x but not a Turbo model\n",ram_addr);
-#endif
- iounmap(ram_mapped) ;
- } /* for */
- for(i=0; i<IBMTR_MAX_ADAPTERS; i++) {
- if(!turbo_io[i]) break;
- for (j=0; j<IBMTR_MAX_ADAPTERS; j++) {
- if ( iolist[j] && iolist[j] != turbo_io[i]) continue;
- iolist[j]=turbo_io[i];
- break;
- }
- }
-}
-
-static void ibmtr_cleanup_card(struct net_device *dev)
-{
- if (dev->base_addr) {
- outb(0,dev->base_addr+ADAPTRESET);
-
- schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
-
- outb(0,dev->base_addr+ADAPTRESETREL);
- }
-
-#ifndef PCMCIA
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, IBMTR_IO_EXTENT);
-
- {
- struct tok_info *ti = netdev_priv(dev);
- iounmap(ti->mmio);
- iounmap(ti->sram_virt);
- }
-#endif
-}
-
-/****************************************************************************
- * ibmtr_probe(): Routine specified in the network device structure
- * to probe for an IBM Token Ring Adapter. Routine outline:
- * I. Interrogate hardware to determine if an adapter exists
- * and what the speeds and feeds are
- * II. Setup data structures to control execution based upon
- * adapter characteristics.
- *
- * We expect ibmtr_probe to be called once for each device entry
- * which references it.
- ****************************************************************************/
-
-static int __devinit ibmtr_probe(struct net_device *dev)
-{
- int i;
- int base_addr = dev->base_addr;
-
- if (base_addr && base_addr <= 0x1ff) /* Don't probe at all. */
- return -ENXIO;
- if (base_addr > 0x1ff) { /* Check a single specified location. */
- if (!ibmtr_probe1(dev, base_addr)) return 0;
- return -ENODEV;
- }
- find_turbo_adapters(ibmtr_portlist);
- for (i = 0; ibmtr_portlist[i]; i++) {
- int ioaddr = ibmtr_portlist[i];
-
- if (!ibmtr_probe1(dev, ioaddr)) return 0;
- }
- return -ENODEV;
-}
-
-int __devinit ibmtr_probe_card(struct net_device *dev)
-{
- int err = ibmtr_probe(dev);
- if (!err) {
- err = register_netdev(dev);
- if (err)
- ibmtr_cleanup_card(dev);
- }
- return err;
-}
-
-/*****************************************************************************/
-
-static int __devinit ibmtr_probe1(struct net_device *dev, int PIOaddr)
-{
-
- unsigned char segment, intr=0, irq=0, i, j, cardpresent=NOTOK, temp=0;
- void __iomem * t_mmio = NULL;
- struct tok_info *ti = netdev_priv(dev);
- void __iomem *cd_chanid;
- unsigned char *tchanid, ctemp;
-#ifndef PCMCIA
- unsigned char t_irq=0;
- unsigned long timeout;
- static int version_printed;
-#endif
-
- /* Query the adapter PIO base port which will return
- * indication of where MMIO was placed. We also have a
- * coded interrupt number.
- */
- segment = inb(PIOaddr);
- if (segment < 0x40 || segment > 0xe0) {
- /* Out of range values so we'll assume non-existent IO device
- * but this is not necessarily a problem, esp if a turbo
- * adapter is being used. */
-#if IBMTR_DEBUG_MESSAGES
- DPRINTK("ibmtr_probe1(): unhappy that inb(0x%X) == 0x%X, "
- "Hardware Problem?\n",PIOaddr,segment);
-#endif
- return -ENODEV;
- }
- /*
- * Compute the linear base address of the MMIO area
- * as LINUX doesn't care about segments
- */
- t_mmio = ioremap(((__u32) (segment & 0xfc) << 11) + 0x80000,2048);
- if (!t_mmio) {
- DPRINTK("Cannot remap mmiobase memory area") ;
- return -ENODEV ;
- }
- intr = segment & 0x03; /* low bits is coded interrupt # */
- if (ibmtr_debug_trace & TRC_INIT)
- DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p intr: %d\n"
- , PIOaddr, (int) segment, t_mmio, (int) intr);
-
- /*
- * Now we will compare expected 'channelid' strings with
- * what we is there to learn of ISA/MCA or not TR card
- */
-#ifdef PCMCIA
- iounmap(t_mmio);
- t_mmio = ti->mmio; /*BMS to get virtual address */
- irq = ti->irq; /*BMS to display the irq! */
-#endif
- cd_chanid = (CHANNEL_ID + t_mmio); /* for efficiency */
- tchanid = pcchannelid;
- cardpresent = TR_ISA; /* try ISA */
-
- /* Suboptimize knowing first byte different */
- ctemp = readb(cd_chanid) & 0x0f;
- if (ctemp != *tchanid) { /* NOT ISA card, try MCA */
- tchanid = mcchannelid;
- cardpresent = TR_MCA;
- if (ctemp != *tchanid) /* Neither ISA nor MCA */
- cardpresent = NOTOK;
- }
- if (cardpresent != NOTOK) {
- /* Know presumed type, try rest of ID */
- for (i = 2, j = 1; i <= 46; i = i + 2, j++) {
- if( (readb(cd_chanid+i)&0x0f) == tchanid[j]) continue;
- /* match failed, not TR card */
- cardpresent = NOTOK;
- break;
- }
- }
- /*
- * If we have an ISA board check for the ISA P&P version,
- * as it has different IRQ settings
- */
- if (cardpresent == TR_ISA && (readb(AIPFID + t_mmio) == 0x0e))
- cardpresent = TR_ISAPNP;
- if (cardpresent == NOTOK) { /* "channel_id" did not match, report */
- if (!(ibmtr_debug_trace & TRC_INIT)) {
-#ifndef PCMCIA
- iounmap(t_mmio);
-#endif
- return -ENODEV;
- }
- DPRINTK( "Channel ID string not found for PIOaddr: %4hx\n",
- PIOaddr);
- DPRINTK("Expected for ISA: ");
- PrtChanID(pcchannelid, 1);
- DPRINTK(" found: ");
-/* BMS Note that this can be misleading, when hardware is flaky, because you
- are reading it a second time here. So with my flaky hardware, I'll see my-
- self in this block, with the HW ID matching the ISA ID exactly! */
- HWPrtChanID(cd_chanid, 2);
- DPRINTK("Expected for MCA: ");
- PrtChanID(mcchannelid, 1);
- }
- /* Now, setup some of the pl0 buffers for this driver.. */
- /* If called from PCMCIA, it is already set up, so no need to
- waste the memory, just use the existing structure */
-#ifndef PCMCIA
- ti->mmio = t_mmio;
- for (i = 0; i < IBMTR_MAX_ADAPTERS; i++) {
- if (turbo_io[i] != PIOaddr)
- continue;
-#if IBMTR_DEBUG_MESSAGES
- printk("ibmtr::tr_probe1, setting PIOaddr %x to Turbo\n",
- PIOaddr);
-#endif
- ti->turbo = 1;
- t_irq = turbo_irq[i];
- }
-#endif /* !PCMCIA */
- ti->readlog_pending = 0;
- init_waitqueue_head(&ti->wait_for_reset);
-
- /* if PCMCIA, the card can be recognized as either TR_ISA or TR_ISAPNP
- * depending which card is inserted. */
-
-#ifndef PCMCIA
- switch (cardpresent) {
- case TR_ISA:
- if (intr == 0) irq = 9; /* irq2 really is irq9 */
- if (intr == 1) irq = 3;
- if (intr == 2) irq = 6;
- if (intr == 3) irq = 7;
- ti->adapter_int_enable = PIOaddr + ADAPTINTREL;
- break;
- case TR_MCA:
- if (intr == 0) irq = 9;
- if (intr == 1) irq = 3;
- if (intr == 2) irq = 10;
- if (intr == 3) irq = 11;
- ti->global_int_enable = 0;
- ti->adapter_int_enable = 0;
- ti->sram_phys=(__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12;
- break;
- case TR_ISAPNP:
- if (!t_irq) {
- if (intr == 0) irq = 9;
- if (intr == 1) irq = 3;
- if (intr == 2) irq = 10;
- if (intr == 3) irq = 11;
- } else
- irq=t_irq;
- timeout = jiffies + TR_SPIN_INTERVAL;
- while (!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)){
- if (!time_after(jiffies, timeout)) continue;
- DPRINTK( "Hardware timeout during initialization.\n");
- iounmap(t_mmio);
- return -ENODEV;
- }
- ti->sram_phys =
- ((__u32)readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_EVEN)<<12);
- ti->adapter_int_enable = PIOaddr + ADAPTINTREL;
- break;
- } /*end switch (cardpresent) */
-#endif /*not PCMCIA */
-
- if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
- DPRINTK("irq=%d", irq);
- printk(", sram_phys=0x%x", ti->sram_phys);
- if(ibmtr_debug_trace&TRC_INITV){ /* full chat in verbose only */
- DPRINTK(", ti->mmio=%p", ti->mmio);
- printk(", segment=%02X", segment);
- }
- printk(".\n");
- }
-
- /* Get hw address of token ring card */
- j = 0;
- for (i = 0; i < 0x18; i = i + 2) {
- /* technical reference states to do this */
- temp = readb(ti->mmio + AIP + i) & 0x0f;
- ti->hw_address[j] = temp;
- if (j & 1)
- dev->dev_addr[(j / 2)] =
- ti->hw_address[j]+ (ti->hw_address[j - 1] << 4);
- ++j;
- }
- /* get Adapter type: 'F' = Adapter/A, 'E' = 16/4 Adapter II,... */
- ti->adapter_type = readb(ti->mmio + AIPADAPTYPE);
-
- /* get Data Rate: F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */
- ti->data_rate = readb(ti->mmio + AIPDATARATE);
-
- /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */
- ti->token_release = readb(ti->mmio + AIPEARLYTOKEN);
-
- /* How much shared RAM is on adapter ? */
- if (ti->turbo) {
- ti->avail_shared_ram=127;
- } else {
- ti->avail_shared_ram = get_sram_size(ti);/*in 512 byte units */
- }
- /* We need to set or do a bunch of work here based on previous results*/
- /* Support paging? What sizes?: F=no, E=16k, D=32k, C=16 & 32k */
- ti->shared_ram_paging = readb(ti->mmio + AIPSHRAMPAGE);
-
- /* Available DHB 4Mb size: F=2048, E=4096, D=4464 */
- switch (readb(ti->mmio + AIP4MBDHB)) {
- case 0xe: ti->dhb_size4mb = 4096; break;
- case 0xd: ti->dhb_size4mb = 4464; break;
- default: ti->dhb_size4mb = 2048; break;
- }
-
- /* Available DHB 16Mb size: F=2048, E=4096, D=8192, C=16384, B=17960 */
- switch (readb(ti->mmio + AIP16MBDHB)) {
- case 0xe: ti->dhb_size16mb = 4096; break;
- case 0xd: ti->dhb_size16mb = 8192; break;
- case 0xc: ti->dhb_size16mb = 16384; break;
- case 0xb: ti->dhb_size16mb = 17960; break;
- default: ti->dhb_size16mb = 2048; break;
- }
-
- /* We must figure out how much shared memory space this adapter
- * will occupy so that if there are two adapters we can fit both
- * in. Given a choice, we will limit this adapter to 32K. The
- * maximum space will will use for two adapters is 64K so if the
- * adapter we are working on demands 64K (it also doesn't support
- * paging), then only one adapter can be supported.
- */
-
- /*
- * determine how much of total RAM is mapped into PC space
- */
- ti->mapped_ram_size= /*sixteen to onehundredtwentyeight 512byte blocks*/
- 1<< ((readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03) + 4);
- ti->page_mask = 0;
- if (ti->turbo) ti->page_mask=0xf0;
- else if (ti->shared_ram_paging == 0xf); /* No paging in adapter */
- else {
-#ifdef ENABLE_PAGING
- unsigned char pg_size = 0;
- /* BMS: page size: PCMCIA, use configuration register;
- ISAPNP, use LANAIDC config tool from www.ibm.com */
- switch (ti->shared_ram_paging) {
- case 0xf:
- break;
- case 0xe:
- ti->page_mask = (ti->mapped_ram_size == 32) ? 0xc0 : 0;
- pg_size = 32; /* 16KB page size */
- break;
- case 0xd:
- ti->page_mask = (ti->mapped_ram_size == 64) ? 0x80 : 0;
- pg_size = 64; /* 32KB page size */
- break;
- case 0xc:
- switch (ti->mapped_ram_size) {
- case 32:
- ti->page_mask = 0xc0;
- pg_size = 32;
- break;
- case 64:
- ti->page_mask = 0x80;
- pg_size = 64;
- break;
- }
- break;
- default:
- DPRINTK("Unknown shared ram paging info %01X\n",
- ti->shared_ram_paging);
- iounmap(t_mmio);
- return -ENODEV;
- break;
- } /*end switch shared_ram_paging */
-
- if (ibmtr_debug_trace & TRC_INIT)
- DPRINTK("Shared RAM paging code: %02X, "
- "mapped RAM size: %dK, shared RAM size: %dK, "
- "page mask: %02X\n:",
- ti->shared_ram_paging, ti->mapped_ram_size / 2,
- ti->avail_shared_ram / 2, ti->page_mask);
-#endif /*ENABLE_PAGING */
- }
-
-#ifndef PCMCIA
- /* finish figuring the shared RAM address */
- if (cardpresent == TR_ISA) {
- static const __u32 ram_bndry_mask[] = {
- 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000
- };
- __u32 new_base, rrr_32, chk_base, rbm;
-
- rrr_32=readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_ODD) >> 2 & 0x03;
- rbm = ram_bndry_mask[rrr_32];
- new_base = (ibmtr_mem_base + (~rbm)) & rbm;/* up to boundary */
- chk_base = new_base + (ti->mapped_ram_size << 9);
- if (chk_base > (ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE)) {
- DPRINTK("Shared RAM for this adapter (%05x) exceeds "
- "driver limit (%05x), adapter not started.\n",
- chk_base, ibmtr_mem_base + IBMTR_SHARED_RAM_SIZE);
- iounmap(t_mmio);
- return -ENODEV;
- } else { /* seems cool, record what we have figured out */
- ti->sram_base = new_base >> 12;
- ibmtr_mem_base = chk_base;
- }
- }
- else ti->sram_base = ti->sram_phys >> 12;
-
- /* The PCMCIA has already got the interrupt line and the io port,
- so no chance of anybody else getting it - MLP */
- if (request_irq(dev->irq = irq, tok_interrupt, 0, "ibmtr", dev) != 0) {
- DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",
- irq);
- iounmap(t_mmio);
- return -ENODEV;
- }
- /*?? Now, allocate some of the PIO PORTs for this driver.. */
- /* record PIOaddr range as busy */
- if (!request_region(PIOaddr, IBMTR_IO_EXTENT, "ibmtr")) {
- DPRINTK("Could not grab PIO range. Halting driver.\n");
- free_irq(dev->irq, dev);
- iounmap(t_mmio);
- return -EBUSY;
- }
-
- if (!version_printed++) {
- printk(version);
- }
-#endif /* !PCMCIA */
- DPRINTK("%s %s found\n",
- channel_def[cardpresent - 1], adapter_def(ti->adapter_type));
- DPRINTK("using irq %d, PIOaddr %hx, %dK shared RAM.\n",
- irq, PIOaddr, ti->mapped_ram_size / 2);
- DPRINTK("Hardware address : %pM\n", dev->dev_addr);
- if (ti->page_mask)
- DPRINTK("Shared RAM paging enabled. "
- "Page size: %uK Shared Ram size %dK\n",
- ((ti->page_mask^0xff)+1) >>2, ti->avail_shared_ram / 2);
- else
- DPRINTK("Shared RAM paging disabled. ti->page_mask %x\n",
- ti->page_mask);
-
- /* Calculate the maximum DHB we can use */
- /* two cases where avail_shared_ram doesn't equal mapped_ram_size:
- 1. avail_shared_ram is 127 but mapped_ram_size is 128 (typical)
- 2. user has configured adapter for less than avail_shared_ram
- but is not using paging (she should use paging, I believe)
- */
- if (!ti->page_mask) {
- ti->avail_shared_ram=
- min(ti->mapped_ram_size,ti->avail_shared_ram);
- }
-
- switch (ti->avail_shared_ram) {
- case 16: /* 8KB shared RAM */
- ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)2048);
- ti->rbuf_len4 = 1032;
- ti->rbuf_cnt4=2;
- ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)2048);
- ti->rbuf_len16 = 1032;
- ti->rbuf_cnt16=2;
- break;
- case 32: /* 16KB shared RAM */
- ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464);
- ti->rbuf_len4 = 1032;
- ti->rbuf_cnt4=4;
- ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)4096);
- ti->rbuf_len16 = 1032; /*1024 usable */
- ti->rbuf_cnt16=4;
- break;
- case 64: /* 32KB shared RAM */
- ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464);
- ti->rbuf_len4 = 1032;
- ti->rbuf_cnt4=6;
- ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)10240);
- ti->rbuf_len16 = 1032;
- ti->rbuf_cnt16=6;
- break;
- case 127: /* 63.5KB shared RAM */
- ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464);
- ti->rbuf_len4 = 1032;
- ti->rbuf_cnt4=6;
- ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)16384);
- ti->rbuf_len16 = 1032;
- ti->rbuf_cnt16=16;
- break;
- case 128: /* 64KB shared RAM */
- ti->dhb_size4mb = min(ti->dhb_size4mb, (unsigned short)4464);
- ti->rbuf_len4 = 1032;
- ti->rbuf_cnt4=6;
- ti->dhb_size16mb = min(ti->dhb_size16mb, (unsigned short)17960);
- ti->rbuf_len16 = 1032;
- ti->rbuf_cnt16=16;
- break;
- default:
- ti->dhb_size4mb = 2048;
- ti->rbuf_len4 = 1032;
- ti->rbuf_cnt4=2;
- ti->dhb_size16mb = 2048;
- ti->rbuf_len16 = 1032;
- ti->rbuf_cnt16=2;
- break;
- }
- /* this formula is not smart enough for the paging case
- ti->rbuf_cnt<x> = (ti->avail_shared_ram * BLOCKSZ - ADAPT_PRIVATE -
- ARBLENGTH - SSBLENGTH - DLC_MAX_SAP * SAPLENGTH -
- DLC_MAX_STA * STALENGTH - ti->dhb_size<x>mb * NUM_DHB -
- SRBLENGTH - ASBLENGTH) / ti->rbuf_len<x>;
- */
- ti->maxmtu16 = (ti->rbuf_len16 - 8) * ti->rbuf_cnt16 - TR_HLEN;
- ti->maxmtu4 = (ti->rbuf_len4 - 8) * ti->rbuf_cnt4 - TR_HLEN;
- /*BMS assuming 18 bytes of Routing Information (usually works) */
- DPRINTK("Maximum Receive Internet Protocol MTU 16Mbps: %d, 4Mbps: %d\n",
- ti->maxmtu16, ti->maxmtu4);
-
- dev->base_addr = PIOaddr; /* set the value for device */
- dev->mem_start = ti->sram_base << 12;
- dev->mem_end = dev->mem_start + (ti->mapped_ram_size << 9) - 1;
- trdev_init(dev);
- return 0; /* Return 0 to indicate we have found a Token Ring card. */
-} /*ibmtr_probe1() */
-
-/*****************************************************************************/
-
-/* query the adapter for the size of shared RAM */
-/* the function returns the RAM size in units of 512 bytes */
-
-static unsigned char __devinit get_sram_size(struct tok_info *adapt_info)
-{
- unsigned char avail_sram_code;
- static unsigned char size_code[] = { 0, 16, 32, 64, 127, 128 };
- /* Adapter gives
- 'F' -- use RRR bits 3,2
- 'E' -- 8kb 'D' -- 16kb
- 'C' -- 32kb 'A' -- 64KB
- 'B' - 64KB less 512 bytes at top
- (WARNING ... must zero top bytes in INIT */
-
- avail_sram_code = 0xf - readb(adapt_info->mmio + AIPAVAILSHRAM);
- if (avail_sram_code) return size_code[avail_sram_code];
- else /* for code 'F', must compute size from RRR(3,2) bits */
- return 1 <<
- ((readb(adapt_info->mmio+ACA_OFFSET+ACA_RW+RRR_ODD)>>2&3)+4);
-}
-
-/*****************************************************************************/
-
-static const struct net_device_ops trdev_netdev_ops = {
- .ndo_open = tok_open,
- .ndo_stop = tok_close,
- .ndo_start_xmit = tok_send_packet,
- .ndo_set_rx_mode = tok_set_multicast_list,
- .ndo_change_mtu = ibmtr_change_mtu,
-};
-
-static int __devinit trdev_init(struct net_device *dev)
-{
- struct tok_info *ti = netdev_priv(dev);
-
- SET_PAGE(ti->srb_page);
- ti->open_failure = NO ;
- dev->netdev_ops = &trdev_netdev_ops;
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int tok_init_card(struct net_device *dev)
-{
- struct tok_info *ti;
- short PIOaddr;
- unsigned long i;
-
- PIOaddr = dev->base_addr;
- ti = netdev_priv(dev);
- /* Special processing for first interrupt after reset */
- ti->do_tok_int = FIRST_INT;
- /* Reset adapter */
- writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
- outb(0, PIOaddr + ADAPTRESET);
-
- schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
-
- outb(0, PIOaddr + ADAPTRESETREL);
-#ifdef ENABLE_PAGING
- if (ti->page_mask)
- writeb(SRPR_ENABLE_PAGING,ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN);
-#endif
- writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
- i = sleep_on_timeout(&ti->wait_for_reset, 4 * HZ);
- return i? 0 : -EAGAIN;
-}
-
-/*****************************************************************************/
-static int tok_open(struct net_device *dev)
-{
- struct tok_info *ti = netdev_priv(dev);
- int i;
-
- /*the case we were left in a failure state during a previous open */
- if (ti->open_failure == YES) {
- DPRINTK("Last time you were disconnected, how about now?\n");
- printk("You can't insert with an ICS connector half-cocked.\n");
- }
-
- ti->open_status = CLOSED; /* CLOSED or OPEN */
- ti->sap_status = CLOSED; /* CLOSED or OPEN */
- ti->open_failure = NO; /* NO or YES */
- ti->open_mode = MANUAL; /* MANUAL or AUTOMATIC */
-
- ti->sram_phys &= ~1; /* to reverse what we do in tok_close */
- /* init the spinlock */
- spin_lock_init(&ti->lock);
- init_timer(&ti->tr_timer);
-
- i = tok_init_card(dev);
- if (i) return i;
-
- while (1){
- tok_open_adapter((unsigned long) dev);
- i= interruptible_sleep_on_timeout(&ti->wait_for_reset, 25 * HZ);
- /* sig catch: estimate opening adapter takes more than .5 sec*/
- if (i>(245*HZ)/10) break; /* fancier than if (i==25*HZ) */
- if (i==0) break;
- if (ti->open_status == OPEN && ti->sap_status==OPEN) {
- netif_start_queue(dev);
- DPRINTK("Adapter is up and running\n");
- return 0;
- }
- i=schedule_timeout_interruptible(TR_RETRY_INTERVAL);
- /* wait 30 seconds */
- if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */
- }
- outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/
- DPRINTK("TERMINATED via signal\n"); /*BMS useful */
- return -EAGAIN;
-}
-
-/*****************************************************************************/
-
-#define COMMAND_OFST 0
-#define OPEN_OPTIONS_OFST 8
-#define NUM_RCV_BUF_OFST 24
-#define RCV_BUF_LEN_OFST 26
-#define DHB_LENGTH_OFST 28
-#define NUM_DHB_OFST 30
-#define DLC_MAX_SAP_OFST 32
-#define DLC_MAX_STA_OFST 33
-
-static void tok_open_adapter(unsigned long dev_addr)
-{
- struct net_device *dev = (struct net_device *) dev_addr;
- struct tok_info *ti;
- int i;
-
- ti = netdev_priv(dev);
- SET_PAGE(ti->init_srb_page);
- writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
- for (i = 0; i < sizeof(struct dir_open_adapter); i++)
- writeb(0, ti->init_srb + i);
- writeb(DIR_OPEN_ADAPTER, ti->init_srb + COMMAND_OFST);
- writew(htons(OPEN_PASS_BCON_MAC), ti->init_srb + OPEN_OPTIONS_OFST);
- if (ti->ring_speed == 16) {
- writew(htons(ti->dhb_size16mb), ti->init_srb + DHB_LENGTH_OFST);
- writew(htons(ti->rbuf_cnt16), ti->init_srb + NUM_RCV_BUF_OFST);
- writew(htons(ti->rbuf_len16), ti->init_srb + RCV_BUF_LEN_OFST);
- } else {
- writew(htons(ti->dhb_size4mb), ti->init_srb + DHB_LENGTH_OFST);
- writew(htons(ti->rbuf_cnt4), ti->init_srb + NUM_RCV_BUF_OFST);
- writew(htons(ti->rbuf_len4), ti->init_srb + RCV_BUF_LEN_OFST);
- }
- writeb(NUM_DHB, /* always 2 */ ti->init_srb + NUM_DHB_OFST);
- writeb(DLC_MAX_SAP, ti->init_srb + DLC_MAX_SAP_OFST);
- writeb(DLC_MAX_STA, ti->init_srb + DLC_MAX_STA_OFST);
- ti->srb = ti->init_srb; /* We use this one in the interrupt handler */
- ti->srb_page = ti->init_srb_page;
- DPRINTK("Opening adapter: Xmit bfrs: %d X %d, Rcv bfrs: %d X %d\n",
- readb(ti->init_srb + NUM_DHB_OFST),
- ntohs(readw(ti->init_srb + DHB_LENGTH_OFST)),
- ntohs(readw(ti->init_srb + NUM_RCV_BUF_OFST)),
- ntohs(readw(ti->init_srb + RCV_BUF_LEN_OFST)));
- writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
- writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-}
-
-/*****************************************************************************/
-
-static void open_sap(unsigned char type, struct net_device *dev)
-{
- int i;
- struct tok_info *ti = netdev_priv(dev);
-
- SET_PAGE(ti->srb_page);
- for (i = 0; i < sizeof(struct dlc_open_sap); i++)
- writeb(0, ti->srb + i);
-
-#define MAX_I_FIELD_OFST 14
-#define SAP_VALUE_OFST 16
-#define SAP_OPTIONS_OFST 17
-#define STATION_COUNT_OFST 18
-
- writeb(DLC_OPEN_SAP, ti->srb + COMMAND_OFST);
- writew(htons(MAX_I_FIELD), ti->srb + MAX_I_FIELD_OFST);
- writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, ti->srb+ SAP_OPTIONS_OFST);
- writeb(SAP_OPEN_STATION_CNT, ti->srb + STATION_COUNT_OFST);
- writeb(type, ti->srb + SAP_VALUE_OFST);
- writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-}
-
-
-/*****************************************************************************/
-
-static void tok_set_multicast_list(struct net_device *dev)
-{
- struct tok_info *ti = netdev_priv(dev);
- struct netdev_hw_addr *ha;
- unsigned char address[4];
-
- int i;
-
- /*BMS the next line is CRUCIAL or you may be sad when you */
- /*BMS ifconfig tr down or hot unplug a PCMCIA card ??hownowbrowncow*/
- if (/*BMSHELPdev->start == 0 ||*/ ti->open_status != OPEN) return;
- address[0] = address[1] = address[2] = address[3] = 0;
- netdev_for_each_mc_addr(ha, dev) {
- address[0] |= ha->addr[2];
- address[1] |= ha->addr[3];
- address[2] |= ha->addr[4];
- address[3] |= ha->addr[5];
- }
- SET_PAGE(ti->srb_page);
- for (i = 0; i < sizeof(struct srb_set_funct_addr); i++)
- writeb(0, ti->srb + i);
-
-#define FUNCT_ADDRESS_OFST 6
-
- writeb(DIR_SET_FUNC_ADDR, ti->srb + COMMAND_OFST);
- for (i = 0; i < 4; i++)
- writeb(address[i], ti->srb + FUNCT_ADDRESS_OFST + i);
- writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-#if TR_VERBOSE
- DPRINTK("Setting functional address: ");
- for (i=0;i<4;i++) printk("%02X ", address[i]);
- printk("\n");
-#endif
-}
-
-/*****************************************************************************/
-
-#define STATION_ID_OFST 4
-
-static netdev_tx_t tok_send_packet(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct tok_info *ti;
- unsigned long flags;
- ti = netdev_priv(dev);
-
- netif_stop_queue(dev);
-
- /* lock against other CPUs */
- spin_lock_irqsave(&(ti->lock), flags);
-
- /* Save skb; we'll need it when the adapter asks for the data */
- ti->current_skb = skb;
- SET_PAGE(ti->srb_page);
- writeb(XMIT_UI_FRAME, ti->srb + COMMAND_OFST);
- writew(ti->exsap_station_id, ti->srb + STATION_ID_OFST);
- writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- spin_unlock_irqrestore(&(ti->lock), flags);
- return NETDEV_TX_OK;
-}
-
-/*****************************************************************************/
-
-static int tok_close(struct net_device *dev)
-{
- struct tok_info *ti = netdev_priv(dev);
-
- /* Important for PCMCIA hot unplug, otherwise, we'll pull the card, */
- /* unloading the module from memory, and then if a timer pops, ouch */
- del_timer_sync(&ti->tr_timer);
- outb(0, dev->base_addr + ADAPTRESET);
- ti->sram_phys |= 1;
- ti->open_status = CLOSED;
-
- netif_stop_queue(dev);
- DPRINTK("Adapter is closed.\n");
- return 0;
-}
-
-/*****************************************************************************/
-
-#define RETCODE_OFST 2
-#define OPEN_ERROR_CODE_OFST 6
-#define ASB_ADDRESS_OFST 8
-#define SRB_ADDRESS_OFST 10
-#define ARB_ADDRESS_OFST 12
-#define SSB_ADDRESS_OFST 14
-
-static char *printphase[]= {"Lobe media test","Physical insertion",
- "Address verification","Roll call poll","Request Parameters"};
-static char *printerror[]={"Function failure","Signal loss","Reserved",
- "Frequency error","Timeout","Ring failure","Ring beaconing",
- "Duplicate node address",
- "Parameter request-retry count exceeded","Remove received",
- "IMPL force received","Duplicate modifier",
- "No monitor detected","Monitor contention failed for RPL"};
-
-static void __iomem *map_address(struct tok_info *ti, unsigned index, __u8 *page)
-{
- if (ti->page_mask) {
- *page = (index >> 8) & ti->page_mask;
- index &= ~(ti->page_mask << 8);
- }
- return ti->sram_virt + index;
-}
-
-static void dir_open_adapter (struct net_device *dev)
-{
- struct tok_info *ti = netdev_priv(dev);
- unsigned char ret_code;
- __u16 err;
-
- ti->srb = map_address(ti,
- ntohs(readw(ti->init_srb + SRB_ADDRESS_OFST)),
- &ti->srb_page);
- ti->ssb = map_address(ti,
- ntohs(readw(ti->init_srb + SSB_ADDRESS_OFST)),
- &ti->ssb_page);
- ti->arb = map_address(ti,
- ntohs(readw(ti->init_srb + ARB_ADDRESS_OFST)),
- &ti->arb_page);
- ti->asb = map_address(ti,
- ntohs(readw(ti->init_srb + ASB_ADDRESS_OFST)),
- &ti->asb_page);
- ti->current_skb = NULL;
- ret_code = readb(ti->init_srb + RETCODE_OFST);
- err = ntohs(readw(ti->init_srb + OPEN_ERROR_CODE_OFST));
- if (!ret_code) {
- ti->open_status = OPEN; /* TR adapter is now available */
- if (ti->open_mode == AUTOMATIC) {
- DPRINTK("Adapter reopened.\n");
- }
- writeb(~SRB_RESP_INT, ti->mmio+ACA_OFFSET+ACA_RESET+ISRP_ODD);
- open_sap(EXTENDED_SAP, dev);
- return;
- }
- ti->open_failure = YES;
- if (ret_code == 7){
- if (err == 0x24) {
- if (!ti->auto_speedsave) {
- DPRINTK("Open failed: Adapter speed must match "
- "ring speed if Automatic Ring Speed Save is "
- "disabled.\n");
- ti->open_action = FAIL;
- }else
- DPRINTK("Retrying open to adjust to "
- "ring speed, ");
- } else if (err == 0x2d) {
- DPRINTK("Physical Insertion: No Monitor Detected, ");
- printk("retrying after %ds delay...\n",
- TR_RETRY_INTERVAL/HZ);
- } else if (err == 0x11) {
- DPRINTK("Lobe Media Function Failure (0x11), ");
- printk(" retrying after %ds delay...\n",
- TR_RETRY_INTERVAL/HZ);
- } else {
- char **prphase = printphase;
- char **prerror = printerror;
- int pnr = err / 16 - 1;
- int enr = err % 16 - 1;
- DPRINTK("TR Adapter misc open failure, error code = ");
- if (pnr < 0 || pnr >= ARRAY_SIZE(printphase) ||
- enr < 0 ||
- enr >= ARRAY_SIZE(printerror))
- printk("0x%x, invalid Phase/Error.", err);
- else
- printk("0x%x, Phase: %s, Error: %s\n", err,
- prphase[pnr], prerror[enr]);
- printk(" retrying after %ds delay...\n",
- TR_RETRY_INTERVAL/HZ);
- }
- } else DPRINTK("open failed: ret_code = %02X..., ", ret_code);
- if (ti->open_action != FAIL) {
- if (ti->open_mode==AUTOMATIC){
- ti->open_action = REOPEN;
- ibmtr_reset_timer(&(ti->tr_timer), dev);
- return;
- }
- wake_up(&ti->wait_for_reset);
- return;
- }
- DPRINTK("FAILURE, CAPUT\n");
-}
-
-/******************************************************************************/
-
-static irqreturn_t tok_interrupt(int irq, void *dev_id)
-{
- unsigned char status;
- /* unsigned char status_even ; */
- struct tok_info *ti;
- struct net_device *dev;
-#ifdef ENABLE_PAGING
- unsigned char save_srpr;
-#endif
-
- dev = dev_id;
-#if TR_VERBOSE
- DPRINTK("Int from tok_driver, dev : %p irq%d\n", dev,irq);
-#endif
- ti = netdev_priv(dev);
- if (ti->sram_phys & 1)
- return IRQ_NONE; /* PCMCIA card extraction flag */
- spin_lock(&(ti->lock));
-#ifdef ENABLE_PAGING
- save_srpr = readb(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
-#endif
-
- /* Disable interrupts till processing is finished */
- writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
-
- /* Reset interrupt for ISA boards */
- if (ti->adapter_int_enable)
- outb(0, ti->adapter_int_enable);
- else /* used for PCMCIA cards */
- outb(0, ti->global_int_enable);
- if (ti->do_tok_int == FIRST_INT){
- initial_tok_int(dev);
-#ifdef ENABLE_PAGING
- writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
-#endif
- spin_unlock(&(ti->lock));
- return IRQ_HANDLED;
- }
- /* Begin interrupt handler HERE inline to avoid the extra
- levels of logic and call depth for the original solution. */
- status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
- /*BMSstatus_even = readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) */
- /*BMSdebugprintk("tok_interrupt: ISRP_ODD = 0x%x ISRP_EVEN = 0x%x\n", */
- /*BMS status,status_even); */
-
- if (status & ADAP_CHK_INT) {
- int i;
- void __iomem *check_reason;
- __u8 check_reason_page = 0;
- check_reason = map_address(ti,
- ntohs(readw(ti->mmio+ ACA_OFFSET+ACA_RW + WWCR_EVEN)),
- &check_reason_page);
- SET_PAGE(check_reason_page);
-
- DPRINTK("Adapter check interrupt\n");
- DPRINTK("8 reason bytes follow: ");
- for (i = 0; i < 8; i++, check_reason++)
- printk("%02X ", (int) readb(check_reason));
- printk("\n");
- writeb(~ADAP_CHK_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD);
- status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRA_EVEN);
- DPRINTK("ISRA_EVEN == 0x02%x\n",status);
- ti->open_status = CLOSED;
- ti->sap_status = CLOSED;
- ti->open_mode = AUTOMATIC;
- netif_carrier_off(dev);
- netif_stop_queue(dev);
- ti->open_action = RESTART;
- outb(0, dev->base_addr + ADAPTRESET);
- ibmtr_reset_timer(&(ti->tr_timer), dev);/*BMS try to reopen*/
- spin_unlock(&(ti->lock));
- return IRQ_HANDLED;
- }
- if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)
- & (TCR_INT | ERR_INT | ACCESS_INT)) {
- DPRINTK("adapter error: ISRP_EVEN : %02x\n",
- (int)readb(ti->mmio+ ACA_OFFSET + ACA_RW + ISRP_EVEN));
- writeb(~(TCR_INT | ERR_INT | ACCESS_INT),
- ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
- status= readb(ti->mmio+ ACA_OFFSET + ACA_RW + ISRA_EVEN);/*BMS*/
- DPRINTK("ISRA_EVEN == 0x02%x\n",status);/*BMS*/
- writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
-#ifdef ENABLE_PAGING
- writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
-#endif
- spin_unlock(&(ti->lock));
- return IRQ_HANDLED;
- }
- if (status & SRB_RESP_INT) { /* SRB response */
- SET_PAGE(ti->srb_page);
-#if TR_VERBOSE
- DPRINTK("SRB resp: cmd=%02X rsp=%02X\n",
- readb(ti->srb), readb(ti->srb + RETCODE_OFST));
-#endif
- switch (readb(ti->srb)) { /* SRB command check */
- case XMIT_DIR_FRAME:{
- unsigned char xmit_ret_code;
- xmit_ret_code = readb(ti->srb + RETCODE_OFST);
- if (xmit_ret_code == 0xff) break;
- DPRINTK("error on xmit_dir_frame request: %02X\n",
- xmit_ret_code);
- if (ti->current_skb) {
- dev_kfree_skb_irq(ti->current_skb);
- ti->current_skb = NULL;
- }
- /*dev->tbusy = 0;*/
- netif_wake_queue(dev);
- if (ti->readlog_pending)
- ibmtr_readlog(dev);
- break;
- }
- case XMIT_UI_FRAME:{
- unsigned char xmit_ret_code;
-
- xmit_ret_code = readb(ti->srb + RETCODE_OFST);
- if (xmit_ret_code == 0xff) break;
- DPRINTK("error on xmit_ui_frame request: %02X\n",
- xmit_ret_code);
- if (ti->current_skb) {
- dev_kfree_skb_irq(ti->current_skb);
- ti->current_skb = NULL;
- }
- netif_wake_queue(dev);
- if (ti->readlog_pending)
- ibmtr_readlog(dev);
- break;
- }
- case DIR_OPEN_ADAPTER:
- dir_open_adapter(dev);
- break;
- case DLC_OPEN_SAP:
- if (readb(ti->srb + RETCODE_OFST)) {
- DPRINTK("open_sap failed: ret_code = %02X, "
- "retrying\n",
- (int) readb(ti->srb + RETCODE_OFST));
- ti->open_action = REOPEN;
- ibmtr_reset_timer(&(ti->tr_timer), dev);
- break;
- }
- ti->exsap_station_id = readw(ti->srb + STATION_ID_OFST);
- ti->sap_status = OPEN;/* TR adapter is now available */
- if (ti->open_mode==MANUAL){
- wake_up(&ti->wait_for_reset);
- break;
- }
- netif_wake_queue(dev);
- netif_carrier_on(dev);
- break;
- case DIR_INTERRUPT:
- case DIR_MOD_OPEN_PARAMS:
- case DIR_SET_GRP_ADDR:
- case DIR_SET_FUNC_ADDR:
- case DLC_CLOSE_SAP:
- if (readb(ti->srb + RETCODE_OFST))
- DPRINTK("error on %02X: %02X\n",
- (int) readb(ti->srb + COMMAND_OFST),
- (int) readb(ti->srb + RETCODE_OFST));
- break;
- case DIR_READ_LOG:
- if (readb(ti->srb + RETCODE_OFST)){
- DPRINTK("error on dir_read_log: %02X\n",
- (int) readb(ti->srb + RETCODE_OFST));
- netif_wake_queue(dev);
- break;
- }
-#if IBMTR_DEBUG_MESSAGES
-
-#define LINE_ERRORS_OFST 0
-#define INTERNAL_ERRORS_OFST 1
-#define BURST_ERRORS_OFST 2
-#define AC_ERRORS_OFST 3
-#define ABORT_DELIMITERS_OFST 4
-#define LOST_FRAMES_OFST 6
-#define RECV_CONGEST_COUNT_OFST 7
-#define FRAME_COPIED_ERRORS_OFST 8
-#define FREQUENCY_ERRORS_OFST 9
-#define TOKEN_ERRORS_OFST 10
-
- DPRINTK("Line errors %02X, Internal errors %02X, "
- "Burst errors %02X\n" "A/C errors %02X, "
- "Abort delimiters %02X, Lost frames %02X\n"
- "Receive congestion count %02X, "
- "Frame copied errors %02X\nFrequency errors %02X, "
- "Token errors %02X\n",
- (int) readb(ti->srb + LINE_ERRORS_OFST),
- (int) readb(ti->srb + INTERNAL_ERRORS_OFST),
- (int) readb(ti->srb + BURST_ERRORS_OFST),
- (int) readb(ti->srb + AC_ERRORS_OFST),
- (int) readb(ti->srb + ABORT_DELIMITERS_OFST),
- (int) readb(ti->srb + LOST_FRAMES_OFST),
- (int) readb(ti->srb + RECV_CONGEST_COUNT_OFST),
- (int) readb(ti->srb + FRAME_COPIED_ERRORS_OFST),
- (int) readb(ti->srb + FREQUENCY_ERRORS_OFST),
- (int) readb(ti->srb + TOKEN_ERRORS_OFST));
-#endif
- netif_wake_queue(dev);
- break;
- default:
- DPRINTK("Unknown command %02X encountered\n",
- (int) readb(ti->srb));
- } /* end switch SRB command check */
- writeb(~SRB_RESP_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD);
- } /* if SRB response */
- if (status & ASB_FREE_INT) { /* ASB response */
- SET_PAGE(ti->asb_page);
-#if TR_VERBOSE
- DPRINTK("ASB resp: cmd=%02X\n", readb(ti->asb));
-#endif
-
- switch (readb(ti->asb)) { /* ASB command check */
- case REC_DATA:
- case XMIT_UI_FRAME:
- case XMIT_DIR_FRAME:
- break;
- default:
- DPRINTK("unknown command in asb %02X\n",
- (int) readb(ti->asb));
- } /* switch ASB command check */
- if (readb(ti->asb + 2) != 0xff) /* checks ret_code */
- DPRINTK("ASB error %02X in cmd %02X\n",
- (int) readb(ti->asb + 2), (int) readb(ti->asb));
- writeb(~ASB_FREE_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD);
- } /* if ASB response */
-
-#define STATUS_OFST 6
-#define NETW_STATUS_OFST 6
-
- if (status & ARB_CMD_INT) { /* ARB response */
- SET_PAGE(ti->arb_page);
-#if TR_VERBOSE
- DPRINTK("ARB resp: cmd=%02X\n", readb(ti->arb));
-#endif
-
- switch (readb(ti->arb)) { /* ARB command check */
- case DLC_STATUS:
- DPRINTK("DLC_STATUS new status: %02X on station %02X\n",
- ntohs(readw(ti->arb + STATUS_OFST)),
- ntohs(readw(ti->arb+ STATION_ID_OFST)));
- break;
- case REC_DATA:
- tr_rx(dev);
- break;
- case RING_STAT_CHANGE:{
- unsigned short ring_status;
- ring_status= ntohs(readw(ti->arb + NETW_STATUS_OFST));
- if (ibmtr_debug_trace & TRC_INIT)
- DPRINTK("Ring Status Change...(0x%x)\n",
- ring_status);
- if(ring_status& (REMOVE_RECV|AUTO_REMOVAL|LOBE_FAULT)){
- netif_stop_queue(dev);
- netif_carrier_off(dev);
- DPRINTK("Remove received, or Auto-removal error"
- ", or Lobe fault\n");
- DPRINTK("We'll try to reopen the closed adapter"
- " after a %d second delay.\n",
- TR_RETRY_INTERVAL/HZ);
- /*I was confused: I saw the TR reopening but */
- /*forgot:with an RJ45 in an RJ45/ICS adapter */
- /*but adapter not in the ring, the TR will */
- /* open, and then soon close and come here. */
- ti->open_mode = AUTOMATIC;
- ti->open_status = CLOSED; /*12/2000 BMS*/
- ti->open_action = REOPEN;
- ibmtr_reset_timer(&(ti->tr_timer), dev);
- } else if (ring_status & LOG_OVERFLOW) {
- if(netif_queue_stopped(dev))
- ti->readlog_pending = 1;
- else
- ibmtr_readlog(dev);
- }
- break;
- }
- case XMIT_DATA_REQ:
- tr_tx(dev);
- break;
- default:
- DPRINTK("Unknown command %02X in arb\n",
- (int) readb(ti->arb));
- break;
- } /* switch ARB command check */
- writeb(~ARB_CMD_INT, ti->mmio+ ACA_OFFSET+ACA_RESET + ISRP_ODD);
- writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- } /* if ARB response */
- if (status & SSB_RESP_INT) { /* SSB response */
- unsigned char retcode;
- SET_PAGE(ti->ssb_page);
-#if TR_VERBOSE
- DPRINTK("SSB resp: cmd=%02X rsp=%02X\n",
- readb(ti->ssb), readb(ti->ssb + 2));
-#endif
-
- switch (readb(ti->ssb)) { /* SSB command check */
- case XMIT_DIR_FRAME:
- case XMIT_UI_FRAME:
- retcode = readb(ti->ssb + 2);
- if (retcode && (retcode != 0x22))/* checks ret_code */
- DPRINTK("xmit ret_code: %02X xmit error code: "
- "%02X\n",
- (int)retcode, (int)readb(ti->ssb + 6));
- else
- dev->stats.tx_packets++;
- break;
- case XMIT_XID_CMD:
- DPRINTK("xmit xid ret_code: %02X\n",
- (int) readb(ti->ssb + 2));
- default:
- DPRINTK("Unknown command %02X in ssb\n",
- (int) readb(ti->ssb));
- } /* SSB command check */
- writeb(~SSB_RESP_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD);
- writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- } /* if SSB response */
-#ifdef ENABLE_PAGING
- writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
-#endif
- writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
- spin_unlock(&(ti->lock));
- return IRQ_HANDLED;
-} /*tok_interrupt */
-
-/*****************************************************************************/
-
-#define INIT_STATUS_OFST 1
-#define INIT_STATUS_2_OFST 2
-#define ENCODED_ADDRESS_OFST 8
-
-static void initial_tok_int(struct net_device *dev)
-{
-
- __u32 encoded_addr, hw_encoded_addr;
- struct tok_info *ti;
- unsigned char init_status; /*BMS 12/2000*/
-
- ti = netdev_priv(dev);
-
- ti->do_tok_int = NOT_FIRST;
-
- /* we assign the shared-ram address for ISA devices */
- writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);
-#ifndef PCMCIA
- ti->sram_virt = ioremap(((__u32)ti->sram_base << 12), ti->avail_shared_ram);
-#endif
- ti->init_srb = map_address(ti,
- ntohs(readw(ti->mmio + ACA_OFFSET + WRBR_EVEN)),
- &ti->init_srb_page);
- if (ti->page_mask && ti->avail_shared_ram == 127) {
- void __iomem *last_512;
- __u8 last_512_page=0;
- int i;
- last_512 = map_address(ti, 0xfe00, &last_512_page);
- /* initialize high section of ram (if necessary) */
- SET_PAGE(last_512_page);
- for (i = 0; i < 512; i++)
- writeb(0, last_512 + i);
- }
- SET_PAGE(ti->init_srb_page);
-
-#if TR_VERBOSE
- {
- int i;
-
- DPRINTK("ti->init_srb_page=0x%x\n", ti->init_srb_page);
- DPRINTK("init_srb(%p):", ti->init_srb );
- for (i = 0; i < 20; i++)
- printk("%02X ", (int) readb(ti->init_srb + i));
- printk("\n");
- }
-#endif
-
- hw_encoded_addr = readw(ti->init_srb + ENCODED_ADDRESS_OFST);
- encoded_addr = ntohs(hw_encoded_addr);
- init_status= /*BMS 12/2000 check for shallow mode possibility (Turbo)*/
- readb(ti->init_srb+offsetof(struct srb_init_response,init_status));
- /*printk("Initial interrupt: init_status= 0x%02x\n",init_status);*/
- ti->ring_speed = init_status & 0x01 ? 16 : 4;
- DPRINTK("Initial interrupt : %d Mbps, shared RAM base %08x.\n",
- ti->ring_speed, (unsigned int)dev->mem_start);
- ti->auto_speedsave = (readb(ti->init_srb+INIT_STATUS_2_OFST) & 4) != 0;
-
- if (ti->open_mode == MANUAL) wake_up(&ti->wait_for_reset);
- else tok_open_adapter((unsigned long)dev);
-
-} /*initial_tok_int() */
-
-/*****************************************************************************/
-
-#define CMD_CORRELATE_OFST 1
-#define DHB_ADDRESS_OFST 6
-
-#define FRAME_LENGTH_OFST 6
-#define HEADER_LENGTH_OFST 8
-#define RSAP_VALUE_OFST 9
-
-static void tr_tx(struct net_device *dev)
-{
- struct tok_info *ti = netdev_priv(dev);
- struct trh_hdr *trhdr = (struct trh_hdr *) ti->current_skb->data;
- unsigned int hdr_len;
- __u32 dhb=0,dhb_base;
- void __iomem *dhbuf = NULL;
- unsigned char xmit_command;
- int i,dhb_len=0x4000,src_len,src_offset;
- struct trllc *llc;
- struct srb_xmit xsrb;
- __u8 dhb_page = 0;
- __u8 llc_ssap;
-
- SET_PAGE(ti->asb_page);
-
- if (readb(ti->asb+RETCODE_OFST) != 0xFF) DPRINTK("ASB not free !!!\n");
-
- /* in providing the transmit interrupts, is telling us it is ready for
- data and providing a shared memory address for us to stuff with data.
- Here we compute the effective address where we will place data.
- */
- SET_PAGE(ti->arb_page);
- dhb=dhb_base=ntohs(readw(ti->arb + DHB_ADDRESS_OFST));
- if (ti->page_mask) {
- dhb_page = (dhb_base >> 8) & ti->page_mask;
- dhb=dhb_base & ~(ti->page_mask << 8);
- }
- dhbuf = ti->sram_virt + dhb;
-
- /* Figure out the size of the 802.5 header */
- if (!(trhdr->saddr[0] & 0x80)) /* RIF present? */
- hdr_len = sizeof(struct trh_hdr) - TR_MAXRIFLEN;
- else
- hdr_len = ((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK) >> 8)
- + sizeof(struct trh_hdr) - TR_MAXRIFLEN;
-
- llc = (struct trllc *) (ti->current_skb->data + hdr_len);
-
- llc_ssap = llc->ssap;
- SET_PAGE(ti->srb_page);
- memcpy_fromio(&xsrb, ti->srb, sizeof(xsrb));
- SET_PAGE(ti->asb_page);
- xmit_command = xsrb.command;
-
- writeb(xmit_command, ti->asb + COMMAND_OFST);
- writew(xsrb.station_id, ti->asb + STATION_ID_OFST);
- writeb(llc_ssap, ti->asb + RSAP_VALUE_OFST);
- writeb(xsrb.cmd_corr, ti->asb + CMD_CORRELATE_OFST);
- writeb(0, ti->asb + RETCODE_OFST);
- if ((xmit_command == XMIT_XID_CMD) || (xmit_command == XMIT_TEST_CMD)) {
- writew(htons(0x11), ti->asb + FRAME_LENGTH_OFST);
- writeb(0x0e, ti->asb + HEADER_LENGTH_OFST);
- SET_PAGE(dhb_page);
- writeb(AC, dhbuf);
- writeb(LLC_FRAME, dhbuf + 1);
- for (i = 0; i < TR_ALEN; i++)
- writeb((int) 0x0FF, dhbuf + i + 2);
- for (i = 0; i < TR_ALEN; i++)
- writeb(0, dhbuf + i + TR_ALEN + 2);
- writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- return;
- }
- /*
- * the token ring packet is copied from sk_buff to the adapter
- * buffer identified in the command data received with the interrupt.
- */
- writeb(hdr_len, ti->asb + HEADER_LENGTH_OFST);
- writew(htons(ti->current_skb->len), ti->asb + FRAME_LENGTH_OFST);
- src_len=ti->current_skb->len;
- src_offset=0;
- dhb=dhb_base;
- while(1) {
- if (ti->page_mask) {
- dhb_page=(dhb >> 8) & ti->page_mask;
- dhb=dhb & ~(ti->page_mask << 8);
- dhb_len=0x4000-dhb; /* remaining size of this page */
- }
- dhbuf = ti->sram_virt + dhb;
- SET_PAGE(dhb_page);
- if (src_len > dhb_len) {
- memcpy_toio(dhbuf,&ti->current_skb->data[src_offset],
- dhb_len);
- src_len -= dhb_len;
- src_offset += dhb_len;
- dhb_base+=dhb_len;
- dhb=dhb_base;
- continue;
- }
- memcpy_toio(dhbuf, &ti->current_skb->data[src_offset], src_len);
- break;
- }
- writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- dev->stats.tx_bytes += ti->current_skb->len;
- dev_kfree_skb_irq(ti->current_skb);
- ti->current_skb = NULL;
- netif_wake_queue(dev);
- if (ti->readlog_pending)
- ibmtr_readlog(dev);
-} /*tr_tx */
-
-/*****************************************************************************/
-
-
-#define RECEIVE_BUFFER_OFST 6
-#define LAN_HDR_LENGTH_OFST 8
-#define DLC_HDR_LENGTH_OFST 9
-
-#define DSAP_OFST 0
-#define SSAP_OFST 1
-#define LLC_OFST 2
-#define PROTID_OFST 3
-#define ETHERTYPE_OFST 6
-
-static void tr_rx(struct net_device *dev)
-{
- struct tok_info *ti = netdev_priv(dev);
- __u32 rbuffer;
- void __iomem *rbuf, *rbufdata, *llc;
- __u8 rbuffer_page = 0;
- unsigned char *data;
- unsigned int rbuffer_len, lan_hdr_len, hdr_len, ip_len, length;
- unsigned char dlc_hdr_len;
- struct sk_buff *skb;
- unsigned int skb_size = 0;
- int IPv4_p = 0;
- unsigned int chksum = 0;
- struct iphdr *iph;
- struct arb_rec_req rarb;
-
- SET_PAGE(ti->arb_page);
- memcpy_fromio(&rarb, ti->arb, sizeof(rarb));
- rbuffer = ntohs(rarb.rec_buf_addr) ;
- rbuf = map_address(ti, rbuffer, &rbuffer_page);
-
- SET_PAGE(ti->asb_page);
-
- if (readb(ti->asb + RETCODE_OFST) !=0xFF) DPRINTK("ASB not free !!!\n");
-
- writeb(REC_DATA, ti->asb + COMMAND_OFST);
- writew(rarb.station_id, ti->asb + STATION_ID_OFST);
- writew(rarb.rec_buf_addr, ti->asb + RECEIVE_BUFFER_OFST);
-
- lan_hdr_len = rarb.lan_hdr_len;
- if (lan_hdr_len > sizeof(struct trh_hdr)) {
- DPRINTK("Linux cannot handle greater than 18 bytes RIF\n");
- return;
- } /*BMS I added this above just to be very safe */
- dlc_hdr_len = readb(ti->arb + DLC_HDR_LENGTH_OFST);
- hdr_len = lan_hdr_len + sizeof(struct trllc) + sizeof(struct iphdr);
-
- SET_PAGE(rbuffer_page);
- llc = rbuf + offsetof(struct rec_buf, data) + lan_hdr_len;
-
-#if TR_VERBOSE
- DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",
- (__u32) offsetof(struct rec_buf, data), (unsigned int) lan_hdr_len);
- DPRINTK("llc: %08X rec_buf_addr: %04X dev->mem_start: %lX\n",
- llc, ntohs(rarb.rec_buf_addr), dev->mem_start);
- DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, "
- "ethertype: %04X\n",
- (int) readb(llc + DSAP_OFST), (int) readb(llc + SSAP_OFST),
- (int) readb(llc + LLC_OFST), (int) readb(llc + PROTID_OFST),
- (int) readb(llc+PROTID_OFST+1),(int)readb(llc+PROTID_OFST + 2),
- (int) ntohs(readw(llc + ETHERTYPE_OFST)));
-#endif
- if (readb(llc + offsetof(struct trllc, llc)) != UI_CMD) {
- SET_PAGE(ti->asb_page);
- writeb(DATA_LOST, ti->asb + RETCODE_OFST);
- dev->stats.rx_dropped++;
- writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- return;
- }
- length = ntohs(rarb.frame_len);
- if (readb(llc + DSAP_OFST) == EXTENDED_SAP &&
- readb(llc + SSAP_OFST) == EXTENDED_SAP &&
- length >= hdr_len) IPv4_p = 1;
-#if TR_VERBOSE
-#define SADDR_OFST 8
-#define DADDR_OFST 2
-
- if (!IPv4_p) {
-
- void __iomem *trhhdr = rbuf + offsetof(struct rec_buf, data);
- u8 saddr[6];
- u8 daddr[6];
- int i;
- for (i = 0 ; i < 6 ; i++)
- saddr[i] = readb(trhhdr + SADDR_OFST + i);
- for (i = 0 ; i < 6 ; i++)
- daddr[i] = readb(trhhdr + DADDR_OFST + i);
- DPRINTK("Probably non-IP frame received.\n");
- DPRINTK("ssap: %02X dsap: %02X "
- "saddr: %pM daddr: %pM\n",
- readb(llc + SSAP_OFST), readb(llc + DSAP_OFST),
- saddr, daddr);
- }
-#endif
-
- /*BMS handle the case she comes in with few hops but leaves with many */
- skb_size=length-lan_hdr_len+sizeof(struct trh_hdr)+sizeof(struct trllc);
-
- if (!(skb = dev_alloc_skb(skb_size))) {
- DPRINTK("out of memory. frame dropped.\n");
- dev->stats.rx_dropped++;
- SET_PAGE(ti->asb_page);
- writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
- writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- return;
- }
- /*BMS again, if she comes in with few but leaves with many */
- skb_reserve(skb, sizeof(struct trh_hdr) - lan_hdr_len);
- skb_put(skb, length);
- data = skb->data;
- rbuffer_len = ntohs(readw(rbuf + offsetof(struct rec_buf, buf_len)));
- rbufdata = rbuf + offsetof(struct rec_buf, data);
-
- if (IPv4_p) {
- /* Copy the headers without checksumming */
- memcpy_fromio(data, rbufdata, hdr_len);
-
- /* Watch for padded packets and bogons */
- iph= (struct iphdr *)(data+ lan_hdr_len + sizeof(struct trllc));
- ip_len = ntohs(iph->tot_len) - sizeof(struct iphdr);
- length -= hdr_len;
- if ((ip_len <= length) && (ip_len > 7))
- length = ip_len;
- data += hdr_len;
- rbuffer_len -= hdr_len;
- rbufdata += hdr_len;
- }
- /* Copy the payload... */
-#define BUFFER_POINTER_OFST 2
-#define BUFFER_LENGTH_OFST 6
- for (;;) {
- if (ibmtr_debug_trace&TRC_INITV && length < rbuffer_len)
- DPRINTK("CURIOUS, length=%d < rbuffer_len=%d\n",
- length,rbuffer_len);
- if (IPv4_p)
- chksum=csum_partial_copy_nocheck((void*)rbufdata,
- data,length<rbuffer_len?length:rbuffer_len,chksum);
- else
- memcpy_fromio(data, rbufdata, rbuffer_len);
- rbuffer = ntohs(readw(rbuf+BUFFER_POINTER_OFST)) ;
- if (!rbuffer)
- break;
- rbuffer -= 2;
- length -= rbuffer_len;
- data += rbuffer_len;
- rbuf = map_address(ti, rbuffer, &rbuffer_page);
- SET_PAGE(rbuffer_page);
- rbuffer_len = ntohs(readw(rbuf + BUFFER_LENGTH_OFST));
- rbufdata = rbuf + offsetof(struct rec_buf, data);
- }
-
- SET_PAGE(ti->asb_page);
- writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
-
- writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-
- dev->stats.rx_bytes += skb->len;
- dev->stats.rx_packets++;
-
- skb->protocol = tr_type_trans(skb, dev);
- if (IPv4_p) {
- skb->csum = chksum;
- skb->ip_summed = CHECKSUM_COMPLETE;
- }
- netif_rx(skb);
-} /*tr_rx */
-
-/*****************************************************************************/
-
-static void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev)
-{
- tmr->expires = jiffies + TR_RETRY_INTERVAL;
- tmr->data = (unsigned long) dev;
- tmr->function = tok_rerun;
- init_timer(tmr);
- add_timer(tmr);
-}
-
-/*****************************************************************************/
-
-static void tok_rerun(unsigned long dev_addr)
-{
- struct net_device *dev = (struct net_device *)dev_addr;
- struct tok_info *ti = netdev_priv(dev);
-
- if ( ti->open_action == RESTART){
- ti->do_tok_int = FIRST_INT;
- outb(0, dev->base_addr + ADAPTRESETREL);
-#ifdef ENABLE_PAGING
- if (ti->page_mask)
- writeb(SRPR_ENABLE_PAGING,
- ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
-#endif
-
- writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
- } else
- tok_open_adapter(dev_addr);
-}
-
-/*****************************************************************************/
-
-static void ibmtr_readlog(struct net_device *dev)
-{
- struct tok_info *ti;
-
- ti = netdev_priv(dev);
-
- ti->readlog_pending = 0;
- SET_PAGE(ti->srb_page);
- writeb(DIR_READ_LOG, ti->srb);
- writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
- writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-
- netif_stop_queue(dev);
-
-}
-
-/*****************************************************************************/
-
-static int ibmtr_change_mtu(struct net_device *dev, int mtu)
-{
- struct tok_info *ti = netdev_priv(dev);
-
- if (ti->ring_speed == 16 && mtu > ti->maxmtu16)
- return -EINVAL;
- if (ti->ring_speed == 4 && mtu > ti->maxmtu4)
- return -EINVAL;
- dev->mtu = mtu;
- return 0;
-}
-
-/*****************************************************************************/
-#ifdef MODULE
-
-/* 3COM 3C619C supports 8 interrupts, 32 I/O ports */
-static struct net_device *dev_ibmtr[IBMTR_MAX_ADAPTERS];
-static int io[IBMTR_MAX_ADAPTERS] = { 0xa20, 0xa24 };
-static int irq[IBMTR_MAX_ADAPTERS];
-static int mem[IBMTR_MAX_ADAPTERS];
-
-MODULE_LICENSE("GPL");
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(mem, int, NULL, 0);
-
-static int __init ibmtr_init(void)
-{
- int i;
- int count=0;
-
- find_turbo_adapters(io);
-
- for (i = 0; i < IBMTR_MAX_ADAPTERS && io[i]; i++) {
- struct net_device *dev;
- irq[i] = 0;
- mem[i] = 0;
- dev = alloc_trdev(sizeof(struct tok_info));
- if (dev == NULL) {
- if (i == 0)
- return -ENOMEM;
- break;
- }
- dev->base_addr = io[i];
- dev->irq = irq[i];
- dev->mem_start = mem[i];
-
- if (ibmtr_probe_card(dev)) {
- free_netdev(dev);
- continue;
- }
- dev_ibmtr[i] = dev;
- count++;
- }
- if (count) return 0;
- printk("ibmtr: register_netdev() returned non-zero.\n");
- return -EIO;
-}
-module_init(ibmtr_init);
-
-static void __exit ibmtr_cleanup(void)
-{
- int i;
-
- for (i = 0; i < IBMTR_MAX_ADAPTERS; i++){
- if (!dev_ibmtr[i])
- continue;
- unregister_netdev(dev_ibmtr[i]);
- ibmtr_cleanup_card(dev_ibmtr[i]);
- free_netdev(dev_ibmtr[i]);
- }
-}
-module_exit(ibmtr_cleanup);
-#endif
diff --git a/drivers/net/tokenring/ibmtr_cs.c b/drivers/net/tokenring/ibmtr_cs.c
deleted file mode 100644
index 356e28e4881b..000000000000
--- a/drivers/net/tokenring/ibmtr_cs.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*======================================================================
-
- A PCMCIA token-ring driver for IBM-based cards
-
- This driver supports the IBM PCMCIA Token-Ring Card.
- Written by Steve Kipisz, kipisz@vnet.ibm.com or
- bungy@ibm.net
-
- Written 1995,1996.
-
- This code is based on pcnet_cs.c from David Hinds.
-
- V2.2.0 February 1999 - Mike Phillips phillim@amtrak.com
-
- Linux V2.2.x presented significant changes to the underlying
- ibmtr.c code. Mainly the code became a lot more organized and
- modular.
-
- This caused the old PCMCIA Token Ring driver to give up and go
- home early. Instead of just patching the old code to make it
- work, the PCMCIA code has been streamlined, updated and possibly
- improved.
-
- This code now only contains code required for the Card Services.
- All we do here is set the card up enough so that the real ibmtr.c
- driver can find it and work with it properly.
-
- i.e. We set up the io port, irq, mmio memory and shared ram
- memory. This enables ibmtr_probe in ibmtr.c to find the card and
- configure it as though it was a normal ISA and/or PnP card.
-
- CHANGES
-
- v2.2.5 April 1999 Mike Phillips (phillim@amtrak.com)
- Obscure bug fix, required changed to ibmtr.c not ibmtr_cs.c
-
- v2.2.7 May 1999 Mike Phillips (phillim@amtrak.com)
- Updated to version 2.2.7 to match the first version of the kernel
- that the modification to ibmtr.c were incorporated into.
-
- v2.2.17 July 2000 Burt Silverman (burts@us.ibm.com)
- Address translation feature of PCMCIA controller is usable so
- memory windows can be placed in High memory (meaning above
- 0xFFFFF.)
-
-======================================================================*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-#include <linux/ibmtr.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#define PCMCIA
-#include "ibmtr.c"
-
-
-/*====================================================================*/
-
-/* Parameters that can be set with 'insmod' */
-
-/* MMIO base address */
-static u_long mmiobase = 0xce000;
-
-/* SRAM base address */
-static u_long srambase = 0xd0000;
-
-/* SRAM size 8,16,32,64 */
-static u_long sramsize = 64;
-
-/* Ringspeed 4,16 */
-static int ringspeed = 16;
-
-module_param(mmiobase, ulong, 0);
-module_param(srambase, ulong, 0);
-module_param(sramsize, ulong, 0);
-module_param(ringspeed, int, 0);
-MODULE_LICENSE("GPL");
-
-/*====================================================================*/
-
-static int ibmtr_config(struct pcmcia_device *link);
-static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
-static void ibmtr_release(struct pcmcia_device *link);
-static void ibmtr_detach(struct pcmcia_device *p_dev);
-
-/*====================================================================*/
-
-typedef struct ibmtr_dev_t {
- struct pcmcia_device *p_dev;
- struct net_device *dev;
- struct tok_info *ti;
-} ibmtr_dev_t;
-
-static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
- ibmtr_dev_t *info = dev_id;
- struct net_device *dev = info->dev;
- return tok_interrupt(irq, dev);
-};
-
-static int __devinit ibmtr_attach(struct pcmcia_device *link)
-{
- ibmtr_dev_t *info;
- struct net_device *dev;
-
- dev_dbg(&link->dev, "ibmtr_attach()\n");
-
- /* Create new token-ring device */
- info = kzalloc(sizeof(*info), GFP_KERNEL);
- if (!info) return -ENOMEM;
- dev = alloc_trdev(sizeof(struct tok_info));
- if (!dev) {
- kfree(info);
- return -ENOMEM;
- }
-
- info->p_dev = link;
- link->priv = info;
- info->ti = netdev_priv(dev);
-
- link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
- link->resource[0]->end = 4;
- link->config_flags |= CONF_ENABLE_IRQ;
- link->config_regs = PRESENT_OPTION;
-
- info->dev = dev;
-
- return ibmtr_config(link);
-} /* ibmtr_attach */
-
-static void ibmtr_detach(struct pcmcia_device *link)
-{
- struct ibmtr_dev_t *info = link->priv;
- struct net_device *dev = info->dev;
- struct tok_info *ti = netdev_priv(dev);
-
- dev_dbg(&link->dev, "ibmtr_detach\n");
-
- /*
- * When the card removal interrupt hits tok_interrupt(),
- * bail out early, so we don't crash the machine
- */
- ti->sram_phys |= 1;
-
- unregister_netdev(dev);
-
- del_timer_sync(&(ti->tr_timer));
-
- ibmtr_release(link);
-
- free_netdev(dev);
- kfree(info);
-} /* ibmtr_detach */
-
-static int __devinit ibmtr_config(struct pcmcia_device *link)
-{
- ibmtr_dev_t *info = link->priv;
- struct net_device *dev = info->dev;
- struct tok_info *ti = netdev_priv(dev);
- int i, ret;
-
- dev_dbg(&link->dev, "ibmtr_config\n");
-
- link->io_lines = 16;
- link->config_index = 0x61;
-
- /* Determine if this is PRIMARY or ALTERNATE. */
-
- /* Try PRIMARY card at 0xA20-0xA23 */
- link->resource[0]->start = 0xA20;
- i = pcmcia_request_io(link);
- if (i != 0) {
- /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
- link->resource[0]->start = 0xA24;
- ret = pcmcia_request_io(link);
- if (ret)
- goto failed;
- }
- dev->base_addr = link->resource[0]->start;
-
- ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
- if (ret)
- goto failed;
- dev->irq = link->irq;
- ti->irq = link->irq;
- ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
-
- /* Allocate the MMIO memory window */
- link->resource[2]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
- link->resource[2]->flags |= WIN_USE_WAIT;
- link->resource[2]->start = 0;
- link->resource[2]->end = 0x2000;
- ret = pcmcia_request_window(link, link->resource[2], 250);
- if (ret)
- goto failed;
-
- ret = pcmcia_map_mem_page(link, link->resource[2], mmiobase);
- if (ret)
- goto failed;
- ti->mmio = ioremap(link->resource[2]->start,
- resource_size(link->resource[2]));
-
- /* Allocate the SRAM memory window */
- link->resource[3]->flags = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
- link->resource[3]->flags |= WIN_USE_WAIT;
- link->resource[3]->start = 0;
- link->resource[3]->end = sramsize * 1024;
- ret = pcmcia_request_window(link, link->resource[3], 250);
- if (ret)
- goto failed;
-
- ret = pcmcia_map_mem_page(link, link->resource[3], srambase);
- if (ret)
- goto failed;
-
- ti->sram_base = srambase >> 12;
- ti->sram_virt = ioremap(link->resource[3]->start,
- resource_size(link->resource[3]));
- ti->sram_phys = link->resource[3]->start;
-
- ret = pcmcia_enable_device(link);
- if (ret)
- goto failed;
-
- /* Set up the Token-Ring Controller Configuration Register and
- turn on the card. Check the "Local Area Network Credit Card
- Adapters Technical Reference" SC30-3585 for this info. */
- ibmtr_hw_setup(dev, mmiobase);
-
- SET_NETDEV_DEV(dev, &link->dev);
-
- i = ibmtr_probe_card(dev);
- if (i != 0) {
- pr_notice("register_netdev() failed\n");
- goto failed;
- }
-
- netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
- dev->base_addr, dev->irq,
- (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
- dev->dev_addr);
- return 0;
-
-failed:
- ibmtr_release(link);
- return -ENODEV;
-} /* ibmtr_config */
-
-static void ibmtr_release(struct pcmcia_device *link)
-{
- ibmtr_dev_t *info = link->priv;
- struct net_device *dev = info->dev;
-
- dev_dbg(&link->dev, "ibmtr_release\n");
-
- if (link->resource[2]->end) {
- struct tok_info *ti = netdev_priv(dev);
- iounmap(ti->mmio);
- }
- pcmcia_disable_device(link);
-}
-
-static int ibmtr_suspend(struct pcmcia_device *link)
-{
- ibmtr_dev_t *info = link->priv;
- struct net_device *dev = info->dev;
-
- if (link->open)
- netif_device_detach(dev);
-
- return 0;
-}
-
-static int __devinit ibmtr_resume(struct pcmcia_device *link)
-{
- ibmtr_dev_t *info = link->priv;
- struct net_device *dev = info->dev;
-
- if (link->open) {
- ibmtr_probe(dev); /* really? */
- netif_device_attach(dev);
- }
-
- return 0;
-}
-
-
-/*====================================================================*/
-
-static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
-{
- int i;
-
- /* Bizarre IBM behavior, there are 16 bits of information we
- need to set, but the card only allows us to send 4 bits at a
- time. For each byte sent to base_addr, bits 7-4 tell the
- card which part of the 16 bits we are setting, bits 3-0 contain
- the actual information */
-
- /* First nibble provides 4 bits of mmio */
- i = (mmiobase >> 16) & 0x0F;
- outb(i, dev->base_addr);
-
- /* Second nibble provides 3 bits of mmio */
- i = 0x10 | ((mmiobase >> 12) & 0x0E);
- outb(i, dev->base_addr);
-
- /* Third nibble, hard-coded values */
- i = 0x26;
- outb(i, dev->base_addr);
-
- /* Fourth nibble sets shared ram page size */
-
- /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */
- i = (sramsize >> 4) & 0x07;
- i = ((i == 4) ? 3 : i) << 2;
- i |= 0x30;
-
- if (ringspeed == 16)
- i |= 2;
- if (dev->base_addr == 0xA24)
- i |= 1;
- outb(i, dev->base_addr);
-
- /* 0x40 will release the card for use */
- outb(0x40, dev->base_addr);
-}
-
-static const struct pcmcia_device_id ibmtr_ids[] = {
- PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
- PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
- PCMCIA_DEVICE_NULL,
-};
-MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
-
-static struct pcmcia_driver ibmtr_cs_driver = {
- .owner = THIS_MODULE,
- .name = "ibmtr_cs",
- .probe = ibmtr_attach,
- .remove = ibmtr_detach,
- .id_table = ibmtr_ids,
- .suspend = ibmtr_suspend,
- .resume = ibmtr_resume,
-};
-
-static int __init init_ibmtr_cs(void)
-{
- return pcmcia_register_driver(&ibmtr_cs_driver);
-}
-
-static void __exit exit_ibmtr_cs(void)
-{
- pcmcia_unregister_driver(&ibmtr_cs_driver);
-}
-
-module_init(init_ibmtr_cs);
-module_exit(exit_ibmtr_cs);
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
deleted file mode 100644
index 97e4c65c1e29..000000000000
--- a/drivers/net/tokenring/lanstreamer.c
+++ /dev/null
@@ -1,1909 +0,0 @@
-/*
- * lanstreamer.c -- driver for the IBM Auto LANStreamer PCI Adapter
- *
- * Written By: Mike Sullivan, IBM Corporation
- *
- * Copyright (C) 1999 IBM Corporation
- *
- * Linux driver for IBM PCI tokenring cards based on the LanStreamer MPC
- * chipset.
- *
- * This driver is based on the olympic driver for IBM PCI TokenRing cards (Pit/Pit-Phy/Olympic
- * chipsets) written by:
- * 1999 Peter De Schrijver All Rights Reserved
- * 1999 Mike Phillips (phillim@amtrak.com)
- *
- * Base Driver Skeleton:
- * Written 1993-94 by Donald Becker.
- *
- * Copyright 1993 United States Government as represented by the
- * Director, National Security Agency.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
- *
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * 12/10/99 - Alpha Release 0.1.0
- * First release to the public
- * 03/03/00 - Merged to kernel, indented -kr -i8 -bri0, fixed some missing
- * malloc free checks, reviewed code. <alan@redhat.com>
- * 03/13/00 - Added spinlocks for smp
- * 03/08/01 - Added support for module_init() and module_exit()
- * 08/15/01 - Added ioctl() functionality for debugging, changed netif_*_queue
- * calls and other incorrectness - Kent Yoder <yoder1@us.ibm.com>
- * 11/05/01 - Restructured the interrupt function, added delays, reduced the
- * the number of TX descriptors to 1, which together can prevent
- * the card from locking up the box - <yoder1@us.ibm.com>
- * 09/27/02 - New PCI interface + bug fix. - <yoder1@us.ibm.com>
- * 11/13/02 - Removed free_irq calls which could cause a hang, added
- * netif_carrier_{on|off} - <yoder1@us.ibm.com>
- *
- * To Do:
- *
- *
- * If Problems do Occur
- * Most problems can be rectified by either closing and opening the interface
- * (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult
- * if compiled into the kernel).
- */
-
-/* Change STREAMER_DEBUG to 1 to get verbose, and I mean really verbose, messages */
-
-#define STREAMER_DEBUG 0
-#define STREAMER_DEBUG_PACKETS 0
-
-/* Change STREAMER_NETWORK_MONITOR to receive mac frames through the arb channel.
- * Will also create a /proc/net/streamer_tr entry if proc_fs is compiled into the
- * kernel.
- * Intended to be used to create a ring-error reporting network module
- * i.e. it will give you the source address of beaconers on the ring
- */
-
-#define STREAMER_NETWORK_MONITOR 0
-
-/* #define CONFIG_PROC_FS */
-
-/*
- * Allow or disallow ioctl's for debugging
- */
-
-#define STREAMER_IOCTL 0
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/proc_fs.h>
-#include <linux/ptrace.h>
-#include <linux/skbuff.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/spinlock.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-
-#include <net/net_namespace.h>
-#include <net/checksum.h>
-
-#include <asm/io.h>
-
-#include "lanstreamer.h"
-
-#if (BITS_PER_LONG == 64)
-#error broken on 64-bit: stores pointer to rx_ring->buffer in 32-bit int
-#endif
-
-
-/* I've got to put some intelligence into the version number so that Peter and I know
- * which version of the code somebody has got.
- * Version Number = a.b.c.d where a.b.c is the level of code and d is the latest author.
- * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike
- *
- * Official releases will only have an a.b.c version number format.
- */
-
-static char version[] = "LanStreamer.c v0.4.0 03/08/01 - Mike Sullivan\n"
- " v0.5.3 11/13/02 - Kent Yoder";
-
-static DEFINE_PCI_DEVICE_TABLE(streamer_pci_tbl) = {
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR, PCI_ANY_ID, PCI_ANY_ID,},
- {} /* terminating entry */
-};
-MODULE_DEVICE_TABLE(pci,streamer_pci_tbl);
-
-
-static char *open_maj_error[] = {
- "No error", "Lobe Media Test", "Physical Insertion",
- "Address Verification", "Neighbor Notification (Ring Poll)",
- "Request Parameters", "FDX Registration Request",
- "FDX Lobe Media Test", "FDX Duplicate Address Check",
- "Unknown stage"
-};
-
-static char *open_min_error[] = {
- "No error", "Function Failure", "Signal Lost", "Wire Fault",
- "Ring Speed Mismatch", "Timeout", "Ring Failure", "Ring Beaconing",
- "Duplicate Node Address", "Request Parameters", "Remove Received",
- "Reserved", "Reserved", "No Monitor Detected for RPL",
- "Monitor Contention failer for RPL", "FDX Protocol Error"
-};
-
-/* Module parameters */
-
-/* Ring Speed 0,4,16
- * 0 = Autosense
- * 4,16 = Selected speed only, no autosense
- * This allows the card to be the first on the ring
- * and become the active monitor.
- *
- * WARNING: Some hubs will allow you to insert
- * at the wrong speed
- */
-
-static int ringspeed[STREAMER_MAX_ADAPTERS] = { 0, };
-
-module_param_array(ringspeed, int, NULL, 0);
-
-/* Packet buffer size */
-
-static int pkt_buf_sz[STREAMER_MAX_ADAPTERS] = { 0, };
-
-module_param_array(pkt_buf_sz, int, NULL, 0);
-
-/* Message Level */
-
-static int message_level[STREAMER_MAX_ADAPTERS] = { 1, };
-
-module_param_array(message_level, int, NULL, 0);
-
-#if STREAMER_IOCTL
-static int streamer_ioctl(struct net_device *, struct ifreq *, int);
-#endif
-
-static int streamer_reset(struct net_device *dev);
-static int streamer_open(struct net_device *dev);
-static netdev_tx_t streamer_xmit(struct sk_buff *skb,
- struct net_device *dev);
-static int streamer_close(struct net_device *dev);
-static void streamer_set_rx_mode(struct net_device *dev);
-static irqreturn_t streamer_interrupt(int irq, void *dev_id);
-static int streamer_set_mac_address(struct net_device *dev, void *addr);
-static void streamer_arb_cmd(struct net_device *dev);
-static int streamer_change_mtu(struct net_device *dev, int mtu);
-static void streamer_srb_bh(struct net_device *dev);
-static void streamer_asb_bh(struct net_device *dev);
-#if STREAMER_NETWORK_MONITOR
-#ifdef CONFIG_PROC_FS
-static int streamer_proc_info(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data);
-static int sprintf_info(char *buffer, struct net_device *dev);
-struct streamer_private *dev_streamer=NULL;
-#endif
-#endif
-
-static const struct net_device_ops streamer_netdev_ops = {
- .ndo_open = streamer_open,
- .ndo_stop = streamer_close,
- .ndo_start_xmit = streamer_xmit,
- .ndo_change_mtu = streamer_change_mtu,
-#if STREAMER_IOCTL
- .ndo_do_ioctl = streamer_ioctl,
-#endif
- .ndo_set_rx_mode = streamer_set_rx_mode,
- .ndo_set_mac_address = streamer_set_mac_address,
-};
-
-static int __devinit streamer_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct net_device *dev;
- struct streamer_private *streamer_priv;
- unsigned long pio_start, pio_end, pio_flags, pio_len;
- unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
- int rc = 0;
- static int card_no=-1;
- u16 pcr;
-
-#if STREAMER_DEBUG
- printk("lanstreamer::streamer_init_one, entry pdev %p\n",pdev);
-#endif
-
- card_no++;
- dev = alloc_trdev(sizeof(*streamer_priv));
- if (dev==NULL) {
- printk(KERN_ERR "lanstreamer: out of memory.\n");
- return -ENOMEM;
- }
-
- streamer_priv = netdev_priv(dev);
-
-#if STREAMER_NETWORK_MONITOR
-#ifdef CONFIG_PROC_FS
- if (!dev_streamer)
- create_proc_read_entry("streamer_tr", 0, init_net.proc_net,
- streamer_proc_info, NULL);
- streamer_priv->next = dev_streamer;
- dev_streamer = streamer_priv;
-#endif
-#endif
-
- rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
- if (rc) {
- printk(KERN_ERR "%s: No suitable PCI mapping available.\n",
- dev->name);
- rc = -ENODEV;
- goto err_out;
- }
-
- rc = pci_enable_device(pdev);
- if (rc) {
- printk(KERN_ERR "lanstreamer: unable to enable pci device\n");
- rc=-EIO;
- goto err_out;
- }
-
- pci_set_master(pdev);
-
- rc = pci_set_mwi(pdev);
- if (rc) {
- printk(KERN_ERR "lanstreamer: unable to enable MWI on pci device\n");
- goto err_out_disable;
- }
-
- pio_start = pci_resource_start(pdev, 0);
- pio_end = pci_resource_end(pdev, 0);
- pio_flags = pci_resource_flags(pdev, 0);
- pio_len = pci_resource_len(pdev, 0);
-
- mmio_start = pci_resource_start(pdev, 1);
- mmio_end = pci_resource_end(pdev, 1);
- mmio_flags = pci_resource_flags(pdev, 1);
- mmio_len = pci_resource_len(pdev, 1);
-
-#if STREAMER_DEBUG
- printk("lanstreamer: pio_start %x pio_end %x pio_len %x pio_flags %x\n",
- pio_start, pio_end, pio_len, pio_flags);
- printk("lanstreamer: mmio_start %x mmio_end %x mmio_len %x mmio_flags %x\n",
- mmio_start, mmio_end, mmio_flags, mmio_len);
-#endif
-
- if (!request_region(pio_start, pio_len, "lanstreamer")) {
- printk(KERN_ERR "lanstreamer: unable to get pci io addr %lx\n",
- pio_start);
- rc= -EBUSY;
- goto err_out_mwi;
- }
-
- if (!request_mem_region(mmio_start, mmio_len, "lanstreamer")) {
- printk(KERN_ERR "lanstreamer: unable to get pci mmio addr %lx\n",
- mmio_start);
- rc= -EBUSY;
- goto err_out_free_pio;
- }
-
- streamer_priv->streamer_mmio=ioremap(mmio_start, mmio_len);
- if (streamer_priv->streamer_mmio == NULL) {
- printk(KERN_ERR "lanstreamer: unable to remap MMIO %lx\n",
- mmio_start);
- rc= -EIO;
- goto err_out_free_mmio;
- }
-
- init_waitqueue_head(&streamer_priv->srb_wait);
- init_waitqueue_head(&streamer_priv->trb_wait);
-
- dev->netdev_ops = &streamer_netdev_ops;
- dev->irq = pdev->irq;
- dev->base_addr=pio_start;
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- streamer_priv->streamer_card_name = (char *)pdev->resource[0].name;
- streamer_priv->pci_dev = pdev;
-
- if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000))
- streamer_priv->pkt_buf_sz = PKT_BUF_SZ;
- else
- streamer_priv->pkt_buf_sz = pkt_buf_sz[card_no];
-
- streamer_priv->streamer_ring_speed = ringspeed[card_no];
- streamer_priv->streamer_message_level = message_level[card_no];
-
- pci_set_drvdata(pdev, dev);
-
- spin_lock_init(&streamer_priv->streamer_lock);
-
- pci_read_config_word (pdev, PCI_COMMAND, &pcr);
- pcr |= PCI_COMMAND_SERR;
- pci_write_config_word (pdev, PCI_COMMAND, pcr);
-
- printk("%s\n", version);
- printk("%s: %s. I/O at %hx, MMIO at %p, using irq %d\n",dev->name,
- streamer_priv->streamer_card_name,
- (unsigned int) dev->base_addr,
- streamer_priv->streamer_mmio,
- dev->irq);
-
- if (streamer_reset(dev))
- goto err_out_unmap;
-
- rc = register_netdev(dev);
- if (rc)
- goto err_out_unmap;
- return 0;
-
-err_out_unmap:
- iounmap(streamer_priv->streamer_mmio);
-err_out_free_mmio:
- release_mem_region(mmio_start, mmio_len);
-err_out_free_pio:
- release_region(pio_start, pio_len);
-err_out_mwi:
- pci_clear_mwi(pdev);
-err_out_disable:
- pci_disable_device(pdev);
-err_out:
- free_netdev(dev);
-#if STREAMER_DEBUG
- printk("lanstreamer: Exit error %x\n",rc);
-#endif
- return rc;
-}
-
-static void __devexit streamer_remove_one(struct pci_dev *pdev)
-{
- struct net_device *dev=pci_get_drvdata(pdev);
- struct streamer_private *streamer_priv;
-
-#if STREAMER_DEBUG
- printk("lanstreamer::streamer_remove_one entry pdev %p\n",pdev);
-#endif
-
- if (dev == NULL) {
- printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev is NULL\n");
- return;
- }
-
- streamer_priv=netdev_priv(dev);
- if (streamer_priv == NULL) {
- printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev->priv is NULL\n");
- return;
- }
-
-#if STREAMER_NETWORK_MONITOR
-#ifdef CONFIG_PROC_FS
- {
- struct streamer_private **p, **next;
-
- for (p = &dev_streamer; *p; p = next) {
- next = &(*p)->next;
- if (*p == streamer_priv) {
- *p = *next;
- break;
- }
- }
- if (!dev_streamer)
- remove_proc_entry("streamer_tr", init_net.proc_net);
- }
-#endif
-#endif
-
- unregister_netdev(dev);
- iounmap(streamer_priv->streamer_mmio);
- release_mem_region(pci_resource_start(pdev, 1), pci_resource_len(pdev,1));
- release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev,0));
- pci_clear_mwi(pdev);
- pci_disable_device(pdev);
- free_netdev(dev);
- pci_set_drvdata(pdev, NULL);
-}
-
-
-static int streamer_reset(struct net_device *dev)
-{
- struct streamer_private *streamer_priv;
- __u8 __iomem *streamer_mmio;
- unsigned long t;
- unsigned int uaa_addr;
- struct sk_buff *skb = NULL;
- __u16 misr;
-
- streamer_priv = netdev_priv(dev);
- streamer_mmio = streamer_priv->streamer_mmio;
-
- writew(readw(streamer_mmio + BCTL) | BCTL_SOFTRESET, streamer_mmio + BCTL);
- t = jiffies;
- /* Hold soft reset bit for a while */
- ssleep(1);
-
- writew(readw(streamer_mmio + BCTL) & ~BCTL_SOFTRESET,
- streamer_mmio + BCTL);
-
-#if STREAMER_DEBUG
- printk("BCTL: %x\n", readw(streamer_mmio + BCTL));
- printk("GPR: %x\n", readw(streamer_mmio + GPR));
- printk("SISRMASK: %x\n", readw(streamer_mmio + SISR_MASK));
-#endif
- writew(readw(streamer_mmio + BCTL) | (BCTL_RX_FIFO_8 | BCTL_TX_FIFO_8), streamer_mmio + BCTL );
-
- if (streamer_priv->streamer_ring_speed == 0) { /* Autosense */
- writew(readw(streamer_mmio + GPR) | GPR_AUTOSENSE,
- streamer_mmio + GPR);
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Ringspeed autosense mode on\n",
- dev->name);
- } else if (streamer_priv->streamer_ring_speed == 16) {
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n",
- dev->name);
- writew(GPR_16MBPS, streamer_mmio + GPR);
- } else if (streamer_priv->streamer_ring_speed == 4) {
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n",
- dev->name);
- writew(0, streamer_mmio + GPR);
- }
-
- skb = dev_alloc_skb(streamer_priv->pkt_buf_sz);
- if (!skb) {
- printk(KERN_INFO "%s: skb allocation for diagnostics failed...proceeding\n",
- dev->name);
- } else {
- struct streamer_rx_desc *rx_ring;
- u8 *data;
-
- rx_ring=(struct streamer_rx_desc *)skb->data;
- data=((u8 *)skb->data)+sizeof(struct streamer_rx_desc);
- rx_ring->forward=0;
- rx_ring->status=0;
- rx_ring->buffer=cpu_to_le32(pci_map_single(streamer_priv->pci_dev, data,
- 512, PCI_DMA_FROMDEVICE));
- rx_ring->framelen_buflen=512;
- writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, rx_ring, 512, PCI_DMA_FROMDEVICE)),
- streamer_mmio+RXBDA);
- }
-
-#if STREAMER_DEBUG
- printk("GPR = %x\n", readw(streamer_mmio + GPR));
-#endif
- /* start solo init */
- writew(SISR_MI, streamer_mmio + SISR_MASK_SUM);
-
- while (!((readw(streamer_mmio + SISR)) & SISR_SRB_REPLY)) {
- msleep_interruptible(100);
- if (time_after(jiffies, t + 40 * HZ)) {
- printk(KERN_ERR
- "IBM PCI tokenring card not responding\n");
- release_region(dev->base_addr, STREAMER_IO_SPACE);
- if (skb)
- dev_kfree_skb(skb);
- return -1;
- }
- }
- writew(~SISR_SRB_REPLY, streamer_mmio + SISR_RUM);
- misr = readw(streamer_mmio + MISR_RUM);
- writew(~misr, streamer_mmio + MISR_RUM);
-
- if (skb)
- dev_kfree_skb(skb); /* release skb used for diagnostics */
-
-#if STREAMER_DEBUG
- printk("LAPWWO: %x, LAPA: %x LAPE: %x\n",
- readw(streamer_mmio + LAPWWO), readw(streamer_mmio + LAPA),
- readw(streamer_mmio + LAPE));
-#endif
-
-#if STREAMER_DEBUG
- {
- int i;
- writew(readw(streamer_mmio + LAPWWO),
- streamer_mmio + LAPA);
- printk("initialization response srb dump: ");
- for (i = 0; i < 10; i++)
- printk("%x:",
- ntohs(readw(streamer_mmio + LAPDINC)));
- printk("\n");
- }
-#endif
-
- writew(readw(streamer_mmio + LAPWWO) + 6, streamer_mmio + LAPA);
- if (readw(streamer_mmio + LAPD)) {
- printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n",
- ntohs(readw(streamer_mmio + LAPD)));
- release_region(dev->base_addr, STREAMER_IO_SPACE);
- return -1;
- }
-
- writew(readw(streamer_mmio + LAPWWO) + 8, streamer_mmio + LAPA);
- uaa_addr = ntohs(readw(streamer_mmio + LAPDINC));
- readw(streamer_mmio + LAPDINC); /* skip over Level.Addr field */
- streamer_priv->streamer_addr_table_addr = ntohs(readw(streamer_mmio + LAPDINC));
- streamer_priv->streamer_parms_addr = ntohs(readw(streamer_mmio + LAPDINC));
-
-#if STREAMER_DEBUG
- printk("UAA resides at %x\n", uaa_addr);
-#endif
-
- /* setup uaa area for access with LAPD */
- {
- int i;
- __u16 addr;
- writew(uaa_addr, streamer_mmio + LAPA);
- for (i = 0; i < 6; i += 2) {
- addr=ntohs(readw(streamer_mmio+LAPDINC));
- dev->dev_addr[i]= (addr >> 8) & 0xff;
- dev->dev_addr[i+1]= addr & 0xff;
- }
-#if STREAMER_DEBUG
- printk("Adapter address: %pM\n", dev->dev_addr);
-#endif
- }
- return 0;
-}
-
-static int streamer_open(struct net_device *dev)
-{
- struct streamer_private *streamer_priv = netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
- unsigned long flags;
- char open_error[255];
- int i, open_finished = 1;
- __u16 srb_word;
- __u16 srb_open;
- int rc;
-
- if (readw(streamer_mmio+BMCTL_SUM) & BMCTL_RX_ENABLED) {
- rc=streamer_reset(dev);
- }
-
- if (request_irq(dev->irq, streamer_interrupt, IRQF_SHARED, "lanstreamer", dev)) {
- return -EAGAIN;
- }
-#if STREAMER_DEBUG
- printk("BMCTL: %x\n", readw(streamer_mmio + BMCTL_SUM));
- printk("pending ints: %x\n", readw(streamer_mmio + SISR));
-#endif
-
- writew(SISR_MI | SISR_SRB_REPLY, streamer_mmio + SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */
- writew(LISR_LIE, streamer_mmio + LISR); /* more ints later */
-
- /* adapter is closed, so SRB is pointed to by LAPWWO */
- writew(readw(streamer_mmio + LAPWWO), streamer_mmio + LAPA);
-
-#if STREAMER_DEBUG
- printk("LAPWWO: %x, LAPA: %x\n", readw(streamer_mmio + LAPWWO),
- readw(streamer_mmio + LAPA));
- printk("LAPE: %x\n", readw(streamer_mmio + LAPE));
- printk("SISR Mask = %04x\n", readw(streamer_mmio + SISR_MASK));
-#endif
- do {
- for (i = 0; i < SRB_COMMAND_SIZE; i += 2) {
- writew(0, streamer_mmio + LAPDINC);
- }
-
- writew(readw(streamer_mmio+LAPWWO),streamer_mmio+LAPA);
- writew(htons(SRB_OPEN_ADAPTER<<8),streamer_mmio+LAPDINC) ; /* open */
- writew(htons(STREAMER_CLEAR_RET_CODE<<8),streamer_mmio+LAPDINC);
- writew(STREAMER_CLEAR_RET_CODE, streamer_mmio + LAPDINC);
-
- writew(readw(streamer_mmio + LAPWWO) + 8, streamer_mmio + LAPA);
-#if STREAMER_NETWORK_MONITOR
- /* If Network Monitor, instruct card to copy MAC frames through the ARB */
- writew(htons(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), streamer_mmio + LAPDINC); /* offset 8 word contains open options */
-#else
- writew(htons(OPEN_ADAPTER_ENABLE_FDX), streamer_mmio + LAPDINC); /* Offset 8 word contains Open.Options */
-#endif
-
- if (streamer_priv->streamer_laa[0]) {
- writew(readw(streamer_mmio + LAPWWO) + 12, streamer_mmio + LAPA);
- writew(htons((streamer_priv->streamer_laa[0] << 8) |
- streamer_priv->streamer_laa[1]),streamer_mmio+LAPDINC);
- writew(htons((streamer_priv->streamer_laa[2] << 8) |
- streamer_priv->streamer_laa[3]),streamer_mmio+LAPDINC);
- writew(htons((streamer_priv->streamer_laa[4] << 8) |
- streamer_priv->streamer_laa[5]),streamer_mmio+LAPDINC);
- memcpy(dev->dev_addr, streamer_priv->streamer_laa, dev->addr_len);
- }
-
- /* save off srb open offset */
- srb_open = readw(streamer_mmio + LAPWWO);
-#if STREAMER_DEBUG
- writew(readw(streamer_mmio + LAPWWO),
- streamer_mmio + LAPA);
- printk("srb open request:\n");
- for (i = 0; i < 16; i++) {
- printk("%x:", ntohs(readw(streamer_mmio + LAPDINC)));
- }
- printk("\n");
-#endif
- spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
- streamer_priv->srb_queued = 1;
-
- /* signal solo that SRB command has been issued */
- writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM);
- spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags);
-
- while (streamer_priv->srb_queued) {
- interruptible_sleep_on_timeout(&streamer_priv->srb_wait, 5 * HZ);
- if (signal_pending(current)) {
- printk(KERN_WARNING "%s: SRB timed out.\n", dev->name);
- printk(KERN_WARNING "SISR=%x MISR=%x, LISR=%x\n",
- readw(streamer_mmio + SISR),
- readw(streamer_mmio + MISR_RUM),
- readw(streamer_mmio + LISR));
- streamer_priv->srb_queued = 0;
- break;
- }
- }
-
-#if STREAMER_DEBUG
- printk("SISR_MASK: %x\n", readw(streamer_mmio + SISR_MASK));
- printk("srb open response:\n");
- writew(srb_open, streamer_mmio + LAPA);
- for (i = 0; i < 10; i++) {
- printk("%x:",
- ntohs(readw(streamer_mmio + LAPDINC)));
- }
-#endif
-
- /* If we get the same return response as we set, the interrupt wasn't raised and the open
- * timed out.
- */
- writew(srb_open + 2, streamer_mmio + LAPA);
- srb_word = ntohs(readw(streamer_mmio + LAPD)) >> 8;
- if (srb_word == STREAMER_CLEAR_RET_CODE) {
- printk(KERN_WARNING "%s: Adapter Open time out or error.\n",
- dev->name);
- return -EIO;
- }
-
- if (srb_word != 0) {
- if (srb_word == 0x07) {
- if (!streamer_priv->streamer_ring_speed && open_finished) { /* Autosense , first time around */
- printk(KERN_WARNING "%s: Retrying at different ring speed\n",
- dev->name);
- open_finished = 0;
- } else {
- __u16 error_code;
-
- writew(srb_open + 6, streamer_mmio + LAPA);
- error_code = ntohs(readw(streamer_mmio + LAPD));
- strcpy(open_error, open_maj_error[(error_code & 0xf0) >> 4]);
- strcat(open_error, " - ");
- strcat(open_error, open_min_error[(error_code & 0x0f)]);
-
- if (!streamer_priv->streamer_ring_speed &&
- ((error_code & 0x0f) == 0x0d))
- {
- printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n", dev->name);
- printk(KERN_WARNING "%s: Please try again with a specified ring speed\n", dev->name);
- free_irq(dev->irq, dev);
- return -EIO;
- }
-
- printk(KERN_WARNING "%s: %s\n",
- dev->name, open_error);
- free_irq(dev->irq, dev);
- return -EIO;
-
- } /* if autosense && open_finished */
- } else {
- printk(KERN_WARNING "%s: Bad OPEN response: %x\n",
- dev->name, srb_word);
- free_irq(dev->irq, dev);
- return -EIO;
- }
- } else
- open_finished = 1;
- } while (!(open_finished)); /* Will only loop if ring speed mismatch re-open attempted && autosense is on */
-
- writew(srb_open + 18, streamer_mmio + LAPA);
- srb_word=ntohs(readw(streamer_mmio+LAPD)) >> 8;
- if (srb_word & (1 << 3))
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Opened in FDX Mode\n", dev->name);
-
- if (srb_word & 1)
- streamer_priv->streamer_ring_speed = 16;
- else
- streamer_priv->streamer_ring_speed = 4;
-
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Opened in %d Mbps mode\n",
- dev->name,
- streamer_priv->streamer_ring_speed);
-
- writew(srb_open + 8, streamer_mmio + LAPA);
- streamer_priv->asb = ntohs(readw(streamer_mmio + LAPDINC));
- streamer_priv->srb = ntohs(readw(streamer_mmio + LAPDINC));
- streamer_priv->arb = ntohs(readw(streamer_mmio + LAPDINC));
- readw(streamer_mmio + LAPDINC); /* offset 14 word is rsvd */
- streamer_priv->trb = ntohs(readw(streamer_mmio + LAPDINC));
-
- streamer_priv->streamer_receive_options = 0x00;
- streamer_priv->streamer_copy_all_options = 0;
-
- /* setup rx ring */
- /* enable rx channel */
- writew(~BMCTL_RX_DIS, streamer_mmio + BMCTL_RUM);
-
- /* setup rx descriptors */
- streamer_priv->streamer_rx_ring=
- kmalloc( sizeof(struct streamer_rx_desc)*
- STREAMER_RX_RING_SIZE,GFP_KERNEL);
- if (!streamer_priv->streamer_rx_ring) {
- printk(KERN_WARNING "%s ALLOC of streamer rx ring FAILED!!\n",dev->name);
- return -EIO;
- }
-
- for (i = 0; i < STREAMER_RX_RING_SIZE; i++) {
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(streamer_priv->pkt_buf_sz);
- if (skb == NULL)
- break;
-
- skb->dev = dev;
-
- streamer_priv->streamer_rx_ring[i].forward =
- cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[i + 1],
- sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE));
- streamer_priv->streamer_rx_ring[i].status = 0;
- streamer_priv->streamer_rx_ring[i].buffer =
- cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data,
- streamer_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
- streamer_priv->streamer_rx_ring[i].framelen_buflen = streamer_priv->pkt_buf_sz;
- streamer_priv->rx_ring_skb[i] = skb;
- }
- streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1].forward =
- cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[0],
- sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE));
-
- if (i == 0) {
- printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n", dev->name);
- free_irq(dev->irq, dev);
- return -EIO;
- }
-
- streamer_priv->rx_ring_last_received = STREAMER_RX_RING_SIZE - 1; /* last processed rx status */
-
- writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[0],
- sizeof(struct streamer_rx_desc), PCI_DMA_TODEVICE)),
- streamer_mmio + RXBDA);
- writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_rx_ring[STREAMER_RX_RING_SIZE - 1],
- sizeof(struct streamer_rx_desc), PCI_DMA_TODEVICE)),
- streamer_mmio + RXLBDA);
-
- /* set bus master interrupt event mask */
- writew(MISR_RX_NOBUF | MISR_RX_EOF, streamer_mmio + MISR_MASK);
-
-
- /* setup tx ring */
- streamer_priv->streamer_tx_ring=kmalloc(sizeof(struct streamer_tx_desc)*
- STREAMER_TX_RING_SIZE,GFP_KERNEL);
- if (!streamer_priv->streamer_tx_ring) {
- printk(KERN_WARNING "%s ALLOC of streamer_tx_ring FAILED\n",dev->name);
- return -EIO;
- }
-
- writew(~BMCTL_TX2_DIS, streamer_mmio + BMCTL_RUM); /* Enables TX channel 2 */
- for (i = 0; i < STREAMER_TX_RING_SIZE; i++) {
- streamer_priv->streamer_tx_ring[i].forward = cpu_to_le32(pci_map_single(streamer_priv->pci_dev,
- &streamer_priv->streamer_tx_ring[i + 1],
- sizeof(struct streamer_tx_desc),
- PCI_DMA_TODEVICE));
- streamer_priv->streamer_tx_ring[i].status = 0;
- streamer_priv->streamer_tx_ring[i].bufcnt_framelen = 0;
- streamer_priv->streamer_tx_ring[i].buffer = 0;
- streamer_priv->streamer_tx_ring[i].buflen = 0;
- streamer_priv->streamer_tx_ring[i].rsvd1 = 0;
- streamer_priv->streamer_tx_ring[i].rsvd2 = 0;
- streamer_priv->streamer_tx_ring[i].rsvd3 = 0;
- }
- streamer_priv->streamer_tx_ring[STREAMER_TX_RING_SIZE - 1].forward =
- cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_tx_ring[0],
- sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE));
-
- streamer_priv->free_tx_ring_entries = STREAMER_TX_RING_SIZE;
- streamer_priv->tx_ring_free = 0; /* next entry in tx ring to use */
- streamer_priv->tx_ring_last_status = STREAMER_TX_RING_SIZE - 1;
-
- /* set Busmaster interrupt event mask (handle receives on interrupt only */
- writew(MISR_TX2_EOF | MISR_RX_NOBUF | MISR_RX_EOF, streamer_mmio + MISR_MASK);
- /* set system event interrupt mask */
- writew(SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE, streamer_mmio + SISR_MASK_SUM);
-
-#if STREAMER_DEBUG
- printk("BMCTL: %x\n", readw(streamer_mmio + BMCTL_SUM));
- printk("SISR MASK: %x\n", readw(streamer_mmio + SISR_MASK));
-#endif
-
-#if STREAMER_NETWORK_MONITOR
-
- writew(streamer_priv->streamer_addr_table_addr, streamer_mmio + LAPA);
- printk("%s: Node Address: %04x:%04x:%04x\n", dev->name,
- ntohs(readw(streamer_mmio + LAPDINC)),
- ntohs(readw(streamer_mmio + LAPDINC)),
- ntohs(readw(streamer_mmio + LAPDINC)));
- readw(streamer_mmio + LAPDINC);
- readw(streamer_mmio + LAPDINC);
- printk("%s: Functional Address: %04x:%04x\n", dev->name,
- ntohs(readw(streamer_mmio + LAPDINC)),
- ntohs(readw(streamer_mmio + LAPDINC)));
-
- writew(streamer_priv->streamer_parms_addr + 4,
- streamer_mmio + LAPA);
- printk("%s: NAUN Address: %04x:%04x:%04x\n", dev->name,
- ntohs(readw(streamer_mmio + LAPDINC)),
- ntohs(readw(streamer_mmio + LAPDINC)),
- ntohs(readw(streamer_mmio + LAPDINC)));
-#endif
-
- netif_start_queue(dev);
- netif_carrier_on(dev);
- return 0;
-}
-
-/*
- * When we enter the rx routine we do not know how many frames have been
- * queued on the rx channel. Therefore we start at the next rx status
- * position and travel around the receive ring until we have completed
- * all the frames.
- *
- * This means that we may process the frame before we receive the end
- * of frame interrupt. This is why we always test the status instead
- * of blindly processing the next frame.
- *
- */
-static void streamer_rx(struct net_device *dev)
-{
- struct streamer_private *streamer_priv =
- netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
- struct streamer_rx_desc *rx_desc;
- int rx_ring_last_received, length, frame_length, buffer_cnt = 0;
- struct sk_buff *skb, *skb2;
-
- /* setup the next rx descriptor to be received */
- rx_desc = &streamer_priv->streamer_rx_ring[(streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1)];
- rx_ring_last_received = streamer_priv->rx_ring_last_received;
-
- while (rx_desc->status & 0x01000000) { /* While processed descriptors are available */
- if (rx_ring_last_received != streamer_priv->rx_ring_last_received)
- {
- printk(KERN_WARNING "RX Error 1 rx_ring_last_received not the same %x %x\n",
- rx_ring_last_received, streamer_priv->rx_ring_last_received);
- }
- streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1);
- rx_ring_last_received = streamer_priv->rx_ring_last_received;
-
- length = rx_desc->framelen_buflen & 0xffff; /* buffer length */
- frame_length = (rx_desc->framelen_buflen >> 16) & 0xffff;
-
- if (rx_desc->status & 0x7E830000) { /* errors */
- if (streamer_priv->streamer_message_level) {
- printk(KERN_WARNING "%s: Rx Error %x\n",
- dev->name, rx_desc->status);
- }
- } else { /* received without errors */
- if (rx_desc->status & 0x80000000) { /* frame complete */
- buffer_cnt = 1;
- skb = dev_alloc_skb(streamer_priv->pkt_buf_sz);
- } else {
- skb = dev_alloc_skb(frame_length);
- }
-
- if (skb == NULL)
- {
- printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers.\n", dev->name);
- dev->stats.rx_dropped++;
- } else { /* we allocated an skb OK */
- if (buffer_cnt == 1) {
- /* release the DMA mapping */
- pci_unmap_single(streamer_priv->pci_dev,
- le32_to_cpu(streamer_priv->streamer_rx_ring[rx_ring_last_received].buffer),
- streamer_priv->pkt_buf_sz,
- PCI_DMA_FROMDEVICE);
- skb2 = streamer_priv->rx_ring_skb[rx_ring_last_received];
-#if STREAMER_DEBUG_PACKETS
- {
- int i;
- printk("streamer_rx packet print: skb->data2 %p skb->head %p\n", skb2->data, skb2->head);
- for (i = 0; i < frame_length; i++)
- {
- printk("%x:", skb2->data[i]);
- if (((i + 1) % 16) == 0)
- printk("\n");
- }
- printk("\n");
- }
-#endif
- skb_put(skb2, length);
- skb2->protocol = tr_type_trans(skb2, dev);
- /* recycle this descriptor */
- streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0;
- streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz;
- streamer_priv->streamer_rx_ring[rx_ring_last_received].buffer =
- cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, streamer_priv->pkt_buf_sz,
- PCI_DMA_FROMDEVICE));
- streamer_priv->rx_ring_skb[rx_ring_last_received] = skb;
- /* place recycled descriptor back on the adapter */
- writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev,
- &streamer_priv->streamer_rx_ring[rx_ring_last_received],
- sizeof(struct streamer_rx_desc), PCI_DMA_FROMDEVICE)),
- streamer_mmio + RXLBDA);
- /* pass the received skb up to the protocol */
- netif_rx(skb2);
- } else {
- do { /* Walk the buffers */
- pci_unmap_single(streamer_priv->pci_dev, le32_to_cpu(rx_desc->buffer), length, PCI_DMA_FROMDEVICE),
- memcpy(skb_put(skb, length), (void *)rx_desc->buffer, length); /* copy this fragment */
- streamer_priv->streamer_rx_ring[rx_ring_last_received].status = 0;
- streamer_priv->streamer_rx_ring[rx_ring_last_received].framelen_buflen = streamer_priv->pkt_buf_sz;
-
- /* give descriptor back to the adapter */
- writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev,
- &streamer_priv->streamer_rx_ring[rx_ring_last_received],
- length, PCI_DMA_FROMDEVICE)),
- streamer_mmio + RXLBDA);
-
- if (rx_desc->status & 0x80000000)
- break; /* this descriptor completes the frame */
-
- /* else get the next pending descriptor */
- if (rx_ring_last_received!= streamer_priv->rx_ring_last_received)
- {
- printk("RX Error rx_ring_last_received not the same %x %x\n",
- rx_ring_last_received,
- streamer_priv->rx_ring_last_received);
- }
- rx_desc = &streamer_priv->streamer_rx_ring[(streamer_priv->rx_ring_last_received+1) & (STREAMER_RX_RING_SIZE-1)];
-
- length = rx_desc->framelen_buflen & 0xffff; /* buffer length */
- streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received+1) & (STREAMER_RX_RING_SIZE - 1);
- rx_ring_last_received = streamer_priv->rx_ring_last_received;
- } while (1);
-
- skb->protocol = tr_type_trans(skb, dev);
- /* send up to the protocol */
- netif_rx(skb);
- }
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += length;
- } /* if skb == null */
- } /* end received without errors */
-
- /* try the next one */
- rx_desc = &streamer_priv->streamer_rx_ring[(rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1)];
- } /* end for all completed rx descriptors */
-}
-
-static irqreturn_t streamer_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = (struct net_device *) dev_id;
- struct streamer_private *streamer_priv =
- netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
- __u16 sisr;
- __u16 misr;
- u8 max_intr = MAX_INTR;
-
- spin_lock(&streamer_priv->streamer_lock);
- sisr = readw(streamer_mmio + SISR);
-
- while((sisr & (SISR_MI | SISR_SRB_REPLY | SISR_ADAPTER_CHECK | SISR_ASB_FREE |
- SISR_ARB_CMD | SISR_TRB_REPLY | SISR_PAR_ERR | SISR_SERR_ERR)) &&
- (max_intr > 0)) {
-
- if(sisr & SISR_PAR_ERR) {
- writew(~SISR_PAR_ERR, streamer_mmio + SISR_RUM);
- (void)readw(streamer_mmio + SISR_RUM);
- }
-
- else if(sisr & SISR_SERR_ERR) {
- writew(~SISR_SERR_ERR, streamer_mmio + SISR_RUM);
- (void)readw(streamer_mmio + SISR_RUM);
- }
-
- else if(sisr & SISR_MI) {
- misr = readw(streamer_mmio + MISR_RUM);
-
- if (misr & MISR_TX2_EOF) {
- while(streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) {
- streamer_priv->tx_ring_last_status = (streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1);
- streamer_priv->free_tx_ring_entries++;
- dev->stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len;
- dev->stats.tx_packets++;
- dev_kfree_skb_irq(streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]);
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buffer = 0xdeadbeef;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].status = 0;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].bufcnt_framelen = 0;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buflen = 0;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd1 = 0;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd2 = 0;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].rsvd3 = 0;
- }
- netif_wake_queue(dev);
- }
-
- if (misr & MISR_RX_EOF) {
- streamer_rx(dev);
- }
- /* MISR_RX_EOF */
-
- if (misr & MISR_RX_NOBUF) {
- /* According to the documentation, we don't have to do anything,
- * but trapping it keeps it out of /var/log/messages.
- */
- } /* SISR_RX_NOBUF */
-
- writew(~misr, streamer_mmio + MISR_RUM);
- (void)readw(streamer_mmio + MISR_RUM);
- }
-
- else if (sisr & SISR_SRB_REPLY) {
- if (streamer_priv->srb_queued == 1) {
- wake_up_interruptible(&streamer_priv->srb_wait);
- } else if (streamer_priv->srb_queued == 2) {
- streamer_srb_bh(dev);
- }
- streamer_priv->srb_queued = 0;
-
- writew(~SISR_SRB_REPLY, streamer_mmio + SISR_RUM);
- (void)readw(streamer_mmio + SISR_RUM);
- }
-
- else if (sisr & SISR_ADAPTER_CHECK) {
- printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
- writel(readl(streamer_mmio + LAPWWO), streamer_mmio + LAPA);
- printk(KERN_WARNING "%s: Words %x:%x:%x:%x:\n",
- dev->name, readw(streamer_mmio + LAPDINC),
- ntohs(readw(streamer_mmio + LAPDINC)),
- ntohs(readw(streamer_mmio + LAPDINC)),
- ntohs(readw(streamer_mmio + LAPDINC)));
- netif_stop_queue(dev);
- netif_carrier_off(dev);
- printk(KERN_WARNING "%s: Adapter must be manually reset.\n", dev->name);
- }
-
- /* SISR_ADAPTER_CHECK */
- else if (sisr & SISR_ASB_FREE) {
- /* Wake up anything that is waiting for the asb response */
- if (streamer_priv->asb_queued) {
- streamer_asb_bh(dev);
- }
- writew(~SISR_ASB_FREE, streamer_mmio + SISR_RUM);
- (void)readw(streamer_mmio + SISR_RUM);
- }
- /* SISR_ASB_FREE */
- else if (sisr & SISR_ARB_CMD) {
- streamer_arb_cmd(dev);
- writew(~SISR_ARB_CMD, streamer_mmio + SISR_RUM);
- (void)readw(streamer_mmio + SISR_RUM);
- }
- /* SISR_ARB_CMD */
- else if (sisr & SISR_TRB_REPLY) {
- /* Wake up anything that is waiting for the trb response */
- if (streamer_priv->trb_queued) {
- wake_up_interruptible(&streamer_priv->
- trb_wait);
- }
- streamer_priv->trb_queued = 0;
- writew(~SISR_TRB_REPLY, streamer_mmio + SISR_RUM);
- (void)readw(streamer_mmio + SISR_RUM);
- }
- /* SISR_TRB_REPLY */
-
- sisr = readw(streamer_mmio + SISR);
- max_intr--;
- } /* while() */
-
- spin_unlock(&streamer_priv->streamer_lock) ;
- return IRQ_HANDLED;
-}
-
-static netdev_tx_t streamer_xmit(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct streamer_private *streamer_priv =
- netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
- unsigned long flags ;
-
- spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
-
- if (streamer_priv->free_tx_ring_entries) {
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].status = 0;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00020000 | skb->len;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buffer =
- cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE));
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd1 = skb->len;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd2 = 0;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd3 = 0;
- streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buflen = skb->len;
-
- streamer_priv->tx_ring_skb[streamer_priv->tx_ring_free] = skb;
- streamer_priv->free_tx_ring_entries--;
-#if STREAMER_DEBUG_PACKETS
- {
- int i;
- printk("streamer_xmit packet print:\n");
- for (i = 0; i < skb->len; i++) {
- printk("%x:", skb->data[i]);
- if (((i + 1) % 16) == 0)
- printk("\n");
- }
- printk("\n");
- }
-#endif
-
- writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev,
- &streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free],
- sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE)),
- streamer_mmio + TX2LFDA);
- (void)readl(streamer_mmio + TX2LFDA);
-
- streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1);
- spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
- return NETDEV_TX_OK;
- } else {
- netif_stop_queue(dev);
- spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
- return NETDEV_TX_BUSY;
- }
-}
-
-
-static int streamer_close(struct net_device *dev)
-{
- struct streamer_private *streamer_priv =
- netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
- unsigned long flags;
- int i;
-
- netif_stop_queue(dev);
- netif_carrier_off(dev);
- writew(streamer_priv->srb, streamer_mmio + LAPA);
- writew(htons(SRB_CLOSE_ADAPTER << 8),streamer_mmio+LAPDINC);
- writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);
-
- spin_lock_irqsave(&streamer_priv->streamer_lock, flags);
-
- streamer_priv->srb_queued = 1;
- writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM);
-
- spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags);
-
- while (streamer_priv->srb_queued)
- {
- interruptible_sleep_on_timeout(&streamer_priv->srb_wait,
- jiffies + 60 * HZ);
- if (signal_pending(current))
- {
- printk(KERN_WARNING "%s: SRB timed out.\n", dev->name);
- printk(KERN_WARNING "SISR=%x MISR=%x LISR=%x\n",
- readw(streamer_mmio + SISR),
- readw(streamer_mmio + MISR_RUM),
- readw(streamer_mmio + LISR));
- streamer_priv->srb_queued = 0;
- break;
- }
- }
-
- streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1);
-
- for (i = 0; i < STREAMER_RX_RING_SIZE; i++) {
- if (streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]) {
- dev_kfree_skb(streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]);
- }
- streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1);
- }
-
- /* reset tx/rx fifo's and busmaster logic */
-
- /* TBD. Add graceful way to reset the LLC channel without doing a soft reset.
- writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL);
- udelay(1);
- writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL);
- */
-
-#if STREAMER_DEBUG
- writew(streamer_priv->srb, streamer_mmio + LAPA);
- printk("srb): ");
- for (i = 0; i < 2; i++) {
- printk("%x ", ntohs(readw(streamer_mmio + LAPDINC)));
- }
- printk("\n");
-#endif
- free_irq(dev->irq, dev);
- return 0;
-}
-
-static void streamer_set_rx_mode(struct net_device *dev)
-{
- struct streamer_private *streamer_priv =
- netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
- __u8 options = 0;
- struct netdev_hw_addr *ha;
- unsigned char dev_mc_address[5];
-
- writel(streamer_priv->srb, streamer_mmio + LAPA);
- options = streamer_priv->streamer_copy_all_options;
-
- if (dev->flags & IFF_PROMISC)
- options |= (3 << 5); /* All LLC and MAC frames, all through the main rx channel */
- else
- options &= ~(3 << 5);
-
- /* Only issue the srb if there is a change in options */
-
- if ((options ^ streamer_priv->streamer_copy_all_options))
- {
- /* Now to issue the srb command to alter the copy.all.options */
- writew(htons(SRB_MODIFY_RECEIVE_OPTIONS << 8), streamer_mmio+LAPDINC);
- writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);
- writew(htons((streamer_priv->streamer_receive_options << 8) | options),streamer_mmio+LAPDINC);
- writew(htons(0x4a41),streamer_mmio+LAPDINC);
- writew(htons(0x4d45),streamer_mmio+LAPDINC);
- writew(htons(0x5320),streamer_mmio+LAPDINC);
- writew(0x2020, streamer_mmio + LAPDINC);
-
- streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */
-
- writel(LISR_SRB_CMD, streamer_mmio + LISR_SUM);
-
- streamer_priv->streamer_copy_all_options = options;
- return;
- }
-
- /* Set the functional addresses we need for multicast */
- writel(streamer_priv->srb,streamer_mmio+LAPA);
- dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ;
-
- netdev_for_each_mc_addr(ha, dev) {
- dev_mc_address[0] |= ha->addr[2];
- dev_mc_address[1] |= ha->addr[3];
- dev_mc_address[2] |= ha->addr[4];
- dev_mc_address[3] |= ha->addr[5];
- }
-
- writew(htons(SRB_SET_FUNC_ADDRESS << 8),streamer_mmio+LAPDINC);
- writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);
- writew(0,streamer_mmio+LAPDINC);
- writew(htons( (dev_mc_address[0] << 8) | dev_mc_address[1]),streamer_mmio+LAPDINC);
- writew(htons( (dev_mc_address[2] << 8) | dev_mc_address[3]),streamer_mmio+LAPDINC);
- streamer_priv->srb_queued = 2 ;
- writel(LISR_SRB_CMD,streamer_mmio+LISR_SUM);
-}
-
-static void streamer_srb_bh(struct net_device *dev)
-{
- struct streamer_private *streamer_priv = netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
- __u16 srb_word;
-
- writew(streamer_priv->srb, streamer_mmio + LAPA);
- srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;
-
- switch (srb_word) {
-
- /* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous)
- * At some point we should do something if we get an error, such as
- * resetting the IFF_PROMISC flag in dev
- */
-
- case SRB_MODIFY_RECEIVE_OPTIONS:
- srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;
-
- switch (srb_word) {
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name);
- break;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name);
- break;
- default:
- if (streamer_priv->streamer_message_level)
- printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n",
- dev->name,
- streamer_priv->streamer_copy_all_options,
- streamer_priv->streamer_receive_options);
- break;
- } /* switch srb[2] */
- break;
-
-
- /* SRB_SET_GROUP_ADDRESS - Multicast group setting
- */
- case SRB_SET_GROUP_ADDRESS:
- srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;
- switch (srb_word) {
- case 0x00:
- break;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name);
- break;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name);
- break;
- case 0x3c:
- printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n", dev->name);
- break;
- case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */
- printk(KERN_WARNING "%s: Group address registers full\n", dev->name);
- break;
- case 0x55:
- printk(KERN_INFO "%s: Group Address already set.\n", dev->name);
- break;
- default:
- break;
- } /* switch srb[2] */
- break;
-
-
- /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list
- */
- case SRB_RESET_GROUP_ADDRESS:
- srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;
- switch (srb_word) {
- case 0x00:
- break;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name);
- break;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name);
- break;
- case 0x39: /* Must deal with this if individual multicast addresses used */
- printk(KERN_INFO "%s: Group address not found\n", dev->name);
- break;
- default:
- break;
- } /* switch srb[2] */
- break;
-
-
- /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode
- */
-
- case SRB_SET_FUNC_ADDRESS:
- srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;
- switch (srb_word) {
- case 0x00:
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Functional Address Mask Set\n", dev->name);
- break;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name);
- break;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name);
- break;
- default:
- break;
- } /* switch srb[2] */
- break;
-
- /* SRB_READ_LOG - Read and reset the adapter error counters
- */
-
- case SRB_READ_LOG:
- srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;
- switch (srb_word) {
- case 0x00:
- {
- int i;
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Read Log command complete\n", dev->name);
- printk("Read Log statistics: ");
- writew(streamer_priv->srb + 6,
- streamer_mmio + LAPA);
- for (i = 0; i < 5; i++) {
- printk("%x:", ntohs(readw(streamer_mmio + LAPDINC)));
- }
- printk("\n");
- }
- break;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name);
- break;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name);
- break;
-
- } /* switch srb[2] */
- break;
-
- /* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */
-
- case SRB_READ_SR_COUNTERS:
- srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8;
- switch (srb_word) {
- case 0x00:
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Read Source Routing Counters issued\n", dev->name);
- break;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name);
- break;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name);
- break;
- default:
- break;
- } /* switch srb[2] */
- break;
-
- default:
- printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n", dev->name);
- break;
- } /* switch srb[0] */
-}
-
-static int streamer_set_mac_address(struct net_device *dev, void *addr)
-{
- struct sockaddr *saddr = addr;
- struct streamer_private *streamer_priv = netdev_priv(dev);
-
- if (netif_running(dev))
- {
- printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name);
- return -EIO;
- }
-
- memcpy(streamer_priv->streamer_laa, saddr->sa_data, dev->addr_len);
-
- if (streamer_priv->streamer_message_level) {
- printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",
- dev->name, streamer_priv->streamer_laa[0],
- streamer_priv->streamer_laa[1],
- streamer_priv->streamer_laa[2],
- streamer_priv->streamer_laa[3],
- streamer_priv->streamer_laa[4],
- streamer_priv->streamer_laa[5]);
- }
- return 0;
-}
-
-static void streamer_arb_cmd(struct net_device *dev)
-{
- struct streamer_private *streamer_priv =
- netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
- __u8 header_len;
- __u16 frame_len, buffer_len;
- struct sk_buff *mac_frame;
- __u8 frame_data[256];
- __u16 buff_off;
- __u16 lan_status = 0, lan_status_diff; /* Initialize to stop compiler warning */
- __u8 fdx_prot_error;
- __u16 next_ptr;
- __u16 arb_word;
-
-#if STREAMER_NETWORK_MONITOR
- struct trh_hdr *mac_hdr;
-#endif
-
- writew(streamer_priv->arb, streamer_mmio + LAPA);
- arb_word=ntohs(readw(streamer_mmio+LAPD)) >> 8;
-
- if (arb_word == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */
- writew(streamer_priv->arb + 6, streamer_mmio + LAPA);
- streamer_priv->mac_rx_buffer = buff_off = ntohs(readw(streamer_mmio + LAPDINC));
- header_len=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; /* 802.5 Token-Ring Header Length */
- frame_len = ntohs(readw(streamer_mmio + LAPDINC));
-
-#if STREAMER_DEBUG
- {
- int i;
- __u16 next;
- __u8 status;
- __u16 len;
-
- writew(ntohs(buff_off), streamer_mmio + LAPA); /*setup window to frame data */
- next = htons(readw(streamer_mmio + LAPDINC));
- status =
- ntohs(readw(streamer_mmio + LAPDINC)) & 0xff;
- len = ntohs(readw(streamer_mmio + LAPDINC));
-
- /* print out 1st 14 bytes of frame data */
- for (i = 0; i < 7; i++) {
- printk("Loc %d = %04x\n", i,
- ntohs(readw
- (streamer_mmio + LAPDINC)));
- }
-
- printk("next %04x, fs %02x, len %04x\n", next,
- status, len);
- }
-#endif
- if (!(mac_frame = dev_alloc_skb(frame_len))) {
- printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n",
- dev->name);
- goto drop_frame;
- }
- /* Walk the buffer chain, creating the frame */
-
- do {
- int i;
- __u16 rx_word;
-
- writew(htons(buff_off), streamer_mmio + LAPA); /* setup window to frame data */
- next_ptr = ntohs(readw(streamer_mmio + LAPDINC));
- readw(streamer_mmio + LAPDINC); /* read thru status word */
- buffer_len = ntohs(readw(streamer_mmio + LAPDINC));
-
- if (buffer_len > 256)
- break;
-
- i = 0;
- while (i < buffer_len) {
- rx_word=ntohs(readw(streamer_mmio+LAPDINC));
- frame_data[i]=rx_word >> 8;
- frame_data[i+1]=rx_word & 0xff;
- i += 2;
- }
-
- memcpy(skb_put(mac_frame, buffer_len),
- frame_data, buffer_len);
- } while (next_ptr && (buff_off = next_ptr));
-
- mac_frame->protocol = tr_type_trans(mac_frame, dev);
-#if STREAMER_NETWORK_MONITOR
- printk(KERN_WARNING "%s: Received MAC Frame, details:\n",
- dev->name);
- mac_hdr = tr_hdr(mac_frame);
- printk(KERN_WARNING
- "%s: MAC Frame Dest. Addr: %pM\n",
- dev->name, mac_hdr->daddr);
- printk(KERN_WARNING
- "%s: MAC Frame Srce. Addr: %pM\n",
- dev->name, mac_hdr->saddr);
-#endif
- netif_rx(mac_frame);
-
- /* Now tell the card we have dealt with the received frame */
-drop_frame:
- /* Set LISR Bit 1 */
- writel(LISR_ARB_FREE, streamer_priv->streamer_mmio + LISR_SUM);
-
- /* Is the ASB free ? */
-
- if (!(readl(streamer_priv->streamer_mmio + SISR) & SISR_ASB_FREE))
- {
- streamer_priv->asb_queued = 1;
- writel(LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM);
- return;
- /* Drop out and wait for the bottom half to be run */
- }
-
-
- writew(streamer_priv->asb, streamer_mmio + LAPA);
- writew(htons(ASB_RECEIVE_DATA << 8), streamer_mmio+LAPDINC);
- writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);
- writew(0, streamer_mmio + LAPDINC);
- writew(htons(streamer_priv->mac_rx_buffer), streamer_mmio + LAPD);
-
- writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM);
-
- streamer_priv->asb_queued = 2;
- return;
-
- } else if (arb_word == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */
- writew(streamer_priv->arb + 6, streamer_mmio + LAPA);
- lan_status = ntohs(readw(streamer_mmio + LAPDINC));
- fdx_prot_error = ntohs(readw(streamer_mmio+LAPD)) >> 8;
-
- /* Issue ARB Free */
- writew(LISR_ARB_FREE, streamer_priv->streamer_mmio + LISR_SUM);
-
- lan_status_diff = (streamer_priv->streamer_lan_status ^ lan_status) &
- lan_status;
-
- if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR))
- {
- if (lan_status_diff & LSC_LWF)
- printk(KERN_WARNING "%s: Short circuit detected on the lobe\n", dev->name);
- if (lan_status_diff & LSC_ARW)
- printk(KERN_WARNING "%s: Auto removal error\n", dev->name);
- if (lan_status_diff & LSC_FPE)
- printk(KERN_WARNING "%s: FDX Protocol Error\n", dev->name);
- if (lan_status_diff & LSC_RR)
- printk(KERN_WARNING "%s: Force remove MAC frame received\n", dev->name);
-
- /* Adapter has been closed by the hardware */
-
- /* reset tx/rx fifo's and busmaster logic */
-
- /* @TBD. no llc reset on autostreamer writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL);
- udelay(1);
- writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL); */
-
- netif_stop_queue(dev);
- netif_carrier_off(dev);
- printk(KERN_WARNING "%s: Adapter must be manually reset.\n", dev->name);
- }
- /* If serious error */
- if (streamer_priv->streamer_message_level) {
- if (lan_status_diff & LSC_SIG_LOSS)
- printk(KERN_WARNING "%s: No receive signal detected\n", dev->name);
- if (lan_status_diff & LSC_HARD_ERR)
- printk(KERN_INFO "%s: Beaconing\n", dev->name);
- if (lan_status_diff & LSC_SOFT_ERR)
- printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n", dev->name);
- if (lan_status_diff & LSC_TRAN_BCN)
- printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n", dev->name);
- if (lan_status_diff & LSC_SS)
- printk(KERN_INFO "%s: Single Station on the ring\n", dev->name);
- if (lan_status_diff & LSC_RING_REC)
- printk(KERN_INFO "%s: Ring recovery ongoing\n", dev->name);
- if (lan_status_diff & LSC_FDX_MODE)
- printk(KERN_INFO "%s: Operating in FDX mode\n", dev->name);
- }
-
- if (lan_status_diff & LSC_CO) {
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Counter Overflow\n", dev->name);
-
- /* Issue READ.LOG command */
-
- writew(streamer_priv->srb, streamer_mmio + LAPA);
- writew(htons(SRB_READ_LOG << 8),streamer_mmio+LAPDINC);
- writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);
- writew(0, streamer_mmio + LAPDINC);
- streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */
-
- writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM);
- }
-
- if (lan_status_diff & LSC_SR_CO) {
- if (streamer_priv->streamer_message_level)
- printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name);
-
- /* Issue a READ.SR.COUNTERS */
- writew(streamer_priv->srb, streamer_mmio + LAPA);
- writew(htons(SRB_READ_SR_COUNTERS << 8),
- streamer_mmio+LAPDINC);
- writew(htons(STREAMER_CLEAR_RET_CODE << 8),
- streamer_mmio+LAPDINC);
- streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */
- writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM);
-
- }
- streamer_priv->streamer_lan_status = lan_status;
- } /* Lan.change.status */
- else
- printk(KERN_WARNING "%s: Unknown arb command\n", dev->name);
-}
-
-static void streamer_asb_bh(struct net_device *dev)
-{
- struct streamer_private *streamer_priv =
- netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
-
- if (streamer_priv->asb_queued == 1)
- {
- /* Dropped through the first time */
-
- writew(streamer_priv->asb, streamer_mmio + LAPA);
- writew(htons(ASB_RECEIVE_DATA << 8),streamer_mmio+LAPDINC);
- writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC);
- writew(0, streamer_mmio + LAPDINC);
- writew(htons(streamer_priv->mac_rx_buffer), streamer_mmio + LAPD);
-
- writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM);
- streamer_priv->asb_queued = 2;
-
- return;
- }
-
- if (streamer_priv->asb_queued == 2) {
- __u8 rc;
- writew(streamer_priv->asb + 2, streamer_mmio + LAPA);
- rc=ntohs(readw(streamer_mmio+LAPD)) >> 8;
- switch (rc) {
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized command code\n", dev->name);
- break;
- case 0x26:
- printk(KERN_WARNING "%s: Unrecognized buffer address\n", dev->name);
- break;
- case 0xFF:
- /* Valid response, everything should be ok again */
- break;
- default:
- printk(KERN_WARNING "%s: Invalid return code in asb\n", dev->name);
- break;
- }
- }
- streamer_priv->asb_queued = 0;
-}
-
-static int streamer_change_mtu(struct net_device *dev, int mtu)
-{
- struct streamer_private *streamer_priv =
- netdev_priv(dev);
- __u16 max_mtu;
-
- if (streamer_priv->streamer_ring_speed == 4)
- max_mtu = 4500;
- else
- max_mtu = 18000;
-
- if (mtu > max_mtu)
- return -EINVAL;
- if (mtu < 100)
- return -EINVAL;
-
- dev->mtu = mtu;
- streamer_priv->pkt_buf_sz = mtu + TR_HLEN;
-
- return 0;
-}
-
-#if STREAMER_NETWORK_MONITOR
-#ifdef CONFIG_PROC_FS
-static int streamer_proc_info(char *buffer, char **start, off_t offset,
- int length, int *eof, void *data)
-{
- struct streamer_private *sdev=NULL;
- struct pci_dev *pci_device = NULL;
- int len = 0;
- off_t begin = 0;
- off_t pos = 0;
- int size;
-
- struct net_device *dev;
-
- size = sprintf(buffer, "IBM LanStreamer/MPC Chipset Token Ring Adapters\n");
-
- pos += size;
- len += size;
-
- for(sdev=dev_streamer; sdev; sdev=sdev->next) {
- pci_device=sdev->pci_dev;
- dev=pci_get_drvdata(pci_device);
-
- size = sprintf_info(buffer + len, dev);
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- break;
- } /* for */
-
- *start = buffer + (offset - begin); /* Start of wanted data */
- len -= (offset - begin); /* Start slop */
- if (len > length)
- len = length; /* Ending slop */
- return len;
-}
-
-static int sprintf_info(char *buffer, struct net_device *dev)
-{
- struct streamer_private *streamer_priv =
- netdev_priv(dev);
- __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio;
- struct streamer_adapter_addr_table sat;
- struct streamer_parameters_table spt;
- int size = 0;
- int i;
-
- writew(streamer_priv->streamer_addr_table_addr, streamer_mmio + LAPA);
- for (i = 0; i < 14; i += 2) {
- __u16 io_word;
- __u8 *datap = (__u8 *) & sat;
- io_word=ntohs(readw(streamer_mmio+LAPDINC));
- datap[size]=io_word >> 8;
- datap[size+1]=io_word & 0xff;
- }
- writew(streamer_priv->streamer_parms_addr, streamer_mmio + LAPA);
- for (i = 0; i < 68; i += 2) {
- __u16 io_word;
- __u8 *datap = (__u8 *) & spt;
- io_word=ntohs(readw(streamer_mmio+LAPDINC));
- datap[size]=io_word >> 8;
- datap[size+1]=io_word & 0xff;
- }
-
- size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name);
-
- size += sprintf(buffer + size,
- "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
- dev->name, dev->dev_addr, sat.node_addr,
- sat.func_addr[0], sat.func_addr[1],
- sat.func_addr[2], sat.func_addr[3]);
-
- size += sprintf(buffer + size, "\n%6s: Token Ring Parameters Table:\n", dev->name);
-
- size += sprintf(buffer + size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n", dev->name);
-
- size += sprintf(buffer + size,
- "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n",
- dev->name, spt.phys_addr[0], spt.phys_addr[1],
- spt.phys_addr[2], spt.phys_addr[3],
- spt.up_node_addr, spt.poll_addr,
- ntohs(spt.acc_priority), ntohs(spt.auth_source_class),
- ntohs(spt.att_code));
-
- size += sprintf(buffer + size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", dev->name);
-
- size += sprintf(buffer + size,
- "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n",
- dev->name, spt.source_addr,
- ntohs(spt.beacon_type), ntohs(spt.major_vector),
- ntohs(spt.lan_status), ntohs(spt.local_ring),
- ntohs(spt.mon_error), ntohs(spt.frame_correl));
-
- size += sprintf(buffer + size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n",
- dev->name);
-
- size += sprintf(buffer + size,
- "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n",
- dev->name, ntohs(spt.beacon_transmit),
- ntohs(spt.beacon_receive),
- spt.beacon_naun,
- spt.beacon_phys[0], spt.beacon_phys[1],
- spt.beacon_phys[2], spt.beacon_phys[3]);
- return size;
-}
-#endif
-#endif
-
-static struct pci_driver streamer_pci_driver = {
- .name = "lanstreamer",
- .id_table = streamer_pci_tbl,
- .probe = streamer_init_one,
- .remove = __devexit_p(streamer_remove_one),
-};
-
-module_pci_driver(streamer_pci_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/tokenring/lanstreamer.h b/drivers/net/tokenring/lanstreamer.h
deleted file mode 100644
index 3c58d6a3fbc9..000000000000
--- a/drivers/net/tokenring/lanstreamer.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * lanstreamer.h -- driver for the IBM Auto LANStreamer PCI Adapter
- *
- * Written By: Mike Sullivan, IBM Corporation
- *
- * Copyright (C) 1999 IBM Corporation
- *
- * Linux driver for IBM PCI tokenring cards based on the LanStreamer MPC
- * chipset.
- *
- * This driver is based on the olympic driver for IBM PCI TokenRing cards (Pit/Pit-Phy/Olympic
- * chipsets) written by:
- * 1999 Peter De Schrijver All Rights Reserved
- * 1999 Mike Phillips (phillim@amtrak.com)
- *
- * Base Driver Skeleton:
- * Written 1993-94 by Donald Becker.
- *
- * Copyright 1993 United States Government as represented by the
- * Director, National Security Agency.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
- *
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * 12/10/99 - Alpha Release 0.1.0
- * First release to the public
- * 08/15/01 - Added ioctl() definitions and others - Kent Yoder <yoder1@us.ibm.com>
- *
- */
-
-/* MAX_INTR - the maximum number of times we can loop
- * inside the interrupt function before returning
- * control to the OS (maximum value is 256)
- */
-#define MAX_INTR 5
-
-#define CLS 0x0C
-#define MLR 0x86
-#define LTR 0x0D
-
-#define BCTL 0x60
-#define BCTL_SOFTRESET (1<<15)
-#define BCTL_RX_FIFO_8 (1<<1)
-#define BCTL_TX_FIFO_8 (1<<3)
-
-#define GPR 0x4a
-#define GPR_AUTOSENSE (1<<2)
-#define GPR_16MBPS (1<<3)
-
-#define LISR 0x10
-#define LISR_SUM 0x12
-#define LISR_RUM 0x14
-
-#define LISR_LIE (1<<15)
-#define LISR_SLIM (1<<13)
-#define LISR_SLI (1<<12)
-#define LISR_BPEI (1<<9)
-#define LISR_BPE (1<<8)
-#define LISR_SRB_CMD (1<<5)
-#define LISR_ASB_REPLY (1<<4)
-#define LISR_ASB_FREE_REQ (1<<2)
-#define LISR_ARB_FREE (1<<1)
-#define LISR_TRB_FRAME (1<<0)
-
-#define SISR 0x16
-#define SISR_SUM 0x18
-#define SISR_RUM 0x1A
-#define SISR_MASK 0x54
-#define SISR_MASK_SUM 0x56
-#define SISR_MASK_RUM 0x58
-
-#define SISR_MI (1<<15)
-#define SISR_SERR_ERR (1<<14)
-#define SISR_TIMER (1<<11)
-#define SISR_LAP_PAR_ERR (1<<10)
-#define SISR_LAP_ACC_ERR (1<<9)
-#define SISR_PAR_ERR (1<<8)
-#define SISR_ADAPTER_CHECK (1<<6)
-#define SISR_SRB_REPLY (1<<5)
-#define SISR_ASB_FREE (1<<4)
-#define SISR_ARB_CMD (1<<3)
-#define SISR_TRB_REPLY (1<<2)
-
-#define MISR_RUM 0x5A
-#define MISR_MASK 0x5C
-#define MISR_MASK_RUM 0x5E
-
-#define MISR_TX2_IDLE (1<<15)
-#define MISR_TX2_NO_STATUS (1<<14)
-#define MISR_TX2_HALT (1<<13)
-#define MISR_TX2_EOF (1<<12)
-#define MISR_TX1_IDLE (1<<11)
-#define MISR_TX1_NO_STATUS (1<<10)
-#define MISR_TX1_HALT (1<<9)
-#define MISR_TX1_EOF (1<<8)
-#define MISR_RX_NOBUF (1<<5)
-#define MISR_RX_EOB (1<<4)
-#define MISR_RX_NO_STATUS (1<<2)
-#define MISR_RX_HALT (1<<1)
-#define MISR_RX_EOF (1<<0)
-
-#define LAPA 0x62
-#define LAPE 0x64
-#define LAPD 0x66
-#define LAPDINC 0x68
-#define LAPWWO 0x6A
-#define LAPWWC 0x6C
-#define LAPCTL 0x6E
-
-#define TIMER 0x4E4
-
-#define BMCTL_SUM 0x50
-#define BMCTL_RUM 0x52
-#define BMCTL_TX1_DIS (1<<14)
-#define BMCTL_TX2_DIS (1<<10)
-#define BMCTL_RX_DIS (1<<6)
-#define BMCTL_RX_ENABLED (1<<5)
-
-#define RXLBDA 0x90
-#define RXBDA 0x94
-#define RXSTAT 0x98
-#define RXDBA 0x9C
-
-#define TX1LFDA 0xA0
-#define TX1FDA 0xA4
-#define TX1STAT 0xA8
-#define TX1DBA 0xAC
-#define TX2LFDA 0xB0
-#define TX2FDA 0xB4
-#define TX2STAT 0xB8
-#define TX2DBA 0xBC
-
-#define STREAMER_IO_SPACE 256
-
-#define SRB_COMMAND_SIZE 50
-
-#define STREAMER_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */
-
-/* Defines for LAN STATUS CHANGE reports */
-#define LSC_SIG_LOSS 0x8000
-#define LSC_HARD_ERR 0x4000
-#define LSC_SOFT_ERR 0x2000
-#define LSC_TRAN_BCN 0x1000
-#define LSC_LWF 0x0800
-#define LSC_ARW 0x0400
-#define LSC_FPE 0x0200
-#define LSC_RR 0x0100
-#define LSC_CO 0x0080
-#define LSC_SS 0x0040
-#define LSC_RING_REC 0x0020
-#define LSC_SR_CO 0x0010
-#define LSC_FDX_MODE 0x0004
-
-/* Defines for OPEN ADAPTER command */
-
-#define OPEN_ADAPTER_EXT_WRAP (1<<15)
-#define OPEN_ADAPTER_DIS_HARDEE (1<<14)
-#define OPEN_ADAPTER_DIS_SOFTERR (1<<13)
-#define OPEN_ADAPTER_PASS_ADC_MAC (1<<12)
-#define OPEN_ADAPTER_PASS_ATT_MAC (1<<11)
-#define OPEN_ADAPTER_ENABLE_EC (1<<10)
-#define OPEN_ADAPTER_CONTENDER (1<<8)
-#define OPEN_ADAPTER_PASS_BEACON (1<<7)
-#define OPEN_ADAPTER_ENABLE_FDX (1<<6)
-#define OPEN_ADAPTER_ENABLE_RPL (1<<5)
-#define OPEN_ADAPTER_INHIBIT_ETR (1<<4)
-#define OPEN_ADAPTER_INTERNAL_WRAP (1<<3)
-
-
-/* Defines for SRB Commands */
-#define SRB_CLOSE_ADAPTER 0x04
-#define SRB_CONFIGURE_BRIDGE 0x0c
-#define SRB_CONFIGURE_HP_CHANNEL 0x13
-#define SRB_MODIFY_BRIDGE_PARMS 0x15
-#define SRB_MODIFY_OPEN_OPTIONS 0x01
-#define SRB_MODIFY_RECEIVE_OPTIONS 0x17
-#define SRB_NO_OPERATION 0x00
-#define SRB_OPEN_ADAPTER 0x03
-#define SRB_READ_LOG 0x08
-#define SRB_READ_SR_COUNTERS 0x16
-#define SRB_RESET_GROUP_ADDRESS 0x02
-#define SRB_RESET_TARGET_SEGMETN 0x14
-#define SRB_SAVE_CONFIGURATION 0x1b
-#define SRB_SET_BRIDGE_PARMS 0x09
-#define SRB_SET_FUNC_ADDRESS 0x07
-#define SRB_SET_GROUP_ADDRESS 0x06
-#define SRB_SET_TARGET_SEGMENT 0x05
-
-/* Clear return code */
-#define STREAMER_CLEAR_RET_CODE 0xfe
-
-/* ARB Commands */
-#define ARB_RECEIVE_DATA 0x81
-#define ARB_LAN_CHANGE_STATUS 0x84
-
-/* ASB Response commands */
-#define ASB_RECEIVE_DATA 0x81
-
-
-/* Streamer defaults for buffers */
-
-#define STREAMER_RX_RING_SIZE 16 /* should be a power of 2 */
-/* Setting the number of TX descriptors to 1 is a workaround for an
- * undocumented hardware problem with the lanstreamer board. Setting
- * this to something higher may slightly increase the throughput you
- * can get from the card, but at the risk of locking up the box. -
- * <yoder1@us.ibm.com>
- */
-#define STREAMER_TX_RING_SIZE 1 /* should be a power of 2 */
-
-#define PKT_BUF_SZ 4096 /* Default packet size */
-
-/* Streamer data structures */
-
-struct streamer_tx_desc {
- __u32 forward;
- __u32 status;
- __u32 bufcnt_framelen;
- __u32 buffer;
- __u32 buflen;
- __u32 rsvd1;
- __u32 rsvd2;
- __u32 rsvd3;
-};
-
-struct streamer_rx_desc {
- __u32 forward;
- __u32 status;
- __u32 buffer;
- __u32 framelen_buflen;
-};
-
-struct mac_receive_buffer {
- __u16 next;
- __u8 padding;
- __u8 frame_status;
- __u16 buffer_length;
- __u8 frame_data;
-};
-
-struct streamer_private {
-
- __u16 srb;
- __u16 trb;
- __u16 arb;
- __u16 asb;
-
- struct streamer_private *next;
- struct pci_dev *pci_dev;
- __u8 __iomem *streamer_mmio;
- char *streamer_card_name;
-
- spinlock_t streamer_lock;
-
- volatile int srb_queued; /* True if an SRB is still posted */
- wait_queue_head_t srb_wait;
-
- volatile int asb_queued; /* True if an ASB is posted */
-
- volatile int trb_queued; /* True if a TRB is posted */
- wait_queue_head_t trb_wait;
-
- struct streamer_rx_desc *streamer_rx_ring;
- struct streamer_tx_desc *streamer_tx_ring;
- struct sk_buff *tx_ring_skb[STREAMER_TX_RING_SIZE],
- *rx_ring_skb[STREAMER_RX_RING_SIZE];
- int tx_ring_free, tx_ring_last_status, rx_ring_last_received,
- free_tx_ring_entries;
-
- __u16 streamer_lan_status;
- __u8 streamer_ring_speed;
- __u16 pkt_buf_sz;
- __u8 streamer_receive_options, streamer_copy_all_options,
- streamer_message_level;
- __u16 streamer_addr_table_addr, streamer_parms_addr;
- __u16 mac_rx_buffer;
- __u8 streamer_laa[6];
-};
-
-struct streamer_adapter_addr_table {
-
- __u8 node_addr[6];
- __u8 reserved[4];
- __u8 func_addr[4];
-};
-
-struct streamer_parameters_table {
-
- __u8 phys_addr[4];
- __u8 up_node_addr[6];
- __u8 up_phys_addr[4];
- __u8 poll_addr[6];
- __u16 reserved;
- __u16 acc_priority;
- __u16 auth_source_class;
- __u16 att_code;
- __u8 source_addr[6];
- __u16 beacon_type;
- __u16 major_vector;
- __u16 lan_status;
- __u16 soft_error_time;
- __u16 reserved1;
- __u16 local_ring;
- __u16 mon_error;
- __u16 beacon_transmit;
- __u16 beacon_receive;
- __u16 frame_correl;
- __u8 beacon_naun[6];
- __u32 reserved2;
- __u8 beacon_phys[4];
-};
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
deleted file mode 100644
index 28adcdf3b14c..000000000000
--- a/drivers/net/tokenring/madgemc.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * madgemc.c: Driver for the Madge Smart 16/4 MC16 MCA token ring card.
- *
- * Written 2000 by Adam Fritzler
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * This driver module supports the following cards:
- * - Madge Smart 16/4 Ringnode MC16
- * - Madge Smart 16/4 Ringnode MC32 (??)
- *
- * Maintainer(s):
- * AF Adam Fritzler
- *
- * Modification History:
- * 16-Jan-00 AF Created
- *
- */
-static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n";
-
-#include <linux/module.h>
-#include <linux/mca.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "tms380tr.h"
-#include "madgemc.h" /* Madge-specific constants */
-
-#define MADGEMC_IO_EXTENT 32
-#define MADGEMC_SIF_OFFSET 0x08
-
-struct card_info {
- /*
- * These are read from the BIA ROM.
- */
- unsigned int manid;
- unsigned int cardtype;
- unsigned int cardrev;
- unsigned int ramsize;
-
- /*
- * These are read from the MCA POS registers.
- */
- unsigned int burstmode:2;
- unsigned int fairness:1; /* 0 = Fair, 1 = Unfair */
- unsigned int arblevel:4;
- unsigned int ringspeed:2; /* 0 = 4mb, 1 = 16, 2 = Auto/none */
- unsigned int cabletype:1; /* 0 = RJ45, 1 = DB9 */
-};
-
-static int madgemc_open(struct net_device *dev);
-static int madgemc_close(struct net_device *dev);
-static int madgemc_chipset_init(struct net_device *dev);
-static void madgemc_read_rom(struct net_device *dev, struct card_info *card);
-static unsigned short madgemc_setnselout_pins(struct net_device *dev);
-static void madgemc_setcabletype(struct net_device *dev, int type);
-
-static int madgemc_mcaproc(char *buf, int slot, void *d);
-
-static void madgemc_setregpage(struct net_device *dev, int page);
-static void madgemc_setsifsel(struct net_device *dev, int val);
-static void madgemc_setint(struct net_device *dev, int val);
-
-static irqreturn_t madgemc_interrupt(int irq, void *dev_id);
-
-/*
- * These work around paging, however they don't guarantee you're on the
- * right page.
- */
-#define SIFREADB(reg) (inb(dev->base_addr + ((reg<0x8)?reg:reg-0x8)))
-#define SIFWRITEB(val, reg) (outb(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8)))
-#define SIFREADW(reg) (inw(dev->base_addr + ((reg<0x8)?reg:reg-0x8)))
-#define SIFWRITEW(val, reg) (outw(val, dev->base_addr + ((reg<0x8)?reg:reg-0x8)))
-
-/*
- * Read a byte-length value from the register.
- */
-static unsigned short madgemc_sifreadb(struct net_device *dev, unsigned short reg)
-{
- unsigned short ret;
- if (reg<0x8)
- ret = SIFREADB(reg);
- else {
- madgemc_setregpage(dev, 1);
- ret = SIFREADB(reg);
- madgemc_setregpage(dev, 0);
- }
- return ret;
-}
-
-/*
- * Write a byte-length value to a register.
- */
-static void madgemc_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- if (reg<0x8)
- SIFWRITEB(val, reg);
- else {
- madgemc_setregpage(dev, 1);
- SIFWRITEB(val, reg);
- madgemc_setregpage(dev, 0);
- }
-}
-
-/*
- * Read a word-length value from a register
- */
-static unsigned short madgemc_sifreadw(struct net_device *dev, unsigned short reg)
-{
- unsigned short ret;
- if (reg<0x8)
- ret = SIFREADW(reg);
- else {
- madgemc_setregpage(dev, 1);
- ret = SIFREADW(reg);
- madgemc_setregpage(dev, 0);
- }
- return ret;
-}
-
-/*
- * Write a word-length value to a register.
- */
-static void madgemc_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- if (reg<0x8)
- SIFWRITEW(val, reg);
- else {
- madgemc_setregpage(dev, 1);
- SIFWRITEW(val, reg);
- madgemc_setregpage(dev, 0);
- }
-}
-
-static struct net_device_ops madgemc_netdev_ops __read_mostly;
-
-static int __devinit madgemc_probe(struct device *device)
-{
- static int versionprinted;
- struct net_device *dev;
- struct net_local *tp;
- struct card_info *card;
- struct mca_device *mdev = to_mca_device(device);
- int ret = 0;
-
- if (versionprinted++ == 0)
- printk("%s", version);
-
- if(mca_device_claimed(mdev))
- return -EBUSY;
- mca_device_set_claim(mdev, 1);
-
- dev = alloc_trdev(sizeof(struct net_local));
- if (!dev) {
- printk("madgemc: unable to allocate dev space\n");
- mca_device_set_claim(mdev, 0);
- ret = -ENOMEM;
- goto getout;
- }
-
- dev->netdev_ops = &madgemc_netdev_ops;
-
- card = kmalloc(sizeof(struct card_info), GFP_KERNEL);
- if (card==NULL) {
- ret = -ENOMEM;
- goto getout1;
- }
-
- /*
- * Parse configuration information. This all comes
- * directly from the publicly available @002d.ADF.
- * Get it from Madge or your local ADF library.
- */
-
- /*
- * Base address
- */
- dev->base_addr = 0x0a20 +
- ((mdev->pos[2] & MC16_POS2_ADDR2)?0x0400:0) +
- ((mdev->pos[0] & MC16_POS0_ADDR1)?0x1000:0) +
- ((mdev->pos[3] & MC16_POS3_ADDR3)?0x2000:0);
-
- /*
- * Interrupt line
- */
- switch(mdev->pos[0] >> 6) { /* upper two bits */
- case 0x1: dev->irq = 3; break;
- case 0x2: dev->irq = 9; break; /* IRQ 2 = IRQ 9 */
- case 0x3: dev->irq = 10; break;
- default: dev->irq = 0; break;
- }
-
- if (dev->irq == 0) {
- printk("%s: invalid IRQ\n", dev->name);
- ret = -EBUSY;
- goto getout2;
- }
-
- if (!request_region(dev->base_addr, MADGEMC_IO_EXTENT,
- "madgemc")) {
- printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", mdev->slot, dev->base_addr);
- dev->base_addr += MADGEMC_SIF_OFFSET;
- ret = -EBUSY;
- goto getout2;
- }
- dev->base_addr += MADGEMC_SIF_OFFSET;
-
- /*
- * Arbitration Level
- */
- card->arblevel = ((mdev->pos[0] >> 1) & 0x7) + 8;
-
- /*
- * Burst mode and Fairness
- */
- card->burstmode = ((mdev->pos[2] >> 6) & 0x3);
- card->fairness = ((mdev->pos[2] >> 4) & 0x1);
-
- /*
- * Ring Speed
- */
- if ((mdev->pos[1] >> 2)&0x1)
- card->ringspeed = 2; /* not selected */
- else if ((mdev->pos[2] >> 5) & 0x1)
- card->ringspeed = 1; /* 16Mb */
- else
- card->ringspeed = 0; /* 4Mb */
-
- /*
- * Cable type
- */
- if ((mdev->pos[1] >> 6)&0x1)
- card->cabletype = 1; /* STP/DB9 */
- else
- card->cabletype = 0; /* UTP/RJ-45 */
-
-
- /*
- * ROM Info. This requires us to actually twiddle
- * bits on the card, so we must ensure above that
- * the base address is free of conflict (request_region above).
- */
- madgemc_read_rom(dev, card);
-
- if (card->manid != 0x4d) { /* something went wrong */
- printk(KERN_INFO "%s: Madge MC ROM read failed (unknown manufacturer ID %02x)\n", dev->name, card->manid);
- goto getout3;
- }
-
- if ((card->cardtype != 0x08) && (card->cardtype != 0x0d)) {
- printk(KERN_INFO "%s: Madge MC ROM read failed (unknown card ID %02x)\n", dev->name, card->cardtype);
- ret = -EIO;
- goto getout3;
- }
-
- /* All cards except Rev 0 and 1 MC16's have 256kb of RAM */
- if ((card->cardtype == 0x08) && (card->cardrev <= 0x01))
- card->ramsize = 128;
- else
- card->ramsize = 256;
-
- printk("%s: %s Rev %d at 0x%04lx IRQ %d\n",
- dev->name,
- (card->cardtype == 0x08)?MADGEMC16_CARDNAME:
- MADGEMC32_CARDNAME, card->cardrev,
- dev->base_addr, dev->irq);
-
- if (card->cardtype == 0x0d)
- printk("%s: Warning: MC32 support is experimental and highly untested\n", dev->name);
-
- if (card->ringspeed==2) { /* Unknown */
- printk("%s: Warning: Ring speed not set in POS -- Please run the reference disk and set it!\n", dev->name);
- card->ringspeed = 1; /* default to 16mb */
- }
-
- printk("%s: RAM Size: %dKB\n", dev->name, card->ramsize);
-
- printk("%s: Ring Speed: %dMb/sec on %s\n", dev->name,
- (card->ringspeed)?16:4,
- card->cabletype?"STP/DB9":"UTP/RJ-45");
- printk("%s: Arbitration Level: %d\n", dev->name,
- card->arblevel);
-
- printk("%s: Burst Mode: ", dev->name);
- switch(card->burstmode) {
- case 0: printk("Cycle steal"); break;
- case 1: printk("Limited burst"); break;
- case 2: printk("Delayed release"); break;
- case 3: printk("Immediate release"); break;
- }
- printk(" (%s)\n", (card->fairness)?"Unfair":"Fair");
-
-
- /*
- * Enable SIF before we assign the interrupt handler,
- * just in case we get spurious interrupts that need
- * handling.
- */
- outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */
- madgemc_setsifsel(dev, 1);
- if (request_irq(dev->irq, madgemc_interrupt, IRQF_SHARED,
- "madgemc", dev)) {
- ret = -EBUSY;
- goto getout3;
- }
-
- madgemc_chipset_init(dev); /* enables interrupts! */
- madgemc_setcabletype(dev, card->cabletype);
-
- /* Setup MCA structures */
- mca_device_set_name(mdev, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME);
- mca_set_adapter_procfn(mdev->slot, madgemc_mcaproc, dev);
-
- printk("%s: Ring Station Address: %pM\n",
- dev->name, dev->dev_addr);
-
- if (tmsdev_init(dev, device)) {
- printk("%s: unable to get memory for dev->priv.\n",
- dev->name);
- ret = -ENOMEM;
- goto getout4;
- }
- tp = netdev_priv(dev);
-
- /*
- * The MC16 is physically a 32bit card. However, Madge
- * insists on calling it 16bit, so I'll assume here that
- * they know what they're talking about. Cut off DMA
- * at 16mb.
- */
- tp->setnselout = madgemc_setnselout_pins;
- tp->sifwriteb = madgemc_sifwriteb;
- tp->sifreadb = madgemc_sifreadb;
- tp->sifwritew = madgemc_sifwritew;
- tp->sifreadw = madgemc_sifreadw;
- tp->DataRate = (card->ringspeed)?SPEED_16:SPEED_4;
-
- memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1);
-
- tp->tmspriv = card;
- dev_set_drvdata(device, dev);
-
- if (register_netdev(dev) == 0)
- return 0;
-
- dev_set_drvdata(device, NULL);
- ret = -ENOMEM;
-getout4:
- free_irq(dev->irq, dev);
-getout3:
- release_region(dev->base_addr-MADGEMC_SIF_OFFSET,
- MADGEMC_IO_EXTENT);
-getout2:
- kfree(card);
-getout1:
- free_netdev(dev);
-getout:
- mca_device_set_claim(mdev, 0);
- return ret;
-}
-
-/*
- * Handle interrupts generated by the card
- *
- * The MicroChannel Madge cards need slightly more handling
- * after an interrupt than other TMS380 cards do.
- *
- * First we must make sure it was this card that generated the
- * interrupt (since interrupt sharing is allowed). Then,
- * because we're using level-triggered interrupts (as is
- * standard on MCA), we must toggle the interrupt line
- * on the card in order to claim and acknowledge the interrupt.
- * Once that is done, the interrupt should be handlable in
- * the normal tms380tr_interrupt() routine.
- *
- * There's two ways we can check to see if the interrupt is ours,
- * both with their own disadvantages...
- *
- * 1) Read in the SIFSTS register from the TMS controller. This
- * is guaranteed to be accurate, however, there's a fairly
- * large performance penalty for doing so: the Madge chips
- * must request the register from the Eagle, the Eagle must
- * read them from its internal bus, and then take the route
- * back out again, for a 16bit read.
- *
- * 2) Use the MC_CONTROL_REG0_SINTR bit from the Madge ASICs.
- * The major disadvantage here is that the accuracy of the
- * bit is in question. However, it cuts out the extra read
- * cycles it takes to read the Eagle's SIF, as its only an
- * 8bit read, and theoretically the Madge bit is directly
- * connected to the interrupt latch coming out of the Eagle
- * hardware (that statement is not verified).
- *
- * I can't determine which of these methods has the best win. For now,
- * we make a compromise. Use the Madge way for the first interrupt,
- * which should be the fast-path, and then once we hit the first
- * interrupt, keep on trying using the SIF method until we've
- * exhausted all contiguous interrupts.
- *
- */
-static irqreturn_t madgemc_interrupt(int irq, void *dev_id)
-{
- int pending,reg1;
- struct net_device *dev;
-
- if (!dev_id) {
- printk("madgemc_interrupt: was not passed a dev_id!\n");
- return IRQ_NONE;
- }
-
- dev = dev_id;
-
- /* Make sure its really us. -- the Madge way */
- pending = inb(dev->base_addr + MC_CONTROL_REG0);
- if (!(pending & MC_CONTROL_REG0_SINTR))
- return IRQ_NONE; /* not our interrupt */
-
- /*
- * Since we're level-triggered, we may miss the rising edge
- * of the next interrupt while we're off handling this one,
- * so keep checking until the SIF verifies that it has nothing
- * left for us to do.
- */
- pending = STS_SYSTEM_IRQ;
- do {
- if (pending & STS_SYSTEM_IRQ) {
-
- /* Toggle the interrupt to reset the latch on card */
- reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
- outb(reg1 ^ MC_CONTROL_REG1_SINTEN,
- dev->base_addr + MC_CONTROL_REG1);
- outb(reg1, dev->base_addr + MC_CONTROL_REG1);
-
- /* Continue handling as normal */
- tms380tr_interrupt(irq, dev_id);
-
- pending = SIFREADW(SIFSTS); /* restart - the SIF way */
-
- } else
- return IRQ_HANDLED;
- } while (1);
-
- return IRQ_HANDLED; /* not reachable */
-}
-
-/*
- * Set the card to the preferred ring speed.
- *
- * Unlike newer cards, the MC16/32 have their speed selection
- * circuit connected to the Madge ASICs and not to the TMS380
- * NSELOUT pins. Set the ASIC bits correctly here, and return
- * zero to leave the TMS NSELOUT bits unaffected.
- *
- */
-static unsigned short madgemc_setnselout_pins(struct net_device *dev)
-{
- unsigned char reg1;
- struct net_local *tp = netdev_priv(dev);
-
- reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
-
- if(tp->DataRate == SPEED_16)
- reg1 |= MC_CONTROL_REG1_SPEED_SEL; /* add for 16mb */
- else if (reg1 & MC_CONTROL_REG1_SPEED_SEL)
- reg1 ^= MC_CONTROL_REG1_SPEED_SEL; /* remove for 4mb */
- outb(reg1, dev->base_addr + MC_CONTROL_REG1);
-
- return 0; /* no change */
-}
-
-/*
- * Set the register page. This equates to the SRSX line
- * on the TMS380Cx6.
- *
- * Register selection is normally done via three contiguous
- * bits. However, some boards (such as the MC16/32) use only
- * two bits, plus a separate bit in the glue chip. This
- * sets the SRSX bit (the top bit). See page 4-17 in the
- * Yellow Book for which registers are affected.
- *
- */
-static void madgemc_setregpage(struct net_device *dev, int page)
-{
- static int reg1;
-
- reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
- if ((page == 0) && (reg1 & MC_CONTROL_REG1_SRSX)) {
- outb(reg1 ^ MC_CONTROL_REG1_SRSX,
- dev->base_addr + MC_CONTROL_REG1);
- }
- else if (page == 1) {
- outb(reg1 | MC_CONTROL_REG1_SRSX,
- dev->base_addr + MC_CONTROL_REG1);
- }
- reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
-}
-
-/*
- * The SIF registers are not mapped into register space by default
- * Set this to 1 to map them, 0 to map the BIA ROM.
- *
- */
-static void madgemc_setsifsel(struct net_device *dev, int val)
-{
- unsigned int reg0;
-
- reg0 = inb(dev->base_addr + MC_CONTROL_REG0);
- if ((val == 0) && (reg0 & MC_CONTROL_REG0_SIFSEL)) {
- outb(reg0 ^ MC_CONTROL_REG0_SIFSEL,
- dev->base_addr + MC_CONTROL_REG0);
- } else if (val == 1) {
- outb(reg0 | MC_CONTROL_REG0_SIFSEL,
- dev->base_addr + MC_CONTROL_REG0);
- }
- reg0 = inb(dev->base_addr + MC_CONTROL_REG0);
-}
-
-/*
- * Enable SIF interrupts
- *
- * This does not enable interrupts in the SIF, but rather
- * enables SIF interrupts to be passed onto the host.
- *
- */
-static void madgemc_setint(struct net_device *dev, int val)
-{
- unsigned int reg1;
-
- reg1 = inb(dev->base_addr + MC_CONTROL_REG1);
- if ((val == 0) && (reg1 & MC_CONTROL_REG1_SINTEN)) {
- outb(reg1 ^ MC_CONTROL_REG1_SINTEN,
- dev->base_addr + MC_CONTROL_REG1);
- } else if (val == 1) {
- outb(reg1 | MC_CONTROL_REG1_SINTEN,
- dev->base_addr + MC_CONTROL_REG1);
- }
-}
-
-/*
- * Cable type is set via control register 7. Bit zero high
- * for UTP, low for STP.
- */
-static void madgemc_setcabletype(struct net_device *dev, int type)
-{
- outb((type==0)?MC_CONTROL_REG7_CABLEUTP:MC_CONTROL_REG7_CABLESTP,
- dev->base_addr + MC_CONTROL_REG7);
-}
-
-/*
- * Enable the functions of the Madge chipset needed for
- * full working order.
- */
-static int madgemc_chipset_init(struct net_device *dev)
-{
- outb(0, dev->base_addr + MC_CONTROL_REG1); /* pull SRESET low */
- tms380tr_wait(100); /* wait for card to reset */
-
- /* bring back into normal operating mode */
- outb(MC_CONTROL_REG1_NSRESET, dev->base_addr + MC_CONTROL_REG1);
-
- /* map SIF registers */
- madgemc_setsifsel(dev, 1);
-
- /* enable SIF interrupts */
- madgemc_setint(dev, 1);
-
- return 0;
-}
-
-/*
- * Disable the board, and put back into power-up state.
- */
-static void madgemc_chipset_close(struct net_device *dev)
-{
- /* disable interrupts */
- madgemc_setint(dev, 0);
- /* unmap SIF registers */
- madgemc_setsifsel(dev, 0);
-}
-
-/*
- * Read the card type (MC16 or MC32) from the card.
- *
- * The configuration registers are stored in two separate
- * pages. Pages are flipped by clearing bit 3 of CONTROL_REG0 (PAGE)
- * for page zero, or setting bit 3 for page one.
- *
- * Page zero contains the following data:
- * Byte 0: Manufacturer ID (0x4D -- ASCII "M")
- * Byte 1: Card type:
- * 0x08 for MC16
- * 0x0D for MC32
- * Byte 2: Card revision
- * Byte 3: Mirror of POS config register 0
- * Byte 4: Mirror of POS 1
- * Byte 5: Mirror of POS 2
- *
- * Page one contains the following data:
- * Byte 0: Unused
- * Byte 1-6: BIA, MSB to LSB.
- *
- * Note that to read the BIA, we must unmap the SIF registers
- * by clearing bit 2 of CONTROL_REG0 (SIFSEL), as the data
- * will reside in the same logical location. For this reason,
- * _never_ read the BIA while the Eagle processor is running!
- * The SIF will be completely inaccessible until the BIA operation
- * is complete.
- *
- */
-static void madgemc_read_rom(struct net_device *dev, struct card_info *card)
-{
- unsigned long ioaddr;
- unsigned char reg0, reg1, tmpreg0, i;
-
- ioaddr = dev->base_addr;
-
- reg0 = inb(ioaddr + MC_CONTROL_REG0);
- reg1 = inb(ioaddr + MC_CONTROL_REG1);
-
- /* Switch to page zero and unmap SIF */
- tmpreg0 = reg0 & ~(MC_CONTROL_REG0_PAGE + MC_CONTROL_REG0_SIFSEL);
- outb(tmpreg0, ioaddr + MC_CONTROL_REG0);
-
- card->manid = inb(ioaddr + MC_ROM_MANUFACTURERID);
- card->cardtype = inb(ioaddr + MC_ROM_ADAPTERID);
- card->cardrev = inb(ioaddr + MC_ROM_REVISION);
-
- /* Switch to rom page one */
- outb(tmpreg0 | MC_CONTROL_REG0_PAGE, ioaddr + MC_CONTROL_REG0);
-
- /* Read BIA */
- dev->addr_len = 6;
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + MC_ROM_BIA_START + i);
-
- /* Restore original register values */
- outb(reg0, ioaddr + MC_CONTROL_REG0);
- outb(reg1, ioaddr + MC_CONTROL_REG1);
-}
-
-static int madgemc_open(struct net_device *dev)
-{
- /*
- * Go ahead and reinitialize the chipset again, just to
- * make sure we didn't get left in a bad state.
- */
- madgemc_chipset_init(dev);
- tms380tr_open(dev);
- return 0;
-}
-
-static int madgemc_close(struct net_device *dev)
-{
- tms380tr_close(dev);
- madgemc_chipset_close(dev);
- return 0;
-}
-
-/*
- * Give some details available from /proc/mca/slotX
- */
-static int madgemc_mcaproc(char *buf, int slot, void *d)
-{
- struct net_device *dev = (struct net_device *)d;
- struct net_local *tp = netdev_priv(dev);
- struct card_info *curcard = tp->tmspriv;
- int len = 0;
-
- len += sprintf(buf+len, "-------\n");
- if (curcard) {
- len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev);
- len += sprintf(buf+len, "RAM Size: %dkb\n", curcard->ramsize);
- len += sprintf(buf+len, "Cable type: %s\n", (curcard->cabletype)?"STP/DB9":"UTP/RJ-45");
- len += sprintf(buf+len, "Configured ring speed: %dMb/sec\n", (curcard->ringspeed)?16:4);
- len += sprintf(buf+len, "Running ring speed: %dMb/sec\n", (tp->DataRate==SPEED_16)?16:4);
- len += sprintf(buf+len, "Device: %s\n", dev->name);
- len += sprintf(buf+len, "IO Port: 0x%04lx\n", dev->base_addr);
- len += sprintf(buf+len, "IRQ: %d\n", dev->irq);
- len += sprintf(buf+len, "Arbitration Level: %d\n", curcard->arblevel);
- len += sprintf(buf+len, "Burst Mode: ");
- switch(curcard->burstmode) {
- case 0: len += sprintf(buf+len, "Cycle steal"); break;
- case 1: len += sprintf(buf+len, "Limited burst"); break;
- case 2: len += sprintf(buf+len, "Delayed release"); break;
- case 3: len += sprintf(buf+len, "Immediate release"); break;
- }
- len += sprintf(buf+len, " (%s)\n", (curcard->fairness)?"Unfair":"Fair");
-
- len += sprintf(buf+len, "Ring Station Address: %pM\n",
- dev->dev_addr);
- } else
- len += sprintf(buf+len, "Card not configured\n");
-
- return len;
-}
-
-static int __devexit madgemc_remove(struct device *device)
-{
- struct net_device *dev = dev_get_drvdata(device);
- struct net_local *tp;
- struct card_info *card;
-
- BUG_ON(!dev);
-
- tp = netdev_priv(dev);
- card = tp->tmspriv;
- kfree(card);
- tp->tmspriv = NULL;
-
- unregister_netdev(dev);
- release_region(dev->base_addr-MADGEMC_SIF_OFFSET, MADGEMC_IO_EXTENT);
- free_irq(dev->irq, dev);
- tmsdev_term(dev);
- free_netdev(dev);
- dev_set_drvdata(device, NULL);
-
- return 0;
-}
-
-static short madgemc_adapter_ids[] __initdata = {
- 0x002d,
- 0x0000
-};
-
-static struct mca_driver madgemc_driver = {
- .id_table = madgemc_adapter_ids,
- .driver = {
- .name = "madgemc",
- .bus = &mca_bus_type,
- .probe = madgemc_probe,
- .remove = __devexit_p(madgemc_remove),
- },
-};
-
-static int __init madgemc_init (void)
-{
- madgemc_netdev_ops = tms380tr_netdev_ops;
- madgemc_netdev_ops.ndo_open = madgemc_open;
- madgemc_netdev_ops.ndo_stop = madgemc_close;
-
- return mca_register_driver (&madgemc_driver);
-}
-
-static void __exit madgemc_exit (void)
-{
- mca_unregister_driver (&madgemc_driver);
-}
-
-module_init(madgemc_init);
-module_exit(madgemc_exit);
-
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/net/tokenring/madgemc.h b/drivers/net/tokenring/madgemc.h
deleted file mode 100644
index fe88e272c531..000000000000
--- a/drivers/net/tokenring/madgemc.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * madgemc.h: Header for the madgemc tms380tr module
- *
- * Authors:
- * - Adam Fritzler
- */
-
-#ifndef __LINUX_MADGEMC_H
-#define __LINUX_MADGEMC_H
-
-#ifdef __KERNEL__
-
-#define MADGEMC16_CARDNAME "Madge Smart 16/4 MC16 Ringnode"
-#define MADGEMC32_CARDNAME "Madge Smart 16/4 MC32 Ringnode"
-
-/*
- * Bit definitions for the POS config registers
- */
-#define MC16_POS0_ADDR1 0x20
-#define MC16_POS2_ADDR2 0x04
-#define MC16_POS3_ADDR3 0x20
-
-#define MC_CONTROL_REG0 ((long)-8) /* 0x00 */
-#define MC_CONTROL_REG1 ((long)-7) /* 0x01 */
-#define MC_ADAPTER_POS_REG0 ((long)-6) /* 0x02 */
-#define MC_ADAPTER_POS_REG1 ((long)-5) /* 0x03 */
-#define MC_ADAPTER_POS_REG2 ((long)-4) /* 0x04 */
-#define MC_ADAPTER_REG5_UNUSED ((long)-3) /* 0x05 */
-#define MC_ADAPTER_REG6_UNUSED ((long)-2) /* 0x06 */
-#define MC_CONTROL_REG7 ((long)-1) /* 0x07 */
-
-#define MC_CONTROL_REG0_UNKNOWN1 0x01
-#define MC_CONTROL_REG0_UNKNOWN2 0x02
-#define MC_CONTROL_REG0_SIFSEL 0x04
-#define MC_CONTROL_REG0_PAGE 0x08
-#define MC_CONTROL_REG0_TESTINTERRUPT 0x10
-#define MC_CONTROL_REG0_UNKNOWN20 0x20
-#define MC_CONTROL_REG0_SINTR 0x40
-#define MC_CONTROL_REG0_UNKNOWN80 0x80
-
-#define MC_CONTROL_REG1_SINTEN 0x01
-#define MC_CONTROL_REG1_BITOFDEATH 0x02
-#define MC_CONTROL_REG1_NSRESET 0x04
-#define MC_CONTROL_REG1_UNKNOWN8 0x08
-#define MC_CONTROL_REG1_UNKNOWN10 0x10
-#define MC_CONTROL_REG1_UNKNOWN20 0x20
-#define MC_CONTROL_REG1_SRSX 0x40
-#define MC_CONTROL_REG1_SPEED_SEL 0x80
-
-#define MC_CONTROL_REG7_CABLESTP 0x00
-#define MC_CONTROL_REG7_CABLEUTP 0x01
-
-/*
- * ROM Page Zero
- */
-#define MC_ROM_MANUFACTURERID 0x00
-#define MC_ROM_ADAPTERID 0x01
-#define MC_ROM_REVISION 0x02
-#define MC_ROM_CONFIG0 0x03
-#define MC_ROM_CONFIG1 0x04
-#define MC_ROM_CONFIG2 0x05
-
-/*
- * ROM Page One
- */
-#define MC_ROM_UNUSED_BYTE 0x00
-#define MC_ROM_BIA_START 0x01
-
-#endif /* __KERNEL__ */
-#endif /* __LINUX_MADGEMC_H */
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
deleted file mode 100644
index 4d45fe8bd206..000000000000
--- a/drivers/net/tokenring/olympic.c
+++ /dev/null
@@ -1,1737 +0,0 @@
-/*
- * olympic.c (c) 1999 Peter De Schrijver All Rights Reserved
- * 1999/2000 Mike Phillips (mikep@linuxtr.net)
- *
- * Linux driver for IBM PCI tokenring cards based on the Pit/Pit-Phy/Olympic
- * chipset.
- *
- * Base Driver Skeleton:
- * Written 1993-94 by Donald Becker.
- *
- * Copyright 1993 United States Government as represented by the
- * Director, National Security Agency.
- *
- * Thanks to Erik De Cock, Adrian Bridgett and Frank Fiene for their
- * assistance and perserverance with the testing of this driver.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * 4/27/99 - Alpha Release 0.1.0
- * First release to the public
- *
- * 6/8/99 - Official Release 0.2.0
- * Merged into the kernel code
- * 8/18/99 - Updated driver for 2.3.13 kernel to use new pci
- * resource. Driver also reports the card name returned by
- * the pci resource.
- * 1/11/00 - Added spinlocks for smp
- * 2/23/00 - Updated to dev_kfree_irq
- * 3/10/00 - Fixed FDX enable which triggered other bugs also
- * squashed.
- * 5/20/00 - Changes to handle Olympic on LinuxPPC. Endian changes.
- * The odd thing about the changes is that the fix for
- * endian issues with the big-endian data in the arb, asb...
- * was to always swab() the bytes, no matter what CPU.
- * That's because the read[wl]() functions always swap the
- * bytes on the way in on PPC.
- * Fixing the hardware descriptors was another matter,
- * because they weren't going through read[wl](), there all
- * the results had to be in memory in le32 values. kdaaker
- *
- * 12/23/00 - Added minimal Cardbus support (Thanks Donald).
- *
- * 03/09/01 - Add new pci api, dev_base_lock, general clean up.
- *
- * 03/27/01 - Add new dma pci (Thanks to Kyle Lucke) and alloc_trdev
- * Change proc_fs behaviour, now one entry per adapter.
- *
- * 04/09/01 - Couple of bug fixes to the dma unmaps and ejecting the
- * adapter when live does not take the system down with it.
- *
- * 06/02/01 - Clean up, copy skb for small packets
- *
- * 06/22/01 - Add EISR error handling routines
- *
- * 07/19/01 - Improve bad LAA reporting, strip out freemem
- * into a separate function, its called from 3
- * different places now.
- * 02/09/02 - Replaced sleep_on.
- * 03/01/02 - Replace access to several registers from 32 bit to
- * 16 bit. Fixes alignment errors on PPC 64 bit machines.
- * Thanks to Al Trautman for this one.
- * 03/10/02 - Fix BUG in arb_cmd. Bug was there all along but was
- * silently ignored until the error checking code
- * went into version 1.0.0
- * 06/04/02 - Add correct start up sequence for the cardbus adapters.
- * Required for strict compliance with pci power mgmt specs.
- * To Do:
- *
- * Wake on lan
- *
- * If Problems do Occur
- * Most problems can be rectified by either closing and opening the interface
- * (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult
- * if compiled into the kernel).
- */
-
-/* Change OLYMPIC_DEBUG to 1 to get verbose, and I mean really verbose, messages */
-
-#define OLYMPIC_DEBUG 0
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/seq_file.h>
-#include <linux/string.h>
-#include <linux/proc_fs.h>
-#include <linux/ptrace.h>
-#include <linux/skbuff.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-
-#include <net/checksum.h>
-#include <net/net_namespace.h>
-
-#include <asm/io.h>
-
-#include "olympic.h"
-
-/* I've got to put some intelligence into the version number so that Peter and I know
- * which version of the code somebody has got.
- * Version Number = a.b.c.d where a.b.c is the level of code and d is the latest author.
- * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike
- *
- * Official releases will only have an a.b.c version number format.
- */
-
-static char version[] =
-"Olympic.c v1.0.5 6/04/02 - Peter De Schrijver & Mike Phillips" ;
-
-static char *open_maj_error[] = {"No error", "Lobe Media Test", "Physical Insertion",
- "Address Verification", "Neighbor Notification (Ring Poll)",
- "Request Parameters","FDX Registration Request",
- "FDX Duplicate Address Check", "Station registration Query Wait",
- "Unknown stage"};
-
-static char *open_min_error[] = {"No error", "Function Failure", "Signal Lost", "Wire Fault",
- "Ring Speed Mismatch", "Timeout","Ring Failure","Ring Beaconing",
- "Duplicate Node Address","Request Parameters","Remove Received",
- "Reserved", "Reserved", "No Monitor Detected for RPL",
- "Monitor Contention failer for RPL", "FDX Protocol Error"};
-
-/* Module parameters */
-
-MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ;
-MODULE_DESCRIPTION("Olympic PCI/Cardbus Chipset Driver") ;
-
-/* Ring Speed 0,4,16,100
- * 0 = Autosense
- * 4,16 = Selected speed only, no autosense
- * This allows the card to be the first on the ring
- * and become the active monitor.
- * 100 = Nothing at present, 100mbps is autodetected
- * if FDX is turned on. May be implemented in the future to
- * fail if 100mpbs is not detected.
- *
- * WARNING: Some hubs will allow you to insert
- * at the wrong speed
- */
-
-static int ringspeed[OLYMPIC_MAX_ADAPTERS] = {0,} ;
-module_param_array(ringspeed, int, NULL, 0);
-
-/* Packet buffer size */
-
-static int pkt_buf_sz[OLYMPIC_MAX_ADAPTERS] = {0,} ;
-module_param_array(pkt_buf_sz, int, NULL, 0) ;
-
-/* Message Level */
-
-static int message_level[OLYMPIC_MAX_ADAPTERS] = {0,} ;
-module_param_array(message_level, int, NULL, 0) ;
-
-/* Change network_monitor to receive mac frames through the arb channel.
- * Will also create a /proc/net/olympic_tr%d entry, where %d is the tr
- * device, i.e. tr0, tr1 etc.
- * Intended to be used to create a ring-error reporting network module
- * i.e. it will give you the source address of beaconers on the ring
- */
-static int network_monitor[OLYMPIC_MAX_ADAPTERS] = {0,};
-module_param_array(network_monitor, int, NULL, 0);
-
-static DEFINE_PCI_DEVICE_TABLE(olympic_pci_tbl) = {
- {PCI_VENDOR_ID_IBM,PCI_DEVICE_ID_IBM_TR_WAKE,PCI_ANY_ID,PCI_ANY_ID,},
- { } /* Terminating Entry */
-};
-MODULE_DEVICE_TABLE(pci,olympic_pci_tbl) ;
-
-
-static int olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
-static int olympic_init(struct net_device *dev);
-static int olympic_open(struct net_device *dev);
-static netdev_tx_t olympic_xmit(struct sk_buff *skb,
- struct net_device *dev);
-static int olympic_close(struct net_device *dev);
-static void olympic_set_rx_mode(struct net_device *dev);
-static void olympic_freemem(struct net_device *dev) ;
-static irqreturn_t olympic_interrupt(int irq, void *dev_id);
-static int olympic_set_mac_address(struct net_device *dev, void *addr) ;
-static void olympic_arb_cmd(struct net_device *dev);
-static int olympic_change_mtu(struct net_device *dev, int mtu);
-static void olympic_srb_bh(struct net_device *dev) ;
-static void olympic_asb_bh(struct net_device *dev) ;
-static const struct file_operations olympic_proc_ops;
-
-static const struct net_device_ops olympic_netdev_ops = {
- .ndo_open = olympic_open,
- .ndo_stop = olympic_close,
- .ndo_start_xmit = olympic_xmit,
- .ndo_change_mtu = olympic_change_mtu,
- .ndo_set_rx_mode = olympic_set_rx_mode,
- .ndo_set_mac_address = olympic_set_mac_address,
-};
-
-static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- struct net_device *dev ;
- struct olympic_private *olympic_priv;
- static int card_no = -1 ;
- int i ;
-
- card_no++ ;
-
- if ((i = pci_enable_device(pdev))) {
- return i ;
- }
-
- pci_set_master(pdev);
-
- if ((i = pci_request_regions(pdev,"olympic"))) {
- goto op_disable_dev;
- }
-
- dev = alloc_trdev(sizeof(struct olympic_private)) ;
- if (!dev) {
- i = -ENOMEM;
- goto op_release_dev;
- }
-
- olympic_priv = netdev_priv(dev) ;
-
- spin_lock_init(&olympic_priv->olympic_lock) ;
-
- init_waitqueue_head(&olympic_priv->srb_wait);
- init_waitqueue_head(&olympic_priv->trb_wait);
-#if OLYMPIC_DEBUG
- printk(KERN_INFO "pci_device: %p, dev:%p, dev->priv: %p\n", pdev, dev, netdev_priv(dev));
-#endif
- dev->irq=pdev->irq;
- dev->base_addr=pci_resource_start(pdev, 0);
- olympic_priv->olympic_card_name = pci_name(pdev);
- olympic_priv->pdev = pdev;
- olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256);
- olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048);
- if (!olympic_priv->olympic_mmio || !olympic_priv->olympic_lap) {
- goto op_free_iomap;
- }
-
- if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
- olympic_priv->pkt_buf_sz = PKT_BUF_SZ ;
- else
- olympic_priv->pkt_buf_sz = pkt_buf_sz[card_no] ;
-
- dev->mtu = olympic_priv->pkt_buf_sz - TR_HLEN ;
- olympic_priv->olympic_ring_speed = ringspeed[card_no] ;
- olympic_priv->olympic_message_level = message_level[card_no] ;
- olympic_priv->olympic_network_monitor = network_monitor[card_no];
-
- if ((i = olympic_init(dev))) {
- goto op_free_iomap;
- }
-
- dev->netdev_ops = &olympic_netdev_ops;
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- pci_set_drvdata(pdev,dev) ;
- register_netdev(dev) ;
- printk("Olympic: %s registered as: %s\n",olympic_priv->olympic_card_name,dev->name);
- if (olympic_priv->olympic_network_monitor) { /* Must go after register_netdev as we need the device name */
- char proc_name[20] ;
- strcpy(proc_name,"olympic_") ;
- strcat(proc_name,dev->name) ;
- proc_create_data(proc_name, 0, init_net.proc_net, &olympic_proc_ops, dev);
- printk("Olympic: Network Monitor information: /proc/%s\n",proc_name);
- }
- return 0 ;
-
-op_free_iomap:
- if (olympic_priv->olympic_mmio)
- iounmap(olympic_priv->olympic_mmio);
- if (olympic_priv->olympic_lap)
- iounmap(olympic_priv->olympic_lap);
-
- free_netdev(dev);
-op_release_dev:
- pci_release_regions(pdev);
-
-op_disable_dev:
- pci_disable_device(pdev);
- return i;
-}
-
-static int olympic_init(struct net_device *dev)
-{
- struct olympic_private *olympic_priv;
- u8 __iomem *olympic_mmio, *init_srb,*adapter_addr;
- unsigned long t;
- unsigned int uaa_addr;
-
- olympic_priv=netdev_priv(dev);
- olympic_mmio=olympic_priv->olympic_mmio;
-
- printk("%s\n", version);
- printk("%s. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n", olympic_priv->olympic_card_name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq);
-
- writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL);
- t=jiffies;
- while((readl(olympic_mmio+BCTL)) & BCTL_SOFTRESET) {
- schedule();
- if(time_after(jiffies, t + 40*HZ)) {
- printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
- return -ENODEV;
- }
- }
-
-
- /* Needed for cardbus */
- if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) {
- writel(readl(olympic_priv->olympic_mmio+FERMASK)|FERMASK_INT_BIT, olympic_mmio+FERMASK);
- }
-
-#if OLYMPIC_DEBUG
- printk("BCTL: %x\n",readl(olympic_mmio+BCTL));
- printk("GPR: %x\n",readw(olympic_mmio+GPR));
- printk("SISRMASK: %x\n",readl(olympic_mmio+SISR_MASK));
-#endif
- /* Aaaahhh, You have got to be real careful setting GPR, the card
- holds the previous values from flash memory, including autosense
- and ring speed */
-
- writel(readl(olympic_mmio+BCTL)|BCTL_MIMREB,olympic_mmio+BCTL);
-
- if (olympic_priv->olympic_ring_speed == 0) { /* Autosense */
- writew(readw(olympic_mmio+GPR)|GPR_AUTOSENSE,olympic_mmio+GPR);
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Ringspeed autosense mode on\n",olympic_priv->olympic_card_name);
- } else if (olympic_priv->olympic_ring_speed == 16) {
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", olympic_priv->olympic_card_name);
- writew(GPR_16MBPS, olympic_mmio+GPR);
- } else if (olympic_priv->olympic_ring_speed == 4) {
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", olympic_priv->olympic_card_name) ;
- writew(0, olympic_mmio+GPR);
- }
-
- writew(readw(olympic_mmio+GPR)|GPR_NEPTUNE_BF,olympic_mmio+GPR);
-
-#if OLYMPIC_DEBUG
- printk("GPR = %x\n",readw(olympic_mmio + GPR) ) ;
-#endif
- /* Solo has been paused to meet the Cardbus power
- * specs if the adapter is cardbus. Check to
- * see its been paused and then restart solo. The
- * adapter should set the pause bit within 1 second.
- */
-
- if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) {
- t=jiffies;
- while (!(readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE)) {
- schedule() ;
- if(time_after(jiffies, t + 2*HZ)) {
- printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ;
- return -ENODEV;
- }
- }
- writel(readl(olympic_mmio+CLKCTL) & ~CLKCTL_PAUSE, olympic_mmio+CLKCTL) ;
- }
-
- /* start solo init */
- writel((1<<15),olympic_mmio+SISR_MASK_SUM);
-
- t=jiffies;
- while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) {
- schedule();
- if(time_after(jiffies, t + 15*HZ)) {
- printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
- return -ENODEV;
- }
- }
-
- writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
-
-#if OLYMPIC_DEBUG
- printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
-#endif
-
- init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));
-
-#if OLYMPIC_DEBUG
-{
- int i;
- printk("init_srb(%p): ",init_srb);
- for(i=0;i<20;i++)
- printk("%x ",readb(init_srb+i));
- printk("\n");
-}
-#endif
- if(readw(init_srb+6)) {
- printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n",readw(init_srb+6));
- return -ENODEV;
- }
-
- if (olympic_priv->olympic_message_level) {
- if ( readb(init_srb +2) & 0x40) {
- printk(KERN_INFO "Olympic: Adapter is FDX capable.\n") ;
- } else {
- printk(KERN_INFO "Olympic: Adapter cannot do FDX.\n");
- }
- }
-
- uaa_addr=swab16(readw(init_srb+8));
-
-#if OLYMPIC_DEBUG
- printk("UAA resides at %x\n",uaa_addr);
-#endif
-
- writel(uaa_addr,olympic_mmio+LAPA);
- adapter_addr=olympic_priv->olympic_lap + (uaa_addr & (~0xf800));
-
- memcpy_fromio(&dev->dev_addr[0], adapter_addr,6);
-
-#if OLYMPIC_DEBUG
- printk("adapter address: %pM\n", dev->dev_addr);
-#endif
-
- olympic_priv->olympic_addr_table_addr = swab16(readw(init_srb + 12));
- olympic_priv->olympic_parms_addr = swab16(readw(init_srb + 14));
-
- return 0;
-
-}
-
-static int olympic_open(struct net_device *dev)
-{
- struct olympic_private *olympic_priv=netdev_priv(dev);
- u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;
- unsigned long flags, t;
- int i, open_finished = 1 ;
- u8 resp, err;
-
- DECLARE_WAITQUEUE(wait,current) ;
-
- olympic_init(dev);
-
- if (request_irq(dev->irq, olympic_interrupt, IRQF_SHARED , "olympic",
- dev))
- return -EAGAIN;
-
-#if OLYMPIC_DEBUG
- printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
- printk("pending ints: %x\n",readl(olympic_mmio+SISR_RR));
-#endif
-
- writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
-
- writel(SISR_MI | SISR_SRB_REPLY, olympic_mmio+SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */
-
- writel(LISR_LIE,olympic_mmio+LISR); /* more ints later */
-
- /* adapter is closed, so SRB is pointed to by LAPWWO */
-
- writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
- init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));
-
-#if OLYMPIC_DEBUG
- printk("LAPWWO: %x, LAPA: %x\n",readw(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
- printk("SISR Mask = %04x\n", readl(olympic_mmio+SISR_MASK));
- printk("Before the open command\n");
-#endif
- do {
- memset_io(init_srb,0,SRB_COMMAND_SIZE);
-
- writeb(SRB_OPEN_ADAPTER,init_srb) ; /* open */
- writeb(OLYMPIC_CLEAR_RET_CODE,init_srb+2);
-
- /* If Network Monitor, instruct card to copy MAC frames through the ARB */
- if (olympic_priv->olympic_network_monitor)
- writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8);
- else
- writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8);
-
- /* Test OR of first 3 bytes as its totally possible for
- * someone to set the first 2 bytes to be zero, although this
- * is an error, the first byte must have bit 6 set to 1 */
-
- if (olympic_priv->olympic_laa[0] | olympic_priv->olympic_laa[1] | olympic_priv->olympic_laa[2]) {
- writeb(olympic_priv->olympic_laa[0],init_srb+12);
- writeb(olympic_priv->olympic_laa[1],init_srb+13);
- writeb(olympic_priv->olympic_laa[2],init_srb+14);
- writeb(olympic_priv->olympic_laa[3],init_srb+15);
- writeb(olympic_priv->olympic_laa[4],init_srb+16);
- writeb(olympic_priv->olympic_laa[5],init_srb+17);
- memcpy(dev->dev_addr,olympic_priv->olympic_laa,dev->addr_len) ;
- }
- writeb(1,init_srb+30);
-
- spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
- olympic_priv->srb_queued=1;
-
- writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
- spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
-
- t = jiffies ;
-
- add_wait_queue(&olympic_priv->srb_wait,&wait) ;
- set_current_state(TASK_INTERRUPTIBLE) ;
-
- while(olympic_priv->srb_queued) {
- schedule() ;
- if(signal_pending(current)) {
- printk(KERN_WARNING "%s: Signal received in open.\n",
- dev->name);
- printk(KERN_WARNING "SISR=%x LISR=%x\n",
- readl(olympic_mmio+SISR),
- readl(olympic_mmio+LISR));
- olympic_priv->srb_queued=0;
- break;
- }
- if (time_after(jiffies, t + 10*HZ)) {
- printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
- olympic_priv->srb_queued=0;
- break ;
- }
- set_current_state(TASK_INTERRUPTIBLE) ;
- }
- remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
- set_current_state(TASK_RUNNING) ;
- olympic_priv->srb_queued = 0 ;
-#if OLYMPIC_DEBUG
- printk("init_srb(%p): ",init_srb);
- for(i=0;i<20;i++)
- printk("%02x ",readb(init_srb+i));
- printk("\n");
-#endif
-
- /* If we get the same return response as we set, the interrupt wasn't raised and the open
- * timed out.
- */
-
- switch (resp = readb(init_srb+2)) {
- case OLYMPIC_CLEAR_RET_CODE:
- printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ;
- goto out;
- case 0:
- open_finished = 1;
- break;
- case 0x07:
- if (!olympic_priv->olympic_ring_speed && open_finished) { /* Autosense , first time around */
- printk(KERN_WARNING "%s: Retrying at different ring speed\n", dev->name);
- open_finished = 0 ;
- continue;
- }
-
- err = readb(init_srb+7);
-
- if (!olympic_priv->olympic_ring_speed && ((err & 0x0f) == 0x0d)) {
- printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n",dev->name);
- printk(KERN_WARNING "%s: Please try again with a specified ring speed\n",dev->name);
- } else {
- printk(KERN_WARNING "%s: %s - %s\n", dev->name,
- open_maj_error[(err & 0xf0) >> 4],
- open_min_error[(err & 0x0f)]);
- }
- goto out;
-
- case 0x32:
- printk(KERN_WARNING "%s: Invalid LAA: %pM\n",
- dev->name, olympic_priv->olympic_laa);
- goto out;
-
- default:
- printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name, resp);
- goto out;
-
- }
- } while (!(open_finished)) ; /* Will only loop if ring speed mismatch re-open attempted && autosense is on */
-
- if (readb(init_srb+18) & (1<<3))
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Opened in FDX Mode\n",dev->name);
-
- if (readb(init_srb+18) & (1<<1))
- olympic_priv->olympic_ring_speed = 100 ;
- else if (readb(init_srb+18) & 1)
- olympic_priv->olympic_ring_speed = 16 ;
- else
- olympic_priv->olympic_ring_speed = 4 ;
-
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Opened in %d Mbps mode\n",dev->name, olympic_priv->olympic_ring_speed);
-
- olympic_priv->asb = swab16(readw(init_srb+8));
- olympic_priv->srb = swab16(readw(init_srb+10));
- olympic_priv->arb = swab16(readw(init_srb+12));
- olympic_priv->trb = swab16(readw(init_srb+16));
-
- olympic_priv->olympic_receive_options = 0x01 ;
- olympic_priv->olympic_copy_all_options = 0 ;
-
- /* setup rx ring */
-
- writel((3<<16),olympic_mmio+BMCTL_RWM); /* Ensure end of frame generated interrupts */
-
- writel(BMCTL_RX_DIS|3,olympic_mmio+BMCTL_RWM); /* Yes, this the enables RX channel */
-
- for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
-
- struct sk_buff *skb;
-
- skb=dev_alloc_skb(olympic_priv->pkt_buf_sz);
- if(skb == NULL)
- break;
-
- skb->dev = dev;
-
- olympic_priv->olympic_rx_ring[i].buffer = cpu_to_le32(pci_map_single(olympic_priv->pdev,
- skb->data,olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)) ;
- olympic_priv->olympic_rx_ring[i].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz);
- olympic_priv->rx_ring_skb[i]=skb;
- }
-
- if (i==0) {
- printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name);
- goto out;
- }
-
- olympic_priv->rx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_rx_ring,
- sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
- writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXDESCQ);
- writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXCDA);
- writew(i, olympic_mmio+RXDESCQCNT);
-
- olympic_priv->rx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_rx_status_ring,
- sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
- writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXSTATQ);
- writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXCSA);
-
- olympic_priv->rx_ring_last_received = OLYMPIC_RX_RING_SIZE - 1; /* last processed rx status */
- olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE - 1;
-
- writew(i, olympic_mmio+RXSTATQCNT);
-
-#if OLYMPIC_DEBUG
- printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
- printk("RXCSA: %x, rx_status_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);
- printk(" stat_ring[1]: %p, stat_ring[2]: %p, stat_ring[3]: %p\n", &(olympic_priv->olympic_rx_status_ring[1]), &(olympic_priv->olympic_rx_status_ring[2]), &(olympic_priv->olympic_rx_status_ring[3]) );
- printk(" stat_ring[4]: %p, stat_ring[5]: %p, stat_ring[6]: %p\n", &(olympic_priv->olympic_rx_status_ring[4]), &(olympic_priv->olympic_rx_status_ring[5]), &(olympic_priv->olympic_rx_status_ring[6]) );
- printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7]) );
-
- printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
- printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr = %08x\n",
- olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ;
-#endif
-
- writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
-
-#if OLYMPIC_DEBUG
- printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
- printk("RXCSA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);
- printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
-#endif
-
- writel(SISR_RX_STATUS | SISR_RX_NOBUF,olympic_mmio+SISR_MASK_SUM);
-
- /* setup tx ring */
-
- writel(BMCTL_TX1_DIS,olympic_mmio+BMCTL_RWM); /* Yes, this enables TX channel 1 */
- for(i=0;i<OLYMPIC_TX_RING_SIZE;i++)
- olympic_priv->olympic_tx_ring[i].buffer=cpu_to_le32(0xdeadbeef);
-
- olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE;
- olympic_priv->tx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_tx_ring,
- sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE,PCI_DMA_TODEVICE) ;
- writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXDESCQ_1);
- writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXCDA_1);
- writew(OLYMPIC_TX_RING_SIZE, olympic_mmio+TXDESCQCNT_1);
-
- olympic_priv->tx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_tx_status_ring,
- sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
- writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXSTATQ_1);
- writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXCSA_1);
- writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXSTATQCNT_1);
-
- olympic_priv->tx_ring_free=0; /* next entry in tx ring to use */
- olympic_priv->tx_ring_last_status=OLYMPIC_TX_RING_SIZE-1; /* last processed tx status */
-
- writel(0xffffffff, olympic_mmio+EISR_RWM) ; /* clean the eisr */
- writel(0,olympic_mmio+EISR) ;
- writel(EISR_MASK_OPTIONS,olympic_mmio+EISR_MASK) ; /* enables most of the TX error interrupts */
- writel(SISR_TX1_EOF | SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE | SISR_ERR,olympic_mmio+SISR_MASK_SUM);
-
-#if OLYMPIC_DEBUG
- printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
- printk("SISR MASK: %x\n",readl(olympic_mmio+SISR_MASK));
-#endif
-
- if (olympic_priv->olympic_network_monitor) {
- u8 __iomem *oat;
- u8 __iomem *opt;
- u8 addr[6];
- oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr);
- opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr);
-
- for (i = 0; i < 6; i++)
- addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+i);
- printk("%s: Node Address: %pM\n", dev->name, addr);
- printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name,
- readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)),
- readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
- readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
- readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
-
- for (i = 0; i < 6; i++)
- addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+i);
- printk("%s: NAUN Address: %pM\n", dev->name, addr);
- }
-
- netif_start_queue(dev);
- return 0;
-
-out:
- free_irq(dev->irq, dev);
- return -EIO;
-}
-
-/*
- * When we enter the rx routine we do not know how many frames have been
- * queued on the rx channel. Therefore we start at the next rx status
- * position and travel around the receive ring until we have completed
- * all the frames.
- *
- * This means that we may process the frame before we receive the end
- * of frame interrupt. This is why we always test the status instead
- * of blindly processing the next frame.
- *
- * We also remove the last 4 bytes from the packet as well, these are
- * just token ring trailer info and upset protocols that don't check
- * their own length, i.e. SNA.
- *
- */
-static void olympic_rx(struct net_device *dev)
-{
- struct olympic_private *olympic_priv=netdev_priv(dev);
- u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
- struct olympic_rx_status *rx_status;
- struct olympic_rx_desc *rx_desc ;
- int rx_ring_last_received,length, buffer_cnt, cpy_length, frag_len;
- struct sk_buff *skb, *skb2;
- int i;
-
- rx_status=&(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received + 1) & (OLYMPIC_RX_RING_SIZE - 1)]) ;
-
- while (rx_status->status_buffercnt) {
- u32 l_status_buffercnt;
-
- olympic_priv->rx_status_last_received++ ;
- olympic_priv->rx_status_last_received &= (OLYMPIC_RX_RING_SIZE -1);
-#if OLYMPIC_DEBUG
- printk("rx status: %x rx len: %x\n", le32_to_cpu(rx_status->status_buffercnt), le32_to_cpu(rx_status->fragmentcnt_framelen));
-#endif
- length = le32_to_cpu(rx_status->fragmentcnt_framelen) & 0xffff;
- buffer_cnt = le32_to_cpu(rx_status->status_buffercnt) & 0xffff;
- i = buffer_cnt ; /* Need buffer_cnt later for rxenq update */
- frag_len = le32_to_cpu(rx_status->fragmentcnt_framelen) >> 16;
-
-#if OLYMPIC_DEBUG
- printk("length: %x, frag_len: %x, buffer_cnt: %x\n", length, frag_len, buffer_cnt);
-#endif
- l_status_buffercnt = le32_to_cpu(rx_status->status_buffercnt);
- if(l_status_buffercnt & 0xC0000000) {
- if (l_status_buffercnt & 0x3B000000) {
- if (olympic_priv->olympic_message_level) {
- if (l_status_buffercnt & (1<<29)) /* Rx Frame Truncated */
- printk(KERN_WARNING "%s: Rx Frame Truncated\n",dev->name);
- if (l_status_buffercnt & (1<<28)) /*Rx receive overrun */
- printk(KERN_WARNING "%s: Rx Frame Receive overrun\n",dev->name);
- if (l_status_buffercnt & (1<<27)) /* No receive buffers */
- printk(KERN_WARNING "%s: No receive buffers\n",dev->name);
- if (l_status_buffercnt & (1<<25)) /* Receive frame error detect */
- printk(KERN_WARNING "%s: Receive frame error detect\n",dev->name);
- if (l_status_buffercnt & (1<<24)) /* Received Error Detect */
- printk(KERN_WARNING "%s: Received Error Detect\n",dev->name);
- }
- olympic_priv->rx_ring_last_received += i ;
- olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
- dev->stats.rx_errors++;
- } else {
-
- if (buffer_cnt == 1) {
- skb = dev_alloc_skb(max_t(int, olympic_priv->pkt_buf_sz,length)) ;
- } else {
- skb = dev_alloc_skb(length) ;
- }
-
- if (skb == NULL) {
- printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers.\n",dev->name) ;
- dev->stats.rx_dropped++;
- /* Update counters even though we don't transfer the frame */
- olympic_priv->rx_ring_last_received += i ;
- olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
- } else {
- /* Optimise based upon number of buffers used.
- If only one buffer is used we can simply swap the buffers around.
- If more than one then we must use the new buffer and copy the information
- first. Ideally all frames would be in a single buffer, this can be tuned by
- altering the buffer size. If the length of the packet is less than
- 1500 bytes we're going to copy it over anyway to stop packets getting
- dropped from sockets with buffers smaller than our pkt_buf_sz. */
-
- if (buffer_cnt==1) {
- olympic_priv->rx_ring_last_received++ ;
- olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
- rx_ring_last_received = olympic_priv->rx_ring_last_received ;
- if (length > 1500) {
- skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ;
- /* unmap buffer */
- pci_unmap_single(olympic_priv->pdev,
- le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
- olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
- skb_put(skb2,length-4);
- skb2->protocol = tr_type_trans(skb2,dev);
- olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer =
- cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data,
- olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
- olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length =
- cpu_to_le32(olympic_priv->pkt_buf_sz);
- olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ;
- netif_rx(skb2) ;
- } else {
- pci_dma_sync_single_for_cpu(olympic_priv->pdev,
- le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
- olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
- skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received],
- skb_put(skb,length - 4),
- length - 4);
- pci_dma_sync_single_for_device(olympic_priv->pdev,
- le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
- olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
- skb->protocol = tr_type_trans(skb,dev) ;
- netif_rx(skb) ;
- }
- } else {
- do { /* Walk the buffers */
- olympic_priv->rx_ring_last_received++ ;
- olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
- rx_ring_last_received = olympic_priv->rx_ring_last_received ;
- pci_dma_sync_single_for_cpu(olympic_priv->pdev,
- le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
- olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
- rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]);
- cpy_length = (i == 1 ? frag_len : le32_to_cpu(rx_desc->res_length));
- skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received],
- skb_put(skb, cpy_length),
- cpy_length);
- pci_dma_sync_single_for_device(olympic_priv->pdev,
- le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
- olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
- } while (--i) ;
- skb_trim(skb,skb->len-4) ;
- skb->protocol = tr_type_trans(skb,dev);
- netif_rx(skb) ;
- }
- dev->stats.rx_packets++ ;
- dev->stats.rx_bytes += length ;
- } /* if skb == null */
- } /* If status & 0x3b */
-
- } else { /*if buffercnt & 0xC */
- olympic_priv->rx_ring_last_received += i ;
- olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE - 1) ;
- }
-
- rx_status->fragmentcnt_framelen = 0 ;
- rx_status->status_buffercnt = 0 ;
- rx_status = &(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received+1) & (OLYMPIC_RX_RING_SIZE -1) ]);
-
- writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | buffer_cnt , olympic_mmio+RXENQ);
- } /* while */
-
-}
-
-static void olympic_freemem(struct net_device *dev)
-{
- struct olympic_private *olympic_priv=netdev_priv(dev);
- int i;
-
- for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
- if (olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] != NULL) {
- dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
- olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] = NULL;
- }
- if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != cpu_to_le32(0xdeadbeef)) {
- pci_unmap_single(olympic_priv->pdev,
- le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
- olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
- }
- olympic_priv->rx_status_last_received++;
- olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
- }
- /* unmap rings */
- pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr,
- sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
- pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
- sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
-
- pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr,
- sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
- pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr,
- sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
-
- return ;
-}
-
-static irqreturn_t olympic_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev= (struct net_device *)dev_id;
- struct olympic_private *olympic_priv=netdev_priv(dev);
- u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
- u32 sisr;
- u8 __iomem *adapter_check_area ;
-
- /*
- * Read sisr but don't reset it yet.
- * The indication bit may have been set but the interrupt latch
- * bit may not be set, so we'd lose the interrupt later.
- */
- sisr=readl(olympic_mmio+SISR) ;
- if (!(sisr & SISR_MI)) /* Interrupt isn't for us */
- return IRQ_NONE;
- sisr=readl(olympic_mmio+SISR_RR) ; /* Read & Reset sisr */
-
- spin_lock(&olympic_priv->olympic_lock);
-
- /* Hotswap gives us this on removal */
- if (sisr == 0xffffffff) {
- printk(KERN_WARNING "%s: Hotswap adapter removal.\n",dev->name) ;
- spin_unlock(&olympic_priv->olympic_lock) ;
- return IRQ_NONE;
- }
-
- if (sisr & (SISR_SRB_REPLY | SISR_TX1_EOF | SISR_RX_STATUS | SISR_ADAPTER_CHECK |
- SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_RX_NOBUF | SISR_ERR)) {
-
- /* If we ever get this the adapter is seriously dead. Only a reset is going to
- * bring it back to life. We're talking pci bus errors and such like :( */
- if((sisr & SISR_ERR) && (readl(olympic_mmio+EISR) & EISR_MASK_OPTIONS)) {
- printk(KERN_ERR "Olympic: EISR Error, EISR=%08x\n",readl(olympic_mmio+EISR)) ;
- printk(KERN_ERR "The adapter must be reset to clear this condition.\n") ;
- printk(KERN_ERR "Please report this error to the driver maintainer and/\n") ;
- printk(KERN_ERR "or the linux-tr mailing list.\n") ;
- wake_up_interruptible(&olympic_priv->srb_wait);
- spin_unlock(&olympic_priv->olympic_lock) ;
- return IRQ_HANDLED;
- } /* SISR_ERR */
-
- if(sisr & SISR_SRB_REPLY) {
- if(olympic_priv->srb_queued==1) {
- wake_up_interruptible(&olympic_priv->srb_wait);
- } else if (olympic_priv->srb_queued==2) {
- olympic_srb_bh(dev) ;
- }
- olympic_priv->srb_queued=0;
- } /* SISR_SRB_REPLY */
-
- /* We shouldn't ever miss the Tx interrupt, but the you never know, hence the loop to ensure
- we get all tx completions. */
- if (sisr & SISR_TX1_EOF) {
- while(olympic_priv->olympic_tx_status_ring[(olympic_priv->tx_ring_last_status + 1) & (OLYMPIC_TX_RING_SIZE-1)].status) {
- olympic_priv->tx_ring_last_status++;
- olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1);
- olympic_priv->free_tx_ring_entries++;
- dev->stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
- dev->stats.tx_packets++ ;
- pci_unmap_single(olympic_priv->pdev,
- le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer),
- olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE);
- dev_kfree_skb_irq(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
- olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=cpu_to_le32(0xdeadbeef);
- olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0;
- }
- netif_wake_queue(dev);
- } /* SISR_TX1_EOF */
-
- if (sisr & SISR_RX_STATUS) {
- olympic_rx(dev);
- } /* SISR_RX_STATUS */
-
- if (sisr & SISR_ADAPTER_CHECK) {
- netif_stop_queue(dev);
- printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
- writel(readl(olympic_mmio+LAPWWC),olympic_mmio+LAPA);
- adapter_check_area = olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWC)) & (~0xf800)) ;
- printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ;
- spin_unlock(&olympic_priv->olympic_lock) ;
- return IRQ_HANDLED;
- } /* SISR_ADAPTER_CHECK */
-
- if (sisr & SISR_ASB_FREE) {
- /* Wake up anything that is waiting for the asb response */
- if (olympic_priv->asb_queued) {
- olympic_asb_bh(dev) ;
- }
- } /* SISR_ASB_FREE */
-
- if (sisr & SISR_ARB_CMD) {
- olympic_arb_cmd(dev) ;
- } /* SISR_ARB_CMD */
-
- if (sisr & SISR_TRB_REPLY) {
- /* Wake up anything that is waiting for the trb response */
- if (olympic_priv->trb_queued) {
- wake_up_interruptible(&olympic_priv->trb_wait);
- }
- olympic_priv->trb_queued = 0 ;
- } /* SISR_TRB_REPLY */
-
- if (sisr & SISR_RX_NOBUF) {
- /* According to the documentation, we don't have to do anything, but trapping it keeps it out of
- /var/log/messages. */
- } /* SISR_RX_NOBUF */
- } else {
- printk(KERN_WARNING "%s: Unexpected interrupt: %x\n",dev->name, sisr);
- printk(KERN_WARNING "%s: SISR_MASK: %x\n",dev->name, readl(olympic_mmio+SISR_MASK)) ;
- } /* One if the interrupts we want */
- writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
-
- spin_unlock(&olympic_priv->olympic_lock) ;
- return IRQ_HANDLED;
-}
-
-static netdev_tx_t olympic_xmit(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct olympic_private *olympic_priv=netdev_priv(dev);
- u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
- unsigned long flags ;
-
- spin_lock_irqsave(&olympic_priv->olympic_lock, flags);
-
- netif_stop_queue(dev);
-
- if(olympic_priv->free_tx_ring_entries) {
- olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer =
- cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, skb->len,PCI_DMA_TODEVICE));
- olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length = cpu_to_le32(skb->len | (0x80000000));
- olympic_priv->tx_ring_skb[olympic_priv->tx_ring_free]=skb;
- olympic_priv->free_tx_ring_entries--;
-
- olympic_priv->tx_ring_free++;
- olympic_priv->tx_ring_free &= (OLYMPIC_TX_RING_SIZE-1);
- writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1);
- netif_wake_queue(dev);
- spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
- return NETDEV_TX_OK;
- } else {
- spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
- return NETDEV_TX_BUSY;
- }
-
-}
-
-
-static int olympic_close(struct net_device *dev)
-{
- struct olympic_private *olympic_priv=netdev_priv(dev);
- u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*srb;
- unsigned long t,flags;
-
- DECLARE_WAITQUEUE(wait,current) ;
-
- netif_stop_queue(dev);
-
- writel(olympic_priv->srb,olympic_mmio+LAPA);
- srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
-
- writeb(SRB_CLOSE_ADAPTER,srb+0);
- writeb(0,srb+1);
- writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
-
- add_wait_queue(&olympic_priv->srb_wait,&wait) ;
- set_current_state(TASK_INTERRUPTIBLE) ;
-
- spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
- olympic_priv->srb_queued=1;
-
- writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
- spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
-
- while(olympic_priv->srb_queued) {
-
- t = schedule_timeout_interruptible(60*HZ);
-
- if(signal_pending(current)) {
- printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
- printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR));
- olympic_priv->srb_queued=0;
- break;
- }
-
- if (t == 0) {
- printk(KERN_WARNING "%s: SRB timed out. May not be fatal.\n",dev->name);
- }
- olympic_priv->srb_queued=0;
- }
- remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
-
- olympic_priv->rx_status_last_received++;
- olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
-
- olympic_freemem(dev) ;
-
- /* reset tx/rx fifo's and busmaster logic */
-
- writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL);
- udelay(1);
- writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
-
-#if OLYMPIC_DEBUG
- {
- int i ;
- printk("srb(%p): ",srb);
- for(i=0;i<4;i++)
- printk("%x ",readb(srb+i));
- printk("\n");
- }
-#endif
- free_irq(dev->irq,dev);
-
- return 0;
-
-}
-
-static void olympic_set_rx_mode(struct net_device *dev)
-{
- struct olympic_private *olympic_priv = netdev_priv(dev);
- u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ;
- u8 options = 0;
- u8 __iomem *srb;
- struct netdev_hw_addr *ha;
- unsigned char dev_mc_address[4] ;
-
- writel(olympic_priv->srb,olympic_mmio+LAPA);
- srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
- options = olympic_priv->olympic_copy_all_options;
-
- if (dev->flags&IFF_PROMISC)
- options |= 0x61 ;
- else
- options &= ~0x61 ;
-
- /* Only issue the srb if there is a change in options */
-
- if ((options ^ olympic_priv->olympic_copy_all_options)) {
-
- /* Now to issue the srb command to alter the copy.all.options */
-
- writeb(SRB_MODIFY_RECEIVE_OPTIONS,srb);
- writeb(0,srb+1);
- writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
- writeb(0,srb+3);
- writeb(olympic_priv->olympic_receive_options,srb+4);
- writeb(options,srb+5);
-
- olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */
-
- writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
-
- olympic_priv->olympic_copy_all_options = options ;
-
- return ;
- }
-
- /* Set the functional addresses we need for multicast */
-
- dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ;
-
- netdev_for_each_mc_addr(ha, dev) {
- dev_mc_address[0] |= ha->addr[2];
- dev_mc_address[1] |= ha->addr[3];
- dev_mc_address[2] |= ha->addr[4];
- dev_mc_address[3] |= ha->addr[5];
- }
-
- writeb(SRB_SET_FUNC_ADDRESS,srb+0);
- writeb(0,srb+1);
- writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
- writeb(0,srb+3);
- writeb(0,srb+4);
- writeb(0,srb+5);
- writeb(dev_mc_address[0],srb+6);
- writeb(dev_mc_address[1],srb+7);
- writeb(dev_mc_address[2],srb+8);
- writeb(dev_mc_address[3],srb+9);
-
- olympic_priv->srb_queued = 2 ;
- writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
-
-}
-
-static void olympic_srb_bh(struct net_device *dev)
-{
- struct olympic_private *olympic_priv = netdev_priv(dev);
- u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ;
- u8 __iomem *srb;
-
- writel(olympic_priv->srb,olympic_mmio+LAPA);
- srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
-
- switch (readb(srb)) {
-
- /* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous)
- * At some point we should do something if we get an error, such as
- * resetting the IFF_PROMISC flag in dev
- */
-
- case SRB_MODIFY_RECEIVE_OPTIONS:
- switch (readb(srb+2)) {
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name) ;
- break ;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);
- break ;
- default:
- if (olympic_priv->olympic_message_level)
- printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n",dev->name,olympic_priv->olympic_copy_all_options, olympic_priv->olympic_receive_options) ;
- break ;
- } /* switch srb[2] */
- break ;
-
- /* SRB_SET_GROUP_ADDRESS - Multicast group setting
- */
-
- case SRB_SET_GROUP_ADDRESS:
- switch (readb(srb+2)) {
- case 0x00:
- break ;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name);
- break ;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);
- break ;
- case 0x3c:
- printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n",dev->name) ;
- break ;
- case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */
- printk(KERN_WARNING "%s: Group address registers full\n",dev->name) ;
- break ;
- case 0x55:
- printk(KERN_INFO "%s: Group Address already set.\n",dev->name) ;
- break ;
- default:
- break ;
- } /* switch srb[2] */
- break ;
-
- /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list
- */
-
- case SRB_RESET_GROUP_ADDRESS:
- switch (readb(srb+2)) {
- case 0x00:
- break ;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name);
- break ;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
- break ;
- case 0x39: /* Must deal with this if individual multicast addresses used */
- printk(KERN_INFO "%s: Group address not found\n",dev->name);
- break ;
- default:
- break ;
- } /* switch srb[2] */
- break ;
-
-
- /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode
- */
-
- case SRB_SET_FUNC_ADDRESS:
- switch (readb(srb+2)) {
- case 0x00:
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Functional Address Mask Set\n",dev->name);
- break ;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name);
- break ;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
- break ;
- default:
- break ;
- } /* switch srb[2] */
- break ;
-
- /* SRB_READ_LOG - Read and reset the adapter error counters
- */
-
- case SRB_READ_LOG:
- switch (readb(srb+2)) {
- case 0x00:
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Read Log issued\n",dev->name) ;
- break ;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name);
- break ;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
- break ;
-
- } /* switch srb[2] */
- break ;
-
- /* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */
-
- case SRB_READ_SR_COUNTERS:
- switch (readb(srb+2)) {
- case 0x00:
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Read Source Routing Counters issued\n",dev->name) ;
- break ;
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name);
- break ;
- case 0x04:
- printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
- break ;
- default:
- break ;
- } /* switch srb[2] */
- break ;
-
- default:
- printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n",dev->name);
- break ;
- } /* switch srb[0] */
-
-}
-
-static int olympic_set_mac_address (struct net_device *dev, void *addr)
-{
- struct sockaddr *saddr = addr ;
- struct olympic_private *olympic_priv = netdev_priv(dev);
-
- if (netif_running(dev)) {
- printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ;
- return -EIO ;
- }
-
- memcpy(olympic_priv->olympic_laa, saddr->sa_data,dev->addr_len) ;
-
- if (olympic_priv->olympic_message_level) {
- printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev->name, olympic_priv->olympic_laa[0],
- olympic_priv->olympic_laa[1], olympic_priv->olympic_laa[2],
- olympic_priv->olympic_laa[3], olympic_priv->olympic_laa[4],
- olympic_priv->olympic_laa[5]);
- }
-
- return 0 ;
-}
-
-static void olympic_arb_cmd(struct net_device *dev)
-{
- struct olympic_private *olympic_priv = netdev_priv(dev);
- u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
- u8 __iomem *arb_block, *asb_block, *srb ;
- u8 header_len ;
- u16 frame_len, buffer_len ;
- struct sk_buff *mac_frame ;
- u8 __iomem *buf_ptr ;
- u8 __iomem *frame_data ;
- u16 buff_off ;
- u16 lan_status = 0, lan_status_diff ; /* Initialize to stop compiler warning */
- u8 fdx_prot_error ;
- u16 next_ptr;
-
- arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ;
- asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ;
- srb = (olympic_priv->olympic_lap + olympic_priv->srb) ;
-
- if (readb(arb_block+0) == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */
-
- header_len = readb(arb_block+8) ; /* 802.5 Token-Ring Header Length */
- frame_len = swab16(readw(arb_block + 10)) ;
-
- buff_off = swab16(readw(arb_block + 6)) ;
-
- buf_ptr = olympic_priv->olympic_lap + buff_off ;
-
-#if OLYMPIC_DEBUG
-{
- int i;
- frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ;
-
- for (i=0 ; i < 14 ; i++) {
- printk("Loc %d = %02x\n",i,readb(frame_data + i));
- }
-
- printk("next %04x, fs %02x, len %04x\n",readw(buf_ptr+offsetof(struct mac_receive_buffer,next)), readb(buf_ptr+offsetof(struct mac_receive_buffer,frame_status)), readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length)));
-}
-#endif
- mac_frame = dev_alloc_skb(frame_len) ;
- if (!mac_frame) {
- printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", dev->name);
- goto drop_frame;
- }
-
- /* Walk the buffer chain, creating the frame */
-
- do {
- frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ;
- buffer_len = swab16(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length)));
- memcpy_fromio(skb_put(mac_frame, buffer_len), frame_data , buffer_len ) ;
- next_ptr=readw(buf_ptr+offsetof(struct mac_receive_buffer,next));
- } while (next_ptr && (buf_ptr=olympic_priv->olympic_lap + swab16(next_ptr)));
-
- mac_frame->protocol = tr_type_trans(mac_frame, dev);
-
- if (olympic_priv->olympic_network_monitor) {
- struct trh_hdr *mac_hdr;
- printk(KERN_WARNING "%s: Received MAC Frame, details:\n",dev->name);
- mac_hdr = tr_hdr(mac_frame);
- printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %pM\n",
- dev->name, mac_hdr->daddr);
- printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %pM\n",
- dev->name, mac_hdr->saddr);
- }
- netif_rx(mac_frame);
-
-drop_frame:
- /* Now tell the card we have dealt with the received frame */
-
- /* Set LISR Bit 1 */
- writel(LISR_ARB_FREE,olympic_priv->olympic_mmio + LISR_SUM);
-
- /* Is the ASB free ? */
-
- if (readb(asb_block + 2) != 0xff) {
- olympic_priv->asb_queued = 1 ;
- writel(LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM);
- return ;
- /* Drop out and wait for the bottom half to be run */
- }
-
- writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */
- writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */
- writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */
- writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */
-
- writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM);
-
- olympic_priv->asb_queued = 2 ;
-
- return ;
-
- } else if (readb(arb_block) == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */
- lan_status = swab16(readw(arb_block+6));
- fdx_prot_error = readb(arb_block+8) ;
-
- /* Issue ARB Free */
- writel(LISR_ARB_FREE,olympic_priv->olympic_mmio+LISR_SUM);
-
- lan_status_diff = olympic_priv->olympic_lan_status ^ lan_status ;
-
- if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) {
- if (lan_status_diff & LSC_LWF)
- printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name);
- if (lan_status_diff & LSC_ARW)
- printk(KERN_WARNING "%s: Auto removal error\n",dev->name);
- if (lan_status_diff & LSC_FPE)
- printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name);
- if (lan_status_diff & LSC_RR)
- printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name);
-
- /* Adapter has been closed by the hardware */
-
- /* reset tx/rx fifo's and busmaster logic */
-
- writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL);
- udelay(1);
- writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
- netif_stop_queue(dev);
- olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ;
- printk(KERN_WARNING "%s: Adapter has been closed\n", dev->name);
- } /* If serious error */
-
- if (olympic_priv->olympic_message_level) {
- if (lan_status_diff & LSC_SIG_LOSS)
- printk(KERN_WARNING "%s: No receive signal detected\n", dev->name);
- if (lan_status_diff & LSC_HARD_ERR)
- printk(KERN_INFO "%s: Beaconing\n",dev->name);
- if (lan_status_diff & LSC_SOFT_ERR)
- printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n",dev->name);
- if (lan_status_diff & LSC_TRAN_BCN)
- printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n",dev->name);
- if (lan_status_diff & LSC_SS)
- printk(KERN_INFO "%s: Single Station on the ring\n", dev->name);
- if (lan_status_diff & LSC_RING_REC)
- printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name);
- if (lan_status_diff & LSC_FDX_MODE)
- printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name);
- }
-
- if (lan_status_diff & LSC_CO) {
-
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Counter Overflow\n", dev->name);
-
- /* Issue READ.LOG command */
-
- writeb(SRB_READ_LOG, srb);
- writeb(0,srb+1);
- writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
- writeb(0,srb+3);
- writeb(0,srb+4);
- writeb(0,srb+5);
-
- olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */
-
- writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
-
- }
-
- if (lan_status_diff & LSC_SR_CO) {
-
- if (olympic_priv->olympic_message_level)
- printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name);
-
- /* Issue a READ.SR.COUNTERS */
-
- writeb(SRB_READ_SR_COUNTERS,srb);
- writeb(0,srb+1);
- writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
- writeb(0,srb+3);
-
- olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */
-
- writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
-
- }
-
- olympic_priv->olympic_lan_status = lan_status ;
-
- } /* Lan.change.status */
- else
- printk(KERN_WARNING "%s: Unknown arb command\n", dev->name);
-}
-
-static void olympic_asb_bh(struct net_device *dev)
-{
- struct olympic_private *olympic_priv = netdev_priv(dev);
- u8 __iomem *arb_block, *asb_block ;
-
- arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ;
- asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ;
-
- if (olympic_priv->asb_queued == 1) { /* Dropped through the first time */
-
- writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */
- writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */
- writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */
- writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */
-
- writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM);
- olympic_priv->asb_queued = 2 ;
-
- return ;
- }
-
- if (olympic_priv->asb_queued == 2) {
- switch (readb(asb_block+2)) {
- case 0x01:
- printk(KERN_WARNING "%s: Unrecognized command code\n", dev->name);
- break ;
- case 0x26:
- printk(KERN_WARNING "%s: Unrecognized buffer address\n", dev->name);
- break ;
- case 0xFF:
- /* Valid response, everything should be ok again */
- break ;
- default:
- printk(KERN_WARNING "%s: Invalid return code in asb\n",dev->name);
- break ;
- }
- }
- olympic_priv->asb_queued = 0 ;
-}
-
-static int olympic_change_mtu(struct net_device *dev, int mtu)
-{
- struct olympic_private *olympic_priv = netdev_priv(dev);
- u16 max_mtu ;
-
- if (olympic_priv->olympic_ring_speed == 4)
- max_mtu = 4500 ;
- else
- max_mtu = 18000 ;
-
- if (mtu > max_mtu)
- return -EINVAL ;
- if (mtu < 100)
- return -EINVAL ;
-
- dev->mtu = mtu ;
- olympic_priv->pkt_buf_sz = mtu + TR_HLEN ;
-
- return 0 ;
-}
-
-static int olympic_proc_show(struct seq_file *m, void *v)
-{
- struct net_device *dev = m->private;
- struct olympic_private *olympic_priv=netdev_priv(dev);
- u8 __iomem *oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ;
- u8 __iomem *opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ;
- u8 addr[6];
- u8 addr2[6];
- int i;
-
- seq_printf(m,
- "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name);
- seq_printf(m, "\n%6s: Adapter Address : Node Address : Functional Addr\n",
- dev->name);
-
- for (i = 0 ; i < 6 ; i++)
- addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr) + i);
-
- seq_printf(m, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
- dev->name,
- dev->dev_addr, addr,
- readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)),
- readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
- readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
- readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
-
- seq_printf(m, "\n%6s: Token Ring Parameters Table:\n", dev->name);
-
- seq_printf(m, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n",
- dev->name) ;
-
- for (i = 0 ; i < 6 ; i++)
- addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr) + i);
- for (i = 0 ; i < 6 ; i++)
- addr2[i] = readb(opt+offsetof(struct olympic_parameters_table, poll_addr) + i);
-
- seq_printf(m, "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n",
- dev->name,
- readb(opt+offsetof(struct olympic_parameters_table, phys_addr)),
- readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1),
- readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+2),
- readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+3),
- addr, addr2,
- swab16(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))),
- swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))),
- swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code))));
-
- seq_printf(m, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n",
- dev->name) ;
-
- for (i = 0 ; i < 6 ; i++)
- addr[i] = readb(opt+offsetof(struct olympic_parameters_table, source_addr) + i);
- seq_printf(m, "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n",
- dev->name, addr,
- swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))),
- swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))),
- swab16(readw(opt+offsetof(struct olympic_parameters_table, lan_status))),
- swab16(readw(opt+offsetof(struct olympic_parameters_table, local_ring))),
- swab16(readw(opt+offsetof(struct olympic_parameters_table, mon_error))),
- swab16(readw(opt+offsetof(struct olympic_parameters_table, frame_correl))));
-
- seq_printf(m, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n",
- dev->name) ;
-
- for (i = 0 ; i < 6 ; i++)
- addr[i] = readb(opt+offsetof(struct olympic_parameters_table, beacon_naun) + i);
- seq_printf(m, "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n",
- dev->name,
- swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))),
- swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))),
- addr,
- readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)),
- readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+1),
- readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2),
- readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+3));
-
- return 0;
-}
-
-static int olympic_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, olympic_proc_show, PDE(inode)->data);
-}
-
-static const struct file_operations olympic_proc_ops = {
- .open = olympic_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static void __devexit olympic_remove_one(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev) ;
- struct olympic_private *olympic_priv=netdev_priv(dev);
-
- if (olympic_priv->olympic_network_monitor) {
- char proc_name[20] ;
- strcpy(proc_name,"olympic_") ;
- strcat(proc_name,dev->name) ;
- remove_proc_entry(proc_name,init_net.proc_net);
- }
- unregister_netdev(dev) ;
- iounmap(olympic_priv->olympic_mmio) ;
- iounmap(olympic_priv->olympic_lap) ;
- pci_release_regions(pdev) ;
- pci_set_drvdata(pdev,NULL) ;
- free_netdev(dev) ;
-}
-
-static struct pci_driver olympic_driver = {
- .name = "olympic",
- .id_table = olympic_pci_tbl,
- .probe = olympic_probe,
- .remove = __devexit_p(olympic_remove_one),
-};
-
-module_pci_driver(olympic_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/tokenring/olympic.h b/drivers/net/tokenring/olympic.h
deleted file mode 100644
index 30631bae4c94..000000000000
--- a/drivers/net/tokenring/olympic.h
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * olympic.h (c) 1999 Peter De Schrijver All Rights Reserved
- * 1999,2000 Mike Phillips (mikep@linuxtr.net)
- *
- * Linux driver for IBM PCI tokenring cards based on the olympic and the PIT/PHY chipset.
- *
- * Base Driver Skeleton:
- * Written 1993-94 by Donald Becker.
- *
- * Copyright 1993 United States Government as represented by the
- * Director, National Security Agency.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- */
-
-#define CID 0x4e
-
-#define BCTL 0x70
-#define BCTL_SOFTRESET (1<<15)
-#define BCTL_MIMREB (1<<6)
-#define BCTL_MODE_INDICATOR (1<<5)
-
-#define GPR 0x4a
-#define GPR_OPTI_BF (1<<6)
-#define GPR_NEPTUNE_BF (1<<4)
-#define GPR_AUTOSENSE (1<<2)
-#define GPR_16MBPS (1<<3)
-
-#define PAG 0x85
-#define LBC 0x8e
-
-#define LISR 0x10
-#define LISR_SUM 0x14
-#define LISR_RWM 0x18
-
-#define LISR_LIE (1<<15)
-#define LISR_SLIM (1<<13)
-#define LISR_SLI (1<<12)
-#define LISR_PCMSRMASK (1<<11)
-#define LISR_PCMSRINT (1<<10)
-#define LISR_WOLMASK (1<<9)
-#define LISR_WOL (1<<8)
-#define LISR_SRB_CMD (1<<5)
-#define LISR_ASB_REPLY (1<<4)
-#define LISR_ASB_FREE_REQ (1<<2)
-#define LISR_ARB_FREE (1<<1)
-#define LISR_TRB_FRAME (1<<0)
-
-#define SISR 0x20
-#define SISR_SUM 0x24
-#define SISR_RWM 0x28
-#define SISR_RR 0x2C
-#define SISR_RESMASK 0x30
-#define SISR_MASK 0x54
-#define SISR_MASK_SUM 0x58
-#define SISR_MASK_RWM 0x5C
-
-#define SISR_TX2_IDLE (1<<31)
-#define SISR_TX2_HALT (1<<29)
-#define SISR_TX2_EOF (1<<28)
-#define SISR_TX1_IDLE (1<<27)
-#define SISR_TX1_HALT (1<<25)
-#define SISR_TX1_EOF (1<<24)
-#define SISR_TIMEOUT (1<<23)
-#define SISR_RX_NOBUF (1<<22)
-#define SISR_RX_STATUS (1<<21)
-#define SISR_RX_HALT (1<<18)
-#define SISR_RX_EOF_EARLY (1<<16)
-#define SISR_MI (1<<15)
-#define SISR_PI (1<<13)
-#define SISR_ERR (1<<9)
-#define SISR_ADAPTER_CHECK (1<<6)
-#define SISR_SRB_REPLY (1<<5)
-#define SISR_ASB_FREE (1<<4)
-#define SISR_ARB_CMD (1<<3)
-#define SISR_TRB_REPLY (1<<2)
-
-#define EISR 0x34
-#define EISR_RWM 0x38
-#define EISR_MASK 0x3c
-#define EISR_MASK_OPTIONS 0x001FFF7F
-
-#define LAPA 0x60
-#define LAPWWO 0x64
-#define LAPWWC 0x68
-#define LAPCTL 0x6C
-#define LAIPD 0x78
-#define LAIPDDINC 0x7C
-
-#define TIMER 0x50
-
-#define CLKCTL 0x74
-#define CLKCTL_PAUSE (1<<15)
-
-#define PM_CON 0x4
-
-#define BMCTL_SUM 0x40
-#define BMCTL_RWM 0x44
-#define BMCTL_TX2_DIS (1<<30)
-#define BMCTL_TX1_DIS (1<<26)
-#define BMCTL_RX_DIS (1<<22)
-
-#define BMASR 0xcc
-
-#define RXDESCQ 0x90
-#define RXDESCQCNT 0x94
-#define RXCDA 0x98
-#define RXENQ 0x9C
-#define RXSTATQ 0xA0
-#define RXSTATQCNT 0xA4
-#define RXCSA 0xA8
-#define RXCLEN 0xAC
-#define RXHLEN 0xAE
-
-#define TXDESCQ_1 0xb0
-#define TXDESCQ_2 0xd0
-#define TXDESCQCNT_1 0xb4
-#define TXDESCQCNT_2 0xd4
-#define TXCDA_1 0xb8
-#define TXCDA_2 0xd8
-#define TXENQ_1 0xbc
-#define TXENQ_2 0xdc
-#define TXSTATQ_1 0xc0
-#define TXSTATQ_2 0xe0
-#define TXSTATQCNT_1 0xc4
-#define TXSTATQCNT_2 0xe4
-#define TXCSA_1 0xc8
-#define TXCSA_2 0xe8
-/* Cardbus */
-#define FERMASK 0xf4
-#define FERMASK_INT_BIT (1<<15)
-
-#define OLYMPIC_IO_SPACE 256
-
-#define SRB_COMMAND_SIZE 50
-
-#define OLYMPIC_MAX_ADAPTERS 8 /* 0x08 __MODULE_STRING can't hand 0xnn */
-
-/* Defines for LAN STATUS CHANGE reports */
-#define LSC_SIG_LOSS 0x8000
-#define LSC_HARD_ERR 0x4000
-#define LSC_SOFT_ERR 0x2000
-#define LSC_TRAN_BCN 0x1000
-#define LSC_LWF 0x0800
-#define LSC_ARW 0x0400
-#define LSC_FPE 0x0200
-#define LSC_RR 0x0100
-#define LSC_CO 0x0080
-#define LSC_SS 0x0040
-#define LSC_RING_REC 0x0020
-#define LSC_SR_CO 0x0010
-#define LSC_FDX_MODE 0x0004
-
-/* Defines for OPEN ADAPTER command */
-
-#define OPEN_ADAPTER_EXT_WRAP (1<<15)
-#define OPEN_ADAPTER_DIS_HARDEE (1<<14)
-#define OPEN_ADAPTER_DIS_SOFTERR (1<<13)
-#define OPEN_ADAPTER_PASS_ADC_MAC (1<<12)
-#define OPEN_ADAPTER_PASS_ATT_MAC (1<<11)
-#define OPEN_ADAPTER_ENABLE_EC (1<<10)
-#define OPEN_ADAPTER_CONTENDER (1<<8)
-#define OPEN_ADAPTER_PASS_BEACON (1<<7)
-#define OPEN_ADAPTER_ENABLE_FDX (1<<6)
-#define OPEN_ADAPTER_ENABLE_RPL (1<<5)
-#define OPEN_ADAPTER_INHIBIT_ETR (1<<4)
-#define OPEN_ADAPTER_INTERNAL_WRAP (1<<3)
-#define OPEN_ADAPTER_USE_OPTS2 (1<<0)
-
-#define OPEN_ADAPTER_2_ENABLE_ONNOW (1<<15)
-
-/* Defines for SRB Commands */
-
-#define SRB_ACCESS_REGISTER 0x1f
-#define SRB_CLOSE_ADAPTER 0x04
-#define SRB_CONFIGURE_BRIDGE 0x0c
-#define SRB_CONFIGURE_WAKEUP_EVENT 0x1a
-#define SRB_MODIFY_BRIDGE_PARMS 0x15
-#define SRB_MODIFY_OPEN_OPTIONS 0x01
-#define SRB_MODIFY_RECEIVE_OPTIONS 0x17
-#define SRB_NO_OPERATION 0x00
-#define SRB_OPEN_ADAPTER 0x03
-#define SRB_READ_LOG 0x08
-#define SRB_READ_SR_COUNTERS 0x16
-#define SRB_RESET_GROUP_ADDRESS 0x02
-#define SRB_SAVE_CONFIGURATION 0x1b
-#define SRB_SET_BRIDGE_PARMS 0x09
-#define SRB_SET_BRIDGE_TARGETS 0x10
-#define SRB_SET_FUNC_ADDRESS 0x07
-#define SRB_SET_GROUP_ADDRESS 0x06
-#define SRB_SET_GROUP_ADDR_OPTIONS 0x11
-#define SRB_UPDATE_WAKEUP_PATTERN 0x19
-
-/* Clear return code */
-
-#define OLYMPIC_CLEAR_RET_CODE 0xfe
-
-/* ARB Commands */
-#define ARB_RECEIVE_DATA 0x81
-#define ARB_LAN_CHANGE_STATUS 0x84
-/* ASB Response commands */
-
-#define ASB_RECEIVE_DATA 0x81
-
-
-/* Olympic defaults for buffers */
-
-#define OLYMPIC_RX_RING_SIZE 16 /* should be a power of 2 */
-#define OLYMPIC_TX_RING_SIZE 8 /* should be a power of 2 */
-
-#define PKT_BUF_SZ 4096 /* Default packet size */
-
-/* Olympic data structures */
-
-/* xxxx These structures are all little endian in hardware. */
-
-struct olympic_tx_desc {
- __le32 buffer;
- __le32 status_length;
-};
-
-struct olympic_tx_status {
- __le32 status;
-};
-
-struct olympic_rx_desc {
- __le32 buffer;
- __le32 res_length;
-};
-
-struct olympic_rx_status {
- __le32 fragmentcnt_framelen;
- __le32 status_buffercnt;
-};
-/* xxxx END These structures are all little endian in hardware. */
-/* xxxx There may be more, but I'm pretty sure about these */
-
-struct mac_receive_buffer {
- __le16 next ;
- u8 padding ;
- u8 frame_status ;
- __le16 buffer_length ;
- u8 frame_data ;
-};
-
-struct olympic_private {
-
- u16 srb; /* be16 */
- u16 trb; /* be16 */
- u16 arb; /* be16 */
- u16 asb; /* be16 */
-
- u8 __iomem *olympic_mmio;
- u8 __iomem *olympic_lap;
- struct pci_dev *pdev ;
- const char *olympic_card_name;
-
- spinlock_t olympic_lock ;
-
- volatile int srb_queued; /* True if an SRB is still posted */
- wait_queue_head_t srb_wait;
-
- volatile int asb_queued; /* True if an ASB is posted */
-
- volatile int trb_queued; /* True if a TRB is posted */
- wait_queue_head_t trb_wait ;
-
- /* These must be on a 4 byte boundary. */
- struct olympic_rx_desc olympic_rx_ring[OLYMPIC_RX_RING_SIZE];
- struct olympic_tx_desc olympic_tx_ring[OLYMPIC_TX_RING_SIZE];
- struct olympic_rx_status olympic_rx_status_ring[OLYMPIC_RX_RING_SIZE];
- struct olympic_tx_status olympic_tx_status_ring[OLYMPIC_TX_RING_SIZE];
-
- struct sk_buff *tx_ring_skb[OLYMPIC_TX_RING_SIZE], *rx_ring_skb[OLYMPIC_RX_RING_SIZE];
- int tx_ring_free, tx_ring_last_status, rx_ring_last_received,rx_status_last_received, free_tx_ring_entries;
-
- u16 olympic_lan_status ;
- u8 olympic_ring_speed ;
- u16 pkt_buf_sz ;
- u8 olympic_receive_options, olympic_copy_all_options,olympic_message_level, olympic_network_monitor;
- u16 olympic_addr_table_addr, olympic_parms_addr ;
- u8 olympic_laa[6] ;
- u32 rx_ring_dma_addr;
- u32 rx_status_ring_dma_addr;
- u32 tx_ring_dma_addr;
- u32 tx_status_ring_dma_addr;
-};
-
-struct olympic_adapter_addr_table {
-
- u8 node_addr[6] ;
- u8 reserved[4] ;
- u8 func_addr[4] ;
-} ;
-
-struct olympic_parameters_table {
-
- u8 phys_addr[4] ;
- u8 up_node_addr[6] ;
- u8 up_phys_addr[4] ;
- u8 poll_addr[6] ;
- u16 reserved ;
- u16 acc_priority ;
- u16 auth_source_class ;
- u16 att_code ;
- u8 source_addr[6] ;
- u16 beacon_type ;
- u16 major_vector ;
- u16 lan_status ;
- u16 soft_error_time ;
- u16 reserved1 ;
- u16 local_ring ;
- u16 mon_error ;
- u16 beacon_transmit ;
- u16 beacon_receive ;
- u16 frame_correl ;
- u8 beacon_naun[6] ;
- u32 reserved2 ;
- u8 beacon_phys[4] ;
-};
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
deleted file mode 100644
index 62d90e40f9ec..000000000000
--- a/drivers/net/tokenring/proteon.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * proteon.c: A network driver for Proteon ISA token ring cards.
- *
- * Based on tmspci written 1999 by Adam Fritzler
- *
- * Written 2003 by Jochen Friedrich
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * This driver module supports the following cards:
- * - Proteon 1392, 1392+
- *
- * Maintainer(s):
- * AF Adam Fritzler
- * JF Jochen Friedrich jochen@scram.de
- *
- * Modification History:
- * 02-Jan-03 JF Created
- *
- */
-static const char version[] = "proteon.c: v1.00 02/01/2003 by Jochen Friedrich\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-#include <linux/platform_device.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/pci.h>
-#include <asm/dma.h>
-
-#include "tms380tr.h"
-
-#define PROTEON_IO_EXTENT 32
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int portlist[] __initdata = {
- 0x0A20, 0x0E20, 0x1A20, 0x1E20, 0x2A20, 0x2E20, 0x3A20, 0x3E20,// Prot.
- 0x4A20, 0x4E20, 0x5A20, 0x5E20, 0x6A20, 0x6E20, 0x7A20, 0x7E20,// Prot.
- 0x8A20, 0x8E20, 0x9A20, 0x9E20, 0xAA20, 0xAE20, 0xBA20, 0xBE20,// Prot.
- 0xCA20, 0xCE20, 0xDA20, 0xDE20, 0xEA20, 0xEE20, 0xFA20, 0xFE20,// Prot.
- 0
-};
-
-/* A zero-terminated list of IRQs to be probed. */
-static unsigned short irqlist[] = {
- 7, 6, 5, 4, 3, 12, 11, 10, 9,
- 0
-};
-
-/* A zero-terminated list of DMAs to be probed. */
-static int dmalist[] __initdata = {
- 5, 6, 7,
- 0
-};
-
-static char cardname[] = "Proteon 1392\0";
-static u64 dma_mask = ISA_MAX_ADDRESS;
-static int proteon_open(struct net_device *dev);
-static void proteon_read_eeprom(struct net_device *dev);
-static unsigned short proteon_setnselout_pins(struct net_device *dev);
-
-static unsigned short proteon_sifreadb(struct net_device *dev, unsigned short reg)
-{
- return inb(dev->base_addr + reg);
-}
-
-static unsigned short proteon_sifreadw(struct net_device *dev, unsigned short reg)
-{
- return inw(dev->base_addr + reg);
-}
-
-static void proteon_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- outb(val, dev->base_addr + reg);
-}
-
-static void proteon_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- outw(val, dev->base_addr + reg);
-}
-
-static int __init proteon_probe1(struct net_device *dev, int ioaddr)
-{
- unsigned char chk1, chk2;
- int i;
-
- if (!request_region(ioaddr, PROTEON_IO_EXTENT, cardname))
- return -ENODEV;
-
-
- chk1 = inb(ioaddr + 0x1f); /* Get Proteon ID reg 1 */
- if (chk1 != 0x1f)
- goto nodev;
-
- chk1 = inb(ioaddr + 0x1e) & 0x07; /* Get Proteon ID reg 0 */
- for (i=0; i<16; i++) {
- chk2 = inb(ioaddr + 0x1e) & 0x07;
- if (((chk1 + 1) & 0x07) != chk2)
- goto nodev;
- chk1 = chk2;
- }
-
- dev->base_addr = ioaddr;
- return 0;
-nodev:
- release_region(ioaddr, PROTEON_IO_EXTENT);
- return -ENODEV;
-}
-
-static struct net_device_ops proteon_netdev_ops __read_mostly;
-
-static int __init setup_card(struct net_device *dev, struct device *pdev)
-{
- struct net_local *tp;
- static int versionprinted;
- const unsigned *port;
- int j,err = 0;
-
- if (!dev)
- return -ENOMEM;
-
- if (dev->base_addr) /* probe specific location */
- err = proteon_probe1(dev, dev->base_addr);
- else {
- for (port = portlist; *port; port++) {
- err = proteon_probe1(dev, *port);
- if (!err)
- break;
- }
- }
- if (err)
- goto out5;
-
- /* At this point we have found a valid card. */
-
- if (versionprinted++ == 0)
- printk(KERN_DEBUG "%s", version);
-
- err = -EIO;
- pdev->dma_mask = &dma_mask;
- if (tmsdev_init(dev, pdev))
- goto out4;
-
- dev->base_addr &= ~3;
-
- proteon_read_eeprom(dev);
-
- printk(KERN_DEBUG "proteon.c: Ring Station Address: %pM\n",
- dev->dev_addr);
-
- tp = netdev_priv(dev);
- tp->setnselout = proteon_setnselout_pins;
-
- tp->sifreadb = proteon_sifreadb;
- tp->sifreadw = proteon_sifreadw;
- tp->sifwriteb = proteon_sifwriteb;
- tp->sifwritew = proteon_sifwritew;
-
- memcpy(tp->ProductID, cardname, PROD_ID_SIZE + 1);
-
- tp->tmspriv = NULL;
-
- dev->netdev_ops = &proteon_netdev_ops;
-
- if (dev->irq == 0)
- {
- for(j = 0; irqlist[j] != 0; j++)
- {
- dev->irq = irqlist[j];
- if (!request_irq(dev->irq, tms380tr_interrupt, 0,
- cardname, dev))
- break;
- }
-
- if(irqlist[j] == 0)
- {
- printk(KERN_INFO "proteon.c: AutoSelect no IRQ available\n");
- goto out3;
- }
- }
- else
- {
- for(j = 0; irqlist[j] != 0; j++)
- if (irqlist[j] == dev->irq)
- break;
- if (irqlist[j] == 0)
- {
- printk(KERN_INFO "proteon.c: Illegal IRQ %d specified\n",
- dev->irq);
- goto out3;
- }
- if (request_irq(dev->irq, tms380tr_interrupt, 0,
- cardname, dev))
- {
- printk(KERN_INFO "proteon.c: Selected IRQ %d not available\n",
- dev->irq);
- goto out3;
- }
- }
-
- if (dev->dma == 0)
- {
- for(j = 0; dmalist[j] != 0; j++)
- {
- dev->dma = dmalist[j];
- if (!request_dma(dev->dma, cardname))
- break;
- }
-
- if(dmalist[j] == 0)
- {
- printk(KERN_INFO "proteon.c: AutoSelect no DMA available\n");
- goto out2;
- }
- }
- else
- {
- for(j = 0; dmalist[j] != 0; j++)
- if (dmalist[j] == dev->dma)
- break;
- if (dmalist[j] == 0)
- {
- printk(KERN_INFO "proteon.c: Illegal DMA %d specified\n",
- dev->dma);
- goto out2;
- }
- if (request_dma(dev->dma, cardname))
- {
- printk(KERN_INFO "proteon.c: Selected DMA %d not available\n",
- dev->dma);
- goto out2;
- }
- }
-
- err = register_netdev(dev);
- if (err)
- goto out;
-
- printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n",
- dev->name, dev->base_addr, dev->irq, dev->dma);
-
- return 0;
-out:
- free_dma(dev->dma);
-out2:
- free_irq(dev->irq, dev);
-out3:
- tmsdev_term(dev);
-out4:
- release_region(dev->base_addr, PROTEON_IO_EXTENT);
-out5:
- return err;
-}
-
-/*
- * Reads MAC address from adapter RAM, which should've read it from
- * the onboard ROM.
- *
- * Calling this on a board that does not support it can be a very
- * dangerous thing. The Madge board, for instance, will lock your
- * machine hard when this is called. Luckily, its supported in a
- * separate driver. --ASF
- */
-static void proteon_read_eeprom(struct net_device *dev)
-{
- int i;
-
- /* Address: 0000:0000 */
- proteon_sifwritew(dev, 0, SIFADX);
- proteon_sifwritew(dev, 0, SIFADR);
-
- /* Read six byte MAC address data */
- dev->addr_len = 6;
- for(i = 0; i < 6; i++)
- dev->dev_addr[i] = proteon_sifreadw(dev, SIFINC) >> 8;
-}
-
-static unsigned short proteon_setnselout_pins(struct net_device *dev)
-{
- return 0;
-}
-
-static int proteon_open(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned short val = 0;
- int i;
-
- /* Proteon reset sequence */
- outb(0, dev->base_addr + 0x11);
- mdelay(20);
- outb(0x04, dev->base_addr + 0x11);
- mdelay(20);
- outb(0, dev->base_addr + 0x11);
- mdelay(100);
-
- /* set control/status reg */
- val = inb(dev->base_addr + 0x11);
- val |= 0x78;
- val &= 0xf9;
- if(tp->DataRate == SPEED_4)
- val |= 0x20;
- else
- val &= ~0x20;
-
- outb(val, dev->base_addr + 0x11);
- outb(0xff, dev->base_addr + 0x12);
- for(i = 0; irqlist[i] != 0; i++)
- {
- if(irqlist[i] == dev->irq)
- break;
- }
- val = i;
- i = (7 - dev->dma) << 4;
- val |= i;
- outb(val, dev->base_addr + 0x13);
-
- return tms380tr_open(dev);
-}
-
-#define ISATR_MAX_ADAPTERS 3
-
-static int io[ISATR_MAX_ADAPTERS];
-static int irq[ISATR_MAX_ADAPTERS];
-static int dma[ISATR_MAX_ADAPTERS];
-
-MODULE_LICENSE("GPL");
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(dma, int, NULL, 0);
-
-static struct platform_device *proteon_dev[ISATR_MAX_ADAPTERS];
-
-static struct platform_driver proteon_driver = {
- .driver = {
- .name = "proteon",
- },
-};
-
-static int __init proteon_init(void)
-{
- struct net_device *dev;
- struct platform_device *pdev;
- int i, num = 0, err = 0;
-
- proteon_netdev_ops = tms380tr_netdev_ops;
- proteon_netdev_ops.ndo_open = proteon_open;
- proteon_netdev_ops.ndo_stop = tms380tr_close;
-
- err = platform_driver_register(&proteon_driver);
- if (err)
- return err;
-
- for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
- dev = alloc_trdev(sizeof(struct net_local));
- if (!dev)
- continue;
-
- dev->base_addr = io[i];
- dev->irq = irq[i];
- dev->dma = dma[i];
- pdev = platform_device_register_simple("proteon",
- i, NULL, 0);
- if (IS_ERR(pdev)) {
- free_netdev(dev);
- continue;
- }
- err = setup_card(dev, &pdev->dev);
- if (!err) {
- proteon_dev[i] = pdev;
- platform_set_drvdata(pdev, dev);
- ++num;
- } else {
- platform_device_unregister(pdev);
- free_netdev(dev);
- }
- }
-
- printk(KERN_NOTICE "proteon.c: %d cards found.\n", num);
- /* Probe for cards. */
- if (num == 0) {
- printk(KERN_NOTICE "proteon.c: No cards found.\n");
- platform_driver_unregister(&proteon_driver);
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit proteon_cleanup(void)
-{
- struct net_device *dev;
- int i;
-
- for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
- struct platform_device *pdev = proteon_dev[i];
-
- if (!pdev)
- continue;
- dev = platform_get_drvdata(pdev);
- unregister_netdev(dev);
- release_region(dev->base_addr, PROTEON_IO_EXTENT);
- free_irq(dev->irq, dev);
- free_dma(dev->dma);
- tmsdev_term(dev);
- free_netdev(dev);
- platform_set_drvdata(pdev, NULL);
- platform_device_unregister(pdev);
- }
- platform_driver_unregister(&proteon_driver);
-}
-
-module_init(proteon_init);
-module_exit(proteon_cleanup);
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
deleted file mode 100644
index ee11e93dc30e..000000000000
--- a/drivers/net/tokenring/skisa.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * skisa.c: A network driver for SK-NET TMS380-based ISA token ring cards.
- *
- * Based on tmspci written 1999 by Adam Fritzler
- *
- * Written 2000 by Jochen Friedrich
- * Dedicated to my girlfriend Steffi Bopp
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * This driver module supports the following cards:
- * - SysKonnect TR4/16(+) ISA (SK-4190)
- *
- * Maintainer(s):
- * AF Adam Fritzler
- * JF Jochen Friedrich jochen@scram.de
- *
- * Modification History:
- * 14-Jan-01 JF Created
- * 28-Oct-02 JF Fixed probe of card for static compilation.
- * Fixed module init to not make hotplug go wild.
- * 09-Nov-02 JF Fixed early bail out on out of memory
- * situations if multiple cards are found.
- * Cleaned up some unnecessary console SPAM.
- * 09-Dec-02 JF Fixed module reference counting.
- * 02-Jan-03 JF Renamed to skisa.c
- *
- */
-static const char version[] = "skisa.c: v1.03 09/12/2002 by Jochen Friedrich\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-#include <linux/platform_device.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/pci.h>
-#include <asm/dma.h>
-
-#include "tms380tr.h"
-
-#define SK_ISA_IO_EXTENT 32
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int portlist[] __initdata = {
- 0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900,// SK
- 0
-};
-
-/* A zero-terminated list of IRQs to be probed.
- * Used again after initial probe for sktr_chipset_init, called from sktr_open.
- */
-static const unsigned short irqlist[] = {
- 3, 5, 9, 10, 11, 12, 15,
- 0
-};
-
-/* A zero-terminated list of DMAs to be probed. */
-static int dmalist[] __initdata = {
- 5, 6, 7,
- 0
-};
-
-static char isa_cardname[] = "SK NET TR 4/16 ISA\0";
-static u64 dma_mask = ISA_MAX_ADDRESS;
-static int sk_isa_open(struct net_device *dev);
-static void sk_isa_read_eeprom(struct net_device *dev);
-static unsigned short sk_isa_setnselout_pins(struct net_device *dev);
-
-static unsigned short sk_isa_sifreadb(struct net_device *dev, unsigned short reg)
-{
- return inb(dev->base_addr + reg);
-}
-
-static unsigned short sk_isa_sifreadw(struct net_device *dev, unsigned short reg)
-{
- return inw(dev->base_addr + reg);
-}
-
-static void sk_isa_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- outb(val, dev->base_addr + reg);
-}
-
-static void sk_isa_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- outw(val, dev->base_addr + reg);
-}
-
-
-static int __init sk_isa_probe1(struct net_device *dev, int ioaddr)
-{
- unsigned char old, chk1, chk2;
-
- if (!request_region(ioaddr, SK_ISA_IO_EXTENT, isa_cardname))
- return -ENODEV;
-
- old = inb(ioaddr + SIFADR); /* Get the old SIFADR value */
-
- chk1 = 0; /* Begin with check value 0 */
- do {
- /* Write new SIFADR value */
- outb(chk1, ioaddr + SIFADR);
-
- /* Read, invert and write */
- chk2 = inb(ioaddr + SIFADD);
- chk2 ^= 0x0FE;
- outb(chk2, ioaddr + SIFADR);
-
- /* Read, invert and compare */
- chk2 = inb(ioaddr + SIFADD);
- chk2 ^= 0x0FE;
-
- if(chk1 != chk2) {
- release_region(ioaddr, SK_ISA_IO_EXTENT);
- return -ENODEV;
- }
-
- chk1 -= 2;
- } while(chk1 != 0); /* Repeat 128 times (all byte values) */
-
- /* Restore the SIFADR value */
- outb(old, ioaddr + SIFADR);
-
- dev->base_addr = ioaddr;
- return 0;
-}
-
-static struct net_device_ops sk_isa_netdev_ops __read_mostly;
-
-static int __init setup_card(struct net_device *dev, struct device *pdev)
-{
- struct net_local *tp;
- static int versionprinted;
- const unsigned *port;
- int j, err = 0;
-
- if (!dev)
- return -ENOMEM;
-
- if (dev->base_addr) /* probe specific location */
- err = sk_isa_probe1(dev, dev->base_addr);
- else {
- for (port = portlist; *port; port++) {
- err = sk_isa_probe1(dev, *port);
- if (!err)
- break;
- }
- }
- if (err)
- goto out5;
-
- /* At this point we have found a valid card. */
-
- if (versionprinted++ == 0)
- printk(KERN_DEBUG "%s", version);
-
- err = -EIO;
- pdev->dma_mask = &dma_mask;
- if (tmsdev_init(dev, pdev))
- goto out4;
-
- dev->base_addr &= ~3;
-
- sk_isa_read_eeprom(dev);
-
- printk(KERN_DEBUG "skisa.c: Ring Station Address: %pM\n",
- dev->dev_addr);
-
- tp = netdev_priv(dev);
- tp->setnselout = sk_isa_setnselout_pins;
-
- tp->sifreadb = sk_isa_sifreadb;
- tp->sifreadw = sk_isa_sifreadw;
- tp->sifwriteb = sk_isa_sifwriteb;
- tp->sifwritew = sk_isa_sifwritew;
-
- memcpy(tp->ProductID, isa_cardname, PROD_ID_SIZE + 1);
-
- tp->tmspriv = NULL;
-
- dev->netdev_ops = &sk_isa_netdev_ops;
-
- if (dev->irq == 0)
- {
- for(j = 0; irqlist[j] != 0; j++)
- {
- dev->irq = irqlist[j];
- if (!request_irq(dev->irq, tms380tr_interrupt, 0,
- isa_cardname, dev))
- break;
- }
-
- if(irqlist[j] == 0)
- {
- printk(KERN_INFO "skisa.c: AutoSelect no IRQ available\n");
- goto out3;
- }
- }
- else
- {
- for(j = 0; irqlist[j] != 0; j++)
- if (irqlist[j] == dev->irq)
- break;
- if (irqlist[j] == 0)
- {
- printk(KERN_INFO "skisa.c: Illegal IRQ %d specified\n",
- dev->irq);
- goto out3;
- }
- if (request_irq(dev->irq, tms380tr_interrupt, 0,
- isa_cardname, dev))
- {
- printk(KERN_INFO "skisa.c: Selected IRQ %d not available\n",
- dev->irq);
- goto out3;
- }
- }
-
- if (dev->dma == 0)
- {
- for(j = 0; dmalist[j] != 0; j++)
- {
- dev->dma = dmalist[j];
- if (!request_dma(dev->dma, isa_cardname))
- break;
- }
-
- if(dmalist[j] == 0)
- {
- printk(KERN_INFO "skisa.c: AutoSelect no DMA available\n");
- goto out2;
- }
- }
- else
- {
- for(j = 0; dmalist[j] != 0; j++)
- if (dmalist[j] == dev->dma)
- break;
- if (dmalist[j] == 0)
- {
- printk(KERN_INFO "skisa.c: Illegal DMA %d specified\n",
- dev->dma);
- goto out2;
- }
- if (request_dma(dev->dma, isa_cardname))
- {
- printk(KERN_INFO "skisa.c: Selected DMA %d not available\n",
- dev->dma);
- goto out2;
- }
- }
-
- err = register_netdev(dev);
- if (err)
- goto out;
-
- printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n",
- dev->name, dev->base_addr, dev->irq, dev->dma);
-
- return 0;
-out:
- free_dma(dev->dma);
-out2:
- free_irq(dev->irq, dev);
-out3:
- tmsdev_term(dev);
-out4:
- release_region(dev->base_addr, SK_ISA_IO_EXTENT);
-out5:
- return err;
-}
-
-/*
- * Reads MAC address from adapter RAM, which should've read it from
- * the onboard ROM.
- *
- * Calling this on a board that does not support it can be a very
- * dangerous thing. The Madge board, for instance, will lock your
- * machine hard when this is called. Luckily, its supported in a
- * separate driver. --ASF
- */
-static void sk_isa_read_eeprom(struct net_device *dev)
-{
- int i;
-
- /* Address: 0000:0000 */
- sk_isa_sifwritew(dev, 0, SIFADX);
- sk_isa_sifwritew(dev, 0, SIFADR);
-
- /* Read six byte MAC address data */
- dev->addr_len = 6;
- for(i = 0; i < 6; i++)
- dev->dev_addr[i] = sk_isa_sifreadw(dev, SIFINC) >> 8;
-}
-
-static unsigned short sk_isa_setnselout_pins(struct net_device *dev)
-{
- return 0;
-}
-
-static int sk_isa_open(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned short val = 0;
- unsigned short oldval;
- int i;
-
- val = 0;
- for(i = 0; irqlist[i] != 0; i++)
- {
- if(irqlist[i] == dev->irq)
- break;
- }
-
- val |= CYCLE_TIME << 2;
- val |= i << 4;
- i = dev->dma - 5;
- val |= i;
- if(tp->DataRate == SPEED_4)
- val |= LINE_SPEED_BIT;
- else
- val &= ~LINE_SPEED_BIT;
- oldval = sk_isa_sifreadb(dev, POSREG);
- /* Leave cycle bits alone */
- oldval |= 0xf3;
- val &= oldval;
- sk_isa_sifwriteb(dev, val, POSREG);
-
- return tms380tr_open(dev);
-}
-
-#define ISATR_MAX_ADAPTERS 3
-
-static int io[ISATR_MAX_ADAPTERS];
-static int irq[ISATR_MAX_ADAPTERS];
-static int dma[ISATR_MAX_ADAPTERS];
-
-MODULE_LICENSE("GPL");
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(dma, int, NULL, 0);
-
-static struct platform_device *sk_isa_dev[ISATR_MAX_ADAPTERS];
-
-static struct platform_driver sk_isa_driver = {
- .driver = {
- .name = "skisa",
- },
-};
-
-static int __init sk_isa_init(void)
-{
- struct net_device *dev;
- struct platform_device *pdev;
- int i, num = 0, err = 0;
-
- sk_isa_netdev_ops = tms380tr_netdev_ops;
- sk_isa_netdev_ops.ndo_open = sk_isa_open;
- sk_isa_netdev_ops.ndo_stop = tms380tr_close;
-
- err = platform_driver_register(&sk_isa_driver);
- if (err)
- return err;
-
- for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
- dev = alloc_trdev(sizeof(struct net_local));
- if (!dev)
- continue;
-
- dev->base_addr = io[i];
- dev->irq = irq[i];
- dev->dma = dma[i];
- pdev = platform_device_register_simple("skisa",
- i, NULL, 0);
- if (IS_ERR(pdev)) {
- free_netdev(dev);
- continue;
- }
- err = setup_card(dev, &pdev->dev);
- if (!err) {
- sk_isa_dev[i] = pdev;
- platform_set_drvdata(sk_isa_dev[i], dev);
- ++num;
- } else {
- platform_device_unregister(pdev);
- free_netdev(dev);
- }
- }
-
- printk(KERN_NOTICE "skisa.c: %d cards found.\n", num);
- /* Probe for cards. */
- if (num == 0) {
- printk(KERN_NOTICE "skisa.c: No cards found.\n");
- platform_driver_unregister(&sk_isa_driver);
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit sk_isa_cleanup(void)
-{
- struct net_device *dev;
- int i;
-
- for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) {
- struct platform_device *pdev = sk_isa_dev[i];
-
- if (!pdev)
- continue;
- dev = platform_get_drvdata(pdev);
- unregister_netdev(dev);
- release_region(dev->base_addr, SK_ISA_IO_EXTENT);
- free_irq(dev->irq, dev);
- free_dma(dev->dma);
- tmsdev_term(dev);
- free_netdev(dev);
- platform_set_drvdata(pdev, NULL);
- platform_device_unregister(pdev);
- }
- platform_driver_unregister(&sk_isa_driver);
-}
-
-module_init(sk_isa_init);
-module_exit(sk_isa_cleanup);
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
deleted file mode 100644
index cb35fb79e016..000000000000
--- a/drivers/net/tokenring/smctr.c
+++ /dev/null
@@ -1,5717 +0,0 @@
-/*
- * smctr.c: A network driver for the SMC Token Ring Adapters.
- *
- * Written by Jay Schulist <jschlst@samba.org>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * This device driver works with the following SMC adapters:
- * - SMC TokenCard Elite (8115T, chips 825/584)
- * - SMC TokenCard Elite/A MCA (8115T/A, chips 825/594)
- *
- * Source(s):
- * - SMC TokenCard SDK.
- *
- * Maintainer(s):
- * JS Jay Schulist <jschlst@samba.org>
- *
- * Changes:
- * 07102000 JS Fixed a timing problem in smctr_wait_cmd();
- * Also added a bit more discriptive error msgs.
- * 07122000 JS Fixed problem with detecting a card with
- * module io/irq/mem specified.
- *
- * To do:
- * 1. Multicast support.
- *
- * Initial 2.5 cleanup Alan Cox <alan@lxorguk.ukuu.org.uk> 2002/10/28
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/time.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/mca-legacy.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/trdevice.h>
-#include <linux/bitops.h>
-#include <linux/firmware.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-
-#if BITS_PER_LONG == 64
-#error FIXME: driver does not support 64-bit platforms
-#endif
-
-#include "smctr.h" /* Our Stuff */
-
-static const char version[] __initdata =
- KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";
-static const char cardname[] = "smctr";
-
-
-#define SMCTR_IO_EXTENT 20
-
-#ifdef CONFIG_MCA_LEGACY
-static unsigned int smctr_posid = 0x6ec6;
-#endif
-
-static int ringspeed;
-
-/* SMC Name of the Adapter. */
-static char smctr_name[] = "SMC TokenCard";
-static char *smctr_model = "Unknown";
-
-/* Use 0 for production, 1 for verification, 2 for debug, and
- * 3 for very verbose debug.
- */
-#ifndef SMCTR_DEBUG
-#define SMCTR_DEBUG 1
-#endif
-static unsigned int smctr_debug = SMCTR_DEBUG;
-
-/* smctr.c prototypes and functions are arranged alphabeticly
- * for clearity, maintainability and pure old fashion fun.
- */
-/* A */
-static int smctr_alloc_shared_memory(struct net_device *dev);
-
-/* B */
-static int smctr_bypass_state(struct net_device *dev);
-
-/* C */
-static int smctr_checksum_firmware(struct net_device *dev);
-static int __init smctr_chk_isa(struct net_device *dev);
-static int smctr_chg_rx_mask(struct net_device *dev);
-static int smctr_clear_int(struct net_device *dev);
-static int smctr_clear_trc_reset(int ioaddr);
-static int smctr_close(struct net_device *dev);
-
-/* D */
-static int smctr_decode_firmware(struct net_device *dev,
- const struct firmware *fw);
-static int smctr_disable_16bit(struct net_device *dev);
-static int smctr_disable_adapter_ctrl_store(struct net_device *dev);
-static int smctr_disable_bic_int(struct net_device *dev);
-
-/* E */
-static int smctr_enable_16bit(struct net_device *dev);
-static int smctr_enable_adapter_ctrl_store(struct net_device *dev);
-static int smctr_enable_adapter_ram(struct net_device *dev);
-static int smctr_enable_bic_int(struct net_device *dev);
-
-/* G */
-static int __init smctr_get_boardid(struct net_device *dev, int mca);
-static int smctr_get_group_address(struct net_device *dev);
-static int smctr_get_functional_address(struct net_device *dev);
-static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev);
-static int smctr_get_physical_drop_number(struct net_device *dev);
-static __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue);
-static int smctr_get_station_id(struct net_device *dev);
-static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
- __u16 bytes_count);
-static int smctr_get_upstream_neighbor_addr(struct net_device *dev);
-
-/* H */
-static int smctr_hardware_send_packet(struct net_device *dev,
- struct net_local *tp);
-/* I */
-static int smctr_init_acbs(struct net_device *dev);
-static int smctr_init_adapter(struct net_device *dev);
-static int smctr_init_card_real(struct net_device *dev);
-static int smctr_init_rx_bdbs(struct net_device *dev);
-static int smctr_init_rx_fcbs(struct net_device *dev);
-static int smctr_init_shared_memory(struct net_device *dev);
-static int smctr_init_tx_bdbs(struct net_device *dev);
-static int smctr_init_tx_fcbs(struct net_device *dev);
-static int smctr_internal_self_test(struct net_device *dev);
-static irqreturn_t smctr_interrupt(int irq, void *dev_id);
-static int smctr_issue_enable_int_cmd(struct net_device *dev,
- __u16 interrupt_enable_mask);
-static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code,
- __u16 ibits);
-static int smctr_issue_init_timers_cmd(struct net_device *dev);
-static int smctr_issue_init_txrx_cmd(struct net_device *dev);
-static int smctr_issue_insert_cmd(struct net_device *dev);
-static int smctr_issue_read_ring_status_cmd(struct net_device *dev);
-static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt);
-static int smctr_issue_remove_cmd(struct net_device *dev);
-static int smctr_issue_resume_acb_cmd(struct net_device *dev);
-static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue);
-static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue);
-static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue);
-static int smctr_issue_test_internal_rom_cmd(struct net_device *dev);
-static int smctr_issue_test_hic_cmd(struct net_device *dev);
-static int smctr_issue_test_mac_reg_cmd(struct net_device *dev);
-static int smctr_issue_trc_loopback_cmd(struct net_device *dev);
-static int smctr_issue_tri_loopback_cmd(struct net_device *dev);
-static int smctr_issue_write_byte_cmd(struct net_device *dev,
- short aword_cnt, void *byte);
-static int smctr_issue_write_word_cmd(struct net_device *dev,
- short aword_cnt, void *word);
-
-/* J */
-static int smctr_join_complete_state(struct net_device *dev);
-
-/* L */
-static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev);
-static int smctr_load_firmware(struct net_device *dev);
-static int smctr_load_node_addr(struct net_device *dev);
-static int smctr_lobe_media_test(struct net_device *dev);
-static int smctr_lobe_media_test_cmd(struct net_device *dev);
-static int smctr_lobe_media_test_state(struct net_device *dev);
-
-/* M */
-static int smctr_make_8025_hdr(struct net_device *dev,
- MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc);
-static int smctr_make_access_pri(struct net_device *dev,
- MAC_SUB_VECTOR *tsv);
-static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv);
-static int smctr_make_auth_funct_class(struct net_device *dev,
- MAC_SUB_VECTOR *tsv);
-static int smctr_make_corr(struct net_device *dev,
- MAC_SUB_VECTOR *tsv, __u16 correlator);
-static int smctr_make_funct_addr(struct net_device *dev,
- MAC_SUB_VECTOR *tsv);
-static int smctr_make_group_addr(struct net_device *dev,
- MAC_SUB_VECTOR *tsv);
-static int smctr_make_phy_drop_num(struct net_device *dev,
- MAC_SUB_VECTOR *tsv);
-static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv);
-static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv);
-static int smctr_make_ring_station_status(struct net_device *dev,
- MAC_SUB_VECTOR *tsv);
-static int smctr_make_ring_station_version(struct net_device *dev,
- MAC_SUB_VECTOR *tsv);
-static int smctr_make_tx_status_code(struct net_device *dev,
- MAC_SUB_VECTOR *tsv, __u16 tx_fstatus);
-static int smctr_make_upstream_neighbor_addr(struct net_device *dev,
- MAC_SUB_VECTOR *tsv);
-static int smctr_make_wrap_data(struct net_device *dev,
- MAC_SUB_VECTOR *tsv);
-
-/* O */
-static int smctr_open(struct net_device *dev);
-static int smctr_open_tr(struct net_device *dev);
-
-/* P */
-struct net_device *smctr_probe(int unit);
-static int __init smctr_probe1(struct net_device *dev, int ioaddr);
-static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
- struct net_device *dev, __u16 rx_status);
-
-/* R */
-static int smctr_ram_memory_test(struct net_device *dev);
-static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf,
- __u16 *correlator);
-static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf,
- __u16 *correlator);
-static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf);
-static int smctr_rcv_rq_addr_state_attch(struct net_device *dev,
- MAC_HEADER *rmf, __u16 *correlator);
-static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf,
- __u16 *correlator);
-static int smctr_reset_adapter(struct net_device *dev);
-static int smctr_restart_tx_chain(struct net_device *dev, short queue);
-static int smctr_ring_status_chg(struct net_device *dev);
-static int smctr_rx_frame(struct net_device *dev);
-
-/* S */
-static int smctr_send_dat(struct net_device *dev);
-static netdev_tx_t smctr_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-static int smctr_send_lobe_media_test(struct net_device *dev);
-static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf,
- __u16 correlator);
-static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf,
- __u16 correlator);
-static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf,
- __u16 correlator);
-static int smctr_send_rpt_tx_forward(struct net_device *dev,
- MAC_HEADER *rmf, __u16 tx_fstatus);
-static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf,
- __u16 rcode, __u16 correlator);
-static int smctr_send_rq_init(struct net_device *dev);
-static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf,
- __u16 *tx_fstatus);
-static int smctr_set_auth_access_pri(struct net_device *dev,
- MAC_SUB_VECTOR *rsv);
-static int smctr_set_auth_funct_class(struct net_device *dev,
- MAC_SUB_VECTOR *rsv);
-static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv,
- __u16 *correlator);
-static int smctr_set_error_timer_value(struct net_device *dev,
- MAC_SUB_VECTOR *rsv);
-static int smctr_set_frame_forward(struct net_device *dev,
- MAC_SUB_VECTOR *rsv, __u8 dc_sc);
-static int smctr_set_local_ring_num(struct net_device *dev,
- MAC_SUB_VECTOR *rsv);
-static unsigned short smctr_set_ctrl_attention(struct net_device *dev);
-static void smctr_set_multicast_list(struct net_device *dev);
-static int smctr_set_page(struct net_device *dev, __u8 *buf);
-static int smctr_set_phy_drop(struct net_device *dev,
- MAC_SUB_VECTOR *rsv);
-static int smctr_set_ring_speed(struct net_device *dev);
-static int smctr_set_rx_look_ahead(struct net_device *dev);
-static int smctr_set_trc_reset(int ioaddr);
-static int smctr_setup_single_cmd(struct net_device *dev,
- __u16 command, __u16 subcommand);
-static int smctr_setup_single_cmd_w_data(struct net_device *dev,
- __u16 command, __u16 subcommand);
-static char *smctr_malloc(struct net_device *dev, __u16 size);
-static int smctr_status_chg(struct net_device *dev);
-
-/* T */
-static void smctr_timeout(struct net_device *dev);
-static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb,
- __u16 queue);
-static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue);
-static unsigned short smctr_tx_move_frame(struct net_device *dev,
- struct sk_buff *skb, __u8 *pbuff, unsigned int bytes);
-
-/* U */
-static int smctr_update_err_stats(struct net_device *dev);
-static int smctr_update_rx_chain(struct net_device *dev, __u16 queue);
-static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb,
- __u16 queue);
-
-/* W */
-static int smctr_wait_cmd(struct net_device *dev);
-static int smctr_wait_while_cbusy(struct net_device *dev);
-
-#define TO_256_BYTE_BOUNDRY(X) (((X + 0xff) & 0xff00) - X)
-#define TO_PARAGRAPH_BOUNDRY(X) (((X + 0x0f) & 0xfff0) - X)
-#define PARAGRAPH_BOUNDRY(X) smctr_malloc(dev, TO_PARAGRAPH_BOUNDRY(X))
-
-/* Allocate Adapter Shared Memory.
- * IMPORTANT NOTE: Any changes to this function MUST be mirrored in the
- * function "get_num_rx_bdbs" below!!!
- *
- * Order of memory allocation:
- *
- * 0. Initial System Configuration Block Pointer
- * 1. System Configuration Block
- * 2. System Control Block
- * 3. Action Command Block
- * 4. Interrupt Status Block
- *
- * 5. MAC TX FCB'S
- * 6. NON-MAC TX FCB'S
- * 7. MAC TX BDB'S
- * 8. NON-MAC TX BDB'S
- * 9. MAC RX FCB'S
- * 10. NON-MAC RX FCB'S
- * 11. MAC RX BDB'S
- * 12. NON-MAC RX BDB'S
- * 13. MAC TX Data Buffer( 1, 256 byte buffer)
- * 14. MAC RX Data Buffer( 1, 256 byte buffer)
- *
- * 15. NON-MAC TX Data Buffer
- * 16. NON-MAC RX Data Buffer
- */
-static int smctr_alloc_shared_memory(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_alloc_shared_memory\n", dev->name);
-
- /* Allocate initial System Control Block pointer.
- * This pointer is located in the last page, last offset - 4.
- */
- tp->iscpb_ptr = (ISCPBlock *)(tp->ram_access + ((__u32)64 * 0x400)
- - (long)ISCP_BLOCK_SIZE);
-
- /* Allocate System Control Blocks. */
- tp->scgb_ptr = (SCGBlock *)smctr_malloc(dev, sizeof(SCGBlock));
- PARAGRAPH_BOUNDRY(tp->sh_mem_used);
-
- tp->sclb_ptr = (SCLBlock *)smctr_malloc(dev, sizeof(SCLBlock));
- PARAGRAPH_BOUNDRY(tp->sh_mem_used);
-
- tp->acb_head = (ACBlock *)smctr_malloc(dev,
- sizeof(ACBlock)*tp->num_acbs);
- PARAGRAPH_BOUNDRY(tp->sh_mem_used);
-
- tp->isb_ptr = (ISBlock *)smctr_malloc(dev, sizeof(ISBlock));
- PARAGRAPH_BOUNDRY(tp->sh_mem_used);
-
- tp->misc_command_data = (__u16 *)smctr_malloc(dev, MISC_DATA_SIZE);
- PARAGRAPH_BOUNDRY(tp->sh_mem_used);
-
- /* Allocate transmit FCBs. */
- tp->tx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev,
- sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE]);
-
- tp->tx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev,
- sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE]);
-
- tp->tx_fcb_head[BUG_QUEUE] = (FCBlock *)smctr_malloc(dev,
- sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE]);
-
- /* Allocate transmit BDBs. */
- tp->tx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev,
- sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE]);
-
- tp->tx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev,
- sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE]);
-
- tp->tx_bdb_head[BUG_QUEUE] = (BDBlock *)smctr_malloc(dev,
- sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE]);
-
- /* Allocate receive FCBs. */
- tp->rx_fcb_head[MAC_QUEUE] = (FCBlock *)smctr_malloc(dev,
- sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE]);
-
- tp->rx_fcb_head[NON_MAC_QUEUE] = (FCBlock *)smctr_malloc(dev,
- sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE]);
-
- /* Allocate receive BDBs. */
- tp->rx_bdb_head[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev,
- sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE]);
-
- tp->rx_bdb_end[MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0);
-
- tp->rx_bdb_head[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev,
- sizeof(BDBlock) * tp->num_rx_bdbs[NON_MAC_QUEUE]);
-
- tp->rx_bdb_end[NON_MAC_QUEUE] = (BDBlock *)smctr_malloc(dev, 0);
-
- /* Allocate MAC transmit buffers.
- * MAC Tx Buffers doen't have to be on an ODD Boundary.
- */
- tp->tx_buff_head[MAC_QUEUE]
- = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[MAC_QUEUE]);
- tp->tx_buff_curr[MAC_QUEUE] = tp->tx_buff_head[MAC_QUEUE];
- tp->tx_buff_end [MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
-
- /* Allocate BUG transmit buffers. */
- tp->tx_buff_head[BUG_QUEUE]
- = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[BUG_QUEUE]);
- tp->tx_buff_curr[BUG_QUEUE] = tp->tx_buff_head[BUG_QUEUE];
- tp->tx_buff_end[BUG_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
-
- /* Allocate MAC receive data buffers.
- * MAC Rx buffer doesn't have to be on a 256 byte boundary.
- */
- tp->rx_buff_head[MAC_QUEUE] = (__u16 *)smctr_malloc(dev,
- RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE]);
- tp->rx_buff_end[MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
-
- /* Allocate Non-MAC transmit buffers.
- * ?? For maximum Netware performance, put Tx Buffers on
- * ODD Boundary and then restore malloc to Even Boundrys.
- */
- smctr_malloc(dev, 1L);
- tp->tx_buff_head[NON_MAC_QUEUE]
- = (__u16 *)smctr_malloc(dev, tp->tx_buff_size[NON_MAC_QUEUE]);
- tp->tx_buff_curr[NON_MAC_QUEUE] = tp->tx_buff_head[NON_MAC_QUEUE];
- tp->tx_buff_end [NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
- smctr_malloc(dev, 1L);
-
- /* Allocate Non-MAC receive data buffers.
- * To guarantee a minimum of 256 contiguous memory to
- * UM_Receive_Packet's lookahead pointer, before a page
- * change or ring end is encountered, place each rx buffer on
- * a 256 byte boundary.
- */
- smctr_malloc(dev, TO_256_BYTE_BOUNDRY(tp->sh_mem_used));
- tp->rx_buff_head[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev,
- RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[NON_MAC_QUEUE]);
- tp->rx_buff_end[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0);
-
- return 0;
-}
-
-/* Enter Bypass state. */
-static int smctr_bypass_state(struct net_device *dev)
-{
- int err;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_bypass_state\n", dev->name);
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_BYPASS_STATE);
-
- return err;
-}
-
-static int smctr_checksum_firmware(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- __u16 i, checksum = 0;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_checksum_firmware\n", dev->name);
-
- smctr_enable_adapter_ctrl_store(dev);
-
- for(i = 0; i < CS_RAM_SIZE; i += 2)
- checksum += *((__u16 *)(tp->ram_access + i));
-
- tp->microcode_version = *(__u16 *)(tp->ram_access
- + CS_RAM_VERSION_OFFSET);
- tp->microcode_version >>= 8;
-
- smctr_disable_adapter_ctrl_store(dev);
-
- if(checksum)
- return checksum;
-
- return 0;
-}
-
-static int __init smctr_chk_mca(struct net_device *dev)
-{
-#ifdef CONFIG_MCA_LEGACY
- struct net_local *tp = netdev_priv(dev);
- int current_slot;
- __u8 r1, r2, r3, r4, r5;
-
- current_slot = mca_find_unused_adapter(smctr_posid, 0);
- if(current_slot == MCA_NOTFOUND)
- return -ENODEV;
-
- mca_set_adapter_name(current_slot, smctr_name);
- mca_mark_as_used(current_slot);
- tp->slot_num = current_slot;
-
- r1 = mca_read_stored_pos(tp->slot_num, 2);
- r2 = mca_read_stored_pos(tp->slot_num, 3);
-
- if(tp->slot_num)
- outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num - 1) | CNFG_SLOT_ENABLE_BIT));
- else
- outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num) | CNFG_SLOT_ENABLE_BIT));
-
- r1 = inb(CNFG_POS_REG1);
- r2 = inb(CNFG_POS_REG0);
-
- tp->bic_type = BIC_594_CHIP;
-
- /* IO */
- r2 = mca_read_stored_pos(tp->slot_num, 2);
- r2 &= 0xF0;
- dev->base_addr = ((__u16)r2 << 8) + (__u16)0x800;
- request_region(dev->base_addr, SMCTR_IO_EXTENT, smctr_name);
-
- /* IRQ */
- r5 = mca_read_stored_pos(tp->slot_num, 5);
- r5 &= 0xC;
- switch(r5)
- {
- case 0:
- dev->irq = 3;
- break;
-
- case 0x4:
- dev->irq = 4;
- break;
-
- case 0x8:
- dev->irq = 10;
- break;
-
- default:
- dev->irq = 15;
- break;
- }
- if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev)) {
- release_region(dev->base_addr, SMCTR_IO_EXTENT);
- return -ENODEV;
- }
-
- /* Get RAM base */
- r3 = mca_read_stored_pos(tp->slot_num, 3);
- tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0C0000;
- if (r3 & 0x8)
- tp->ram_base += 0x010000;
- if (r3 & 0x80)
- tp->ram_base += 0xF00000;
-
- /* Get Ram Size */
- r3 &= 0x30;
- r3 >>= 4;
-
- tp->ram_usable = (__u16)CNFG_SIZE_8KB << r3;
- tp->ram_size = (__u16)CNFG_SIZE_64KB;
- tp->board_id |= TOKEN_MEDIA;
-
- r4 = mca_read_stored_pos(tp->slot_num, 4);
- tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0x0C0000;
- if (r4 & 0x8)
- tp->rom_base += 0x010000;
-
- /* Get ROM size. */
- r4 >>= 4;
- switch (r4) {
- case 0:
- tp->rom_size = CNFG_SIZE_8KB;
- break;
- case 1:
- tp->rom_size = CNFG_SIZE_16KB;
- break;
- case 2:
- tp->rom_size = CNFG_SIZE_32KB;
- break;
- default:
- tp->rom_size = ROM_DISABLE;
- }
-
- /* Get Media Type. */
- r5 = mca_read_stored_pos(tp->slot_num, 5);
- r5 &= CNFG_MEDIA_TYPE_MASK;
- switch(r5)
- {
- case (0):
- tp->media_type = MEDIA_STP_4;
- break;
-
- case (1):
- tp->media_type = MEDIA_STP_16;
- break;
-
- case (3):
- tp->media_type = MEDIA_UTP_16;
- break;
-
- default:
- tp->media_type = MEDIA_UTP_4;
- break;
- }
- tp->media_menu = 14;
-
- r2 = mca_read_stored_pos(tp->slot_num, 2);
- if(!(r2 & 0x02))
- tp->mode_bits |= EARLY_TOKEN_REL;
-
- /* Disable slot */
- outb(CNFG_POS_CONTROL_REG, 0);
-
- tp->board_id = smctr_get_boardid(dev, 1);
- switch(tp->board_id & 0xffff)
- {
- case WD8115TA:
- smctr_model = "8115T/A";
- break;
-
- case WD8115T:
- if(tp->extra_info & CHIP_REV_MASK)
- smctr_model = "8115T rev XE";
- else
- smctr_model = "8115T rev XD";
- break;
-
- default:
- smctr_model = "Unknown";
- break;
- }
-
- return 0;
-#else
- return -1;
-#endif /* CONFIG_MCA_LEGACY */
-}
-
-static int smctr_chg_rx_mask(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err = 0;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_chg_rx_mask\n", dev->name);
-
- smctr_enable_16bit(dev);
- smctr_set_page(dev, (__u8 *)tp->ram_access);
-
- if(tp->mode_bits & LOOPING_MODE_MASK)
- tp->config_word0 |= RX_OWN_BIT;
- else
- tp->config_word0 &= ~RX_OWN_BIT;
-
- if(tp->receive_mask & PROMISCUOUS_MODE)
- tp->config_word0 |= PROMISCUOUS_BIT;
- else
- tp->config_word0 &= ~PROMISCUOUS_BIT;
-
- if(tp->receive_mask & ACCEPT_ERR_PACKETS)
- tp->config_word0 |= SAVBAD_BIT;
- else
- tp->config_word0 &= ~SAVBAD_BIT;
-
- if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)
- tp->config_word0 |= RXATMAC;
- else
- tp->config_word0 &= ~RXATMAC;
-
- if(tp->receive_mask & ACCEPT_MULTI_PROM)
- tp->config_word1 |= MULTICAST_ADDRESS_BIT;
- else
- tp->config_word1 &= ~MULTICAST_ADDRESS_BIT;
-
- if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING)
- tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS;
- else
- {
- if(tp->receive_mask & ACCEPT_SOURCE_ROUTING)
- tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT;
- else
- tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS;
- }
-
- if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_0,
- &tp->config_word0)))
- {
- return err;
- }
-
- if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_1,
- &tp->config_word1)))
- {
- return err;
- }
-
- smctr_disable_16bit(dev);
-
- return 0;
-}
-
-static int smctr_clear_int(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR);
-
- return 0;
-}
-
-static int smctr_clear_trc_reset(int ioaddr)
-{
- __u8 r;
-
- r = inb(ioaddr + MSR);
- outb(~MSR_RST & r, ioaddr + MSR);
-
- return 0;
-}
-
-/*
- * The inverse routine to smctr_open().
- */
-static int smctr_close(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- struct sk_buff *skb;
- int err;
-
- netif_stop_queue(dev);
-
- tp->cleanup = 1;
-
- /* Check to see if adapter is already in a closed state. */
- if(tp->status != OPEN)
- return 0;
-
- smctr_enable_16bit(dev);
- smctr_set_page(dev, (__u8 *)tp->ram_access);
-
- if((err = smctr_issue_remove_cmd(dev)))
- {
- smctr_disable_16bit(dev);
- return err;
- }
-
- for(;;)
- {
- skb = skb_dequeue(&tp->SendSkbQueue);
- if(skb == NULL)
- break;
- tp->QueueSkb++;
- dev_kfree_skb(skb);
- }
-
-
- return 0;
-}
-
-static int smctr_decode_firmware(struct net_device *dev,
- const struct firmware *fw)
-{
- struct net_local *tp = netdev_priv(dev);
- short bit = 0x80, shift = 12;
- DECODE_TREE_NODE *tree;
- short branch, tsize;
- __u16 buff = 0;
- long weight;
- __u8 *ucode;
- __u16 *mem;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_decode_firmware\n", dev->name);
-
- weight = *(long *)(fw->data + WEIGHT_OFFSET);
- tsize = *(__u8 *)(fw->data + TREE_SIZE_OFFSET);
- tree = (DECODE_TREE_NODE *)(fw->data + TREE_OFFSET);
- ucode = (__u8 *)(fw->data + TREE_OFFSET
- + (tsize * sizeof(DECODE_TREE_NODE)));
- mem = (__u16 *)(tp->ram_access);
-
- while(weight)
- {
- branch = ROOT;
- while((tree + branch)->tag != LEAF && weight)
- {
- branch = *ucode & bit ? (tree + branch)->llink
- : (tree + branch)->rlink;
-
- bit >>= 1;
- weight--;
-
- if(bit == 0)
- {
- bit = 0x80;
- ucode++;
- }
- }
-
- buff |= (tree + branch)->info << shift;
- shift -= 4;
-
- if(shift < 0)
- {
- *(mem++) = SWAP_BYTES(buff);
- buff = 0;
- shift = 12;
- }
- }
-
- /* The following assumes the Control Store Memory has
- * been initialized to zero. If the last partial word
- * is zero, it will not be written.
- */
- if(buff)
- *(mem++) = SWAP_BYTES(buff);
-
- return 0;
-}
-
-static int smctr_disable_16bit(struct net_device *dev)
-{
- return 0;
-}
-
-/*
- * On Exit, Adapter is:
- * 1. TRC is in a reset state and un-initialized.
- * 2. Adapter memory is enabled.
- * 3. Control Store memory is out of context (-WCSS is 1).
- */
-static int smctr_disable_adapter_ctrl_store(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_disable_adapter_ctrl_store\n", dev->name);
-
- tp->trc_mask |= CSR_WCSS;
- outb(tp->trc_mask, ioaddr + CSR);
-
- return 0;
-}
-
-static int smctr_disable_bic_int(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- tp->trc_mask = CSR_MSK_ALL | CSR_MSKCBUSY
- | CSR_MSKTINT | CSR_WCSS;
- outb(tp->trc_mask, ioaddr + CSR);
-
- return 0;
-}
-
-static int smctr_enable_16bit(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- __u8 r;
-
- if(tp->adapter_bus == BUS_ISA16_TYPE)
- {
- r = inb(dev->base_addr + LAAR);
- outb((r | LAAR_MEM16ENB), dev->base_addr + LAAR);
- }
-
- return 0;
-}
-
-/*
- * To enable the adapter control store memory:
- * 1. Adapter must be in a RESET state.
- * 2. Adapter memory must be enabled.
- * 3. Control Store Memory is in context (-WCSS is 0).
- */
-static int smctr_enable_adapter_ctrl_store(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_enable_adapter_ctrl_store\n", dev->name);
-
- smctr_set_trc_reset(ioaddr);
- smctr_enable_adapter_ram(dev);
-
- tp->trc_mask &= ~CSR_WCSS;
- outb(tp->trc_mask, ioaddr + CSR);
-
- return 0;
-}
-
-static int smctr_enable_adapter_ram(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- __u8 r;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_enable_adapter_ram\n", dev->name);
-
- r = inb(ioaddr + MSR);
- outb(MSR_MEMB | r, ioaddr + MSR);
-
- return 0;
-}
-
-static int smctr_enable_bic_int(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- __u8 r;
-
- switch(tp->bic_type)
- {
- case (BIC_584_CHIP):
- tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS;
- outb(tp->trc_mask, ioaddr + CSR);
- r = inb(ioaddr + IRR);
- outb(r | IRR_IEN, ioaddr + IRR);
- break;
-
- case (BIC_594_CHIP):
- tp->trc_mask = CSR_MSKCBUSY | CSR_WCSS;
- outb(tp->trc_mask, ioaddr + CSR);
- r = inb(ioaddr + IMCCR);
- outb(r | IMCCR_EIL, ioaddr + IMCCR);
- break;
- }
-
- return 0;
-}
-
-static int __init smctr_chk_isa(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- __u8 r1, r2, b, chksum = 0;
- __u16 r;
- int i;
- int err = -ENODEV;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_chk_isa %#4x\n", dev->name, ioaddr);
-
- if((ioaddr & 0x1F) != 0)
- goto out;
-
- /* Grab the region so that no one else tries to probe our ioports. */
- if (!request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name)) {
- err = -EBUSY;
- goto out;
- }
-
- /* Checksum SMC node address */
- for(i = 0; i < 8; i++)
- {
- b = inb(ioaddr + LAR0 + i);
- chksum += b;
- }
-
- if (chksum != NODE_ADDR_CKSUM)
- goto out2;
-
- b = inb(ioaddr + BDID);
- if(b != BRD_ID_8115T)
- {
- printk(KERN_ERR "%s: The adapter found is not supported\n", dev->name);
- goto out2;
- }
-
- /* Check for 8115T Board ID */
- r2 = 0;
- for(r = 0; r < 8; r++)
- {
- r1 = inb(ioaddr + 0x8 + r);
- r2 += r1;
- }
-
- /* value of RegF adds up the sum to 0xFF */
- if((r2 != 0xFF) && (r2 != 0xEE))
- goto out2;
-
- /* Get adapter ID */
- tp->board_id = smctr_get_boardid(dev, 0);
- switch(tp->board_id & 0xffff)
- {
- case WD8115TA:
- smctr_model = "8115T/A";
- break;
-
- case WD8115T:
- if(tp->extra_info & CHIP_REV_MASK)
- smctr_model = "8115T rev XE";
- else
- smctr_model = "8115T rev XD";
- break;
-
- default:
- smctr_model = "Unknown";
- break;
- }
-
- /* Store BIC type. */
- tp->bic_type = BIC_584_CHIP;
- tp->nic_type = NIC_825_CHIP;
-
- /* Copy Ram Size */
- tp->ram_usable = CNFG_SIZE_16KB;
- tp->ram_size = CNFG_SIZE_64KB;
-
- /* Get 58x Ram Base */
- r1 = inb(ioaddr);
- r1 &= 0x3F;
-
- r2 = inb(ioaddr + CNFG_LAAR_584);
- r2 &= CNFG_LAAR_MASK;
- r2 <<= 3;
- r2 |= ((r1 & 0x38) >> 3);
-
- tp->ram_base = ((__u32)r2 << 16) + (((__u32)(r1 & 0x7)) << 13);
-
- /* Get 584 Irq */
- r1 = 0;
- r1 = inb(ioaddr + CNFG_ICR_583);
- r1 &= CNFG_ICR_IR2_584;
-
- r2 = inb(ioaddr + CNFG_IRR_583);
- r2 &= CNFG_IRR_IRQS; /* 0x60 */
- r2 >>= 5;
-
- switch(r2)
- {
- case 0:
- if(r1 == 0)
- dev->irq = 2;
- else
- dev->irq = 10;
- break;
-
- case 1:
- if(r1 == 0)
- dev->irq = 3;
- else
- dev->irq = 11;
- break;
-
- case 2:
- if(r1 == 0)
- {
- if(tp->extra_info & ALTERNATE_IRQ_BIT)
- dev->irq = 5;
- else
- dev->irq = 4;
- }
- else
- dev->irq = 15;
- break;
-
- case 3:
- if(r1 == 0)
- dev->irq = 7;
- else
- dev->irq = 4;
- break;
-
- default:
- printk(KERN_ERR "%s: No IRQ found aborting\n", dev->name);
- goto out2;
- }
-
- if (request_irq(dev->irq, smctr_interrupt, IRQF_SHARED, smctr_name, dev))
- goto out2;
-
- /* Get 58x Rom Base */
- r1 = inb(ioaddr + CNFG_BIO_583);
- r1 &= 0x3E;
- r1 |= 0x40;
-
- tp->rom_base = (__u32)r1 << 13;
-
- /* Get 58x Rom Size */
- r1 = inb(ioaddr + CNFG_BIO_583);
- r1 &= 0xC0;
- if(r1 == 0)
- tp->rom_size = ROM_DISABLE;
- else
- {
- r1 >>= 6;
- tp->rom_size = (__u16)CNFG_SIZE_8KB << r1;
- }
-
- /* Get 58x Boot Status */
- r1 = inb(ioaddr + CNFG_GP2);
-
- tp->mode_bits &= (~BOOT_STATUS_MASK);
-
- if(r1 & CNFG_GP2_BOOT_NIBBLE)
- tp->mode_bits |= BOOT_TYPE_1;
-
- /* Get 58x Zero Wait State */
- tp->mode_bits &= (~ZERO_WAIT_STATE_MASK);
-
- r1 = inb(ioaddr + CNFG_IRR_583);
-
- if(r1 & CNFG_IRR_ZWS)
- tp->mode_bits |= ZERO_WAIT_STATE_8_BIT;
-
- if(tp->board_id & BOARD_16BIT)
- {
- r1 = inb(ioaddr + CNFG_LAAR_584);
-
- if(r1 & CNFG_LAAR_ZWS)
- tp->mode_bits |= ZERO_WAIT_STATE_16_BIT;
- }
-
- /* Get 584 Media Menu */
- tp->media_menu = 14;
- r1 = inb(ioaddr + CNFG_IRR_583);
-
- tp->mode_bits &= 0xf8ff; /* (~CNFG_INTERFACE_TYPE_MASK) */
- if((tp->board_id & TOKEN_MEDIA) == TOKEN_MEDIA)
- {
- /* Get Advanced Features */
- if(((r1 & 0x6) >> 1) == 0x3)
- tp->media_type |= MEDIA_UTP_16;
- else
- {
- if(((r1 & 0x6) >> 1) == 0x2)
- tp->media_type |= MEDIA_STP_16;
- else
- {
- if(((r1 & 0x6) >> 1) == 0x1)
- tp->media_type |= MEDIA_UTP_4;
-
- else
- tp->media_type |= MEDIA_STP_4;
- }
- }
-
- r1 = inb(ioaddr + CNFG_GP2);
- if(!(r1 & 0x2) ) /* GP2_ETRD */
- tp->mode_bits |= EARLY_TOKEN_REL;
-
- /* see if the chip is corrupted
- if(smctr_read_584_chksum(ioaddr))
- {
- printk(KERN_ERR "%s: EEPROM Checksum Failure\n", dev->name);
- free_irq(dev->irq, dev);
- goto out2;
- }
- */
- }
-
- return 0;
-
-out2:
- release_region(ioaddr, SMCTR_IO_EXTENT);
-out:
- return err;
-}
-
-static int __init smctr_get_boardid(struct net_device *dev, int mca)
-{
- struct net_local *tp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
- __u8 r, r1, IdByte;
- __u16 BoardIdMask;
-
- tp->board_id = BoardIdMask = 0;
-
- if(mca)
- {
- BoardIdMask |= (MICROCHANNEL+INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT);
- tp->extra_info |= (INTERFACE_594_CHIP+RAM_SIZE_64K+NIC_825_BIT+ALTERNATE_IRQ_BIT+SLOT_16BIT);
- }
- else
- {
- BoardIdMask|=(INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT);
- tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K
- + NIC_825_BIT + ALTERNATE_IRQ_BIT);
- }
-
- if(!mca)
- {
- r = inb(ioaddr + BID_REG_1);
- r &= 0x0c;
- outb(r, ioaddr + BID_REG_1);
- r = inb(ioaddr + BID_REG_1);
-
- if(r & BID_SIXTEEN_BIT_BIT)
- {
- tp->extra_info |= SLOT_16BIT;
- tp->adapter_bus = BUS_ISA16_TYPE;
- }
- else
- tp->adapter_bus = BUS_ISA8_TYPE;
- }
- else
- tp->adapter_bus = BUS_MCA_TYPE;
-
- /* Get Board Id Byte */
- IdByte = inb(ioaddr + BID_BOARD_ID_BYTE);
-
- /* if Major version > 1.0 then
- * return;
- */
- if(IdByte & 0xF8)
- return -1;
-
- r1 = inb(ioaddr + BID_REG_1);
- r1 &= BID_ICR_MASK;
- r1 |= BID_OTHER_BIT;
-
- outb(r1, ioaddr + BID_REG_1);
- r1 = inb(ioaddr + BID_REG_3);
-
- r1 &= BID_EAR_MASK;
- r1 |= BID_ENGR_PAGE;
-
- outb(r1, ioaddr + BID_REG_3);
- r1 = inb(ioaddr + BID_REG_1);
- r1 &= BID_ICR_MASK;
- r1 |= (BID_RLA | BID_OTHER_BIT);
-
- outb(r1, ioaddr + BID_REG_1);
-
- r1 = inb(ioaddr + BID_REG_1);
- while(r1 & BID_RECALL_DONE_MASK)
- r1 = inb(ioaddr + BID_REG_1);
-
- r = inb(ioaddr + BID_LAR_0 + BID_REG_6);
-
- /* clear chip rev bits */
- tp->extra_info &= ~CHIP_REV_MASK;
- tp->extra_info |= ((r & BID_EEPROM_CHIP_REV_MASK) << 6);
-
- r1 = inb(ioaddr + BID_REG_1);
- r1 &= BID_ICR_MASK;
- r1 |= BID_OTHER_BIT;
-
- outb(r1, ioaddr + BID_REG_1);
- r1 = inb(ioaddr + BID_REG_3);
-
- r1 &= BID_EAR_MASK;
- r1 |= BID_EA6;
-
- outb(r1, ioaddr + BID_REG_3);
- r1 = inb(ioaddr + BID_REG_1);
-
- r1 &= BID_ICR_MASK;
- r1 |= BID_RLA;
-
- outb(r1, ioaddr + BID_REG_1);
- r1 = inb(ioaddr + BID_REG_1);
-
- while(r1 & BID_RECALL_DONE_MASK)
- r1 = inb(ioaddr + BID_REG_1);
-
- return BoardIdMask;
-}
-
-static int smctr_get_group_address(struct net_device *dev)
-{
- smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_GROUP_ADDR);
-
- return smctr_wait_cmd(dev);
-}
-
-static int smctr_get_functional_address(struct net_device *dev)
-{
- smctr_issue_read_word_cmd(dev, RW_FUNCTIONAL_ADDR);
-
- return smctr_wait_cmd(dev);
-}
-
-/* Calculate number of Non-MAC receive BDB's and data buffers.
- * This function must simulate allocateing shared memory exactly
- * as the allocate_shared_memory function above.
- */
-static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int mem_used = 0;
-
- /* Allocate System Control Blocks. */
- mem_used += sizeof(SCGBlock);
-
- mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
- mem_used += sizeof(SCLBlock);
-
- mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
- mem_used += sizeof(ACBlock) * tp->num_acbs;
-
- mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
- mem_used += sizeof(ISBlock);
-
- mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
- mem_used += MISC_DATA_SIZE;
-
- /* Allocate transmit FCB's. */
- mem_used += TO_PARAGRAPH_BOUNDRY(mem_used);
-
- mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[MAC_QUEUE];
- mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[NON_MAC_QUEUE];
- mem_used += sizeof(FCBlock) * tp->num_tx_fcbs[BUG_QUEUE];
-
- /* Allocate transmit BDBs. */
- mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[MAC_QUEUE];
- mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[NON_MAC_QUEUE];
- mem_used += sizeof(BDBlock) * tp->num_tx_bdbs[BUG_QUEUE];
-
- /* Allocate receive FCBs. */
- mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[MAC_QUEUE];
- mem_used += sizeof(FCBlock) * tp->num_rx_fcbs[NON_MAC_QUEUE];
-
- /* Allocate receive BDBs. */
- mem_used += sizeof(BDBlock) * tp->num_rx_bdbs[MAC_QUEUE];
-
- /* Allocate MAC transmit buffers.
- * MAC transmit buffers don't have to be on an ODD Boundary.
- */
- mem_used += tp->tx_buff_size[MAC_QUEUE];
-
- /* Allocate BUG transmit buffers. */
- mem_used += tp->tx_buff_size[BUG_QUEUE];
-
- /* Allocate MAC receive data buffers.
- * MAC receive buffers don't have to be on a 256 byte boundary.
- */
- mem_used += RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[MAC_QUEUE];
-
- /* Allocate Non-MAC transmit buffers.
- * For maximum Netware performance, put Tx Buffers on
- * ODD Boundary,and then restore malloc to Even Boundrys.
- */
- mem_used += 1L;
- mem_used += tp->tx_buff_size[NON_MAC_QUEUE];
- mem_used += 1L;
-
- /* CALCULATE NUMBER OF NON-MAC RX BDB'S
- * AND NON-MAC RX DATA BUFFERS
- *
- * Make sure the mem_used offset at this point is the
- * same as in allocate_shared memory or the following
- * boundary adjustment will be incorrect (i.e. not allocating
- * the non-mac receive buffers above cannot change the 256
- * byte offset).
- *
- * Since this cannot be guaranteed, adding the full 256 bytes
- * to the amount of shared memory used at this point will guaranteed
- * that the rx data buffers do not overflow shared memory.
- */
- mem_used += 0x100;
-
- return (0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock));
-}
-
-static int smctr_get_physical_drop_number(struct net_device *dev)
-{
- smctr_issue_read_word_cmd(dev, RW_PHYSICAL_DROP_NUMBER);
-
- return smctr_wait_cmd(dev);
-}
-
-static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue)
-{
- struct net_local *tp = netdev_priv(dev);
- BDBlock *bdb;
-
- bdb = (BDBlock *)((__u32)tp->ram_access
- + (__u32)(tp->rx_fcb_curr[queue]->trc_bdb_ptr));
-
- tp->rx_fcb_curr[queue]->bdb_ptr = bdb;
-
- return (__u8 *)bdb->data_block_ptr;
-}
-
-static int smctr_get_station_id(struct net_device *dev)
-{
- smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_MAC_ADDRESS);
-
- return smctr_wait_cmd(dev);
-}
-
-/*
- * Get the current statistics. This may be called with the card open
- * or closed.
- */
-static struct net_device_stats *smctr_get_stats(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- return (struct net_device_stats *)&tp->MacStat;
-}
-
-static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
- __u16 bytes_count)
-{
- struct net_local *tp = netdev_priv(dev);
- FCBlock *pFCB;
- BDBlock *pbdb;
- unsigned short alloc_size;
- unsigned short *temp;
-
- if(smctr_debug > 20)
- printk(KERN_DEBUG "smctr_get_tx_fcb\n");
-
- /* check if there is enough FCB blocks */
- if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue])
- return (FCBlock *)(-1L);
-
- /* round off the input pkt size to the nearest even number */
- alloc_size = (bytes_count + 1) & 0xfffe;
-
- /* check if enough mem */
- if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue])
- return (FCBlock *)(-1L);
-
- /* check if past the end ;
- * if exactly enough mem to end of ring, alloc from front.
- * this avoids update of curr when curr = end
- */
- if(((unsigned long)(tp->tx_buff_curr[queue]) + alloc_size)
- >= (unsigned long)(tp->tx_buff_end[queue]))
- {
- /* check if enough memory from ring head */
- alloc_size = alloc_size +
- (__u16)((__u32)tp->tx_buff_end[queue]
- - (__u32)tp->tx_buff_curr[queue]);
-
- if((tp->tx_buff_used[queue] + alloc_size)
- > tp->tx_buff_size[queue])
- {
- return (FCBlock *)(-1L);
- }
-
- /* ring wrap */
- tp->tx_buff_curr[queue] = tp->tx_buff_head[queue];
- }
-
- tp->tx_buff_used[queue] += alloc_size;
- tp->num_tx_fcbs_used[queue]++;
- tp->tx_fcb_curr[queue]->frame_length = bytes_count;
- tp->tx_fcb_curr[queue]->memory_alloc = alloc_size;
- temp = tp->tx_buff_curr[queue];
- tp->tx_buff_curr[queue]
- = (__u16 *)((__u32)temp + (__u32)((bytes_count + 1) & 0xfffe));
-
- pbdb = tp->tx_fcb_curr[queue]->bdb_ptr;
- pbdb->buffer_length = bytes_count;
- pbdb->data_block_ptr = temp;
- pbdb->trc_data_block_ptr = TRC_POINTER(temp);
-
- pFCB = tp->tx_fcb_curr[queue];
- tp->tx_fcb_curr[queue] = tp->tx_fcb_curr[queue]->next_ptr;
-
- return pFCB;
-}
-
-static int smctr_get_upstream_neighbor_addr(struct net_device *dev)
-{
- smctr_issue_read_word_cmd(dev, RW_UPSTREAM_NEIGHBOR_ADDRESS);
-
- return smctr_wait_cmd(dev);
-}
-
-static int smctr_hardware_send_packet(struct net_device *dev,
- struct net_local *tp)
-{
- struct tr_statistics *tstat = &tp->MacStat;
- struct sk_buff *skb;
- FCBlock *fcb;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG"%s: smctr_hardware_send_packet\n", dev->name);
-
- if(tp->status != OPEN)
- return -1;
-
- if(tp->monitor_state_ready != 1)
- return -1;
-
- for(;;)
- {
- /* Send first buffer from queue */
- skb = skb_dequeue(&tp->SendSkbQueue);
- if(skb == NULL)
- return -1;
-
- tp->QueueSkb++;
-
- if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size)
- return -1;
-
- smctr_enable_16bit(dev);
- smctr_set_page(dev, (__u8 *)tp->ram_access);
-
- if((fcb = smctr_get_tx_fcb(dev, NON_MAC_QUEUE, skb->len))
- == (FCBlock *)(-1L))
- {
- smctr_disable_16bit(dev);
- return -1;
- }
-
- smctr_tx_move_frame(dev, skb,
- (__u8 *)fcb->bdb_ptr->data_block_ptr, skb->len);
-
- smctr_set_page(dev, (__u8 *)fcb);
-
- smctr_trc_send_packet(dev, fcb, NON_MAC_QUEUE);
- dev_kfree_skb(skb);
-
- tstat->tx_packets++;
-
- smctr_disable_16bit(dev);
- }
-
- return 0;
-}
-
-static int smctr_init_acbs(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i;
- ACBlock *acb;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_init_acbs\n", dev->name);
-
- acb = tp->acb_head;
- acb->cmd_done_status = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL);
- acb->cmd_info = ACB_CHAIN_END;
- acb->cmd = 0;
- acb->subcmd = 0;
- acb->data_offset_lo = 0;
- acb->data_offset_hi = 0;
- acb->next_ptr
- = (ACBlock *)(((char *)acb) + sizeof(ACBlock));
- acb->trc_next_ptr = TRC_POINTER(acb->next_ptr);
-
- for(i = 1; i < tp->num_acbs; i++)
- {
- acb = acb->next_ptr;
- acb->cmd_done_status
- = (ACB_COMMAND_DONE | ACB_COMMAND_SUCCESSFUL);
- acb->cmd_info = ACB_CHAIN_END;
- acb->cmd = 0;
- acb->subcmd = 0;
- acb->data_offset_lo = 0;
- acb->data_offset_hi = 0;
- acb->next_ptr
- = (ACBlock *)(((char *)acb) + sizeof(ACBlock));
- acb->trc_next_ptr = TRC_POINTER(acb->next_ptr);
- }
-
- acb->next_ptr = tp->acb_head;
- acb->trc_next_ptr = TRC_POINTER(tp->acb_head);
- tp->acb_next = tp->acb_head->next_ptr;
- tp->acb_curr = tp->acb_head->next_ptr;
- tp->num_acbs_used = 0;
-
- return 0;
-}
-
-static int smctr_init_adapter(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_init_adapter\n", dev->name);
-
- tp->status = CLOSED;
- tp->page_offset_mask = (tp->ram_usable * 1024) - 1;
- skb_queue_head_init(&tp->SendSkbQueue);
- tp->QueueSkb = MAX_TX_QUEUE;
-
- if(!(tp->group_address_0 & 0x0080))
- tp->group_address_0 |= 0x00C0;
-
- if(!(tp->functional_address_0 & 0x00C0))
- tp->functional_address_0 |= 0x00C0;
-
- tp->functional_address[0] &= 0xFF7F;
-
- if(tp->authorized_function_classes == 0)
- tp->authorized_function_classes = 0x7FFF;
-
- if(tp->authorized_access_priority == 0)
- tp->authorized_access_priority = 0x06;
-
- smctr_disable_bic_int(dev);
- smctr_set_trc_reset(dev->base_addr);
-
- smctr_enable_16bit(dev);
- smctr_set_page(dev, (__u8 *)tp->ram_access);
-
- if(smctr_checksum_firmware(dev))
- {
- printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name);
- return -ENOENT;
- }
-
- if((err = smctr_ram_memory_test(dev)))
- {
- printk(KERN_ERR "%s: RAM memory test failed.\n", dev->name);
- return -EIO;
- }
-
- smctr_set_rx_look_ahead(dev);
- smctr_load_node_addr(dev);
-
- /* Initialize adapter for Internal Self Test. */
- smctr_reset_adapter(dev);
- if((err = smctr_init_card_real(dev)))
- {
- printk(KERN_ERR "%s: Initialization of card failed (%d)\n",
- dev->name, err);
- return -EINVAL;
- }
-
- /* This routine clobbers the TRC's internal registers. */
- if((err = smctr_internal_self_test(dev)))
- {
- printk(KERN_ERR "%s: Card failed internal self test (%d)\n",
- dev->name, err);
- return -EINVAL;
- }
-
- /* Re-Initialize adapter's internal registers */
- smctr_reset_adapter(dev);
- if((err = smctr_init_card_real(dev)))
- {
- printk(KERN_ERR "%s: Initialization of card failed (%d)\n",
- dev->name, err);
- return -EINVAL;
- }
-
- smctr_enable_bic_int(dev);
-
- if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK)))
- return err;
-
- smctr_disable_16bit(dev);
-
- return 0;
-}
-
-static int smctr_init_card_real(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err = 0;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_init_card_real\n", dev->name);
-
- tp->sh_mem_used = 0;
- tp->num_acbs = NUM_OF_ACBS;
-
- /* Range Check Max Packet Size */
- if(tp->max_packet_size < 256)
- tp->max_packet_size = 256;
- else
- {
- if(tp->max_packet_size > NON_MAC_TX_BUFFER_MEMORY)
- tp->max_packet_size = NON_MAC_TX_BUFFER_MEMORY;
- }
-
- tp->num_of_tx_buffs = (NON_MAC_TX_BUFFER_MEMORY
- / tp->max_packet_size) - 1;
-
- if(tp->num_of_tx_buffs > NUM_NON_MAC_TX_FCBS)
- tp->num_of_tx_buffs = NUM_NON_MAC_TX_FCBS;
- else
- {
- if(tp->num_of_tx_buffs == 0)
- tp->num_of_tx_buffs = 1;
- }
-
- /* Tx queue constants */
- tp->num_tx_fcbs [BUG_QUEUE] = NUM_BUG_TX_FCBS;
- tp->num_tx_bdbs [BUG_QUEUE] = NUM_BUG_TX_BDBS;
- tp->tx_buff_size [BUG_QUEUE] = BUG_TX_BUFFER_MEMORY;
- tp->tx_buff_used [BUG_QUEUE] = 0;
- tp->tx_queue_status [BUG_QUEUE] = NOT_TRANSMITING;
-
- tp->num_tx_fcbs [MAC_QUEUE] = NUM_MAC_TX_FCBS;
- tp->num_tx_bdbs [MAC_QUEUE] = NUM_MAC_TX_BDBS;
- tp->tx_buff_size [MAC_QUEUE] = MAC_TX_BUFFER_MEMORY;
- tp->tx_buff_used [MAC_QUEUE] = 0;
- tp->tx_queue_status [MAC_QUEUE] = NOT_TRANSMITING;
-
- tp->num_tx_fcbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_FCBS;
- tp->num_tx_bdbs [NON_MAC_QUEUE] = NUM_NON_MAC_TX_BDBS;
- tp->tx_buff_size [NON_MAC_QUEUE] = NON_MAC_TX_BUFFER_MEMORY;
- tp->tx_buff_used [NON_MAC_QUEUE] = 0;
- tp->tx_queue_status [NON_MAC_QUEUE] = NOT_TRANSMITING;
-
- /* Receive Queue Constants */
- tp->num_rx_fcbs[MAC_QUEUE] = NUM_MAC_RX_FCBS;
- tp->num_rx_bdbs[MAC_QUEUE] = NUM_MAC_RX_BDBS;
-
- if(tp->extra_info & CHIP_REV_MASK)
- tp->num_rx_fcbs[NON_MAC_QUEUE] = 78; /* 825 Rev. XE */
- else
- tp->num_rx_fcbs[NON_MAC_QUEUE] = 7; /* 825 Rev. XD */
-
- tp->num_rx_bdbs[NON_MAC_QUEUE] = smctr_get_num_rx_bdbs(dev);
-
- smctr_alloc_shared_memory(dev);
- smctr_init_shared_memory(dev);
-
- if((err = smctr_issue_init_timers_cmd(dev)))
- return err;
-
- if((err = smctr_issue_init_txrx_cmd(dev)))
- {
- printk(KERN_ERR "%s: Hardware failure\n", dev->name);
- return err;
- }
-
- return 0;
-}
-
-static int smctr_init_rx_bdbs(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i, j;
- BDBlock *bdb;
- __u16 *buf;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_init_rx_bdbs\n", dev->name);
-
- for(i = 0; i < NUM_RX_QS_USED; i++)
- {
- bdb = tp->rx_bdb_head[i];
- buf = tp->rx_buff_head[i];
- bdb->info = (BDB_CHAIN_END | BDB_NO_WARNING);
- bdb->buffer_length = RX_DATA_BUFFER_SIZE;
- bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock));
- bdb->data_block_ptr = buf;
- bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);
-
- if(i == NON_MAC_QUEUE)
- bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf);
- else
- bdb->trc_data_block_ptr = TRC_POINTER(buf);
-
- for(j = 1; j < tp->num_rx_bdbs[i]; j++)
- {
- bdb->next_ptr->back_ptr = bdb;
- bdb = bdb->next_ptr;
- buf = (__u16 *)((char *)buf + RX_DATA_BUFFER_SIZE);
- bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING);
- bdb->buffer_length = RX_DATA_BUFFER_SIZE;
- bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock));
- bdb->data_block_ptr = buf;
- bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);
-
- if(i == NON_MAC_QUEUE)
- bdb->trc_data_block_ptr = RX_BUFF_TRC_POINTER(buf);
- else
- bdb->trc_data_block_ptr = TRC_POINTER(buf);
- }
-
- bdb->next_ptr = tp->rx_bdb_head[i];
- bdb->trc_next_ptr = TRC_POINTER(tp->rx_bdb_head[i]);
-
- tp->rx_bdb_head[i]->back_ptr = bdb;
- tp->rx_bdb_curr[i] = tp->rx_bdb_head[i]->next_ptr;
- }
-
- return 0;
-}
-
-static int smctr_init_rx_fcbs(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i, j;
- FCBlock *fcb;
-
- for(i = 0; i < NUM_RX_QS_USED; i++)
- {
- fcb = tp->rx_fcb_head[i];
- fcb->frame_status = 0;
- fcb->frame_length = 0;
- fcb->info = FCB_CHAIN_END;
- fcb->next_ptr = (FCBlock *)(((char*)fcb) + sizeof(FCBlock));
- if(i == NON_MAC_QUEUE)
- fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr);
- else
- fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);
-
- for(j = 1; j < tp->num_rx_fcbs[i]; j++)
- {
- fcb->next_ptr->back_ptr = fcb;
- fcb = fcb->next_ptr;
- fcb->frame_status = 0;
- fcb->frame_length = 0;
- fcb->info = FCB_WARNING;
- fcb->next_ptr
- = (FCBlock *)(((char *)fcb) + sizeof(FCBlock));
-
- if(i == NON_MAC_QUEUE)
- fcb->trc_next_ptr
- = RX_FCB_TRC_POINTER(fcb->next_ptr);
- else
- fcb->trc_next_ptr
- = TRC_POINTER(fcb->next_ptr);
- }
-
- fcb->next_ptr = tp->rx_fcb_head[i];
-
- if(i == NON_MAC_QUEUE)
- fcb->trc_next_ptr = RX_FCB_TRC_POINTER(fcb->next_ptr);
- else
- fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);
-
- tp->rx_fcb_head[i]->back_ptr = fcb;
- tp->rx_fcb_curr[i] = tp->rx_fcb_head[i]->next_ptr;
- }
-
- return 0;
-}
-
-static int smctr_init_shared_memory(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i;
- __u32 *iscpb;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_init_shared_memory\n", dev->name);
-
- smctr_set_page(dev, (__u8 *)(unsigned int)tp->iscpb_ptr);
-
- /* Initialize Initial System Configuration Point. (ISCP) */
- iscpb = (__u32 *)PAGE_POINTER(&tp->iscpb_ptr->trc_scgb_ptr);
- *iscpb = (__u32)(SWAP_WORDS(TRC_POINTER(tp->scgb_ptr)));
-
- smctr_set_page(dev, (__u8 *)tp->ram_access);
-
- /* Initialize System Configuration Pointers. (SCP) */
- tp->scgb_ptr->config = (SCGB_ADDRESS_POINTER_FORMAT
- | SCGB_MULTI_WORD_CONTROL | SCGB_DATA_FORMAT
- | SCGB_BURST_LENGTH);
-
- tp->scgb_ptr->trc_sclb_ptr = TRC_POINTER(tp->sclb_ptr);
- tp->scgb_ptr->trc_acb_ptr = TRC_POINTER(tp->acb_head);
- tp->scgb_ptr->trc_isb_ptr = TRC_POINTER(tp->isb_ptr);
- tp->scgb_ptr->isbsiz = (sizeof(ISBlock)) - 2;
-
- /* Initialize System Control Block. (SCB) */
- tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_NOP;
- tp->sclb_ptr->iack_code = 0;
- tp->sclb_ptr->resume_control = 0;
- tp->sclb_ptr->int_mask_control = 0;
- tp->sclb_ptr->int_mask_state = 0;
-
- /* Initialize Interrupt Status Block. (ISB) */
- for(i = 0; i < NUM_OF_INTERRUPTS; i++)
- {
- tp->isb_ptr->IStatus[i].IType = 0xf0;
- tp->isb_ptr->IStatus[i].ISubtype = 0;
- }
-
- tp->current_isb_index = 0;
-
- /* Initialize Action Command Block. (ACB) */
- smctr_init_acbs(dev);
-
- /* Initialize transmit FCB's and BDB's. */
- smctr_link_tx_fcbs_to_bdbs(dev);
- smctr_init_tx_bdbs(dev);
- smctr_init_tx_fcbs(dev);
-
- /* Initialize receive FCB's and BDB's. */
- smctr_init_rx_bdbs(dev);
- smctr_init_rx_fcbs(dev);
-
- return 0;
-}
-
-static int smctr_init_tx_bdbs(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i, j;
- BDBlock *bdb;
-
- for(i = 0; i < NUM_TX_QS_USED; i++)
- {
- bdb = tp->tx_bdb_head[i];
- bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING);
- bdb->next_ptr = (BDBlock *)(((char *)bdb) + sizeof(BDBlock));
- bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);
-
- for(j = 1; j < tp->num_tx_bdbs[i]; j++)
- {
- bdb->next_ptr->back_ptr = bdb;
- bdb = bdb->next_ptr;
- bdb->info = (BDB_NOT_CHAIN_END | BDB_NO_WARNING);
- bdb->next_ptr
- = (BDBlock *)(((char *)bdb) + sizeof( BDBlock)); bdb->trc_next_ptr = TRC_POINTER(bdb->next_ptr);
- }
-
- bdb->next_ptr = tp->tx_bdb_head[i];
- bdb->trc_next_ptr = TRC_POINTER(tp->tx_bdb_head[i]);
- tp->tx_bdb_head[i]->back_ptr = bdb;
- }
-
- return 0;
-}
-
-static int smctr_init_tx_fcbs(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i, j;
- FCBlock *fcb;
-
- for(i = 0; i < NUM_TX_QS_USED; i++)
- {
- fcb = tp->tx_fcb_head[i];
- fcb->frame_status = 0;
- fcb->frame_length = 0;
- fcb->info = FCB_CHAIN_END;
- fcb->next_ptr = (FCBlock *)(((char *)fcb) + sizeof(FCBlock));
- fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);
-
- for(j = 1; j < tp->num_tx_fcbs[i]; j++)
- {
- fcb->next_ptr->back_ptr = fcb;
- fcb = fcb->next_ptr;
- fcb->frame_status = 0;
- fcb->frame_length = 0;
- fcb->info = FCB_CHAIN_END;
- fcb->next_ptr
- = (FCBlock *)(((char *)fcb) + sizeof(FCBlock));
- fcb->trc_next_ptr = TRC_POINTER(fcb->next_ptr);
- }
-
- fcb->next_ptr = tp->tx_fcb_head[i];
- fcb->trc_next_ptr = TRC_POINTER(tp->tx_fcb_head[i]);
-
- tp->tx_fcb_head[i]->back_ptr = fcb;
- tp->tx_fcb_end[i] = tp->tx_fcb_head[i]->next_ptr;
- tp->tx_fcb_curr[i] = tp->tx_fcb_head[i]->next_ptr;
- tp->num_tx_fcbs_used[i] = 0;
- }
-
- return 0;
-}
-
-static int smctr_internal_self_test(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- if((err = smctr_issue_test_internal_rom_cmd(dev)))
- return err;
-
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- if(tp->acb_head->cmd_done_status & 0xff)
- return -1;
-
- if((err = smctr_issue_test_hic_cmd(dev)))
- return err;
-
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- if(tp->acb_head->cmd_done_status & 0xff)
- return -1;
-
- if((err = smctr_issue_test_mac_reg_cmd(dev)))
- return err;
-
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- if(tp->acb_head->cmd_done_status & 0xff)
- return -1;
-
- return 0;
-}
-
-/*
- * The typical workload of the driver: Handle the network interface interrupts.
- */
-static irqreturn_t smctr_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *tp;
- int ioaddr;
- __u16 interrupt_unmask_bits = 0, interrupt_ack_code = 0xff00;
- __u16 err1, err = NOT_MY_INTERRUPT;
- __u8 isb_type, isb_subtype;
- __u16 isb_index;
-
- ioaddr = dev->base_addr;
- tp = netdev_priv(dev);
-
- if(tp->status == NOT_INITIALIZED)
- return IRQ_NONE;
-
- spin_lock(&tp->lock);
-
- smctr_disable_bic_int(dev);
- smctr_enable_16bit(dev);
-
- smctr_clear_int(dev);
-
- /* First read the LSB */
- while((tp->isb_ptr->IStatus[tp->current_isb_index].IType & 0xf0) == 0)
- {
- isb_index = tp->current_isb_index;
- isb_type = tp->isb_ptr->IStatus[isb_index].IType;
- isb_subtype = tp->isb_ptr->IStatus[isb_index].ISubtype;
-
- (tp->current_isb_index)++;
- if(tp->current_isb_index == NUM_OF_INTERRUPTS)
- tp->current_isb_index = 0;
-
- if(isb_type >= 0x10)
- {
- smctr_disable_16bit(dev);
- spin_unlock(&tp->lock);
- return IRQ_HANDLED;
- }
-
- err = HARDWARE_FAILED;
- interrupt_ack_code = isb_index;
- tp->isb_ptr->IStatus[isb_index].IType |= 0xf0;
-
- interrupt_unmask_bits |= (1 << (__u16)isb_type);
-
- switch(isb_type)
- {
- case ISB_IMC_MAC_TYPE_3:
- smctr_disable_16bit(dev);
-
- switch(isb_subtype)
- {
- case 0:
- tp->monitor_state = MS_MONITOR_FSM_INACTIVE;
- break;
-
- case 1:
- tp->monitor_state = MS_REPEAT_BEACON_STATE;
- break;
-
- case 2:
- tp->monitor_state = MS_REPEAT_CLAIM_TOKEN_STATE;
- break;
-
- case 3:
- tp->monitor_state = MS_TRANSMIT_CLAIM_TOKEN_STATE; break;
-
- case 4:
- tp->monitor_state = MS_STANDBY_MONITOR_STATE;
- break;
-
- case 5:
- tp->monitor_state = MS_TRANSMIT_BEACON_STATE;
- break;
-
- case 6:
- tp->monitor_state = MS_ACTIVE_MONITOR_STATE;
- break;
-
- case 7:
- tp->monitor_state = MS_TRANSMIT_RING_PURGE_STATE;
- break;
-
- case 8: /* diagnostic state */
- break;
-
- case 9:
- tp->monitor_state = MS_BEACON_TEST_STATE;
- if(smctr_lobe_media_test(dev))
- {
- tp->ring_status_flags = RING_STATUS_CHANGED;
- tp->ring_status = AUTO_REMOVAL_ERROR;
- smctr_ring_status_chg(dev);
- smctr_bypass_state(dev);
- }
- else
- smctr_issue_insert_cmd(dev);
- break;
-
- /* case 0x0a-0xff, illegal states */
- default:
- break;
- }
-
- tp->ring_status_flags = MONITOR_STATE_CHANGED;
- err = smctr_ring_status_chg(dev);
-
- smctr_enable_16bit(dev);
- break;
-
- /* Type 0x02 - MAC Error Counters Interrupt
- * One or more MAC Error Counter is half full
- * MAC Error Counters
- * Lost_FR_Error_Counter
- * RCV_Congestion_Counter
- * FR_copied_Error_Counter
- * FREQ_Error_Counter
- * Token_Error_Counter
- * Line_Error_Counter
- * Internal_Error_Count
- */
- case ISB_IMC_MAC_ERROR_COUNTERS:
- /* Read 802.5 Error Counters */
- err = smctr_issue_read_ring_status_cmd(dev);
- break;
-
- /* Type 0x04 - MAC Type 2 Interrupt
- * HOST needs to enqueue MAC Frame for transmission
- * SubType Bit 15 - RQ_INIT_PDU( Request Initialization) * Changed from RQ_INIT_PDU to
- * TRC_Status_Changed_Indicate
- */
- case ISB_IMC_MAC_TYPE_2:
- err = smctr_issue_read_ring_status_cmd(dev);
- break;
-
-
- /* Type 0x05 - TX Frame Interrupt (FI). */
- case ISB_IMC_TX_FRAME:
- /* BUG QUEUE for TRC stuck receive BUG */
- if(isb_subtype & TX_PENDING_PRIORITY_2)
- {
- if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS)
- break;
- }
-
- /* NON-MAC frames only */
- if(isb_subtype & TX_PENDING_PRIORITY_1)
- {
- if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS)
- break;
- }
-
- /* MAC frames only */
- if(isb_subtype & TX_PENDING_PRIORITY_0)
- err = smctr_tx_complete(dev, MAC_QUEUE); break;
-
- /* Type 0x06 - TX END OF QUEUE (FE) */
- case ISB_IMC_END_OF_TX_QUEUE:
- /* BUG queue */
- if(isb_subtype & TX_PENDING_PRIORITY_2)
- {
- /* ok to clear Receive FIFO overrun
- * imask send_BUG now completes.
- */
- interrupt_unmask_bits |= 0x800;
-
- tp->tx_queue_status[BUG_QUEUE] = NOT_TRANSMITING;
- if((err = smctr_tx_complete(dev, BUG_QUEUE)) != SUCCESS)
- break;
- if((err = smctr_restart_tx_chain(dev, BUG_QUEUE)) != SUCCESS)
- break;
- }
-
- /* NON-MAC queue only */
- if(isb_subtype & TX_PENDING_PRIORITY_1)
- {
- tp->tx_queue_status[NON_MAC_QUEUE] = NOT_TRANSMITING;
- if((err = smctr_tx_complete(dev, NON_MAC_QUEUE)) != SUCCESS)
- break;
- if((err = smctr_restart_tx_chain(dev, NON_MAC_QUEUE)) != SUCCESS)
- break;
- }
-
- /* MAC queue only */
- if(isb_subtype & TX_PENDING_PRIORITY_0)
- {
- tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
- if((err = smctr_tx_complete(dev, MAC_QUEUE)) != SUCCESS)
- break;
-
- err = smctr_restart_tx_chain(dev, MAC_QUEUE);
- }
- break;
-
- /* Type 0x07 - NON-MAC RX Resource Interrupt
- * Subtype bit 12 - (BW) BDB warning
- * Subtype bit 13 - (FW) FCB warning
- * Subtype bit 14 - (BE) BDB End of chain
- * Subtype bit 15 - (FE) FCB End of chain
- */
- case ISB_IMC_NON_MAC_RX_RESOURCE:
- tp->rx_fifo_overrun_count = 0;
- tp->receive_queue_number = NON_MAC_QUEUE;
- err1 = smctr_rx_frame(dev);
-
- if(isb_subtype & NON_MAC_RX_RESOURCE_FE)
- {
- if((err = smctr_issue_resume_rx_fcb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break;
-
- if(tp->ptr_rx_fcb_overruns)
- (*tp->ptr_rx_fcb_overruns)++;
- }
-
- if(isb_subtype & NON_MAC_RX_RESOURCE_BE)
- {
- if((err = smctr_issue_resume_rx_bdb_cmd( dev, NON_MAC_QUEUE)) != SUCCESS) break;
-
- if(tp->ptr_rx_bdb_overruns)
- (*tp->ptr_rx_bdb_overruns)++;
- }
- err = err1;
- break;
-
- /* Type 0x08 - MAC RX Resource Interrupt
- * Subtype bit 12 - (BW) BDB warning
- * Subtype bit 13 - (FW) FCB warning
- * Subtype bit 14 - (BE) BDB End of chain
- * Subtype bit 15 - (FE) FCB End of chain
- */
- case ISB_IMC_MAC_RX_RESOURCE:
- tp->receive_queue_number = MAC_QUEUE;
- err1 = smctr_rx_frame(dev);
-
- if(isb_subtype & MAC_RX_RESOURCE_FE)
- {
- if((err = smctr_issue_resume_rx_fcb_cmd( dev, MAC_QUEUE)) != SUCCESS)
- break;
-
- if(tp->ptr_rx_fcb_overruns)
- (*tp->ptr_rx_fcb_overruns)++;
- }
-
- if(isb_subtype & MAC_RX_RESOURCE_BE)
- {
- if((err = smctr_issue_resume_rx_bdb_cmd( dev, MAC_QUEUE)) != SUCCESS)
- break;
-
- if(tp->ptr_rx_bdb_overruns)
- (*tp->ptr_rx_bdb_overruns)++;
- }
- err = err1;
- break;
-
- /* Type 0x09 - NON_MAC RX Frame Interrupt */
- case ISB_IMC_NON_MAC_RX_FRAME:
- tp->rx_fifo_overrun_count = 0;
- tp->receive_queue_number = NON_MAC_QUEUE;
- err = smctr_rx_frame(dev);
- break;
-
- /* Type 0x0A - MAC RX Frame Interrupt */
- case ISB_IMC_MAC_RX_FRAME:
- tp->receive_queue_number = MAC_QUEUE;
- err = smctr_rx_frame(dev);
- break;
-
- /* Type 0x0B - TRC status
- * TRC has encountered an error condition
- * subtype bit 14 - transmit FIFO underrun
- * subtype bit 15 - receive FIFO overrun
- */
- case ISB_IMC_TRC_FIFO_STATUS:
- if(isb_subtype & TRC_FIFO_STATUS_TX_UNDERRUN)
- {
- if(tp->ptr_tx_fifo_underruns)
- (*tp->ptr_tx_fifo_underruns)++;
- }
-
- if(isb_subtype & TRC_FIFO_STATUS_RX_OVERRUN)
- {
- /* update overrun stuck receive counter
- * if >= 3, has to clear it by sending
- * back to back frames. We pick
- * DAT(duplicate address MAC frame)
- */
- tp->rx_fifo_overrun_count++;
-
- if(tp->rx_fifo_overrun_count >= 3)
- {
- tp->rx_fifo_overrun_count = 0;
-
- /* delay clearing fifo overrun
- * imask till send_BUG tx
- * complete posted
- */
- interrupt_unmask_bits &= (~0x800);
- printk(KERN_CRIT "Jay please send bug\n");// smctr_send_bug(dev);
- }
-
- if(tp->ptr_rx_fifo_overruns)
- (*tp->ptr_rx_fifo_overruns)++;
- }
-
- err = SUCCESS;
- break;
-
- /* Type 0x0C - Action Command Status Interrupt
- * Subtype bit 14 - CB end of command chain (CE)
- * Subtype bit 15 - CB command interrupt (CI)
- */
- case ISB_IMC_COMMAND_STATUS:
- err = SUCCESS;
- if(tp->acb_head->cmd == ACB_CMD_HIC_NOP)
- {
- printk(KERN_ERR "i1\n");
- smctr_disable_16bit(dev);
-
- /* XXXXXXXXXXXXXXXXX */
- /* err = UM_Interrupt(dev); */
-
- smctr_enable_16bit(dev);
- }
- else
- {
- if((tp->acb_head->cmd
- == ACB_CMD_READ_TRC_STATUS) &&
- (tp->acb_head->subcmd
- == RW_TRC_STATUS_BLOCK))
- {
- if(tp->ptr_bcn_type)
- {
- *(tp->ptr_bcn_type)
- = (__u32)((SBlock *)tp->misc_command_data)->BCN_Type;
- }
-
- if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & ERROR_COUNTERS_CHANGED)
- {
- smctr_update_err_stats(dev);
- }
-
- if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & TI_NDIS_RING_STATUS_CHANGED)
- {
- tp->ring_status
- = ((SBlock*)tp->misc_command_data)->TI_NDIS_Ring_Status;
- smctr_disable_16bit(dev);
- err = smctr_ring_status_chg(dev);
- smctr_enable_16bit(dev);
- if((tp->ring_status & REMOVE_RECEIVED) &&
- (tp->config_word0 & NO_AUTOREMOVE))
- {
- smctr_issue_remove_cmd(dev);
- }
-
- if(err != SUCCESS)
- {
- tp->acb_pending = 0;
- break;
- }
- }
-
- if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & UNA_CHANGED)
- {
- if(tp->ptr_una)
- {
- tp->ptr_una[0] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[0]);
- tp->ptr_una[1] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[1]);
- tp->ptr_una[2] = SWAP_BYTES(((SBlock *)tp->misc_command_data)->UNA[2]);
- }
-
- }
-
- if(((SBlock *)tp->misc_command_data)->Status_CHG_Indicate & READY_TO_SEND_RQ_INIT) {
- err = smctr_send_rq_init(dev);
- }
- }
- }
-
- tp->acb_pending = 0;
- break;
-
- /* Type 0x0D - MAC Type 1 interrupt
- * Subtype -- 00 FR_BCN received at S12
- * 01 FR_BCN received at S21
- * 02 FR_DAT(DA=MA, A<>0) received at S21
- * 03 TSM_EXP at S21
- * 04 FR_REMOVE received at S42
- * 05 TBR_EXP, BR_FLAG_SET at S42
- * 06 TBT_EXP at S53
- */
- case ISB_IMC_MAC_TYPE_1:
- if(isb_subtype > 8)
- {
- err = HARDWARE_FAILED;
- break;
- }
-
- err = SUCCESS;
- switch(isb_subtype)
- {
- case 0:
- tp->join_state = JS_BYPASS_STATE;
- if(tp->status != CLOSED)
- {
- tp->status = CLOSED;
- err = smctr_status_chg(dev);
- }
- break;
-
- case 1:
- tp->join_state = JS_LOBE_TEST_STATE;
- break;
-
- case 2:
- tp->join_state = JS_DETECT_MONITOR_PRESENT_STATE;
- break;
-
- case 3:
- tp->join_state = JS_AWAIT_NEW_MONITOR_STATE;
- break;
-
- case 4:
- tp->join_state = JS_DUPLICATE_ADDRESS_TEST_STATE;
- break;
-
- case 5:
- tp->join_state = JS_NEIGHBOR_NOTIFICATION_STATE;
- break;
-
- case 6:
- tp->join_state = JS_REQUEST_INITIALIZATION_STATE;
- break;
-
- case 7:
- tp->join_state = JS_JOIN_COMPLETE_STATE;
- tp->status = OPEN;
- err = smctr_status_chg(dev);
- break;
-
- case 8:
- tp->join_state = JS_BYPASS_WAIT_STATE;
- break;
- }
- break ;
-
- /* Type 0x0E - TRC Initialization Sequence Interrupt
- * Subtype -- 00-FF Initializatin sequence complete
- */
- case ISB_IMC_TRC_INTRNL_TST_STATUS:
- tp->status = INITIALIZED;
- smctr_disable_16bit(dev);
- err = smctr_status_chg(dev);
- smctr_enable_16bit(dev);
- break;
-
- /* other interrupt types, illegal */
- default:
- break;
- }
-
- if(err != SUCCESS)
- break;
- }
-
- /* Checking the ack code instead of the unmask bits here is because :
- * while fixing the stuck receive, DAT frame are sent and mask off
- * FIFO overrun interrupt temporarily (interrupt_unmask_bits = 0)
- * but we still want to issue ack to ISB
- */
- if(!(interrupt_ack_code & 0xff00))
- smctr_issue_int_ack(dev, interrupt_ack_code, interrupt_unmask_bits);
-
- smctr_disable_16bit(dev);
- smctr_enable_bic_int(dev);
- spin_unlock(&tp->lock);
-
- return IRQ_HANDLED;
-}
-
-static int smctr_issue_enable_int_cmd(struct net_device *dev,
- __u16 interrupt_enable_mask)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- tp->sclb_ptr->int_mask_control = interrupt_enable_mask;
- tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK;
-
- smctr_set_ctrl_attention(dev);
-
- return 0;
-}
-
-static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(smctr_wait_while_cbusy(dev))
- return -1;
-
- tp->sclb_ptr->int_mask_control = ibits;
- tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */ tp->sclb_ptr->resume_control = 0;
- tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_IACK_CODE_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK;
-
- smctr_set_ctrl_attention(dev);
-
- return 0;
-}
-
-static int smctr_issue_init_timers_cmd(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i;
- int err;
- __u16 *pTimer_Struc = (__u16 *)tp->misc_command_data;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE;
- tp->config_word1 = 0;
-
- if((tp->media_type == MEDIA_STP_16) ||
- (tp->media_type == MEDIA_UTP_16) ||
- (tp->media_type == MEDIA_STP_16_UTP_16))
- {
- tp->config_word0 |= FREQ_16MB_BIT;
- }
-
- if(tp->mode_bits & EARLY_TOKEN_REL)
- tp->config_word0 |= ETREN;
-
- if(tp->mode_bits & LOOPING_MODE_MASK)
- tp->config_word0 |= RX_OWN_BIT;
- else
- tp->config_word0 &= ~RX_OWN_BIT;
-
- if(tp->receive_mask & PROMISCUOUS_MODE)
- tp->config_word0 |= PROMISCUOUS_BIT;
- else
- tp->config_word0 &= ~PROMISCUOUS_BIT;
-
- if(tp->receive_mask & ACCEPT_ERR_PACKETS)
- tp->config_word0 |= SAVBAD_BIT;
- else
- tp->config_word0 &= ~SAVBAD_BIT;
-
- if(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES)
- tp->config_word0 |= RXATMAC;
- else
- tp->config_word0 &= ~RXATMAC;
-
- if(tp->receive_mask & ACCEPT_MULTI_PROM)
- tp->config_word1 |= MULTICAST_ADDRESS_BIT;
- else
- tp->config_word1 &= ~MULTICAST_ADDRESS_BIT;
-
- if(tp->receive_mask & ACCEPT_SOURCE_ROUTING_SPANNING)
- tp->config_word1 |= SOURCE_ROUTING_SPANNING_BITS;
- else
- {
- if(tp->receive_mask & ACCEPT_SOURCE_ROUTING)
- tp->config_word1 |= SOURCE_ROUTING_EXPLORER_BIT;
- else
- tp->config_word1 &= ~SOURCE_ROUTING_SPANNING_BITS;
- }
-
- if((tp->media_type == MEDIA_STP_16) ||
- (tp->media_type == MEDIA_UTP_16) ||
- (tp->media_type == MEDIA_STP_16_UTP_16))
- {
- tp->config_word1 |= INTERFRAME_SPACING_16;
- }
- else
- tp->config_word1 |= INTERFRAME_SPACING_4;
-
- *pTimer_Struc++ = tp->config_word0;
- *pTimer_Struc++ = tp->config_word1;
-
- if((tp->media_type == MEDIA_STP_4) ||
- (tp->media_type == MEDIA_UTP_4) ||
- (tp->media_type == MEDIA_STP_4_UTP_4))
- {
- *pTimer_Struc++ = 0x00FA; /* prescale */
- *pTimer_Struc++ = 0x2710; /* TPT_limit */
- *pTimer_Struc++ = 0x2710; /* TQP_limit */
- *pTimer_Struc++ = 0x0A28; /* TNT_limit */
- *pTimer_Struc++ = 0x3E80; /* TBT_limit */
- *pTimer_Struc++ = 0x3A98; /* TSM_limit */
- *pTimer_Struc++ = 0x1B58; /* TAM_limit */
- *pTimer_Struc++ = 0x00C8; /* TBR_limit */
- *pTimer_Struc++ = 0x07D0; /* TER_limit */
- *pTimer_Struc++ = 0x000A; /* TGT_limit */
- *pTimer_Struc++ = 0x1162; /* THT_limit */
- *pTimer_Struc++ = 0x07D0; /* TRR_limit */
- *pTimer_Struc++ = 0x1388; /* TVX_limit */
- *pTimer_Struc++ = 0x0000; /* reserved */
- }
- else
- {
- *pTimer_Struc++ = 0x03E8; /* prescale */
- *pTimer_Struc++ = 0x9C40; /* TPT_limit */
- *pTimer_Struc++ = 0x9C40; /* TQP_limit */
- *pTimer_Struc++ = 0x0A28; /* TNT_limit */
- *pTimer_Struc++ = 0x3E80; /* TBT_limit */
- *pTimer_Struc++ = 0x3A98; /* TSM_limit */
- *pTimer_Struc++ = 0x1B58; /* TAM_limit */
- *pTimer_Struc++ = 0x00C8; /* TBR_limit */
- *pTimer_Struc++ = 0x07D0; /* TER_limit */
- *pTimer_Struc++ = 0x000A; /* TGT_limit */
- *pTimer_Struc++ = 0x4588; /* THT_limit */
- *pTimer_Struc++ = 0x1F40; /* TRR_limit */
- *pTimer_Struc++ = 0x4E20; /* TVX_limit */
- *pTimer_Struc++ = 0x0000; /* reserved */
- }
-
- /* Set node address. */
- *pTimer_Struc++ = dev->dev_addr[0] << 8
- | (dev->dev_addr[1] & 0xFF);
- *pTimer_Struc++ = dev->dev_addr[2] << 8
- | (dev->dev_addr[3] & 0xFF);
- *pTimer_Struc++ = dev->dev_addr[4] << 8
- | (dev->dev_addr[5] & 0xFF);
-
- /* Set group address. */
- *pTimer_Struc++ = tp->group_address_0 << 8
- | tp->group_address_0 >> 8;
- *pTimer_Struc++ = tp->group_address[0] << 8
- | tp->group_address[0] >> 8;
- *pTimer_Struc++ = tp->group_address[1] << 8
- | tp->group_address[1] >> 8;
-
- /* Set functional address. */
- *pTimer_Struc++ = tp->functional_address_0 << 8
- | tp->functional_address_0 >> 8;
- *pTimer_Struc++ = tp->functional_address[0] << 8
- | tp->functional_address[0] >> 8;
- *pTimer_Struc++ = tp->functional_address[1] << 8
- | tp->functional_address[1] >> 8;
-
- /* Set Bit-Wise group address. */
- *pTimer_Struc++ = tp->bitwise_group_address[0] << 8
- | tp->bitwise_group_address[0] >> 8;
- *pTimer_Struc++ = tp->bitwise_group_address[1] << 8
- | tp->bitwise_group_address[1] >> 8;
-
- /* Set ring number address. */
- *pTimer_Struc++ = tp->source_ring_number;
- *pTimer_Struc++ = tp->target_ring_number;
-
- /* Physical drop number. */
- *pTimer_Struc++ = (unsigned short)0;
- *pTimer_Struc++ = (unsigned short)0;
-
- /* Product instance ID. */
- for(i = 0; i < 9; i++)
- *pTimer_Struc++ = (unsigned short)0;
-
- err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TRC_TIMERS, 0);
-
- return err;
-}
-
-static int smctr_issue_init_txrx_cmd(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i;
- int err;
- void **txrx_ptrs = (void *)tp->misc_command_data;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- if((err = smctr_wait_cmd(dev)))
- {
- printk(KERN_ERR "%s: Hardware failure\n", dev->name);
- return err;
- }
-
- /* Initialize Transmit Queue Pointers that are used, to point to
- * a single FCB.
- */
- for(i = 0; i < NUM_TX_QS_USED; i++)
- *txrx_ptrs++ = (void *)TRC_POINTER(tp->tx_fcb_head[i]);
-
- /* Initialize Transmit Queue Pointers that are NOT used to ZERO. */
- for(; i < MAX_TX_QS; i++)
- *txrx_ptrs++ = (void *)0;
-
- /* Initialize Receive Queue Pointers (MAC and Non-MAC) that are
- * used, to point to a single FCB and a BDB chain of buffers.
- */
- for(i = 0; i < NUM_RX_QS_USED; i++)
- {
- *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_fcb_head[i]);
- *txrx_ptrs++ = (void *)TRC_POINTER(tp->rx_bdb_head[i]);
- }
-
- /* Initialize Receive Queue Pointers that are NOT used to ZERO. */
- for(; i < MAX_RX_QS; i++)
- {
- *txrx_ptrs++ = (void *)0;
- *txrx_ptrs++ = (void *)0;
- }
-
- err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TX_RX, 0);
-
- return err;
-}
-
-static int smctr_issue_insert_cmd(struct net_device *dev)
-{
- int err;
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_INSERT, ACB_SUB_CMD_NOP);
-
- return err;
-}
-
-static int smctr_issue_read_ring_status_cmd(struct net_device *dev)
-{
- int err;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_READ_TRC_STATUS,
- RW_TRC_STATUS_BLOCK);
-
- return err;
-}
-
-static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt)
-{
- int err;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_READ_VALUE,
- aword_cnt);
-
- return err;
-}
-
-static int smctr_issue_remove_cmd(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- tp->sclb_ptr->resume_control = 0;
- tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_REMOVE;
-
- smctr_set_ctrl_attention(dev);
-
- return 0;
-}
-
-static int smctr_issue_resume_acb_cmd(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- tp->sclb_ptr->resume_control = SCLB_RC_ACB;
- tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID;
-
- tp->acb_pending = 1;
-
- smctr_set_ctrl_attention(dev);
-
- return 0;
-}
-
-static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- if(queue == MAC_QUEUE)
- tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_BDB;
- else
- tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_BDB;
-
- tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID;
-
- smctr_set_ctrl_attention(dev);
-
- return 0;
-}
-
-static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name);
-
- if(smctr_wait_while_cbusy(dev))
- return -1;
-
- if(queue == MAC_QUEUE)
- tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_FCB;
- else
- tp->sclb_ptr->resume_control = SCLB_RC_RX_NON_MAC_FCB;
-
- tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID;
-
- smctr_set_ctrl_attention(dev);
-
- return 0;
-}
-
-static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name);
-
- if(smctr_wait_while_cbusy(dev))
- return -1;
-
- tp->sclb_ptr->resume_control = (SCLB_RC_TFCB0 << queue);
- tp->sclb_ptr->valid_command = SCLB_RESUME_CONTROL_VALID | SCLB_VALID;
-
- smctr_set_ctrl_attention(dev);
-
- return 0;
-}
-
-static int smctr_issue_test_internal_rom_cmd(struct net_device *dev)
-{
- int err;
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
- TRC_INTERNAL_ROM_TEST);
-
- return err;
-}
-
-static int smctr_issue_test_hic_cmd(struct net_device *dev)
-{
- int err;
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_HIC_TEST,
- TRC_HOST_INTERFACE_REG_TEST);
-
- return err;
-}
-
-static int smctr_issue_test_mac_reg_cmd(struct net_device *dev)
-{
- int err;
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
- TRC_MAC_REGISTERS_TEST);
-
- return err;
-}
-
-static int smctr_issue_trc_loopback_cmd(struct net_device *dev)
-{
- int err;
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
- TRC_INTERNAL_LOOPBACK);
-
- return err;
-}
-
-static int smctr_issue_tri_loopback_cmd(struct net_device *dev)
-{
- int err;
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
- TRC_TRI_LOOPBACK);
-
- return err;
-}
-
-static int smctr_issue_write_byte_cmd(struct net_device *dev,
- short aword_cnt, void *byte)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int iword, ibyte;
- int err;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- for(iword = 0, ibyte = 0; iword < (unsigned int)(aword_cnt & 0xff);
- iword++, ibyte += 2)
- {
- tp->misc_command_data[iword] = (*((__u8 *)byte + ibyte) << 8)
- | (*((__u8 *)byte + ibyte + 1));
- }
-
- return smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE,
- aword_cnt);
-}
-
-static int smctr_issue_write_word_cmd(struct net_device *dev,
- short aword_cnt, void *word)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i, err;
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- for(i = 0; i < (unsigned int)(aword_cnt & 0xff); i++)
- tp->misc_command_data[i] = *((__u16 *)word + i);
-
- err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE,
- aword_cnt);
-
- return err;
-}
-
-static int smctr_join_complete_state(struct net_device *dev)
-{
- int err;
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE,
- JS_JOIN_COMPLETE_STATE);
-
- return err;
-}
-
-static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i, j;
- FCBlock *fcb;
- BDBlock *bdb;
-
- for(i = 0; i < NUM_TX_QS_USED; i++)
- {
- fcb = tp->tx_fcb_head[i];
- bdb = tp->tx_bdb_head[i];
-
- for(j = 0; j < tp->num_tx_fcbs[i]; j++)
- {
- fcb->bdb_ptr = bdb;
- fcb->trc_bdb_ptr = TRC_POINTER(bdb);
- fcb = (FCBlock *)((char *)fcb + sizeof(FCBlock));
- bdb = (BDBlock *)((char *)bdb + sizeof(BDBlock));
- }
- }
-
- return 0;
-}
-
-static int smctr_load_firmware(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- const struct firmware *fw;
- __u16 i, checksum = 0;
- int err = 0;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_load_firmware\n", dev->name);
-
- if (request_firmware(&fw, "tr_smctr.bin", &dev->dev)) {
- printk(KERN_ERR "%s: firmware not found\n", dev->name);
- return UCODE_NOT_PRESENT;
- }
-
- tp->num_of_tx_buffs = 4;
- tp->mode_bits |= UMAC;
- tp->receive_mask = 0;
- tp->max_packet_size = 4177;
-
- /* Can only upload the firmware once per adapter reset. */
- if (tp->microcode_version != 0) {
- err = (UCODE_PRESENT);
- goto out;
- }
-
- /* Verify the firmware exists and is there in the right amount. */
- if (!fw->data ||
- (*(fw->data + UCODE_VERSION_OFFSET) < UCODE_VERSION))
- {
- err = (UCODE_NOT_PRESENT);
- goto out;
- }
-
- /* UCODE_SIZE is not included in Checksum. */
- for(i = 0; i < *((__u16 *)(fw->data + UCODE_SIZE_OFFSET)); i += 2)
- checksum += *((__u16 *)(fw->data + 2 + i));
- if (checksum) {
- err = (UCODE_NOT_PRESENT);
- goto out;
- }
-
- /* At this point we have a valid firmware image, lets kick it on up. */
- smctr_enable_adapter_ram(dev);
- smctr_enable_16bit(dev);
- smctr_set_page(dev, (__u8 *)tp->ram_access);
-
- if((smctr_checksum_firmware(dev)) ||
- (*(fw->data + UCODE_VERSION_OFFSET) > tp->microcode_version))
- {
- smctr_enable_adapter_ctrl_store(dev);
-
- /* Zero out ram space for firmware. */
- for(i = 0; i < CS_RAM_SIZE; i += 2)
- *((__u16 *)(tp->ram_access + i)) = 0;
-
- smctr_decode_firmware(dev, fw);
-
- tp->microcode_version = *(fw->data + UCODE_VERSION_OFFSET); *((__u16 *)(tp->ram_access + CS_RAM_VERSION_OFFSET))
- = (tp->microcode_version << 8);
- *((__u16 *)(tp->ram_access + CS_RAM_CHECKSUM_OFFSET))
- = ~(tp->microcode_version << 8) + 1;
-
- smctr_disable_adapter_ctrl_store(dev);
-
- if(smctr_checksum_firmware(dev))
- err = HARDWARE_FAILED;
- }
- else
- err = UCODE_PRESENT;
-
- smctr_disable_16bit(dev);
- out:
- release_firmware(fw);
- return err;
-}
-
-static int smctr_load_node_addr(struct net_device *dev)
-{
- int ioaddr = dev->base_addr;
- unsigned int i;
- __u8 r;
-
- for(i = 0; i < 6; i++)
- {
- r = inb(ioaddr + LAR0 + i);
- dev->dev_addr[i] = (char)r;
- }
- dev->addr_len = 6;
-
- return 0;
-}
-
-/* Lobe Media Test.
- * During the transmission of the initial 1500 lobe media MAC frames,
- * the phase lock loop in the 805 chip may lock, and then un-lock, causing
- * the 825 to go into a PURGE state. When performing a PURGE, the MCT
- * microcode will not transmit any frames given to it by the host, and
- * will consequently cause a timeout.
- *
- * NOTE 1: If the monitor_state is MS_BEACON_TEST_STATE, all transmit
- * queues other than the one used for the lobe_media_test should be
- * disabled.!?
- *
- * NOTE 2: If the monitor_state is MS_BEACON_TEST_STATE and the receive_mask
- * has any multi-cast or promiscuous bits set, the receive_mask needs to
- * be changed to clear the multi-cast or promiscuous mode bits, the lobe_test
- * run, and then the receive mask set back to its original value if the test
- * is successful.
- */
-static int smctr_lobe_media_test(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i, perror = 0;
- unsigned short saved_rcv_mask;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_lobe_media_test\n", dev->name);
-
- /* Clear receive mask for lobe test. */
- saved_rcv_mask = tp->receive_mask;
- tp->receive_mask = 0;
-
- smctr_chg_rx_mask(dev);
-
- /* Setup the lobe media test. */
- smctr_lobe_media_test_cmd(dev);
- if(smctr_wait_cmd(dev))
- goto err;
-
- /* Tx lobe media test frames. */
- for(i = 0; i < 1500; ++i)
- {
- if(smctr_send_lobe_media_test(dev))
- {
- if(perror)
- goto err;
- else
- {
- perror = 1;
- if(smctr_lobe_media_test_cmd(dev))
- goto err;
- }
- }
- }
-
- if(smctr_send_dat(dev))
- {
- if(smctr_send_dat(dev))
- goto err;
- }
-
- /* Check if any frames received during test. */
- if((tp->rx_fcb_curr[MAC_QUEUE]->frame_status) ||
- (tp->rx_fcb_curr[NON_MAC_QUEUE]->frame_status))
- goto err;
-
- /* Set receive mask to "Promisc" mode. */
- tp->receive_mask = saved_rcv_mask;
-
- smctr_chg_rx_mask(dev);
-
- return 0;
-err:
- smctr_reset_adapter(dev);
- tp->status = CLOSED;
- return LOBE_MEDIA_TEST_FAILED;
-}
-
-static int smctr_lobe_media_test_cmd(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_lobe_media_test_cmd\n", dev->name);
-
- /* Change to lobe media test state. */
- if(tp->monitor_state != MS_BEACON_TEST_STATE)
- {
- smctr_lobe_media_test_state(dev);
- if(smctr_wait_cmd(dev))
- {
- printk(KERN_ERR "Lobe Failed test state\n");
- return LOBE_MEDIA_TEST_FAILED;
- }
- }
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST,
- TRC_LOBE_MEDIA_TEST);
-
- return err;
-}
-
-static int smctr_lobe_media_test_state(struct net_device *dev)
-{
- int err;
-
- err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE,
- JS_LOBE_TEST_STATE);
-
- return err;
-}
-
-static int smctr_make_8025_hdr(struct net_device *dev,
- MAC_HEADER *rmf, MAC_HEADER *tmf, __u16 ac_fc)
-{
- tmf->ac = MSB(ac_fc); /* msb is access control */
- tmf->fc = LSB(ac_fc); /* lsb is frame control */
-
- tmf->sa[0] = dev->dev_addr[0];
- tmf->sa[1] = dev->dev_addr[1];
- tmf->sa[2] = dev->dev_addr[2];
- tmf->sa[3] = dev->dev_addr[3];
- tmf->sa[4] = dev->dev_addr[4];
- tmf->sa[5] = dev->dev_addr[5];
-
- switch(tmf->vc)
- {
- /* Send RQ_INIT to RPS */
- case RQ_INIT:
- tmf->da[0] = 0xc0;
- tmf->da[1] = 0x00;
- tmf->da[2] = 0x00;
- tmf->da[3] = 0x00;
- tmf->da[4] = 0x00;
- tmf->da[5] = 0x02;
- break;
-
- /* Send RPT_TX_FORWARD to CRS */
- case RPT_TX_FORWARD:
- tmf->da[0] = 0xc0;
- tmf->da[1] = 0x00;
- tmf->da[2] = 0x00;
- tmf->da[3] = 0x00;
- tmf->da[4] = 0x00;
- tmf->da[5] = 0x10;
- break;
-
- /* Everything else goes to sender */
- default:
- tmf->da[0] = rmf->sa[0];
- tmf->da[1] = rmf->sa[1];
- tmf->da[2] = rmf->sa[2];
- tmf->da[3] = rmf->sa[3];
- tmf->da[4] = rmf->sa[4];
- tmf->da[5] = rmf->sa[5];
- break;
- }
-
- return 0;
-}
-
-static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- tsv->svi = AUTHORIZED_ACCESS_PRIORITY;
- tsv->svl = S_AUTHORIZED_ACCESS_PRIORITY;
-
- tsv->svv[0] = MSB(tp->authorized_access_priority);
- tsv->svv[1] = LSB(tp->authorized_access_priority);
-
- return 0;
-}
-
-static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv)
-{
- tsv->svi = ADDRESS_MODIFER;
- tsv->svl = S_ADDRESS_MODIFER;
-
- tsv->svv[0] = 0;
- tsv->svv[1] = 0;
-
- return 0;
-}
-
-static int smctr_make_auth_funct_class(struct net_device *dev,
- MAC_SUB_VECTOR *tsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- tsv->svi = AUTHORIZED_FUNCTION_CLASS;
- tsv->svl = S_AUTHORIZED_FUNCTION_CLASS;
-
- tsv->svv[0] = MSB(tp->authorized_function_classes);
- tsv->svv[1] = LSB(tp->authorized_function_classes);
-
- return 0;
-}
-
-static int smctr_make_corr(struct net_device *dev,
- MAC_SUB_VECTOR *tsv, __u16 correlator)
-{
- tsv->svi = CORRELATOR;
- tsv->svl = S_CORRELATOR;
-
- tsv->svv[0] = MSB(correlator);
- tsv->svv[1] = LSB(correlator);
-
- return 0;
-}
-
-static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- smctr_get_functional_address(dev);
-
- tsv->svi = FUNCTIONAL_ADDRESS;
- tsv->svl = S_FUNCTIONAL_ADDRESS;
-
- tsv->svv[0] = MSB(tp->misc_command_data[0]);
- tsv->svv[1] = LSB(tp->misc_command_data[0]);
-
- tsv->svv[2] = MSB(tp->misc_command_data[1]);
- tsv->svv[3] = LSB(tp->misc_command_data[1]);
-
- return 0;
-}
-
-static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- smctr_get_group_address(dev);
-
- tsv->svi = GROUP_ADDRESS;
- tsv->svl = S_GROUP_ADDRESS;
-
- tsv->svv[0] = MSB(tp->misc_command_data[0]);
- tsv->svv[1] = LSB(tp->misc_command_data[0]);
-
- tsv->svv[2] = MSB(tp->misc_command_data[1]);
- tsv->svv[3] = LSB(tp->misc_command_data[1]);
-
- /* Set Group Address Sub-vector to all zeros if only the
- * Group Address/Functional Address Indicator is set.
- */
- if(tsv->svv[0] == 0x80 && tsv->svv[1] == 0x00 &&
- tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00)
- tsv->svv[0] = 0x00;
-
- return 0;
-}
-
-static int smctr_make_phy_drop_num(struct net_device *dev,
- MAC_SUB_VECTOR *tsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- smctr_get_physical_drop_number(dev);
-
- tsv->svi = PHYSICAL_DROP;
- tsv->svl = S_PHYSICAL_DROP;
-
- tsv->svv[0] = MSB(tp->misc_command_data[0]);
- tsv->svv[1] = LSB(tp->misc_command_data[0]);
-
- tsv->svv[2] = MSB(tp->misc_command_data[1]);
- tsv->svv[3] = LSB(tp->misc_command_data[1]);
-
- return 0;
-}
-
-static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv)
-{
- int i;
-
- tsv->svi = PRODUCT_INSTANCE_ID;
- tsv->svl = S_PRODUCT_INSTANCE_ID;
-
- for(i = 0; i < 18; i++)
- tsv->svv[i] = 0xF0;
-
- return 0;
-}
-
-static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- smctr_get_station_id(dev);
-
- tsv->svi = STATION_IDENTIFER;
- tsv->svl = S_STATION_IDENTIFER;
-
- tsv->svv[0] = MSB(tp->misc_command_data[0]);
- tsv->svv[1] = LSB(tp->misc_command_data[0]);
-
- tsv->svv[2] = MSB(tp->misc_command_data[1]);
- tsv->svv[3] = LSB(tp->misc_command_data[1]);
-
- tsv->svv[4] = MSB(tp->misc_command_data[2]);
- tsv->svv[5] = LSB(tp->misc_command_data[2]);
-
- return 0;
-}
-
-static int smctr_make_ring_station_status(struct net_device *dev,
- MAC_SUB_VECTOR * tsv)
-{
- tsv->svi = RING_STATION_STATUS;
- tsv->svl = S_RING_STATION_STATUS;
-
- tsv->svv[0] = 0;
- tsv->svv[1] = 0;
- tsv->svv[2] = 0;
- tsv->svv[3] = 0;
- tsv->svv[4] = 0;
- tsv->svv[5] = 0;
-
- return 0;
-}
-
-static int smctr_make_ring_station_version(struct net_device *dev,
- MAC_SUB_VECTOR *tsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- tsv->svi = RING_STATION_VERSION_NUMBER;
- tsv->svl = S_RING_STATION_VERSION_NUMBER;
-
- tsv->svv[0] = 0xe2; /* EBCDIC - S */
- tsv->svv[1] = 0xd4; /* EBCDIC - M */
- tsv->svv[2] = 0xc3; /* EBCDIC - C */
- tsv->svv[3] = 0x40; /* EBCDIC - */
- tsv->svv[4] = 0xe5; /* EBCDIC - V */
- tsv->svv[5] = 0xF0 + (tp->microcode_version >> 4);
- tsv->svv[6] = 0xF0 + (tp->microcode_version & 0x0f);
- tsv->svv[7] = 0x40; /* EBCDIC - */
- tsv->svv[8] = 0xe7; /* EBCDIC - X */
-
- if(tp->extra_info & CHIP_REV_MASK)
- tsv->svv[9] = 0xc5; /* EBCDIC - E */
- else
- tsv->svv[9] = 0xc4; /* EBCDIC - D */
-
- return 0;
-}
-
-static int smctr_make_tx_status_code(struct net_device *dev,
- MAC_SUB_VECTOR *tsv, __u16 tx_fstatus)
-{
- tsv->svi = TRANSMIT_STATUS_CODE;
- tsv->svl = S_TRANSMIT_STATUS_CODE;
-
- tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) | IBM_PASS_SOURCE_ADDR);
-
- /* Stripped frame status of Transmitted Frame */
- tsv->svv[1] = tx_fstatus & 0xff;
-
- return 0;
-}
-
-static int smctr_make_upstream_neighbor_addr(struct net_device *dev,
- MAC_SUB_VECTOR *tsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- smctr_get_upstream_neighbor_addr(dev);
-
- tsv->svi = UPSTREAM_NEIGHBOR_ADDRESS;
- tsv->svl = S_UPSTREAM_NEIGHBOR_ADDRESS;
-
- tsv->svv[0] = MSB(tp->misc_command_data[0]);
- tsv->svv[1] = LSB(tp->misc_command_data[0]);
-
- tsv->svv[2] = MSB(tp->misc_command_data[1]);
- tsv->svv[3] = LSB(tp->misc_command_data[1]);
-
- tsv->svv[4] = MSB(tp->misc_command_data[2]);
- tsv->svv[5] = LSB(tp->misc_command_data[2]);
-
- return 0;
-}
-
-static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv)
-{
- tsv->svi = WRAP_DATA;
- tsv->svl = S_WRAP_DATA;
-
- return 0;
-}
-
-/*
- * Open/initialize the board. This is called sometime after
- * booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is non-reboot way to recover if something goes wrong.
- */
-static int smctr_open(struct net_device *dev)
-{
- int err;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_open\n", dev->name);
-
- err = smctr_init_adapter(dev);
- if(err < 0)
- return err;
-
- return err;
-}
-
-/* Interrupt driven open of Token card. */
-static int smctr_open_tr(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_open_tr\n", dev->name);
-
- /* Now we can actually open the adapter. */
- if(tp->status == OPEN)
- return 0;
- if(tp->status != INITIALIZED)
- return -1;
-
- /* FIXME: it would work a lot better if we masked the irq sources
- on the card here, then we could skip the locking and poll nicely */
- spin_lock_irqsave(&tp->lock, flags);
-
- smctr_set_page(dev, (__u8 *)tp->ram_access);
-
- if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)MAC_QUEUE)))
- goto out;
-
- if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)MAC_QUEUE)))
- goto out;
-
- if((err = smctr_issue_resume_rx_fcb_cmd(dev, (short)NON_MAC_QUEUE)))
- goto out;
-
- if((err = smctr_issue_resume_rx_bdb_cmd(dev, (short)NON_MAC_QUEUE)))
- goto out;
-
- tp->status = CLOSED;
-
- /* Insert into the Ring or Enter Loopback Mode. */
- if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_1)
- {
- tp->status = CLOSED;
-
- if(!(err = smctr_issue_trc_loopback_cmd(dev)))
- {
- if(!(err = smctr_wait_cmd(dev)))
- tp->status = OPEN;
- }
-
- smctr_status_chg(dev);
- }
- else
- {
- if((tp->mode_bits & LOOPING_MODE_MASK) == LOOPBACK_MODE_2)
- {
- tp->status = CLOSED;
- if(!(err = smctr_issue_tri_loopback_cmd(dev)))
- {
- if(!(err = smctr_wait_cmd(dev)))
- tp->status = OPEN;
- }
-
- smctr_status_chg(dev);
- }
- else
- {
- if((tp->mode_bits & LOOPING_MODE_MASK)
- == LOOPBACK_MODE_3)
- {
- tp->status = CLOSED;
- if(!(err = smctr_lobe_media_test_cmd(dev)))
- {
- if(!(err = smctr_wait_cmd(dev)))
- tp->status = OPEN;
- }
- smctr_status_chg(dev);
- }
- else
- {
- if(!(err = smctr_lobe_media_test(dev)))
- err = smctr_issue_insert_cmd(dev);
- else
- {
- if(err == LOBE_MEDIA_TEST_FAILED)
- printk(KERN_WARNING "%s: Lobe Media Test Failure - Check cable?\n", dev->name);
- }
- }
- }
- }
-
-out:
- spin_unlock_irqrestore(&tp->lock, flags);
-
- return err;
-}
-
-/* Check for a network adapter of this type,
- * and return device structure if one exists.
- */
-struct net_device __init *smctr_probe(int unit)
-{
- struct net_device *dev = alloc_trdev(sizeof(struct net_local));
- static const unsigned ports[] = {
- 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0, 0x300,
- 0x320, 0x340, 0x360, 0x380, 0
- };
- const unsigned *port;
- int err = 0;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- if (unit >= 0) {
- sprintf(dev->name, "tr%d", unit);
- netdev_boot_setup_check(dev);
- }
-
- if (dev->base_addr > 0x1ff) /* Check a single specified location. */
- err = smctr_probe1(dev, dev->base_addr);
- else if(dev->base_addr != 0) /* Don't probe at all. */
- err =-ENXIO;
- else {
- for (port = ports; *port; port++) {
- err = smctr_probe1(dev, *port);
- if (!err)
- break;
- }
- }
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
-out1:
-#ifdef CONFIG_MCA_LEGACY
- { struct net_local *tp = netdev_priv(dev);
- if (tp->slot_num)
- mca_mark_as_unused(tp->slot_num);
- }
-#endif
- release_region(dev->base_addr, SMCTR_IO_EXTENT);
- free_irq(dev->irq, dev);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-static const struct net_device_ops smctr_netdev_ops = {
- .ndo_open = smctr_open,
- .ndo_stop = smctr_close,
- .ndo_start_xmit = smctr_send_packet,
- .ndo_tx_timeout = smctr_timeout,
- .ndo_get_stats = smctr_get_stats,
- .ndo_set_rx_mode = smctr_set_multicast_list,
-};
-
-static int __init smctr_probe1(struct net_device *dev, int ioaddr)
-{
- static unsigned version_printed;
- struct net_local *tp = netdev_priv(dev);
- int err;
- __u32 *ram;
-
- if(smctr_debug && version_printed++ == 0)
- printk(version);
-
- spin_lock_init(&tp->lock);
- dev->base_addr = ioaddr;
-
- /* Actually detect an adapter now. */
- err = smctr_chk_isa(dev);
- if(err < 0)
- {
- if ((err = smctr_chk_mca(dev)) < 0) {
- err = -ENODEV;
- goto out;
- }
- }
-
- tp = netdev_priv(dev);
- dev->mem_start = tp->ram_base;
- dev->mem_end = dev->mem_start + 0x10000;
- ram = (__u32 *)phys_to_virt(dev->mem_start);
- tp->ram_access = *(__u32 *)&ram;
- tp->status = NOT_INITIALIZED;
-
- err = smctr_load_firmware(dev);
- if(err != UCODE_PRESENT && err != SUCCESS)
- {
- printk(KERN_ERR "%s: Firmware load failed (%d)\n", dev->name, err);
- err = -EIO;
- goto out;
- }
-
- /* Allow user to specify ring speed on module insert. */
- if(ringspeed == 4)
- tp->media_type = MEDIA_UTP_4;
- else
- tp->media_type = MEDIA_UTP_16;
-
- printk(KERN_INFO "%s: %s %s at Io %#4x, Irq %d, Rom %#4x, Ram %#4x.\n",
- dev->name, smctr_name, smctr_model,
- (unsigned int)dev->base_addr,
- dev->irq, tp->rom_base, tp->ram_base);
-
- dev->netdev_ops = &smctr_netdev_ops;
- dev->watchdog_timeo = HZ;
- return 0;
-
-out:
- return err;
-}
-
-static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size,
- struct net_device *dev, __u16 rx_status)
-{
- struct net_local *tp = netdev_priv(dev);
- struct sk_buff *skb;
- __u16 rcode, correlator;
- int err = 0;
- __u8 xframe = 1;
-
- rmf->vl = SWAP_BYTES(rmf->vl);
- if(rx_status & FCB_RX_STATUS_DA_MATCHED)
- {
- switch(rmf->vc)
- {
- /* Received MAC Frames Processed by RS. */
- case INIT:
- if((rcode = smctr_rcv_init(dev, rmf, &correlator)) == HARDWARE_FAILED)
- {
- return rcode;
- }
-
- if((err = smctr_send_rsp(dev, rmf, rcode,
- correlator)))
- {
- return err;
- }
- break;
-
- case CHG_PARM:
- if((rcode = smctr_rcv_chg_param(dev, rmf,
- &correlator)) ==HARDWARE_FAILED)
- {
- return rcode;
- }
-
- if((err = smctr_send_rsp(dev, rmf, rcode,
- correlator)))
- {
- return err;
- }
- break;
-
- case RQ_ADDR:
- if((rcode = smctr_rcv_rq_addr_state_attch(dev,
- rmf, &correlator)) != POSITIVE_ACK)
- {
- if(rcode == HARDWARE_FAILED)
- return rcode;
- else
- return smctr_send_rsp(dev, rmf,
- rcode, correlator);
- }
-
- if((err = smctr_send_rpt_addr(dev, rmf,
- correlator)))
- {
- return err;
- }
- break;
-
- case RQ_ATTCH:
- if((rcode = smctr_rcv_rq_addr_state_attch(dev,
- rmf, &correlator)) != POSITIVE_ACK)
- {
- if(rcode == HARDWARE_FAILED)
- return rcode;
- else
- return smctr_send_rsp(dev, rmf,
- rcode,
- correlator);
- }
-
- if((err = smctr_send_rpt_attch(dev, rmf,
- correlator)))
- {
- return err;
- }
- break;
-
- case RQ_STATE:
- if((rcode = smctr_rcv_rq_addr_state_attch(dev,
- rmf, &correlator)) != POSITIVE_ACK)
- {
- if(rcode == HARDWARE_FAILED)
- return rcode;
- else
- return smctr_send_rsp(dev, rmf,
- rcode,
- correlator);
- }
-
- if((err = smctr_send_rpt_state(dev, rmf,
- correlator)))
- {
- return err;
- }
- break;
-
- case TX_FORWARD: {
- __u16 uninitialized_var(tx_fstatus);
-
- if((rcode = smctr_rcv_tx_forward(dev, rmf))
- != POSITIVE_ACK)
- {
- if(rcode == HARDWARE_FAILED)
- return rcode;
- else
- return smctr_send_rsp(dev, rmf,
- rcode,
- correlator);
- }
-
- if((err = smctr_send_tx_forward(dev, rmf,
- &tx_fstatus)) == HARDWARE_FAILED)
- {
- return err;
- }
-
- if(err == A_FRAME_WAS_FORWARDED)
- {
- if((err = smctr_send_rpt_tx_forward(dev,
- rmf, tx_fstatus))
- == HARDWARE_FAILED)
- {
- return err;
- }
- }
- break;
- }
-
- /* Received MAC Frames Processed by CRS/REM/RPS. */
- case RSP:
- case RQ_INIT:
- case RPT_NEW_MON:
- case RPT_SUA_CHG:
- case RPT_ACTIVE_ERR:
- case RPT_NN_INCMP:
- case RPT_ERROR:
- case RPT_ATTCH:
- case RPT_STATE:
- case RPT_ADDR:
- break;
-
- /* Rcvd Att. MAC Frame (if RXATMAC set) or UNKNOWN */
- default:
- xframe = 0;
- if(!(tp->receive_mask & ACCEPT_ATT_MAC_FRAMES))
- {
- rcode = smctr_rcv_unknown(dev, rmf,
- &correlator);
- if((err = smctr_send_rsp(dev, rmf,rcode,
- correlator)))
- {
- return err;
- }
- }
-
- break;
- }
- }
- else
- {
- /* 1. DA doesn't match (Promiscuous Mode).
- * 2. Parse for Extended MAC Frame Type.
- */
- switch(rmf->vc)
- {
- case RSP:
- case INIT:
- case RQ_INIT:
- case RQ_ADDR:
- case RQ_ATTCH:
- case RQ_STATE:
- case CHG_PARM:
- case RPT_ADDR:
- case RPT_ERROR:
- case RPT_ATTCH:
- case RPT_STATE:
- case RPT_NEW_MON:
- case RPT_SUA_CHG:
- case RPT_NN_INCMP:
- case RPT_ACTIVE_ERR:
- break;
-
- default:
- xframe = 0;
- break;
- }
- }
-
- /* NOTE: UNKNOWN MAC frames will NOT be passed up unless
- * ACCEPT_ATT_MAC_FRAMES is set.
- */
- if(((tp->receive_mask & ACCEPT_ATT_MAC_FRAMES) &&
- (xframe == (__u8)0)) ||
- ((tp->receive_mask & ACCEPT_EXT_MAC_FRAMES) &&
- (xframe == (__u8)1)))
- {
- rmf->vl = SWAP_BYTES(rmf->vl);
-
- if (!(skb = dev_alloc_skb(size)))
- return -ENOMEM;
- skb->len = size;
-
- /* Slide data into a sleek skb. */
- skb_put(skb, skb->len);
- skb_copy_to_linear_data(skb, rmf, skb->len);
-
- /* Update Counters */
- tp->MacStat.rx_packets++;
- tp->MacStat.rx_bytes += skb->len;
-
- /* Kick the packet on up. */
- skb->protocol = tr_type_trans(skb, dev);
- netif_rx(skb);
- err = 0;
- }
-
- return err;
-}
-
-/* Adapter RAM test. Incremental word ODD boundary data test. */
-static int smctr_ram_memory_test(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- __u16 page, pages_of_ram, start_pattern = 0, word_pattern = 0,
- word_read = 0, err_word = 0, err_pattern = 0;
- unsigned int err_offset;
- __u32 j, pword;
- __u8 err = 0;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_ram_memory_test\n", dev->name);
-
- start_pattern = 0x0001;
- pages_of_ram = tp->ram_size / tp->ram_usable;
- pword = tp->ram_access;
-
- /* Incremental word ODD boundary test. */
- for(page = 0; (page < pages_of_ram) && (~err);
- page++, start_pattern += 0x8000)
- {
- smctr_set_page(dev, (__u8 *)(tp->ram_access
- + (page * tp->ram_usable * 1024) + 1));
- word_pattern = start_pattern;
-
- for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1; j += 2)
- *(__u16 *)(pword + j) = word_pattern++;
-
- word_pattern = start_pattern;
-
- for(j = 1; j < (__u32)(tp->ram_usable * 1024) - 1 && (~err);
- j += 2, word_pattern++)
- {
- word_read = *(__u16 *)(pword + j);
- if(word_read != word_pattern)
- {
- err = (__u8)1;
- err_offset = j;
- err_word = word_read;
- err_pattern = word_pattern;
- return RAM_TEST_FAILED;
- }
- }
- }
-
- /* Zero out memory. */
- for(page = 0; page < pages_of_ram && (~err); page++)
- {
- smctr_set_page(dev, (__u8 *)(tp->ram_access
- + (page * tp->ram_usable * 1024)));
- word_pattern = 0;
-
- for(j = 0; j < (__u32)tp->ram_usable * 1024; j +=2)
- *(__u16 *)(pword + j) = word_pattern;
-
- for(j =0; j < (__u32)tp->ram_usable * 1024 && (~err); j += 2)
- {
- word_read = *(__u16 *)(pword + j);
- if(word_read != word_pattern)
- {
- err = (__u8)1;
- err_offset = j;
- err_word = word_read;
- err_pattern = word_pattern;
- return RAM_TEST_FAILED;
- }
- }
- }
-
- smctr_set_page(dev, (__u8 *)tp->ram_access);
-
- return 0;
-}
-
-static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf,
- __u16 *correlator)
-{
- MAC_SUB_VECTOR *rsv;
- signed short vlen;
- __u16 rcode = POSITIVE_ACK;
- unsigned int svectors = F_NO_SUB_VECTORS_FOUND;
-
- /* This Frame can only come from a CRS */
- if((rmf->dc_sc & SC_MASK) != SC_CRS)
- return E_INAPPROPRIATE_SOURCE_CLASS;
-
- /* Remove MVID Length from total length. */
- vlen = (signed short)rmf->vl - 4;
-
- /* Point to First SVID */
- rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
-
- /* Search for Appropriate SVID's. */
- while((vlen > 0) && (rcode == POSITIVE_ACK))
- {
- switch(rsv->svi)
- {
- case CORRELATOR:
- svectors |= F_CORRELATOR;
- rcode = smctr_set_corr(dev, rsv, correlator);
- break;
-
- case LOCAL_RING_NUMBER:
- svectors |= F_LOCAL_RING_NUMBER;
- rcode = smctr_set_local_ring_num(dev, rsv);
- break;
-
- case ASSIGN_PHYSICAL_DROP:
- svectors |= F_ASSIGN_PHYSICAL_DROP;
- rcode = smctr_set_phy_drop(dev, rsv);
- break;
-
- case ERROR_TIMER_VALUE:
- svectors |= F_ERROR_TIMER_VALUE;
- rcode = smctr_set_error_timer_value(dev, rsv);
- break;
-
- case AUTHORIZED_FUNCTION_CLASS:
- svectors |= F_AUTHORIZED_FUNCTION_CLASS;
- rcode = smctr_set_auth_funct_class(dev, rsv);
- break;
-
- case AUTHORIZED_ACCESS_PRIORITY:
- svectors |= F_AUTHORIZED_ACCESS_PRIORITY;
- rcode = smctr_set_auth_access_pri(dev, rsv);
- break;
-
- default:
- rcode = E_SUB_VECTOR_UNKNOWN;
- break;
- }
-
- /* Let Sender Know if SUM of SV length's is
- * larger then length in MVID length field
- */
- if((vlen -= rsv->svl) < 0)
- rcode = E_VECTOR_LENGTH_ERROR;
-
- rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
- }
-
- if(rcode == POSITIVE_ACK)
- {
- /* Let Sender Know if MVID length field
- * is larger then SUM of SV length's
- */
- if(vlen != 0)
- rcode = E_VECTOR_LENGTH_ERROR;
- else
- {
- /* Let Sender Know if Expected SVID Missing */
- if((svectors & R_CHG_PARM) ^ R_CHG_PARM)
- rcode = E_MISSING_SUB_VECTOR;
- }
- }
-
- return rcode;
-}
-
-static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf,
- __u16 *correlator)
-{
- MAC_SUB_VECTOR *rsv;
- signed short vlen;
- __u16 rcode = POSITIVE_ACK;
- unsigned int svectors = F_NO_SUB_VECTORS_FOUND;
-
- /* This Frame can only come from a RPS */
- if((rmf->dc_sc & SC_MASK) != SC_RPS)
- return E_INAPPROPRIATE_SOURCE_CLASS;
-
- /* Remove MVID Length from total length. */
- vlen = (signed short)rmf->vl - 4;
-
- /* Point to First SVID */
- rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
-
- /* Search for Appropriate SVID's */
- while((vlen > 0) && (rcode == POSITIVE_ACK))
- {
- switch(rsv->svi)
- {
- case CORRELATOR:
- svectors |= F_CORRELATOR;
- rcode = smctr_set_corr(dev, rsv, correlator);
- break;
-
- case LOCAL_RING_NUMBER:
- svectors |= F_LOCAL_RING_NUMBER;
- rcode = smctr_set_local_ring_num(dev, rsv);
- break;
-
- case ASSIGN_PHYSICAL_DROP:
- svectors |= F_ASSIGN_PHYSICAL_DROP;
- rcode = smctr_set_phy_drop(dev, rsv);
- break;
-
- case ERROR_TIMER_VALUE:
- svectors |= F_ERROR_TIMER_VALUE;
- rcode = smctr_set_error_timer_value(dev, rsv);
- break;
-
- default:
- rcode = E_SUB_VECTOR_UNKNOWN;
- break;
- }
-
- /* Let Sender Know if SUM of SV length's is
- * larger then length in MVID length field
- */
- if((vlen -= rsv->svl) < 0)
- rcode = E_VECTOR_LENGTH_ERROR;
-
- rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
- }
-
- if(rcode == POSITIVE_ACK)
- {
- /* Let Sender Know if MVID length field
- * is larger then SUM of SV length's
- */
- if(vlen != 0)
- rcode = E_VECTOR_LENGTH_ERROR;
- else
- {
- /* Let Sender Know if Expected SV Missing */
- if((svectors & R_INIT) ^ R_INIT)
- rcode = E_MISSING_SUB_VECTOR;
- }
- }
-
- return rcode;
-}
-
-static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf)
-{
- MAC_SUB_VECTOR *rsv;
- signed short vlen;
- __u16 rcode = POSITIVE_ACK;
- unsigned int svectors = F_NO_SUB_VECTORS_FOUND;
-
- /* This Frame can only come from a CRS */
- if((rmf->dc_sc & SC_MASK) != SC_CRS)
- return E_INAPPROPRIATE_SOURCE_CLASS;
-
- /* Remove MVID Length from total length */
- vlen = (signed short)rmf->vl - 4;
-
- /* Point to First SVID */
- rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
-
- /* Search for Appropriate SVID's */
- while((vlen > 0) && (rcode == POSITIVE_ACK))
- {
- switch(rsv->svi)
- {
- case FRAME_FORWARD:
- svectors |= F_FRAME_FORWARD;
- rcode = smctr_set_frame_forward(dev, rsv,
- rmf->dc_sc);
- break;
-
- default:
- rcode = E_SUB_VECTOR_UNKNOWN;
- break;
- }
-
- /* Let Sender Know if SUM of SV length's is
- * larger then length in MVID length field
- */
- if((vlen -= rsv->svl) < 0)
- rcode = E_VECTOR_LENGTH_ERROR;
-
- rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
- }
-
- if(rcode == POSITIVE_ACK)
- {
- /* Let Sender Know if MVID length field
- * is larger then SUM of SV length's
- */
- if(vlen != 0)
- rcode = E_VECTOR_LENGTH_ERROR;
- else
- {
- /* Let Sender Know if Expected SV Missing */
- if((svectors & R_TX_FORWARD) ^ R_TX_FORWARD)
- rcode = E_MISSING_SUB_VECTOR;
- }
- }
-
- return rcode;
-}
-
-static int smctr_rcv_rq_addr_state_attch(struct net_device *dev,
- MAC_HEADER *rmf, __u16 *correlator)
-{
- MAC_SUB_VECTOR *rsv;
- signed short vlen;
- __u16 rcode = POSITIVE_ACK;
- unsigned int svectors = F_NO_SUB_VECTORS_FOUND;
-
- /* Remove MVID Length from total length */
- vlen = (signed short)rmf->vl - 4;
-
- /* Point to First SVID */
- rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
-
- /* Search for Appropriate SVID's */
- while((vlen > 0) && (rcode == POSITIVE_ACK))
- {
- switch(rsv->svi)
- {
- case CORRELATOR:
- svectors |= F_CORRELATOR;
- rcode = smctr_set_corr(dev, rsv, correlator);
- break;
-
- default:
- rcode = E_SUB_VECTOR_UNKNOWN;
- break;
- }
-
- /* Let Sender Know if SUM of SV length's is
- * larger then length in MVID length field
- */
- if((vlen -= rsv->svl) < 0)
- rcode = E_VECTOR_LENGTH_ERROR;
-
- rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
- }
-
- if(rcode == POSITIVE_ACK)
- {
- /* Let Sender Know if MVID length field
- * is larger then SUM of SV length's
- */
- if(vlen != 0)
- rcode = E_VECTOR_LENGTH_ERROR;
- else
- {
- /* Let Sender Know if Expected SVID Missing */
- if((svectors & R_RQ_ATTCH_STATE_ADDR)
- ^ R_RQ_ATTCH_STATE_ADDR)
- rcode = E_MISSING_SUB_VECTOR;
- }
- }
-
- return rcode;
-}
-
-static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf,
- __u16 *correlator)
-{
- MAC_SUB_VECTOR *rsv;
- signed short vlen;
-
- *correlator = 0;
-
- /* Remove MVID Length from total length */
- vlen = (signed short)rmf->vl - 4;
-
- /* Point to First SVID */
- rsv = (MAC_SUB_VECTOR *)((__u32)rmf + sizeof(MAC_HEADER));
-
- /* Search for CORRELATOR for RSP to UNKNOWN */
- while((vlen > 0) && (*correlator == 0))
- {
- switch(rsv->svi)
- {
- case CORRELATOR:
- smctr_set_corr(dev, rsv, correlator);
- break;
-
- default:
- break;
- }
-
- vlen -= rsv->svl;
- rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl);
- }
-
- return E_UNRECOGNIZED_VECTOR_ID;
-}
-
-/*
- * Reset the 825 NIC and exit w:
- * 1. The NIC reset cleared (non-reset state), halted and un-initialized.
- * 2. TINT masked.
- * 3. CBUSY masked.
- * 4. TINT clear.
- * 5. CBUSY clear.
- */
-static int smctr_reset_adapter(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- /* Reseting the NIC will put it in a halted and un-initialized state. */ smctr_set_trc_reset(ioaddr);
- mdelay(200); /* ~2 ms */
-
- smctr_clear_trc_reset(ioaddr);
- mdelay(200); /* ~2 ms */
-
- /* Remove any latched interrupts that occurred prior to reseting the
- * adapter or possibily caused by line glitches due to the reset.
- */
- outb(tp->trc_mask | CSR_CLRTINT | CSR_CLRCBUSY, ioaddr + CSR);
-
- return 0;
-}
-
-static int smctr_restart_tx_chain(struct net_device *dev, short queue)
-{
- struct net_local *tp = netdev_priv(dev);
- int err = 0;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_restart_tx_chain\n", dev->name);
-
- if(tp->num_tx_fcbs_used[queue] != 0 &&
- tp->tx_queue_status[queue] == NOT_TRANSMITING)
- {
- tp->tx_queue_status[queue] = TRANSMITING;
- err = smctr_issue_resume_tx_fcb_cmd(dev, queue);
- }
-
- return err;
-}
-
-static int smctr_ring_status_chg(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_ring_status_chg\n", dev->name);
-
- /* Check for ring_status_flag: whenever MONITOR_STATE_BIT
- * Bit is set, check value of monitor_state, only then we
- * enable and start transmit/receive timeout (if and only
- * if it is MS_ACTIVE_MONITOR_STATE or MS_STANDBY_MONITOR_STATE)
- */
- if(tp->ring_status_flags == MONITOR_STATE_CHANGED)
- {
- if((tp->monitor_state == MS_ACTIVE_MONITOR_STATE) ||
- (tp->monitor_state == MS_STANDBY_MONITOR_STATE))
- {
- tp->monitor_state_ready = 1;
- }
- else
- {
- /* if adapter is NOT in either active monitor
- * or standby monitor state => Disable
- * transmit/receive timeout.
- */
- tp->monitor_state_ready = 0;
-
- /* Ring speed problem, switching to auto mode. */
- if(tp->monitor_state == MS_MONITOR_FSM_INACTIVE &&
- !tp->cleanup)
- {
- printk(KERN_INFO "%s: Incorrect ring speed switching.\n",
- dev->name);
- smctr_set_ring_speed(dev);
- }
- }
- }
-
- if(!(tp->ring_status_flags & RING_STATUS_CHANGED))
- return 0;
-
- switch(tp->ring_status)
- {
- case RING_RECOVERY:
- printk(KERN_INFO "%s: Ring Recovery\n", dev->name);
- break;
-
- case SINGLE_STATION:
- printk(KERN_INFO "%s: Single Statinon\n", dev->name);
- break;
-
- case COUNTER_OVERFLOW:
- printk(KERN_INFO "%s: Counter Overflow\n", dev->name);
- break;
-
- case REMOVE_RECEIVED:
- printk(KERN_INFO "%s: Remove Received\n", dev->name);
- break;
-
- case AUTO_REMOVAL_ERROR:
- printk(KERN_INFO "%s: Auto Remove Error\n", dev->name);
- break;
-
- case LOBE_WIRE_FAULT:
- printk(KERN_INFO "%s: Lobe Wire Fault\n", dev->name);
- break;
-
- case TRANSMIT_BEACON:
- printk(KERN_INFO "%s: Transmit Beacon\n", dev->name);
- break;
-
- case SOFT_ERROR:
- printk(KERN_INFO "%s: Soft Error\n", dev->name);
- break;
-
- case HARD_ERROR:
- printk(KERN_INFO "%s: Hard Error\n", dev->name);
- break;
-
- case SIGNAL_LOSS:
- printk(KERN_INFO "%s: Signal Loss\n", dev->name);
- break;
-
- default:
- printk(KERN_INFO "%s: Unknown ring status change\n",
- dev->name);
- break;
- }
-
- return 0;
-}
-
-static int smctr_rx_frame(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- __u16 queue, status, rx_size, err = 0;
- __u8 *pbuff;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_rx_frame\n", dev->name);
-
- queue = tp->receive_queue_number;
-
- while((status = tp->rx_fcb_curr[queue]->frame_status) != SUCCESS)
- {
- err = HARDWARE_FAILED;
-
- if(((status & 0x007f) == 0) ||
- ((tp->receive_mask & ACCEPT_ERR_PACKETS) != 0))
- {
- /* frame length less the CRC (4 bytes) + FS (1 byte) */
- rx_size = tp->rx_fcb_curr[queue]->frame_length - 5;
-
- pbuff = smctr_get_rx_pointer(dev, queue);
-
- smctr_set_page(dev, pbuff);
- smctr_disable_16bit(dev);
-
- /* pbuff points to addr within one page */
- pbuff = (__u8 *)PAGE_POINTER(pbuff);
-
- if(queue == NON_MAC_QUEUE)
- {
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(rx_size);
- if (skb) {
- skb_put(skb, rx_size);
-
- skb_copy_to_linear_data(skb, pbuff, rx_size);
-
- /* Update Counters */
- tp->MacStat.rx_packets++;
- tp->MacStat.rx_bytes += skb->len;
-
- /* Kick the packet on up. */
- skb->protocol = tr_type_trans(skb, dev);
- netif_rx(skb);
- } else {
- }
- }
- else
- smctr_process_rx_packet((MAC_HEADER *)pbuff,
- rx_size, dev, status);
- }
-
- smctr_enable_16bit(dev);
- smctr_set_page(dev, (__u8 *)tp->ram_access);
- smctr_update_rx_chain(dev, queue);
-
- if(err != SUCCESS)
- break;
- }
-
- return err;
-}
-
-static int smctr_send_dat(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int i, err;
- MAC_HEADER *tmf;
- FCBlock *fcb;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_send_dat\n", dev->name);
-
- if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE,
- sizeof(MAC_HEADER))) == (FCBlock *)(-1L))
- {
- return OUT_OF_RESOURCES;
- }
-
- /* Initialize DAT Data Fields. */
- tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
- tmf->ac = MSB(AC_FC_DAT);
- tmf->fc = LSB(AC_FC_DAT);
-
- for(i = 0; i < 6; i++)
- {
- tmf->sa[i] = dev->dev_addr[i];
- tmf->da[i] = dev->dev_addr[i];
-
- }
-
- tmf->vc = DAT;
- tmf->dc_sc = DC_RS | SC_RS;
- tmf->vl = 4;
- tmf->vl = SWAP_BYTES(tmf->vl);
-
- /* Start Transmit. */
- if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
- return err;
-
- /* Wait for Transmit to Complete */
- for(i = 0; i < 10000; i++)
- {
- if(fcb->frame_status & FCB_COMMAND_DONE)
- break;
- mdelay(1);
- }
-
- /* Check if GOOD frame Tx'ed. */
- if(!(fcb->frame_status & FCB_COMMAND_DONE) ||
- fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
- {
- return INITIALIZE_FAILED;
- }
-
- /* De-allocated Tx FCB and Frame Buffer
- * The FCB must be de-allocated manually if executing with
- * interrupts disabled, other wise the ISR (LM_Service_Events)
- * will de-allocate it when the interrupt occurs.
- */
- tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
- smctr_update_tx_chain(dev, fcb, MAC_QUEUE);
-
- return 0;
-}
-
-static void smctr_timeout(struct net_device *dev)
-{
- /*
- * If we get here, some higher level has decided we are broken.
- * There should really be a "kick me" function call instead.
- *
- * Resetting the token ring adapter takes a long time so just
- * fake transmission time and go on trying. Our own timeout
- * routine is in sktr_timer_chk()
- */
- dev->trans_start = jiffies; /* prevent tx timeout */
- netif_wake_queue(dev);
-}
-
-/*
- * Gets skb from system, queues it and checks if it can be sent
- */
-static netdev_tx_t smctr_send_packet(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_send_packet\n", dev->name);
-
- /*
- * Block a transmit overlap
- */
-
- netif_stop_queue(dev);
-
- if(tp->QueueSkb == 0)
- return NETDEV_TX_BUSY; /* Return with tbusy set: queue full */
-
- tp->QueueSkb--;
- skb_queue_tail(&tp->SendSkbQueue, skb);
- smctr_hardware_send_packet(dev, tp);
- if(tp->QueueSkb > 0)
- netif_wake_queue(dev);
-
- return NETDEV_TX_OK;
-}
-
-static int smctr_send_lobe_media_test(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- MAC_SUB_VECTOR *tsv;
- MAC_HEADER *tmf;
- FCBlock *fcb;
- __u32 i;
- int err;
-
- if(smctr_debug > 15)
- printk(KERN_DEBUG "%s: smctr_send_lobe_media_test\n", dev->name);
-
- if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr)
- + S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L))
- {
- return OUT_OF_RESOURCES;
- }
-
- /* Initialize DAT Data Fields. */
- tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
- tmf->ac = MSB(AC_FC_LOBE_MEDIA_TEST);
- tmf->fc = LSB(AC_FC_LOBE_MEDIA_TEST);
-
- for(i = 0; i < 6; i++)
- {
- tmf->da[i] = 0;
- tmf->sa[i] = dev->dev_addr[i];
- }
-
- tmf->vc = LOBE_MEDIA_TEST;
- tmf->dc_sc = DC_RS | SC_RS;
- tmf->vl = 4;
-
- tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
- smctr_make_wrap_data(dev, tsv);
- tmf->vl += tsv->svl;
-
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_wrap_data(dev, tsv);
- tmf->vl += tsv->svl;
-
- /* Start Transmit. */
- tmf->vl = SWAP_BYTES(tmf->vl);
- if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
- return err;
-
- /* Wait for Transmit to Complete. (10 ms). */
- for(i=0; i < 10000; i++)
- {
- if(fcb->frame_status & FCB_COMMAND_DONE)
- break;
- mdelay(1);
- }
-
- /* Check if GOOD frame Tx'ed */
- if(!(fcb->frame_status & FCB_COMMAND_DONE) ||
- fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS))
- {
- return LOBE_MEDIA_TEST_FAILED;
- }
-
- /* De-allocated Tx FCB and Frame Buffer
- * The FCB must be de-allocated manually if executing with
- * interrupts disabled, other wise the ISR (LM_Service_Events)
- * will de-allocate it when the interrupt occurs.
- */
- tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
- smctr_update_tx_chain(dev, fcb, MAC_QUEUE);
-
- return 0;
-}
-
-static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf,
- __u16 correlator)
-{
- MAC_HEADER *tmf;
- MAC_SUB_VECTOR *tsv;
- FCBlock *fcb;
-
- if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
- + S_CORRELATOR + S_PHYSICAL_DROP + S_UPSTREAM_NEIGHBOR_ADDRESS
- + S_ADDRESS_MODIFER + S_GROUP_ADDRESS + S_FUNCTIONAL_ADDRESS))
- == (FCBlock *)(-1L))
- {
- return 0;
- }
-
- tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
- tmf->vc = RPT_ADDR;
- tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4;
- tmf->vl = 4;
-
- smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ADDR);
-
- tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
- smctr_make_corr(dev, tsv, correlator);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_phy_drop_num(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_upstream_neighbor_addr(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_addr_mod(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_group_addr(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_funct_addr(dev, tsv);
-
- tmf->vl += tsv->svl;
-
- /* Subtract out MVID and MVL which is
- * include in both vl and MAC_HEADER
- */
-/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4;
- fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
-*/
- tmf->vl = SWAP_BYTES(tmf->vl);
-
- return smctr_trc_send_packet(dev, fcb, MAC_QUEUE);
-}
-
-static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf,
- __u16 correlator)
-{
- MAC_HEADER *tmf;
- MAC_SUB_VECTOR *tsv;
- FCBlock *fcb;
-
- if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
- + S_CORRELATOR + S_PRODUCT_INSTANCE_ID + S_FUNCTIONAL_ADDRESS
- + S_AUTHORIZED_FUNCTION_CLASS + S_AUTHORIZED_ACCESS_PRIORITY))
- == (FCBlock *)(-1L))
- {
- return 0;
- }
-
- tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
- tmf->vc = RPT_ATTCH;
- tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4;
- tmf->vl = 4;
-
- smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_ATTCH);
-
- tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
- smctr_make_corr(dev, tsv, correlator);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_product_id(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_funct_addr(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_auth_funct_class(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_access_pri(dev, tsv);
-
- tmf->vl += tsv->svl;
-
- /* Subtract out MVID and MVL which is
- * include in both vl and MAC_HEADER
- */
-/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4;
- fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
-*/
- tmf->vl = SWAP_BYTES(tmf->vl);
-
- return smctr_trc_send_packet(dev, fcb, MAC_QUEUE);
-}
-
-static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf,
- __u16 correlator)
-{
- MAC_HEADER *tmf;
- MAC_SUB_VECTOR *tsv;
- FCBlock *fcb;
-
- if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
- + S_CORRELATOR + S_RING_STATION_VERSION_NUMBER
- + S_RING_STATION_STATUS + S_STATION_IDENTIFER))
- == (FCBlock *)(-1L))
- {
- return 0;
- }
-
- tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
- tmf->vc = RPT_STATE;
- tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4;
- tmf->vl = 4;
-
- smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_STATE);
-
- tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
- smctr_make_corr(dev, tsv, correlator);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_ring_station_version(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_ring_station_status(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_station_id(dev, tsv);
-
- tmf->vl += tsv->svl;
-
- /* Subtract out MVID and MVL which is
- * include in both vl and MAC_HEADER
- */
-/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4;
- fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
-*/
- tmf->vl = SWAP_BYTES(tmf->vl);
-
- return smctr_trc_send_packet(dev, fcb, MAC_QUEUE);
-}
-
-static int smctr_send_rpt_tx_forward(struct net_device *dev,
- MAC_HEADER *rmf, __u16 tx_fstatus)
-{
- MAC_HEADER *tmf;
- MAC_SUB_VECTOR *tsv;
- FCBlock *fcb;
-
- if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
- + S_TRANSMIT_STATUS_CODE)) == (FCBlock *)(-1L))
- {
- return 0;
- }
-
- tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
- tmf->vc = RPT_TX_FORWARD;
- tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4;
- tmf->vl = 4;
-
- smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RPT_TX_FORWARD);
-
- tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
- smctr_make_tx_status_code(dev, tsv, tx_fstatus);
-
- tmf->vl += tsv->svl;
-
- /* Subtract out MVID and MVL which is
- * include in both vl and MAC_HEADER
- */
-/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4;
- fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
-*/
- tmf->vl = SWAP_BYTES(tmf->vl);
-
- return smctr_trc_send_packet(dev, fcb, MAC_QUEUE);
-}
-
-static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf,
- __u16 rcode, __u16 correlator)
-{
- MAC_HEADER *tmf;
- MAC_SUB_VECTOR *tsv;
- FCBlock *fcb;
-
- if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
- + S_CORRELATOR + S_RESPONSE_CODE)) == (FCBlock *)(-1L))
- {
- return 0;
- }
-
- tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
- tmf->vc = RSP;
- tmf->dc_sc = (rmf->dc_sc & SC_MASK) << 4;
- tmf->vl = 4;
-
- smctr_make_8025_hdr(dev, rmf, tmf, AC_FC_RSP);
-
- tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
- smctr_make_corr(dev, tsv, correlator);
-
- return 0;
-}
-
-static int smctr_send_rq_init(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- MAC_HEADER *tmf;
- MAC_SUB_VECTOR *tsv;
- FCBlock *fcb;
- unsigned int i, count = 0;
- __u16 fstatus;
- int err;
-
- do {
- if(((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER)
- + S_PRODUCT_INSTANCE_ID + S_UPSTREAM_NEIGHBOR_ADDRESS
- + S_RING_STATION_VERSION_NUMBER + S_ADDRESS_MODIFER))
- == (FCBlock *)(-1L)))
- {
- return 0;
- }
-
- tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr;
- tmf->vc = RQ_INIT;
- tmf->dc_sc = DC_RPS | SC_RS;
- tmf->vl = 4;
-
- smctr_make_8025_hdr(dev, NULL, tmf, AC_FC_RQ_INIT);
-
- tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER));
- smctr_make_product_id(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_upstream_neighbor_addr(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_ring_station_version(dev, tsv);
-
- tmf->vl += tsv->svl;
- tsv = (MAC_SUB_VECTOR *)((__u32)tsv + tsv->svl);
- smctr_make_addr_mod(dev, tsv);
-
- tmf->vl += tsv->svl;
-
- /* Subtract out MVID and MVL which is
- * include in both vl and MAC_HEADER
- */
-/* fcb->frame_length = tmf->vl + sizeof(MAC_HEADER) - 4;
- fcb->bdb_ptr->buffer_length = tmf->vl + sizeof(MAC_HEADER) - 4;
-*/
- tmf->vl = SWAP_BYTES(tmf->vl);
-
- if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
- return err;
-
- /* Wait for Transmit to Complete */
- for(i = 0; i < 10000; i++)
- {
- if(fcb->frame_status & FCB_COMMAND_DONE)
- break;
- mdelay(1);
- }
-
- /* Check if GOOD frame Tx'ed */
- fstatus = fcb->frame_status;
-
- if(!(fstatus & FCB_COMMAND_DONE))
- return HARDWARE_FAILED;
-
- if(!(fstatus & FCB_TX_STATUS_E))
- count++;
-
- /* De-allocated Tx FCB and Frame Buffer
- * The FCB must be de-allocated manually if executing with
- * interrupts disabled, other wise the ISR (LM_Service_Events)
- * will de-allocate it when the interrupt occurs.
- */
- tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING;
- smctr_update_tx_chain(dev, fcb, MAC_QUEUE);
- } while(count < 4 && ((fstatus & FCB_TX_AC_BITS) ^ FCB_TX_AC_BITS));
-
- return smctr_join_complete_state(dev);
-}
-
-static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf,
- __u16 *tx_fstatus)
-{
- struct net_local *tp = netdev_priv(dev);
- FCBlock *fcb;
- unsigned int i;
- int err;
-
- /* Check if this is the END POINT of the Transmit Forward Chain. */
- if(rmf->vl <= 18)
- return 0;
-
- /* Allocate Transmit FCB only by requesting 0 bytes
- * of data buffer.
- */
- if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 0)) == (FCBlock *)(-1L))
- return 0;
-
- /* Set pointer to Transmit Frame Buffer to the data
- * portion of the received TX Forward frame, making
- * sure to skip over the Vector Code (vc) and Vector
- * length (vl).
- */
- fcb->bdb_ptr->trc_data_block_ptr = TRC_POINTER((__u32)rmf
- + sizeof(MAC_HEADER) + 2);
- fcb->bdb_ptr->data_block_ptr = (__u16 *)((__u32)rmf
- + sizeof(MAC_HEADER) + 2);
-
- fcb->frame_length = rmf->vl - 4 - 2;
- fcb->bdb_ptr->buffer_length = rmf->vl - 4 - 2;
-
- if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE)))
- return err;
-
- /* Wait for Transmit to Complete */
- for(i = 0; i < 10000; i++)
- {
- if(fcb->frame_status & FCB_COMMAND_DONE)
- break;
- mdelay(1);
- }
-
- /* Check if GOOD frame Tx'ed */
- if(!(fcb->frame_status & FCB_COMMAND_DONE))
- {
- if((err = smctr_issue_resume_tx_fcb_cmd(dev, MAC_QUEUE)))
- return err;
-
- for(i = 0; i < 10000; i++)
- {
- if(fcb->frame_status & FCB_COMMAND_DONE)
- break;
- mdelay(1);
- }
-
- if(!(fcb->frame_status & FCB_COMMAND_DONE))
- return HARDWARE_FAILED;
- }
-
- *tx_fstatus = fcb->frame_status;
-
- return A_FRAME_WAS_FORWARDED;
-}
-
-static int smctr_set_auth_access_pri(struct net_device *dev,
- MAC_SUB_VECTOR *rsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY)
- return E_SUB_VECTOR_LENGTH_ERROR;
-
- tp->authorized_access_priority = (rsv->svv[0] << 8 | rsv->svv[1]);
-
- return POSITIVE_ACK;
-}
-
-static int smctr_set_auth_funct_class(struct net_device *dev,
- MAC_SUB_VECTOR *rsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS)
- return E_SUB_VECTOR_LENGTH_ERROR;
-
- tp->authorized_function_classes = (rsv->svv[0] << 8 | rsv->svv[1]);
-
- return POSITIVE_ACK;
-}
-
-static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv,
- __u16 *correlator)
-{
- if(rsv->svl != S_CORRELATOR)
- return E_SUB_VECTOR_LENGTH_ERROR;
-
- *correlator = (rsv->svv[0] << 8 | rsv->svv[1]);
-
- return POSITIVE_ACK;
-}
-
-static int smctr_set_error_timer_value(struct net_device *dev,
- MAC_SUB_VECTOR *rsv)
-{
- __u16 err_tval;
- int err;
-
- if(rsv->svl != S_ERROR_TIMER_VALUE)
- return E_SUB_VECTOR_LENGTH_ERROR;
-
- err_tval = (rsv->svv[0] << 8 | rsv->svv[1])*10;
-
- smctr_issue_write_word_cmd(dev, RW_TER_THRESHOLD, &err_tval);
-
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- return POSITIVE_ACK;
-}
-
-static int smctr_set_frame_forward(struct net_device *dev,
- MAC_SUB_VECTOR *rsv, __u8 dc_sc)
-{
- if((rsv->svl < 2) || (rsv->svl > S_FRAME_FORWARD))
- return E_SUB_VECTOR_LENGTH_ERROR;
-
- if((dc_sc & DC_MASK) != DC_CRS)
- {
- if(rsv->svl >= 2 && rsv->svl < 20)
- return E_TRANSMIT_FORWARD_INVALID;
-
- if((rsv->svv[0] != 0) || (rsv->svv[1] != 0))
- return E_TRANSMIT_FORWARD_INVALID;
- }
-
- return POSITIVE_ACK;
-}
-
-static int smctr_set_local_ring_num(struct net_device *dev,
- MAC_SUB_VECTOR *rsv)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(rsv->svl != S_LOCAL_RING_NUMBER)
- return E_SUB_VECTOR_LENGTH_ERROR;
-
- if(tp->ptr_local_ring_num)
- *(__u16 *)(tp->ptr_local_ring_num)
- = (rsv->svv[0] << 8 | rsv->svv[1]);
-
- return POSITIVE_ACK;
-}
-
-static unsigned short smctr_set_ctrl_attention(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int ioaddr = dev->base_addr;
-
- if(tp->bic_type == BIC_585_CHIP)
- outb((tp->trc_mask | HWR_CA), ioaddr + HWR);
- else
- {
- outb((tp->trc_mask | CSR_CA), ioaddr + CSR);
- outb(tp->trc_mask, ioaddr + CSR);
- }
-
- return 0;
-}
-
-static void smctr_set_multicast_list(struct net_device *dev)
-{
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_set_multicast_list\n", dev->name);
-}
-
-static int smctr_set_page(struct net_device *dev, __u8 *buf)
-{
- struct net_local *tp = netdev_priv(dev);
- __u8 amask;
- __u32 tptr;
-
- tptr = (__u32)buf - (__u32)tp->ram_access;
- amask = (__u8)((tptr & PR_PAGE_MASK) >> 8);
- outb(amask, dev->base_addr + PR);
-
- return 0;
-}
-
-static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv)
-{
- int err;
-
- if(rsv->svl != S_PHYSICAL_DROP)
- return E_SUB_VECTOR_LENGTH_ERROR;
-
- smctr_issue_write_byte_cmd(dev, RW_PHYSICAL_DROP_NUMBER, &rsv->svv[0]);
- if((err = smctr_wait_cmd(dev)))
- return err;
-
- return POSITIVE_ACK;
-}
-
-/* Reset the ring speed to the opposite of what it was. This auto-pilot
- * mode requires a complete reset and re-init of the adapter.
- */
-static int smctr_set_ring_speed(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- if(tp->media_type == MEDIA_UTP_16)
- tp->media_type = MEDIA_UTP_4;
- else
- tp->media_type = MEDIA_UTP_16;
-
- smctr_enable_16bit(dev);
-
- /* Re-Initialize adapter's internal registers */
- smctr_reset_adapter(dev);
-
- if((err = smctr_init_card_real(dev)))
- return err;
-
- smctr_enable_bic_int(dev);
-
- if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK)))
- return err;
-
- smctr_disable_16bit(dev);
-
- return 0;
-}
-
-static int smctr_set_rx_look_ahead(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- __u16 sword, rword;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_set_rx_look_ahead_flag\n", dev->name);
-
- tp->adapter_flags &= ~(FORCED_16BIT_MODE);
- tp->adapter_flags |= RX_VALID_LOOKAHEAD;
-
- if(tp->adapter_bus == BUS_ISA16_TYPE)
- {
- sword = *((__u16 *)(tp->ram_access));
- *((__u16 *)(tp->ram_access)) = 0x1234;
-
- smctr_disable_16bit(dev);
- rword = *((__u16 *)(tp->ram_access));
- smctr_enable_16bit(dev);
-
- if(rword != 0x1234)
- tp->adapter_flags |= FORCED_16BIT_MODE;
-
- *((__u16 *)(tp->ram_access)) = sword;
- }
-
- return 0;
-}
-
-static int smctr_set_trc_reset(int ioaddr)
-{
- __u8 r;
-
- r = inb(ioaddr + MSR);
- outb(MSR_RST | r, ioaddr + MSR);
-
- return 0;
-}
-
-/*
- * This function can be called if the adapter is busy or not.
- */
-static int smctr_setup_single_cmd(struct net_device *dev,
- __u16 command, __u16 subcommand)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int err;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_setup_single_cmd\n", dev->name);
-
- if((err = smctr_wait_while_cbusy(dev)))
- return err;
-
- if((err = (unsigned int)smctr_wait_cmd(dev)))
- return err;
-
- tp->acb_head->cmd_done_status = 0;
- tp->acb_head->cmd = command;
- tp->acb_head->subcmd = subcommand;
-
- err = smctr_issue_resume_acb_cmd(dev);
-
- return err;
-}
-
-/*
- * This function can not be called with the adapter busy.
- */
-static int smctr_setup_single_cmd_w_data(struct net_device *dev,
- __u16 command, __u16 subcommand)
-{
- struct net_local *tp = netdev_priv(dev);
-
- tp->acb_head->cmd_done_status = ACB_COMMAND_NOT_DONE;
- tp->acb_head->cmd = command;
- tp->acb_head->subcmd = subcommand;
- tp->acb_head->data_offset_lo
- = (__u16)TRC_POINTER(tp->misc_command_data);
-
- return smctr_issue_resume_acb_cmd(dev);
-}
-
-static char *smctr_malloc(struct net_device *dev, __u16 size)
-{
- struct net_local *tp = netdev_priv(dev);
- char *m;
-
- m = (char *)(tp->ram_access + tp->sh_mem_used);
- tp->sh_mem_used += (__u32)size;
-
- return m;
-}
-
-static int smctr_status_chg(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_status_chg\n", dev->name);
-
- switch(tp->status)
- {
- case OPEN:
- break;
-
- case CLOSED:
- break;
-
- /* Interrupt driven open() completion. XXX */
- case INITIALIZED:
- tp->group_address_0 = 0;
- tp->group_address[0] = 0;
- tp->group_address[1] = 0;
- tp->functional_address_0 = 0;
- tp->functional_address[0] = 0;
- tp->functional_address[1] = 0;
- smctr_open_tr(dev);
- break;
-
- default:
- printk(KERN_INFO "%s: status change unknown %x\n",
- dev->name, tp->status);
- break;
- }
-
- return 0;
-}
-
-static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb,
- __u16 queue)
-{
- struct net_local *tp = netdev_priv(dev);
- int err = 0;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_trc_send_packet\n", dev->name);
-
- fcb->info = FCB_CHAIN_END | FCB_ENABLE_TFS;
- if(tp->num_tx_fcbs[queue] != 1)
- fcb->back_ptr->info = FCB_INTERRUPT_ENABLE | FCB_ENABLE_TFS;
-
- if(tp->tx_queue_status[queue] == NOT_TRANSMITING)
- {
- tp->tx_queue_status[queue] = TRANSMITING;
- err = smctr_issue_resume_tx_fcb_cmd(dev, queue);
- }
-
- return err;
-}
-
-static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue)
-{
- struct net_local *tp = netdev_priv(dev);
- __u16 status, err = 0;
- int cstatus;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_tx_complete\n", dev->name);
-
- while((status = tp->tx_fcb_end[queue]->frame_status) != SUCCESS)
- {
- if(status & 0x7e00 )
- {
- err = HARDWARE_FAILED;
- break;
- }
-
- if((err = smctr_update_tx_chain(dev, tp->tx_fcb_end[queue],
- queue)) != SUCCESS)
- break;
-
- smctr_disable_16bit(dev);
-
- if(tp->mode_bits & UMAC)
- {
- if(!(status & (FCB_TX_STATUS_AR1 | FCB_TX_STATUS_AR2)))
- cstatus = NO_SUCH_DESTINATION;
- else
- {
- if(!(status & (FCB_TX_STATUS_CR1 | FCB_TX_STATUS_CR2)))
- cstatus = DEST_OUT_OF_RESOURCES;
- else
- {
- if(status & FCB_TX_STATUS_E)
- cstatus = MAX_COLLISIONS;
- else
- cstatus = SUCCESS;
- }
- }
- }
- else
- cstatus = SUCCESS;
-
- if(queue == BUG_QUEUE)
- err = SUCCESS;
-
- smctr_enable_16bit(dev);
- if(err != SUCCESS)
- break;
- }
-
- return err;
-}
-
-static unsigned short smctr_tx_move_frame(struct net_device *dev,
- struct sk_buff *skb, __u8 *pbuff, unsigned int bytes)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int ram_usable;
- __u32 flen, len, offset = 0;
- __u8 *frag, *page;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_tx_move_frame\n", dev->name);
-
- ram_usable = ((unsigned int)tp->ram_usable) << 10;
- frag = skb->data;
- flen = skb->len;
-
- while(flen > 0 && bytes > 0)
- {
- smctr_set_page(dev, pbuff);
-
- offset = SMC_PAGE_OFFSET(pbuff);
-
- if(offset + flen > ram_usable)
- len = ram_usable - offset;
- else
- len = flen;
-
- if(len > bytes)
- len = bytes;
-
- page = (char *) (offset + tp->ram_access);
- memcpy(page, frag, len);
-
- flen -=len;
- bytes -= len;
- frag += len;
- pbuff += len;
- }
-
- return 0;
-}
-
-/* Update the error statistic counters for this adapter. */
-static int smctr_update_err_stats(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- struct tr_statistics *tstat = &tp->MacStat;
-
- if(tstat->internal_errors)
- tstat->internal_errors
- += *(tp->misc_command_data + 0) & 0x00ff;
-
- if(tstat->line_errors)
- tstat->line_errors += *(tp->misc_command_data + 0) >> 8;
-
- if(tstat->A_C_errors)
- tstat->A_C_errors += *(tp->misc_command_data + 1) & 0x00ff;
-
- if(tstat->burst_errors)
- tstat->burst_errors += *(tp->misc_command_data + 1) >> 8;
-
- if(tstat->abort_delimiters)
- tstat->abort_delimiters += *(tp->misc_command_data + 2) >> 8;
-
- if(tstat->recv_congest_count)
- tstat->recv_congest_count
- += *(tp->misc_command_data + 3) & 0x00ff;
-
- if(tstat->lost_frames)
- tstat->lost_frames
- += *(tp->misc_command_data + 3) >> 8;
-
- if(tstat->frequency_errors)
- tstat->frequency_errors += *(tp->misc_command_data + 4) & 0x00ff;
-
- if(tstat->frame_copied_errors)
- tstat->frame_copied_errors
- += *(tp->misc_command_data + 4) >> 8;
-
- if(tstat->token_errors)
- tstat->token_errors += *(tp->misc_command_data + 5) >> 8;
-
- return 0;
-}
-
-static int smctr_update_rx_chain(struct net_device *dev, __u16 queue)
-{
- struct net_local *tp = netdev_priv(dev);
- FCBlock *fcb;
- BDBlock *bdb;
- __u16 size, len;
-
- fcb = tp->rx_fcb_curr[queue];
- len = fcb->frame_length;
-
- fcb->frame_status = 0;
- fcb->info = FCB_CHAIN_END;
- fcb->back_ptr->info = FCB_WARNING;
-
- tp->rx_fcb_curr[queue] = tp->rx_fcb_curr[queue]->next_ptr;
-
- /* update RX BDBs */
- size = (len >> RX_BDB_SIZE_SHIFT);
- if(len & RX_DATA_BUFFER_SIZE_MASK)
- size += sizeof(BDBlock);
- size &= (~RX_BDB_SIZE_MASK);
-
- /* check if wrap around */
- bdb = (BDBlock *)((__u32)(tp->rx_bdb_curr[queue]) + (__u32)(size));
- if((__u32)bdb >= (__u32)tp->rx_bdb_end[queue])
- {
- bdb = (BDBlock *)((__u32)(tp->rx_bdb_head[queue])
- + (__u32)(bdb) - (__u32)(tp->rx_bdb_end[queue]));
- }
-
- bdb->back_ptr->info = BDB_CHAIN_END;
- tp->rx_bdb_curr[queue]->back_ptr->info = BDB_NOT_CHAIN_END;
- tp->rx_bdb_curr[queue] = bdb;
-
- return 0;
-}
-
-static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb,
- __u16 queue)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(smctr_debug > 20)
- printk(KERN_DEBUG "smctr_update_tx_chain\n");
-
- if(tp->num_tx_fcbs_used[queue] <= 0)
- return HARDWARE_FAILED;
- else
- {
- if(tp->tx_buff_used[queue] < fcb->memory_alloc)
- {
- tp->tx_buff_used[queue] = 0;
- return HARDWARE_FAILED;
- }
-
- tp->tx_buff_used[queue] -= fcb->memory_alloc;
-
- /* if all transmit buffer are cleared
- * need to set the tx_buff_curr[] to tx_buff_head[]
- * otherwise, tx buffer will be segregate and cannot
- * accommodate and buffer greater than (curr - head) and
- * (end - curr) since we do not allow wrap around allocation.
- */
- if(tp->tx_buff_used[queue] == 0)
- tp->tx_buff_curr[queue] = tp->tx_buff_head[queue];
-
- tp->num_tx_fcbs_used[queue]--;
- fcb->frame_status = 0;
- tp->tx_fcb_end[queue] = fcb->next_ptr;
- netif_wake_queue(dev);
- return 0;
- }
-}
-
-static int smctr_wait_cmd(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int loop_count = 0x20000;
-
- if(smctr_debug > 10)
- printk(KERN_DEBUG "%s: smctr_wait_cmd\n", dev->name);
-
- while(loop_count)
- {
- if(tp->acb_head->cmd_done_status & ACB_COMMAND_DONE)
- break;
- udelay(1);
- loop_count--;
- }
-
- if(loop_count == 0)
- return HARDWARE_FAILED;
-
- if(tp->acb_head->cmd_done_status & 0xff)
- return HARDWARE_FAILED;
-
- return 0;
-}
-
-static int smctr_wait_while_cbusy(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int timeout = 0x20000;
- int ioaddr = dev->base_addr;
- __u8 r;
-
- if(tp->bic_type == BIC_585_CHIP)
- {
- while(timeout)
- {
- r = inb(ioaddr + HWR);
- if((r & HWR_CBUSY) == 0)
- break;
- timeout--;
- }
- }
- else
- {
- while(timeout)
- {
- r = inb(ioaddr + CSR);
- if((r & CSR_CBUSY) == 0)
- break;
- timeout--;
- }
- }
-
- if(timeout)
- return 0;
- else
- return HARDWARE_FAILED;
-}
-
-#ifdef MODULE
-
-static struct net_device* dev_smctr[SMCTR_MAX_ADAPTERS];
-static int io[SMCTR_MAX_ADAPTERS];
-static int irq[SMCTR_MAX_ADAPTERS];
-
-MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("tr_smctr.bin");
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param(ringspeed, int, 0);
-
-static struct net_device * __init setup_card(int n)
-{
- struct net_device *dev = alloc_trdev(sizeof(struct net_local));
- int err;
-
- if (!dev)
- return ERR_PTR(-ENOMEM);
-
- dev->irq = irq[n];
- err = smctr_probe1(dev, io[n]);
- if (err)
- goto out;
-
- err = register_netdev(dev);
- if (err)
- goto out1;
- return dev;
- out1:
-#ifdef CONFIG_MCA_LEGACY
- { struct net_local *tp = netdev_priv(dev);
- if (tp->slot_num)
- mca_mark_as_unused(tp->slot_num);
- }
-#endif
- release_region(dev->base_addr, SMCTR_IO_EXTENT);
- free_irq(dev->irq, dev);
-out:
- free_netdev(dev);
- return ERR_PTR(err);
-}
-
-int __init init_module(void)
-{
- int i, found = 0;
- struct net_device *dev;
-
- for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) {
- dev = io[0]? setup_card(i) : smctr_probe(-1);
- if (!IS_ERR(dev)) {
- ++found;
- dev_smctr[i] = dev;
- }
- }
-
- return found ? 0 : -ENODEV;
-}
-
-void __exit cleanup_module(void)
-{
- int i;
-
- for(i = 0; i < SMCTR_MAX_ADAPTERS; i++) {
- struct net_device *dev = dev_smctr[i];
-
- if (dev) {
-
- unregister_netdev(dev);
-#ifdef CONFIG_MCA_LEGACY
- { struct net_local *tp = netdev_priv(dev);
- if (tp->slot_num)
- mca_mark_as_unused(tp->slot_num);
- }
-#endif
- release_region(dev->base_addr, SMCTR_IO_EXTENT);
- if (dev->irq)
- free_irq(dev->irq, dev);
-
- free_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h
deleted file mode 100644
index 6e5700ab4fc3..000000000000
--- a/drivers/net/tokenring/smctr.h
+++ /dev/null
@@ -1,1585 +0,0 @@
-/* smctr.h: SMC Token Ring driver header for Linux
- *
- * Authors:
- * - Jay Schulist <jschlst@samba.org>
- */
-
-#ifndef __LINUX_SMCTR_H
-#define __LINUX_SMCTR_H
-
-#ifdef __KERNEL__
-
-#define MAX_TX_QUEUE 10
-
-#define SMC_HEADER_SIZE 14
-
-#define SMC_PAGE_OFFSET(X) (((unsigned long)(X) - tp->ram_access) & tp->page_offset_mask)
-
-#define INIT 0x0D
-#define RQ_ATTCH 0x10
-#define RQ_STATE 0x0F
-#define RQ_ADDR 0x0E
-#define CHG_PARM 0x0C
-#define RSP 0x00
-#define TX_FORWARD 0x09
-
-#define AC_FC_DAT ((3<<13) | 1)
-#define DAT 0x07
-
-#define RPT_NEW_MON 0x25
-#define RPT_SUA_CHG 0x26
-#define RPT_ACTIVE_ERR 0x28
-#define RPT_NN_INCMP 0x27
-#define RPT_ERROR 0x29
-
-#define RQ_INIT 0x20
-#define RPT_ATTCH 0x24
-#define RPT_STATE 0x23
-#define RPT_ADDR 0x22
-
-#define POSITIVE_ACK 0x0001
-#define A_FRAME_WAS_FORWARDED 0x8888
-
-#define GROUP_ADDRESS 0x2B
-#define PHYSICAL_DROP 0x0B
-#define AUTHORIZED_ACCESS_PRIORITY 0x07
-#define AUTHORIZED_FUNCTION_CLASS 0x06
-#define FUNCTIONAL_ADDRESS 0x2C
-#define RING_STATION_STATUS 0x29
-#define TRANSMIT_STATUS_CODE 0x2A
-#define IBM_PASS_SOURCE_ADDR 0x01
-#define AC_FC_RPT_TX_FORWARD ((0<<13) | 0)
-#define AC_FC_RPT_STATE ((0<<13) | 0)
-#define AC_FC_RPT_ADDR ((0<<13) | 0)
-#define CORRELATOR 0x09
-
-#define POSITIVE_ACK 0x0001 /* */
-#define E_MAC_DATA_INCOMPLETE 0x8001 /* not used */
-#define E_VECTOR_LENGTH_ERROR 0x8002 /* */
-#define E_UNRECOGNIZED_VECTOR_ID 0x8003 /* */
-#define E_INAPPROPRIATE_SOURCE_CLASS 0x8004 /* */
-#define E_SUB_VECTOR_LENGTH_ERROR 0x8005 /* */
-#define E_TRANSMIT_FORWARD_INVALID 0x8006 /* def. by IBM */
-#define E_MISSING_SUB_VECTOR 0x8007 /* */
-#define E_SUB_VECTOR_UNKNOWN 0x8008 /* */
-#define E_MAC_HEADER_TOO_LONG 0x8009 /* */
-#define E_FUNCTION_DISABLED 0x800A /* not used */
-
-#define A_FRAME_WAS_FORWARDED 0x8888 /* used by send_TX_FORWARD */
-
-#define UPSTREAM_NEIGHBOR_ADDRESS 0x02
-#define LOCAL_RING_NUMBER 0x03
-#define ASSIGN_PHYSICAL_DROP 0x04
-#define ERROR_TIMER_VALUE 0x05
-#define AUTHORIZED_FUNCTION_CLASS 0x06
-#define AUTHORIZED_ACCESS_PRIORITY 0x07
-#define CORRELATOR 0x09
-#define PHYSICAL_DROP 0x0B
-#define RESPONSE_CODE 0x20
-#define ADDRESS_MODIFER 0x21
-#define PRODUCT_INSTANCE_ID 0x22
-#define RING_STATION_VERSION_NUMBER 0x23
-#define WRAP_DATA 0x26
-#define FRAME_FORWARD 0x27
-#define STATION_IDENTIFER 0x28
-#define RING_STATION_STATUS 0x29
-#define TRANSMIT_STATUS_CODE 0x2A
-#define GROUP_ADDRESS 0x2B
-#define FUNCTIONAL_ADDRESS 0x2C
-
-#define F_NO_SUB_VECTORS_FOUND 0x0000
-#define F_UPSTREAM_NEIGHBOR_ADDRESS 0x0001
-#define F_LOCAL_RING_NUMBER 0x0002
-#define F_ASSIGN_PHYSICAL_DROP 0x0004
-#define F_ERROR_TIMER_VALUE 0x0008
-#define F_AUTHORIZED_FUNCTION_CLASS 0x0010
-#define F_AUTHORIZED_ACCESS_PRIORITY 0x0020
-#define F_CORRELATOR 0x0040
-#define F_PHYSICAL_DROP 0x0080
-#define F_RESPONSE_CODE 0x0100
-#define F_PRODUCT_INSTANCE_ID 0x0200
-#define F_RING_STATION_VERSION_NUMBER 0x0400
-#define F_STATION_IDENTIFER 0x0800
-#define F_RING_STATION_STATUS 0x1000
-#define F_GROUP_ADDRESS 0x2000
-#define F_FUNCTIONAL_ADDRESS 0x4000
-#define F_FRAME_FORWARD 0x8000
-
-#define R_INIT 0x00
-#define R_RQ_ATTCH_STATE_ADDR 0x00
-#define R_CHG_PARM 0x00
-#define R_TX_FORWARD F_FRAME_FORWARD
-
-
-#define UPSTREAM_NEIGHBOR_ADDRESS 0x02
-#define ADDRESS_MODIFER 0x21
-#define RING_STATION_VERSION_NUMBER 0x23
-#define PRODUCT_INSTANCE_ID 0x22
-
-#define RPT_TX_FORWARD 0x2A
-
-#define AC_FC_INIT (3<<13) | 0 /* */
-#define AC_FC_RQ_INIT ((3<<13) | 0) /* */
-#define AC_FC_RQ_ATTCH (3<<13) | 0 /* DC = SC of rx frame */
-#define AC_FC_RQ_STATE (3<<13) | 0 /* DC = SC of rx frame */
-#define AC_FC_RQ_ADDR (3<<13) | 0 /* DC = SC of rx frame */
-#define AC_FC_CHG_PARM (3<<13) | 0 /* */
-#define AC_FC_RSP (0<<13) | 0 /* DC = SC of rx frame */
-#define AC_FC_RPT_ATTCH (0<<13) | 0
-
-#define S_UPSTREAM_NEIGHBOR_ADDRESS 6 + 2
-#define S_LOCAL_RING_NUMBER 2 + 2
-#define S_ASSIGN_PHYSICAL_DROP 4 + 2
-#define S_ERROR_TIMER_VALUE 2 + 2
-#define S_AUTHORIZED_FUNCTION_CLASS 2 + 2
-#define S_AUTHORIZED_ACCESS_PRIORITY 2 + 2
-#define S_CORRELATOR 2 + 2
-#define S_PHYSICAL_DROP 4 + 2
-#define S_RESPONSE_CODE 4 + 2
-#define S_ADDRESS_MODIFER 2 + 2
-#define S_PRODUCT_INSTANCE_ID 18 + 2
-#define S_RING_STATION_VERSION_NUMBER 10 + 2
-#define S_STATION_IDENTIFER 6 + 2
-#define S_RING_STATION_STATUS 6 + 2
-#define S_GROUP_ADDRESS 4 + 2
-#define S_FUNCTIONAL_ADDRESS 4 + 2
-#define S_FRAME_FORWARD 252 + 2
-#define S_TRANSMIT_STATUS_CODE 2 + 2
-
-#define ISB_IMC_RES0 0x0000 /* */
-#define ISB_IMC_MAC_TYPE_3 0x0001 /* MAC_ARC_INDICATE */
-#define ISB_IMC_MAC_ERROR_COUNTERS 0x0002 /* */
-#define ISB_IMC_RES1 0x0003 /* */
-#define ISB_IMC_MAC_TYPE_2 0x0004 /* QUE_MAC_INDICATE */
-#define ISB_IMC_TX_FRAME 0x0005 /* */
-#define ISB_IMC_END_OF_TX_QUEUE 0x0006 /* */
-#define ISB_IMC_NON_MAC_RX_RESOURCE 0x0007 /* */
-#define ISB_IMC_MAC_RX_RESOURCE 0x0008 /* */
-#define ISB_IMC_NON_MAC_RX_FRAME 0x0009 /* */
-#define ISB_IMC_MAC_RX_FRAME 0x000A /* */
-#define ISB_IMC_TRC_FIFO_STATUS 0x000B /* */
-#define ISB_IMC_COMMAND_STATUS 0x000C /* */
-#define ISB_IMC_MAC_TYPE_1 0x000D /* Self Removed */
-#define ISB_IMC_TRC_INTRNL_TST_STATUS 0x000E /* */
-#define ISB_IMC_RES2 0x000F /* */
-
-#define NON_MAC_RX_RESOURCE_BW 0x10 /* shifted right 8 bits */
-#define NON_MAC_RX_RESOURCE_FW 0x20 /* shifted right 8 bits */
-#define NON_MAC_RX_RESOURCE_BE 0x40 /* shifted right 8 bits */
-#define NON_MAC_RX_RESOURCE_FE 0x80 /* shifted right 8 bits */
-#define RAW_NON_MAC_RX_RESOURCE_BW 0x1000 /* */
-#define RAW_NON_MAC_RX_RESOURCE_FW 0x2000 /* */
-#define RAW_NON_MAC_RX_RESOURCE_BE 0x4000 /* */
-#define RAW_NON_MAC_RX_RESOURCE_FE 0x8000 /* */
-
-#define MAC_RX_RESOURCE_BW 0x10 /* shifted right 8 bits */
-#define MAC_RX_RESOURCE_FW 0x20 /* shifted right 8 bits */
-#define MAC_RX_RESOURCE_BE 0x40 /* shifted right 8 bits */
-#define MAC_RX_RESOURCE_FE 0x80 /* shifted right 8 bits */
-#define RAW_MAC_RX_RESOURCE_BW 0x1000 /* */
-#define RAW_MAC_RX_RESOURCE_FW 0x2000 /* */
-#define RAW_MAC_RX_RESOURCE_BE 0x4000 /* */
-#define RAW_MAC_RX_RESOURCE_FE 0x8000 /* */
-
-#define TRC_FIFO_STATUS_TX_UNDERRUN 0x40 /* shifted right 8 bits */
-#define TRC_FIFO_STATUS_RX_OVERRUN 0x80 /* shifted right 8 bits */
-#define RAW_TRC_FIFO_STATUS_TX_UNDERRUN 0x4000 /* */
-#define RAW_TRC_FIFO_STATUS_RX_OVERRUN 0x8000 /* */
-
-#define CSR_CLRTINT 0x08
-
-#define MSB(X) ((__u8)((__u16) X >> 8))
-#define LSB(X) ((__u8)((__u16) X & 0xff))
-
-#define AC_FC_LOBE_MEDIA_TEST ((3<<13) | 0)
-#define S_WRAP_DATA 248 + 2 /* 500 + 2 */
-#define WRAP_DATA 0x26
-#define LOBE_MEDIA_TEST 0x08
-
-/* Destination Class (dc) */
-
-#define DC_MASK 0xF0
-#define DC_RS 0x00
-#define DC_CRS 0x40
-#define DC_RPS 0x50
-#define DC_REM 0x60
-
-/* Source Classes (sc) */
-
-#define SC_MASK 0x0F
-#define SC_RS 0x00
-#define SC_CRS 0x04
-#define SC_RPS 0x05
-#define SC_REM 0x06
-
-#define PR 0x11
-#define PR_PAGE_MASK 0x0C000
-
-#define MICROCHANNEL 0x0008
-#define INTERFACE_CHIP 0x0010
-#define BOARD_16BIT 0x0040
-#define PAGED_RAM 0x0080
-#define WD8115TA (TOKEN_MEDIA | MICROCHANNEL | INTERFACE_CHIP | PAGED_RAM)
-#define WD8115T (TOKEN_MEDIA | INTERFACE_CHIP | BOARD_16BIT | PAGED_RAM)
-
-#define BRD_ID_8316 0x50
-
-#define r587_SER 0x001
-#define SER_DIN 0x80
-#define SER_DOUT 0x40
-#define SER_CLK 0x20
-#define SER_ECS 0x10
-#define SER_E806 0x08
-#define SER_PNP 0x04
-#define SER_BIO 0x02
-#define SER_16B 0x01
-
-#define r587_IDR 0x004
-#define IDR_IRQ_MASK 0x0F0
-#define IDR_DCS_MASK 0x007
-#define IDR_RWS 0x008
-
-
-#define r587_BIO 0x003
-#define BIO_ENB 0x080
-#define BIO_MASK 0x03F
-
-#define r587_PCR 0x005
-#define PCR_RAMS 0x040
-
-
-
-#define NUM_ADDR_BITS 8
-
-#define ISA_MAX_ADDRESS 0x00ffffff
-
-#define SMCTR_MAX_ADAPTERS 7
-
-#define MC_TABLE_ENTRIES 16
-
-#define MAXFRAGMENTS 32
-
-#define CHIP_REV_MASK 0x3000
-
-#define MAX_TX_QS 8
-#define NUM_TX_QS_USED 3
-
-#define MAX_RX_QS 2
-#define NUM_RX_QS_USED 2
-
-#define INTEL_DATA_FORMAT 0x4000
-#define INTEL_ADDRESS_POINTER_FORMAT 0x8000
-#define PAGE_POINTER(X) ((((unsigned long)(X) - tp->ram_access) & tp->page_offset_mask) + tp->ram_access)
-#define SWAP_WORDS(X) (((X & 0xFFFF) << 16) | (X >> 16))
-
-#define INTERFACE_CHIP 0x0010 /* Soft Config Adapter */
-#define ADVANCED_FEATURES 0x0020 /* Adv. netw. interface features */
-#define BOARD_16BIT 0x0040 /* 16 bit capability */
-#define PAGED_RAM 0x0080 /* Adapter has paged RAM */
-
-#define PAGED_ROM 0x0100 /* Adapter has paged ROM */
-
-#define RAM_SIZE_UNKNOWN 0x0000 /* Unknown RAM size */
-#define RAM_SIZE_0K 0x0001 /* 0K RAM */
-#define RAM_SIZE_8K 0x0002 /* 8k RAM */
-#define RAM_SIZE_16K 0x0003 /* 16k RAM */
-#define RAM_SIZE_32K 0x0004 /* 32k RAM */
-#define RAM_SIZE_64K 0x0005 /* 64k RAM */
-#define RAM_SIZE_RESERVED_6 0x0006 /* Reserved RAM size */
-#define RAM_SIZE_RESERVED_7 0x0007 /* Reserved RAM size */
-#define RAM_SIZE_MASK 0x0007 /* Isolates RAM Size */
-
-#define TOKEN_MEDIA 0x0005
-
-#define BID_REG_0 0x00
-#define BID_REG_1 0x01
-#define BID_REG_2 0x02
-#define BID_REG_3 0x03
-#define BID_REG_4 0x04
-#define BID_REG_5 0x05
-#define BID_REG_6 0x06
-#define BID_REG_7 0x07
-#define BID_LAR_0 0x08
-#define BID_LAR_1 0x09
-#define BID_LAR_2 0x0A
-#define BID_LAR_3 0x0B
-#define BID_LAR_4 0x0C
-#define BID_LAR_5 0x0D
-
-#define BID_BOARD_ID_BYTE 0x0E
-#define BID_CHCKSM_BYTE 0x0F
-#define BID_LAR_OFFSET 0x08
-
-#define BID_MSZ_583_BIT 0x08
-#define BID_SIXTEEN_BIT_BIT 0x01
-
-#define BID_BOARD_REV_MASK 0x1E
-
-#define BID_MEDIA_TYPE_BIT 0x01
-#define BID_SOFT_CONFIG_BIT 0x20
-#define BID_RAM_SIZE_BIT 0x40
-#define BID_BUS_TYPE_BIT 0x80
-
-#define BID_CR 0x10
-
-#define BID_TXP 0x04 /* Transmit Packet Command */
-
-#define BID_TCR_DIFF 0x0D /* Transmit Configuration Register */
-
-#define BID_TCR_VAL 0x18 /* Value to Test 8390 or 690 */
-#define BID_PS0 0x00 /* Register Page Select 0 */
-#define BID_PS1 0x40 /* Register Page Select 1 */
-#define BID_PS2 0x80 /* Register Page Select 2 */
-#define BID_PS_MASK 0x3F /* For Masking Off Page Select Bits */
-
-#define BID_EEPROM_0 0x08
-#define BID_EEPROM_1 0x09
-#define BID_EEPROM_2 0x0A
-#define BID_EEPROM_3 0x0B
-#define BID_EEPROM_4 0x0C
-#define BID_EEPROM_5 0x0D
-#define BID_EEPROM_6 0x0E
-#define BID_EEPROM_7 0x0F
-
-#define BID_OTHER_BIT 0x02
-#define BID_ICR_MASK 0x0C
-#define BID_EAR_MASK 0x0F
-#define BID_ENGR_PAGE 0x0A0
-#define BID_RLA 0x10
-#define BID_EA6 0x80
-#define BID_RECALL_DONE_MASK 0x10
-#define BID_BID_EEPROM_OVERRIDE 0xFFB0
-#define BID_EXTRA_EEPROM_OVERRIDE 0xFFD0
-#define BID_EEPROM_MEDIA_MASK 0x07
-#define BID_STARLAN_TYPE 0x00
-#define BID_ETHERNET_TYPE 0x01
-#define BID_TP_TYPE 0x02
-#define BID_EW_TYPE 0x03
-#define BID_TOKEN_RING_TYPE 0x04
-#define BID_UTP2_TYPE 0x05
-#define BID_EEPROM_IRQ_MASK 0x18
-#define BID_PRIMARY_IRQ 0x00
-#define BID_ALTERNATE_IRQ_1 0x08
-#define BID_ALTERNATE_IRQ_2 0x10
-#define BID_ALTERNATE_IRQ_3 0x18
-#define BID_EEPROM_RAM_SIZE_MASK 0xE0
-#define BID_EEPROM_RAM_SIZE_RES1 0x00
-#define BID_EEPROM_RAM_SIZE_RES2 0x20
-#define BID_EEPROM_RAM_SIZE_8K 0x40
-#define BID_EEPROM_RAM_SIZE_16K 0x60
-#define BID_EEPROM_RAM_SIZE_32K 0x80
-#define BID_EEPROM_RAM_SIZE_64K 0xA0
-#define BID_EEPROM_RAM_SIZE_RES3 0xC0
-#define BID_EEPROM_RAM_SIZE_RES4 0xE0
-#define BID_EEPROM_BUS_TYPE_MASK 0x07
-#define BID_EEPROM_BUS_TYPE_AT 0x00
-#define BID_EEPROM_BUS_TYPE_MCA 0x01
-#define BID_EEPROM_BUS_TYPE_EISA 0x02
-#define BID_EEPROM_BUS_TYPE_NEC 0x03
-#define BID_EEPROM_BUS_SIZE_MASK 0x18
-#define BID_EEPROM_BUS_SIZE_8BIT 0x00
-#define BID_EEPROM_BUS_SIZE_16BIT 0x08
-#define BID_EEPROM_BUS_SIZE_32BIT 0x10
-#define BID_EEPROM_BUS_SIZE_64BIT 0x18
-#define BID_EEPROM_BUS_MASTER 0x20
-#define BID_EEPROM_RAM_PAGING 0x40
-#define BID_EEPROM_ROM_PAGING 0x80
-#define BID_EEPROM_PAGING_MASK 0xC0
-#define BID_EEPROM_LOW_COST 0x08
-#define BID_EEPROM_IO_MAPPED 0x10
-#define BID_EEPROM_HMI 0x01
-#define BID_EEPROM_AUTO_MEDIA_DETECT 0x01
-#define BID_EEPROM_CHIP_REV_MASK 0x0C
-
-#define BID_EEPROM_LAN_ADDR 0x30
-
-#define BID_EEPROM_MEDIA_OPTION 0x54
-#define BID_EEPROM_MEDIA_UTP 0x01
-#define BID_EEPROM_4MB_RING 0x08
-#define BID_EEPROM_16MB_RING 0x10
-#define BID_EEPROM_MEDIA_STP 0x40
-
-#define BID_EEPROM_MISC_DATA 0x56
-#define BID_EEPROM_EARLY_TOKEN_RELEASE 0x02
-
-#define CNFG_ID_8003E 0x6fc0
-#define CNFG_ID_8003S 0x6fc1
-#define CNFG_ID_8003W 0x6fc2
-#define CNFG_ID_8115TRA 0x6ec6
-#define CNFG_ID_8013E 0x61C8
-#define CNFG_ID_8013W 0x61C9
-#define CNFG_ID_BISTRO03E 0xEFE5
-#define CNFG_ID_BISTRO13E 0xEFD5
-#define CNFG_ID_BISTRO13W 0xEFD4
-#define CNFG_MSR_583 0x0
-#define CNFG_ICR_583 0x1
-#define CNFG_IAR_583 0x2
-#define CNFG_BIO_583 0x3
-#define CNFG_EAR_583 0x3
-#define CNFG_IRR_583 0x4
-#define CNFG_LAAR_584 0x5
-#define CNFG_GP2 0x7
-#define CNFG_LAAR_MASK 0x1F
-#define CNFG_LAAR_ZWS 0x20
-#define CNFG_LAAR_L16E 0x40
-#define CNFG_ICR_IR2_584 0x04
-#define CNFG_ICR_MASK 0x08
-#define CNFG_ICR_MSZ 0x08
-#define CNFG_ICR_RLA 0x10
-#define CNFG_ICR_STO 0x80
-#define CNFG_IRR_IRQS 0x60
-#define CNFG_IRR_IEN 0x80
-#define CNFG_IRR_ZWS 0x01
-#define CNFG_GP2_BOOT_NIBBLE 0x0F
-#define CNFG_IRR_OUT2 0x04
-#define CNFG_IRR_OUT1 0x02
-
-#define CNFG_SIZE_8KB 8
-#define CNFG_SIZE_16KB 16
-#define CNFG_SIZE_32KB 32
-#define CNFG_SIZE_64KB 64
-#define CNFG_SIZE_128KB 128
-#define CNFG_SIZE_256KB 256
-#define ROM_DISABLE 0x0
-
-#define CNFG_SLOT_ENABLE_BIT 0x08
-
-#define CNFG_POS_CONTROL_REG 0x096
-#define CNFG_POS_REG0 0x100
-#define CNFG_POS_REG1 0x101
-#define CNFG_POS_REG2 0x102
-#define CNFG_POS_REG3 0x103
-#define CNFG_POS_REG4 0x104
-#define CNFG_POS_REG5 0x105
-
-#define CNFG_ADAPTER_TYPE_MASK 0x0e
-
-#define SLOT_16BIT 0x0008
-#define INTERFACE_5X3_CHIP 0x0000 /* 0000 = 583 or 593 chips */
-#define NIC_690_BIT 0x0010 /* NIC is 690 */
-#define ALTERNATE_IRQ_BIT 0x0020 /* Alternate IRQ is used */
-#define INTERFACE_584_CHIP 0x0040 /* 0001 = 584 chip */
-#define INTERFACE_594_CHIP 0x0080 /* 0010 = 594 chip */
-#define INTERFACE_585_CHIP 0x0100 /* 0100 = 585/790 chip */
-#define INTERFACE_CHIP_MASK 0x03C0 /* Isolates Intfc Chip Type */
-
-#define BOARD_16BIT 0x0040
-#define NODE_ADDR_CKSUM 0xEE
-#define BRD_ID_8115T 0x04
-
-#define NIC_825_BIT 0x0400 /* TRC 83C825 NIC */
-#define NIC_790_BIT 0x0800 /* NIC is 83C790 Ethernet */
-
-#define CHIP_REV_MASK 0x3000
-
-#define HWR_CBUSY 0x02
-#define HWR_CA 0x01
-
-#define MAC_QUEUE 0
-#define NON_MAC_QUEUE 1
-#define BUG_QUEUE 2 /* NO RECEIVE QUEUE, ONLY TX */
-
-#define NUM_MAC_TX_FCBS 8
-#define NUM_MAC_TX_BDBS NUM_MAC_TX_FCBS
-#define NUM_MAC_RX_FCBS 7
-#define NUM_MAC_RX_BDBS 8
-
-#define NUM_NON_MAC_TX_FCBS 6
-#define NUM_NON_MAC_TX_BDBS NUM_NON_MAC_TX_FCBS
-
-#define NUM_NON_MAC_RX_BDBS 0 /* CALCULATED DYNAMICALLY */
-
-#define NUM_BUG_TX_FCBS 8
-#define NUM_BUG_TX_BDBS NUM_BUG_TX_FCBS
-
-#define MAC_TX_BUFFER_MEMORY 1024
-#define NON_MAC_TX_BUFFER_MEMORY (20 * 1024)
-#define BUG_TX_BUFFER_MEMORY (NUM_BUG_TX_FCBS * 32)
-
-#define RX_BUFFER_MEMORY 0 /* CALCULATED DYNAMICALLY */
-#define RX_DATA_BUFFER_SIZE 256
-#define RX_BDB_SIZE_SHIFT 3 /* log2(RX_DATA_BUFFER_SIZE)-log2(sizeof(BDBlock)) */
-#define RX_BDB_SIZE_MASK (sizeof(BDBlock) - 1)
-#define RX_DATA_BUFFER_SIZE_MASK (RX_DATA_BUFFER_SIZE-1)
-
-#define NUM_OF_INTERRUPTS 0x20
-
-#define NOT_TRANSMITING 0
-#define TRANSMITING 1
-
-#define TRC_INTERRUPT_ENABLE_MASK 0x7FF6
-
-#define UCODE_VERSION 0x58
-
-#define UCODE_SIZE_OFFSET 0x0000 /* WORD */
-#define UCODE_CHECKSUM_OFFSET 0x0002 /* WORD */
-#define UCODE_VERSION_OFFSET 0x0004 /* BYTE */
-
-#define CS_RAM_SIZE 0X2000
-#define CS_RAM_CHECKSUM_OFFSET 0x1FFE /* WORD 1FFE(MSB)-1FFF(LSB)*/
-#define CS_RAM_VERSION_OFFSET 0x1FFC /* WORD 1FFC(MSB)-1FFD(LSB)*/
-
-#define MISC_DATA_SIZE 128
-#define NUM_OF_ACBS 1
-
-#define ACB_COMMAND_NOT_DONE 0x0000 /* Init, command not done */
-#define ACB_COMMAND_DONE 0x8000 /* TRC says command done */
-#define ACB_COMMAND_STATUS_MASK 0x00FF /* low byte is status */
-#define ACB_COMMAND_SUCCESSFUL 0x0000 /* means cmd was successful */
-#define ACB_NOT_CHAIN_END 0x0000 /* tell TRC more CBs in chain */
-#define ACB_CHAIN_END 0x8000 /* tell TRC last CB in chain */
-#define ACB_COMMAND_NO_INTERRUPT 0x0000 /* tell TRC no INT after CB */
-#define ACB_COMMAND_INTERRUPT 0x2000 /* tell TRC to INT after CB */
-#define ACB_SUB_CMD_NOP 0x0000
-#define ACB_CMD_HIC_NOP 0x0080
-#define ACB_CMD_MCT_NOP 0x0000
-#define ACB_CMD_MCT_TEST 0x0001
-#define ACB_CMD_HIC_TEST 0x0081
-#define ACB_CMD_INSERT 0x0002
-#define ACB_CMD_REMOVE 0x0003
-#define ACB_CMD_MCT_WRITE_VALUE 0x0004
-#define ACB_CMD_HIC_WRITE_VALUE 0x0084
-#define ACB_CMD_MCT_READ_VALUE 0x0005
-#define ACB_CMD_HIC_READ_VALUE 0x0085
-#define ACB_CMD_INIT_TX_RX 0x0086
-#define ACB_CMD_INIT_TRC_TIMERS 0x0006
-#define ACB_CMD_READ_TRC_STATUS 0x0007
-#define ACB_CMD_CHANGE_JOIN_STATE 0x0008
-#define ACB_CMD_RESERVED_9 0x0009
-#define ACB_CMD_RESERVED_A 0x000A
-#define ACB_CMD_RESERVED_B 0x000B
-#define ACB_CMD_RESERVED_C 0x000C
-#define ACB_CMD_RESERVED_D 0x000D
-#define ACB_CMD_RESERVED_E 0x000E
-#define ACB_CMD_RESERVED_F 0x000F
-
-#define TRC_MAC_REGISTERS_TEST 0x0000
-#define TRC_INTERNAL_LOOPBACK 0x0001
-#define TRC_TRI_LOOPBACK 0x0002
-#define TRC_INTERNAL_ROM_TEST 0x0003
-#define TRC_LOBE_MEDIA_TEST 0x0004
-#define TRC_ANALOG_TEST 0x0005
-#define TRC_HOST_INTERFACE_REG_TEST 0x0003
-
-#define TEST_DMA_1 0x0000
-#define TEST_DMA_2 0x0001
-#define TEST_MCT_ROM 0x0002
-#define HIC_INTERNAL_DIAG 0x0003
-
-#define ABORT_TRANSMIT_PRIORITY_0 0x0001
-#define ABORT_TRANSMIT_PRIORITY_1 0x0002
-#define ABORT_TRANSMIT_PRIORITY_2 0x0004
-#define ABORT_TRANSMIT_PRIORITY_3 0x0008
-#define ABORT_TRANSMIT_PRIORITY_4 0x0010
-#define ABORT_TRANSMIT_PRIORITY_5 0x0020
-#define ABORT_TRANSMIT_PRIORITY_6 0x0040
-#define ABORT_TRANSMIT_PRIORITY_7 0x0080
-
-#define TX_PENDING_PRIORITY_0 0x0001
-#define TX_PENDING_PRIORITY_1 0x0002
-#define TX_PENDING_PRIORITY_2 0x0004
-#define TX_PENDING_PRIORITY_3 0x0008
-#define TX_PENDING_PRIORITY_4 0x0010
-#define TX_PENDING_PRIORITY_5 0x0020
-#define TX_PENDING_PRIORITY_6 0x0040
-#define TX_PENDING_PRIORITY_7 0x0080
-
-#define FCB_FRAME_LENGTH 0x100
-#define FCB_COMMAND_DONE 0x8000 /* FCB Word 0 */
-#define FCB_NOT_CHAIN_END 0x0000 /* FCB Word 1 */
-#define FCB_CHAIN_END 0x8000
-#define FCB_NO_WARNING 0x0000
-#define FCB_WARNING 0x4000
-#define FCB_INTERRUPT_DISABLE 0x0000
-#define FCB_INTERRUPT_ENABLE 0x2000
-
-#define FCB_ENABLE_IMA 0x0008
-#define FCB_ENABLE_TES 0x0004 /* Guarantee Tx before Int */
-#define FCB_ENABLE_TFS 0x0002 /* Post Tx Frame Status */
-#define FCB_ENABLE_NTC 0x0001 /* No Tx CRC */
-
-#define FCB_TX_STATUS_CR2 0x0004
-#define FCB_TX_STATUS_AR2 0x0008
-#define FCB_TX_STATUS_CR1 0x0040
-#define FCB_TX_STATUS_AR1 0x0080
-#define FCB_TX_AC_BITS (FCB_TX_STATUS_AR1+FCB_TX_STATUS_AR2+FCB_TX_STATUS_CR1+FCB_TX_STATUS_CR2)
-#define FCB_TX_STATUS_E 0x0100
-
-#define FCB_RX_STATUS_ANY_ERROR 0x0001
-#define FCB_RX_STATUS_FCS_ERROR 0x0002
-
-#define FCB_RX_STATUS_IA_MATCHED 0x0400
-#define FCB_RX_STATUS_IGA_BSGA_MATCHED 0x0500
-#define FCB_RX_STATUS_FA_MATCHED 0x0600
-#define FCB_RX_STATUS_BA_MATCHED 0x0700
-#define FCB_RX_STATUS_DA_MATCHED 0x0400
-#define FCB_RX_STATUS_SOURCE_ROUTING 0x0800
-
-#define BDB_BUFFER_SIZE 0x100
-#define BDB_NOT_CHAIN_END 0x0000
-#define BDB_CHAIN_END 0x8000
-#define BDB_NO_WARNING 0x0000
-#define BDB_WARNING 0x4000
-
-#define ERROR_COUNTERS_CHANGED 0x0001
-#define TI_NDIS_RING_STATUS_CHANGED 0x0002
-#define UNA_CHANGED 0x0004
-#define READY_TO_SEND_RQ_INIT 0x0008
-
-#define SCGB_ADDRESS_POINTER_FORMAT INTEL_ADDRESS_POINTER_FORMAT
-#define SCGB_DATA_FORMAT INTEL_DATA_FORMAT
-#define SCGB_MULTI_WORD_CONTROL 0
-#define SCGB_BURST_LENGTH 0x000E /* DMA Burst Length */
-
-#define SCGB_CONFIG (INTEL_ADDRESS_POINTER_FORMAT+INTEL_DATA_FORMAT+SCGB_BURST_LENGTH)
-
-#define ISCP_BLOCK_SIZE 0x0A
-#define RAM_SIZE 0x10000
-#define INIT_SYS_CONFIG_PTR_OFFSET (RAM_SIZE-ISCP_BLOCK_SIZE)
-#define SCGP_BLOCK_OFFSET 0
-
-#define SCLB_NOT_VALID 0x0000 /* Initially, SCLB not valid */
-#define SCLB_VALID 0x8000 /* Host tells TRC SCLB valid */
-#define SCLB_PROCESSED 0x0000 /* TRC says SCLB processed */
-#define SCLB_RESUME_CONTROL_NOT_VALID 0x0000 /* Initially, RC not valid */
-#define SCLB_RESUME_CONTROL_VALID 0x4000 /* Host tells TRC RC valid */
-#define SCLB_IACK_CODE_NOT_VALID 0x0000 /* Initially, IACK not valid */
-#define SCLB_IACK_CODE_VALID 0x2000 /* Host tells TRC IACK valid */
-#define SCLB_CMD_NOP 0x0000
-#define SCLB_CMD_REMOVE 0x0001
-#define SCLB_CMD_SUSPEND_ACB_CHAIN 0x0002
-#define SCLB_CMD_SET_INTERRUPT_MASK 0x0003
-#define SCLB_CMD_CLEAR_INTERRUPT_MASK 0x0004
-#define SCLB_CMD_RESERVED_5 0x0005
-#define SCLB_CMD_RESERVED_6 0x0006
-#define SCLB_CMD_RESERVED_7 0x0007
-#define SCLB_CMD_RESERVED_8 0x0008
-#define SCLB_CMD_RESERVED_9 0x0009
-#define SCLB_CMD_RESERVED_A 0x000A
-#define SCLB_CMD_RESERVED_B 0x000B
-#define SCLB_CMD_RESERVED_C 0x000C
-#define SCLB_CMD_RESERVED_D 0x000D
-#define SCLB_CMD_RESERVED_E 0x000E
-#define SCLB_CMD_RESERVED_F 0x000F
-
-#define SCLB_RC_ACB 0x0001 /* Action Command Block Chain */
-#define SCLB_RC_RES0 0x0002 /* Always Zero */
-#define SCLB_RC_RES1 0x0004 /* Always Zero */
-#define SCLB_RC_RES2 0x0008 /* Always Zero */
-#define SCLB_RC_RX_MAC_FCB 0x0010 /* RX_MAC_FCB Chain */
-#define SCLB_RC_RX_MAC_BDB 0x0020 /* RX_MAC_BDB Chain */
-#define SCLB_RC_RX_NON_MAC_FCB 0x0040 /* RX_NON_MAC_FCB Chain */
-#define SCLB_RC_RX_NON_MAC_BDB 0x0080 /* RX_NON_MAC_BDB Chain */
-#define SCLB_RC_TFCB0 0x0100 /* TX Priority 0 FCB Chain */
-#define SCLB_RC_TFCB1 0x0200 /* TX Priority 1 FCB Chain */
-#define SCLB_RC_TFCB2 0x0400 /* TX Priority 2 FCB Chain */
-#define SCLB_RC_TFCB3 0x0800 /* TX Priority 3 FCB Chain */
-#define SCLB_RC_TFCB4 0x1000 /* TX Priority 4 FCB Chain */
-#define SCLB_RC_TFCB5 0x2000 /* TX Priority 5 FCB Chain */
-#define SCLB_RC_TFCB6 0x4000 /* TX Priority 6 FCB Chain */
-#define SCLB_RC_TFCB7 0x8000 /* TX Priority 7 FCB Chain */
-
-#define SCLB_IMC_RES0 0x0001 /* */
-#define SCLB_IMC_MAC_TYPE_3 0x0002 /* MAC_ARC_INDICATE */
-#define SCLB_IMC_MAC_ERROR_COUNTERS 0x0004 /* */
-#define SCLB_IMC_RES1 0x0008 /* */
-#define SCLB_IMC_MAC_TYPE_2 0x0010 /* QUE_MAC_INDICATE */
-#define SCLB_IMC_TX_FRAME 0x0020 /* */
-#define SCLB_IMC_END_OF_TX_QUEUE 0x0040 /* */
-#define SCLB_IMC_NON_MAC_RX_RESOURCE 0x0080 /* */
-#define SCLB_IMC_MAC_RX_RESOURCE 0x0100 /* */
-#define SCLB_IMC_NON_MAC_RX_FRAME 0x0200 /* */
-#define SCLB_IMC_MAC_RX_FRAME 0x0400 /* */
-#define SCLB_IMC_TRC_FIFO_STATUS 0x0800 /* */
-#define SCLB_IMC_COMMAND_STATUS 0x1000 /* */
-#define SCLB_IMC_MAC_TYPE_1 0x2000 /* Self Removed */
-#define SCLB_IMC_TRC_INTRNL_TST_STATUS 0x4000 /* */
-#define SCLB_IMC_RES2 0x8000 /* */
-
-#define DMA_TRIGGER 0x0004
-#define FREQ_16MB_BIT 0x0010
-#define THDREN 0x0020
-#define CFG0_RSV1 0x0040
-#define CFG0_RSV2 0x0080
-#define ETREN 0x0100
-#define RX_OWN_BIT 0x0200
-#define RXATMAC 0x0400
-#define PROMISCUOUS_BIT 0x0800
-#define USETPT 0x1000
-#define SAVBAD_BIT 0x2000
-#define ONEQUE 0x4000
-#define NO_AUTOREMOVE 0x8000
-
-#define RX_FCB_AREA_8316 0x00000000
-#define RX_BUFF_AREA_8316 0x00000000
-
-#define TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access)
-#define RX_FCB_TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access + RX_FCB_AREA_8316)
-#define RX_BUFF_TRC_POINTER(X) ((unsigned long)(X) - tp->ram_access + RX_BUFF_AREA_8316)
-
-// Offset 0: MSR - Memory Select Register
-//
-#define r587_MSR 0x000 // Register Offset
-//#define MSR_RST 0x080 // LAN Controller Reset
-#define MSR_MENB 0x040 // Shared Memory Enable
-#define MSR_RA18 0x020 // Ram Address bit 18 (583, 584, 587)
-#define MSR_RA17 0x010 // Ram Address bit 17 (583, 584, 585/790)
-#define MSR_RA16 0x008 // Ram Address bit 16 (583, 584, 585/790)
-#define MSR_RA15 0x004 // Ram Address bit 15 (583, 584, 585/790)
-#define MSR_RA14 0x002 // Ram Address bit 14 (583, 584, 585/790)
-#define MSR_RA13 0x001 // Ram Address bit 13 (583, 584, 585/790)
-
-#define MSR_MASK 0x03F // Mask for Address bits RA18-RA13 (583, 584, 587)
-
-#define MSR 0x00
-#define IRR 0x04
-#define HWR 0x04
-#define LAAR 0x05
-#define IMCCR 0x05
-#define LAR0 0x08
-#define BDID 0x0E // Adapter ID byte register offset
-#define CSR 0x10
-#define PR 0x11
-
-#define MSR_RST 0x80
-#define MSR_MEMB 0x40
-#define MSR_0WS 0x20
-
-#define FORCED_16BIT_MODE 0x0002
-
-#define INTERFRAME_SPACING_16 0x0003 /* 6 bytes */
-#define INTERFRAME_SPACING_4 0x0001 /* 2 bytes */
-#define MULTICAST_ADDRESS_BIT 0x0010
-#define NON_SRC_ROUTING_BIT 0x0020
-
-#define LOOPING_MODE_MASK 0x0007
-
-/*
- * Decode firmware defines.
- */
-#define SWAP_BYTES(X) ((X & 0xff) << 8) | (X >> 8)
-#define WEIGHT_OFFSET 5
-#define TREE_SIZE_OFFSET 9
-#define TREE_OFFSET 11
-
-/* The Huffman Encoding Tree is constructed of these nodes. */
-typedef struct {
- __u8 llink; /* Short version of above node. */
- __u8 tag;
- __u8 info; /* This node is used on decodes. */
- __u8 rlink;
-} DECODE_TREE_NODE;
-
-#define ROOT 0 /* Branch value. */
-#define LEAF 0 /* Tag field value. */
-#define BRANCH 1 /* Tag field value. */
-
-/*
- * Multicast Table Structure
- */
-typedef struct {
- __u8 address[6];
- __u8 instance_count;
-} McTable;
-
-/*
- * Fragment Descriptor Definition
- */
-typedef struct {
- __u8 *fragment_ptr;
- __u32 fragment_length;
-} FragmentStructure;
-
-/*
- * Data Buffer Structure Definition
- */
-typedef struct {
- __u32 fragment_count;
- FragmentStructure fragment_list[MAXFRAGMENTS];
-} DataBufferStructure;
-
-#pragma pack(1)
-typedef struct {
- __u8 IType;
- __u8 ISubtype;
-} Interrupt_Status_Word;
-
-#pragma pack(1)
-typedef struct BDBlockType {
- __u16 info; /* 02 */
- __u32 trc_next_ptr; /* 06 */
- __u32 trc_data_block_ptr; /* 10 */
- __u16 buffer_length; /* 12 */
-
- __u16 *data_block_ptr; /* 16 */
- struct BDBlockType *next_ptr; /* 20 */
- struct BDBlockType *back_ptr; /* 24 */
- __u8 filler[8]; /* 32 */
-} BDBlock;
-
-#pragma pack(1)
-typedef struct FCBlockType {
- __u16 frame_status; /* 02 */
- __u16 info; /* 04 */
- __u32 trc_next_ptr; /* 08 */
- __u32 trc_bdb_ptr; /* 12 */
- __u16 frame_length; /* 14 */
-
- BDBlock *bdb_ptr; /* 18 */
- struct FCBlockType *next_ptr; /* 22 */
- struct FCBlockType *back_ptr; /* 26 */
- __u16 memory_alloc; /* 28 */
- __u8 filler[4]; /* 32 */
-
-} FCBlock;
-
-#pragma pack(1)
-typedef struct SBlockType{
- __u8 Internal_Error_Count;
- __u8 Line_Error_Count;
- __u8 AC_Error_Count;
- __u8 Burst_Error_Count;
- __u8 RESERVED_COUNTER_0;
- __u8 AD_TRANS_Count;
- __u8 RCV_Congestion_Count;
- __u8 Lost_FR_Error_Count;
- __u8 FREQ_Error_Count;
- __u8 FR_Copied_Error_Count;
- __u8 RESERVED_COUNTER_1;
- __u8 Token_Error_Count;
-
- __u16 TI_NDIS_Ring_Status;
- __u16 BCN_Type;
- __u16 Error_Code;
- __u16 SA_of_Last_AMP_SMP[3];
- __u16 UNA[3];
- __u16 Ucode_Version_Number;
- __u16 Status_CHG_Indicate;
- __u16 RESERVED_STATUS_0;
-} SBlock;
-
-#pragma pack(1)
-typedef struct ACBlockType {
- __u16 cmd_done_status; /* 02 */
- __u16 cmd_info; /* 04 */
- __u32 trc_next_ptr; /* 08 */
- __u16 cmd; /* 10 */
- __u16 subcmd; /* 12 */
- __u16 data_offset_lo; /* 14 */
- __u16 data_offset_hi; /* 16 */
-
- struct ACBlockType *next_ptr; /* 20 */
-
- __u8 filler[12]; /* 32 */
-} ACBlock;
-
-#define NUM_OF_INTERRUPTS 0x20
-
-#pragma pack(1)
-typedef struct {
- Interrupt_Status_Word IStatus[NUM_OF_INTERRUPTS];
-} ISBlock;
-
-#pragma pack(1)
-typedef struct {
- __u16 valid_command; /* 02 */
- __u16 iack_code; /* 04 */
- __u16 resume_control; /* 06 */
- __u16 int_mask_control; /* 08 */
- __u16 int_mask_state; /* 10 */
-
- __u8 filler[6]; /* 16 */
-} SCLBlock;
-
-#pragma pack(1)
-typedef struct
-{
- __u16 config; /* 02 */
- __u32 trc_sclb_ptr; /* 06 */
- __u32 trc_acb_ptr; /* 10 */
- __u32 trc_isb_ptr; /* 14 */
- __u16 isbsiz; /* 16 */
-
- SCLBlock *sclb_ptr; /* 20 */
- ACBlock *acb_ptr; /* 24 */
- ISBlock *isb_ptr; /* 28 */
-
- __u16 Non_Mac_Rx_Bdbs; /* 30 DEBUG */
- __u8 filler[2]; /* 32 */
-
-} SCGBlock;
-
-#pragma pack(1)
-typedef struct
-{
- __u32 trc_scgb_ptr;
- SCGBlock *scgb_ptr;
-} ISCPBlock;
-#pragma pack()
-
-typedef struct net_local {
- ISCPBlock *iscpb_ptr;
- SCGBlock *scgb_ptr;
- SCLBlock *sclb_ptr;
- ISBlock *isb_ptr;
-
- ACBlock *acb_head;
- ACBlock *acb_curr;
- ACBlock *acb_next;
-
- __u8 adapter_name[12];
-
- __u16 num_rx_bdbs [NUM_RX_QS_USED];
- __u16 num_rx_fcbs [NUM_RX_QS_USED];
-
- __u16 num_tx_bdbs [NUM_TX_QS_USED];
- __u16 num_tx_fcbs [NUM_TX_QS_USED];
-
- __u16 num_of_tx_buffs;
-
- __u16 tx_buff_size [NUM_TX_QS_USED];
- __u16 tx_buff_used [NUM_TX_QS_USED];
- __u16 tx_queue_status [NUM_TX_QS_USED];
-
- FCBlock *tx_fcb_head[NUM_TX_QS_USED];
- FCBlock *tx_fcb_curr[NUM_TX_QS_USED];
- FCBlock *tx_fcb_end[NUM_TX_QS_USED];
- BDBlock *tx_bdb_head[NUM_TX_QS_USED];
- __u16 *tx_buff_head[NUM_TX_QS_USED];
- __u16 *tx_buff_end[NUM_TX_QS_USED];
- __u16 *tx_buff_curr[NUM_TX_QS_USED];
- __u16 num_tx_fcbs_used[NUM_TX_QS_USED];
-
- FCBlock *rx_fcb_head[NUM_RX_QS_USED];
- FCBlock *rx_fcb_curr[NUM_RX_QS_USED];
- BDBlock *rx_bdb_head[NUM_RX_QS_USED];
- BDBlock *rx_bdb_curr[NUM_RX_QS_USED];
- BDBlock *rx_bdb_end[NUM_RX_QS_USED];
- __u16 *rx_buff_head[NUM_RX_QS_USED];
- __u16 *rx_buff_end[NUM_RX_QS_USED];
-
- __u32 *ptr_local_ring_num;
-
- __u32 sh_mem_used;
-
- __u16 page_offset_mask;
-
- __u16 authorized_function_classes;
- __u16 authorized_access_priority;
-
- __u16 num_acbs;
- __u16 num_acbs_used;
- __u16 acb_pending;
-
- __u16 current_isb_index;
-
- __u8 monitor_state;
- __u8 monitor_state_ready;
- __u16 ring_status;
- __u8 ring_status_flags;
- __u8 state;
-
- __u8 join_state;
-
- __u8 slot_num;
- __u16 pos_id;
-
- __u32 *ptr_una;
- __u32 *ptr_bcn_type;
- __u32 *ptr_tx_fifo_underruns;
- __u32 *ptr_rx_fifo_underruns;
- __u32 *ptr_rx_fifo_overruns;
- __u32 *ptr_tx_fifo_overruns;
- __u32 *ptr_tx_fcb_overruns;
- __u32 *ptr_rx_fcb_overruns;
- __u32 *ptr_tx_bdb_overruns;
- __u32 *ptr_rx_bdb_overruns;
-
- __u16 receive_queue_number;
-
- __u8 rx_fifo_overrun_count;
- __u8 tx_fifo_overrun_count;
-
- __u16 adapter_flags;
- __u16 adapter_flags1;
- __u16 *misc_command_data;
- __u16 max_packet_size;
-
- __u16 config_word0;
- __u16 config_word1;
-
- __u8 trc_mask;
-
- __u16 source_ring_number;
- __u16 target_ring_number;
-
- __u16 microcode_version;
-
- __u16 bic_type;
- __u16 nic_type;
- __u16 board_id;
-
- __u16 rom_size;
- __u32 rom_base;
- __u16 ram_size;
- __u16 ram_usable;
- __u32 ram_base;
- __u32 ram_access;
-
- __u16 extra_info;
- __u16 mode_bits;
- __u16 media_menu;
- __u16 media_type;
- __u16 adapter_bus;
-
- __u16 status;
- __u16 receive_mask;
-
- __u16 group_address_0;
- __u16 group_address[2];
- __u16 functional_address_0;
- __u16 functional_address[2];
- __u16 bitwise_group_address[2];
-
- __u8 cleanup;
-
- struct sk_buff_head SendSkbQueue;
- __u16 QueueSkb;
-
- struct tr_statistics MacStat; /* MAC statistics structure */
-
- spinlock_t lock;
-} NET_LOCAL;
-
-/************************************
- * SNMP-ON-BOARD Agent Link Structure
- ************************************/
-
-typedef struct {
- __u8 LnkSigStr[12]; /* signature string "SmcLinkTable" */
- __u8 LnkDrvTyp; /* 1=Redbox ODI, 2=ODI DOS, 3=ODI OS/2, 4=NDIS DOS */
- __u8 LnkFlg; /* 0 if no agent linked, 1 if agent linked */
- void *LnkNfo; /* routine which returns pointer to NIC info */
- void *LnkAgtRcv; /* pointer to agent receive trap entry */
- void *LnkAgtXmt; /* pointer to agent transmit trap
-entry */
-void *LnkGet; /* pointer to NIC receive data
-copy routine */
- void *LnkSnd; /* pointer to NIC send routine
-*/
- void *LnkRst; /* pointer to NIC driver reset
-routine */
- void *LnkMib; /* pointer to MIB data base */
- void *LnkMibAct; /* pointer to MIB action routine list */
- __u16 LnkCntOffset; /* offset to error counters */
- __u16 LnkCntNum; /* number of error counters */
- __u16 LnkCntSize; /* size of error counters i.e. 32 = 32 bits */
- void *LnkISR; /* pointer to interrupt vector */
- __u8 LnkFrmTyp; /* 1=Ethernet, 2=Token Ring */
- __u8 LnkDrvVer1 ; /* driver major version */
- __u8 LnkDrvVer2 ; /* driver minor version */
-} AgentLink;
-
-/*
- * Definitions for pcm_card_flags(bit_mapped)
- */
-#define REG_COMPLETE 0x0001
-#define INSERTED 0x0002
-#define PCC_INSERTED 0x0004 /* 1=currently inserted, 0=cur removed */
-
-/*
- * Adapter RAM test patterns
- */
-#define RAM_PATTERN_1 0x55AA
-#define RAM_PATTERN_2 0x9249
-#define RAM_PATTERN_3 0xDB6D
-
-/*
- * definitions for RAM test
- */
-#define ROM_SIGNATURE 0xAA55
-#define MIN_ROM_SIZE 0x2000
-
-/*
- * Return Codes
- */
-#define SUCCESS 0x0000
-#define ADAPTER_AND_CONFIG 0x0001
-#define ADAPTER_NO_CONFIG 0x0002
-#define NOT_MY_INTERRUPT 0x0003
-#define FRAME_REJECTED 0x0004
-#define EVENTS_DISABLED 0x0005
-#define OUT_OF_RESOURCES 0x0006
-#define INVALID_PARAMETER 0x0007
-#define INVALID_FUNCTION 0x0008
-#define INITIALIZE_FAILED 0x0009
-#define CLOSE_FAILED 0x000A
-#define MAX_COLLISIONS 0x000B
-#define NO_SUCH_DESTINATION 0x000C
-#define BUFFER_TOO_SMALL_ERROR 0x000D
-#define ADAPTER_CLOSED 0x000E
-#define UCODE_NOT_PRESENT 0x000F
-#define FIFO_UNDERRUN 0x0010
-#define DEST_OUT_OF_RESOURCES 0x0011
-#define ADAPTER_NOT_INITIALIZED 0x0012
-#define PENDING 0x0013
-#define UCODE_PRESENT 0x0014
-#define NOT_INIT_BY_BRIDGE 0x0015
-
-#define OPEN_FAILED 0x0080
-#define HARDWARE_FAILED 0x0081
-#define SELF_TEST_FAILED 0x0082
-#define RAM_TEST_FAILED 0x0083
-#define RAM_CONFLICT 0x0084
-#define ROM_CONFLICT 0x0085
-#define UNKNOWN_ADAPTER 0x0086
-#define CONFIG_ERROR 0x0087
-#define CONFIG_WARNING 0x0088
-#define NO_FIXED_CNFG 0x0089
-#define EEROM_CKSUM_ERROR 0x008A
-#define ROM_SIGNATURE_ERROR 0x008B
-#define ROM_CHECKSUM_ERROR 0x008C
-#define ROM_SIZE_ERROR 0x008D
-#define UNSUPPORTED_NIC_CHIP 0x008E
-#define NIC_REG_ERROR 0x008F
-#define BIC_REG_ERROR 0x0090
-#define MICROCODE_TEST_ERROR 0x0091
-#define LOBE_MEDIA_TEST_FAILED 0x0092
-
-#define ADAPTER_FOUND_LAN_CORRUPT 0x009B
-
-#define ADAPTER_NOT_FOUND 0xFFFF
-
-#define ILLEGAL_FUNCTION INVALID_FUNCTION
-
-/* Errors */
-#define IO_BASE_INVALID 0x0001
-#define IO_BASE_RANGE 0x0002
-#define IRQ_INVALID 0x0004
-#define IRQ_RANGE 0x0008
-#define RAM_BASE_INVALID 0x0010
-#define RAM_BASE_RANGE 0x0020
-#define RAM_SIZE_RANGE 0x0040
-#define MEDIA_INVALID 0x0800
-
-/* Warnings */
-#define IRQ_MISMATCH 0x0080
-#define RAM_BASE_MISMATCH 0x0100
-#define RAM_SIZE_MISMATCH 0x0200
-#define BUS_MODE_MISMATCH 0x0400
-
-#define RX_CRC_ERROR 0x01
-#define RX_ALIGNMENT_ERROR 0x02
-#define RX_HW_FAILED 0x80
-
-/*
- * Definitions for the field RING_STATUS_FLAGS
- */
-#define RING_STATUS_CHANGED 0X01
-#define MONITOR_STATE_CHANGED 0X02
-#define JOIN_STATE_CHANGED 0X04
-
-/*
- * Definitions for the field JOIN_STATE
- */
-#define JS_BYPASS_STATE 0x00
-#define JS_LOBE_TEST_STATE 0x01
-#define JS_DETECT_MONITOR_PRESENT_STATE 0x02
-#define JS_AWAIT_NEW_MONITOR_STATE 0x03
-#define JS_DUPLICATE_ADDRESS_TEST_STATE 0x04
-#define JS_NEIGHBOR_NOTIFICATION_STATE 0x05
-#define JS_REQUEST_INITIALIZATION_STATE 0x06
-#define JS_JOIN_COMPLETE_STATE 0x07
-#define JS_BYPASS_WAIT_STATE 0x08
-
-/*
- * Definitions for the field MONITOR_STATE
- */
-#define MS_MONITOR_FSM_INACTIVE 0x00
-#define MS_REPEAT_BEACON_STATE 0x01
-#define MS_REPEAT_CLAIM_TOKEN_STATE 0x02
-#define MS_TRANSMIT_CLAIM_TOKEN_STATE 0x03
-#define MS_STANDBY_MONITOR_STATE 0x04
-#define MS_TRANSMIT_BEACON_STATE 0x05
-#define MS_ACTIVE_MONITOR_STATE 0x06
-#define MS_TRANSMIT_RING_PURGE_STATE 0x07
-#define MS_BEACON_TEST_STATE 0x09
-
-/*
- * Definitions for the bit-field RING_STATUS
- */
-#define SIGNAL_LOSS 0x8000
-#define HARD_ERROR 0x4000
-#define SOFT_ERROR 0x2000
-#define TRANSMIT_BEACON 0x1000
-#define LOBE_WIRE_FAULT 0x0800
-#define AUTO_REMOVAL_ERROR 0x0400
-#define REMOVE_RECEIVED 0x0100
-#define COUNTER_OVERFLOW 0x0080
-#define SINGLE_STATION 0x0040
-#define RING_RECOVERY 0x0020
-
-/*
- * Definitions for the field BUS_TYPE
- */
-#define AT_BUS 0x00
-#define MCA_BUS 0x01
-#define EISA_BUS 0x02
-#define PCI_BUS 0x03
-#define PCMCIA_BUS 0x04
-
-/*
- * Definitions for adapter_flags
- */
-#define RX_VALID_LOOKAHEAD 0x0001
-#define FORCED_16BIT_MODE 0x0002
-#define ADAPTER_DISABLED 0x0004
-#define TRANSMIT_CHAIN_INT 0x0008
-#define EARLY_RX_FRAME 0x0010
-#define EARLY_TX 0x0020
-#define EARLY_RX_COPY 0x0040
-#define USES_PHYSICAL_ADDR 0x0080 /* Rsvd for DEC PCI and 9232 */
-#define NEEDS_PHYSICAL_ADDR 0x0100 /* Reserved*/
-#define RX_STATUS_PENDING 0x0200
-#define ERX_DISABLED 0x0400 /* EARLY_RX_ENABLE rcv_mask */
-#define ENABLE_TX_PENDING 0x0800
-#define ENABLE_RX_PENDING 0x1000
-#define PERM_CLOSE 0x2000
-#define IO_MAPPED 0x4000 /* IOmapped bus interface 795 */
-#define ETX_DISABLED 0x8000
-
-
-/*
- * Definitions for adapter_flags1
- */
-#define TX_PHY_RX_VIRT 0x0001
-#define NEEDS_HOST_RAM 0x0002
-#define NEEDS_MEDIA_TYPE 0x0004
-#define EARLY_RX_DONE 0x0008
-#define PNP_BOOT_BIT 0x0010 /* activates PnP & config on power-up */
- /* clear => regular PnP operation */
-#define PNP_ENABLE 0x0020 /* regular PnP operation clear => */
- /* no PnP, overrides PNP_BOOT_BIT */
-#define SATURN_ENABLE 0x0040
-
-#define ADAPTER_REMOVABLE 0x0080 /* adapter is hot swappable */
-#define TX_PHY 0x0100 /* Uses physical address for tx bufs */
-#define RX_PHY 0x0200 /* Uses physical address for rx bufs */
-#define TX_VIRT 0x0400 /* Uses virtual addr for tx bufs */
-#define RX_VIRT 0x0800
-#define NEEDS_SERVICE 0x1000
-
-/*
- * Adapter Status Codes
- */
-#define OPEN 0x0001
-#define INITIALIZED 0x0002
-#define CLOSED 0x0003
-#define FAILED 0x0005
-#define NOT_INITIALIZED 0x0006
-#define IO_CONFLICT 0x0007
-#define CARD_REMOVED 0x0008
-#define CARD_INSERTED 0x0009
-
-/*
- * Mode Bit Definitions
- */
-#define INTERRUPT_STATUS_BIT 0x8000 /* PC Interrupt Line: 0 = Not Enabled */
-#define BOOT_STATUS_MASK 0x6000 /* Mask to isolate BOOT_STATUS */
-#define BOOT_INHIBIT 0x0000 /* BOOT_STATUS is 'inhibited' */
-#define BOOT_TYPE_1 0x2000 /* Unused BOOT_STATUS value */
-#define BOOT_TYPE_2 0x4000 /* Unused BOOT_STATUS value */
-#define BOOT_TYPE_3 0x6000 /* Unused BOOT_STATUS value */
-#define ZERO_WAIT_STATE_MASK 0x1800 /* Mask to isolate Wait State flags */
-#define ZERO_WAIT_STATE_8_BIT 0x1000 /* 0 = Disabled (Inserts Wait States) */
-#define ZERO_WAIT_STATE_16_BIT 0x0800 /* 0 = Disabled (Inserts Wait States) */
-#define LOOPING_MODE_MASK 0x0007
-#define LOOPBACK_MODE_0 0x0000
-#define LOOPBACK_MODE_1 0x0001
-#define LOOPBACK_MODE_2 0x0002
-#define LOOPBACK_MODE_3 0x0003
-#define LOOPBACK_MODE_4 0x0004
-#define LOOPBACK_MODE_5 0x0005
-#define LOOPBACK_MODE_6 0x0006
-#define LOOPBACK_MODE_7 0x0007
-#define AUTO_MEDIA_DETECT 0x0008
-#define MANUAL_CRC 0x0010
-#define EARLY_TOKEN_REL 0x0020 /* Early Token Release for Token Ring */
-#define UMAC 0x0040
-#define UTP2_PORT 0x0080 /* For 8216T2, 0=port A, 1=Port B. */
-#define BNC_10BT_INTERFACE 0x0600 /* BNC and UTP current media set */
-#define UTP_INTERFACE 0x0500 /* Ethernet UTP Only. */
-#define BNC_INTERFACE 0x0400
-#define AUI_INTERFACE 0x0300
-#define AUI_10BT_INTERFACE 0x0200
-#define STARLAN_10_INTERFACE 0x0100
-#define INTERFACE_TYPE_MASK 0x0700
-
-/*
- * Media Type Bit Definitions
- *
- * legend: TP = Twisted Pair
- * STP = Shielded twisted pair
- * UTP = Unshielded twisted pair
- */
-
-#define CNFG_MEDIA_TYPE_MASK 0x001e /* POS Register 3 Mask */
-
-#define MEDIA_S10 0x0000 /* Ethernet adapter, TP. */
-#define MEDIA_AUI_UTP 0x0001 /* Ethernet adapter, AUI/UTP media */
-#define MEDIA_BNC 0x0002 /* Ethernet adapter, BNC media. */
-#define MEDIA_AUI 0x0003 /* Ethernet Adapter, AUI media. */
-#define MEDIA_STP_16 0x0004 /* TokenRing adap, 16Mbit STP. */
-#define MEDIA_STP_4 0x0005 /* TokenRing adap, 4Mbit STP. */
-#define MEDIA_UTP_16 0x0006 /* TokenRing adap, 16Mbit UTP. */
-#define MEDIA_UTP_4 0x0007 /* TokenRing adap, 4Mbit UTP. */
-#define MEDIA_UTP 0x0008 /* Ethernet adapter, UTP media (no AUI)
-*/
-#define MEDIA_BNC_UTP 0x0010 /* Ethernet adapter, BNC/UTP media */
-#define MEDIA_UTPFD 0x0011 /* Ethernet adapter, TP full duplex */
-#define MEDIA_UTPNL 0x0012 /* Ethernet adapter, TP with link integrity test disabled */
-#define MEDIA_AUI_BNC 0x0013 /* Ethernet adapter, AUI/BNC media */
-#define MEDIA_AUI_BNC_UTP 0x0014 /* Ethernet adapter, AUI_BNC/UTP */
-#define MEDIA_UTPA 0x0015 /* Ethernet UTP-10Mbps Ports A */
-#define MEDIA_UTPB 0x0016 /* Ethernet UTP-10Mbps Ports B */
-#define MEDIA_STP_16_UTP_16 0x0017 /* Token Ring STP-16Mbps/UTP-16Mbps */
-#define MEDIA_STP_4_UTP_4 0x0018 /* Token Ring STP-4Mbps/UTP-4Mbps */
-
-#define MEDIA_STP100_UTP100 0x0020 /* Ethernet STP-100Mbps/UTP-100Mbps */
-#define MEDIA_UTP100FD 0x0021 /* Ethernet UTP-100Mbps, full duplex */
-#define MEDIA_UTP100 0x0022 /* Ethernet UTP-100Mbps */
-
-
-#define MEDIA_UNKNOWN 0xFFFF /* Unknown adapter/media type */
-
-/*
- * Definitions for the field:
- * media_type2
- */
-#define MEDIA_TYPE_MII 0x0001
-#define MEDIA_TYPE_UTP 0x0002
-#define MEDIA_TYPE_BNC 0x0004
-#define MEDIA_TYPE_AUI 0x0008
-#define MEDIA_TYPE_S10 0x0010
-#define MEDIA_TYPE_AUTO_SENSE 0x1000
-#define MEDIA_TYPE_AUTO_DETECT 0x4000
-#define MEDIA_TYPE_AUTO_NEGOTIATE 0x8000
-
-/*
- * Definitions for the field:
- * line_speed
- */
-#define LINE_SPEED_UNKNOWN 0x0000
-#define LINE_SPEED_4 0x0001
-#define LINE_SPEED_10 0x0002
-#define LINE_SPEED_16 0x0004
-#define LINE_SPEED_100 0x0008
-#define LINE_SPEED_T4 0x0008 /* 100BaseT4 aliased for 9332BVT */
-#define LINE_SPEED_FULL_DUPLEX 0x8000
-
-/*
- * Definitions for the field:
- * bic_type (Bus interface chip type)
- */
-#define BIC_NO_CHIP 0x0000 /* Bus interface chip not implemented */
-#define BIC_583_CHIP 0x0001 /* 83C583 bus interface chip */
-#define BIC_584_CHIP 0x0002 /* 83C584 bus interface chip */
-#define BIC_585_CHIP 0x0003 /* 83C585 bus interface chip */
-#define BIC_593_CHIP 0x0004 /* 83C593 bus interface chip */
-#define BIC_594_CHIP 0x0005 /* 83C594 bus interface chip */
-#define BIC_564_CHIP 0x0006 /* PCMCIA Bus interface chip */
-#define BIC_790_CHIP 0x0007 /* 83C790 bus i-face/Ethernet NIC chip */
-#define BIC_571_CHIP 0x0008 /* 83C571 EISA bus master i-face */
-#define BIC_587_CHIP 0x0009 /* Token Ring AT bus master i-face */
-#define BIC_574_CHIP 0x0010 /* FEAST bus interface chip */
-#define BIC_8432_CHIP 0x0011 /* 8432 bus i-face/Ethernet NIC(DEC PCI) */
-#define BIC_9332_CHIP 0x0012 /* 9332 bus i-face/100Mbps Ether NIC(DEC PCI) */
-#define BIC_8432E_CHIP 0x0013 /* 8432 Enhanced bus iface/Ethernet NIC(DEC) */
-#define BIC_EPIC100_CHIP 0x0014 /* EPIC/100 10/100 Mbps Ethernet BIC/NIC */
-#define BIC_C94_CHIP 0x0015 /* 91C94 bus i-face in PCMCIA mode */
-#define BIC_X8020_CHIP 0x0016 /* Xilinx PCMCIA multi-func i-face */
-
-/*
- * Definitions for the field:
- * nic_type (Bus interface chip type)
- */
-#define NIC_UNK_CHIP 0x0000 /* Unknown NIC chip */
-#define NIC_8390_CHIP 0x0001 /* DP8390 Ethernet NIC */
-#define NIC_690_CHIP 0x0002 /* 83C690 Ethernet NIC */
-#define NIC_825_CHIP 0x0003 /* 83C825 Token Ring NIC */
-/* #define NIC_???_CHIP 0x0004 */ /* Not used */
-/* #define NIC_???_CHIP 0x0005 */ /* Not used */
-/* #define NIC_???_CHIP 0x0006 */ /* Not used */
-#define NIC_790_CHIP 0x0007 /* 83C790 bus i-face/Ethernet NIC chip */
-#define NIC_C100_CHIP 0x0010 /* FEAST 100Mbps Ethernet NIC */
-#define NIC_8432_CHIP 0x0011 /* 8432 bus i-face/Ethernet NIC(DEC PCI) */
-#define NIC_9332_CHIP 0x0012 /* 9332 bus i-face/100Mbps Ether NIC(DEC PCI) */
-#define NIC_8432E_CHIP 0x0013 /* 8432 enhanced bus iface/Ethernet NIC(DEC) */
-#define NIC_EPIC100_CHIP 0x0014 /* EPIC/100 10/100 Mbps Ethernet BIC/NIC */
-#define NIC_C94_CHIP 0x0015 /* 91C94 PC Card with multi func */
-
-/*
- * Definitions for the field:
- * adapter_type The adapter_type field describes the adapter/bus
- * configuration.
- */
-#define BUS_ISA16_TYPE 0x0001 /* 16 bit adap in 16 bit (E)ISA slot */
-#define BUS_ISA8_TYPE 0x0002 /* 8/16b adap in 8 bit XT/(E)ISA slot */
-#define BUS_MCA_TYPE 0x0003 /* Micro Channel adapter */
-
-/*
- * Receive Mask definitions
- */
-#define ACCEPT_MULTICAST 0x0001
-#define ACCEPT_BROADCAST 0x0002
-#define PROMISCUOUS_MODE 0x0004
-#define ACCEPT_SOURCE_ROUTING 0x0008
-#define ACCEPT_ERR_PACKETS 0x0010
-#define ACCEPT_ATT_MAC_FRAMES 0x0020
-#define ACCEPT_MULTI_PROM 0x0040
-#define TRANSMIT_ONLY 0x0080
-#define ACCEPT_EXT_MAC_FRAMES 0x0100
-#define EARLY_RX_ENABLE 0x0200
-#define PKT_SIZE_NOT_NEEDED 0x0400
-#define ACCEPT_SOURCE_ROUTING_SPANNING 0x0808
-
-#define ACCEPT_ALL_MAC_FRAMES 0x0120
-
-/*
- * config_mode defs
- */
-#define STORE_EEROM 0x0001 /* Store config in EEROM. */
-#define STORE_REGS 0x0002 /* Store config in register set. */
-
-/*
- * equates for lmac_flags in adapter structure (Ethernet)
- */
-#define MEM_DISABLE 0x0001
-#define RX_STATUS_POLL 0x0002
-#define USE_RE_BIT 0x0004
-/*#define RESERVED 0x0008 */
-/*#define RESERVED 0x0010 */
-/*#define RESERVED 0x0020 */
-/*#define RESERVED 0x0040 */
-/*#define RESERVED 0x0080 */
-/*#define RESERVED 0x0100 */
-/*#define RESERVED 0x0200 */
-/*#define RESERVED 0x0400 */
-/*#define RESERVED 0x0800 */
-/*#define RESERVED 0x1000 */
-/*#define RESERVED 0x2000 */
-/*#define RESERVED 0x4000 */
-/*#define RESERVED 0x8000 */
-
-/* media_opts & media_set Fields bit defs for Ethernet ... */
-#define MED_OPT_BNC 0x01
-#define MED_OPT_UTP 0x02
-#define MED_OPT_AUI 0x04
-#define MED_OPT_10MB 0x08
-#define MED_OPT_100MB 0x10
-#define MED_OPT_S10 0x20
-
-/* media_opts & media_set Fields bit defs for Token Ring ... */
-#define MED_OPT_4MB 0x08
-#define MED_OPT_16MB 0x10
-#define MED_OPT_STP 0x40
-
-#define MAX_8023_SIZE 1500 /* Max 802.3 size of frame. */
-#define DEFAULT_ERX_VALUE 4 /* Number of 16-byte blocks for 790B early Rx. */
-#define DEFAULT_ETX_VALUE 32 /* Number of bytes for 790B early Tx. */
-#define DEFAULT_TX_RETRIES 3 /* Number of transmit retries */
-#define LPBK_FRAME_SIZE 1024 /* Default loopback frame for Rx calibration test. */
-#define MAX_LOOKAHEAD_SIZE 252 /* Max lookahead size for ethernet. */
-
-#define RW_MAC_STATE 0x1101
-#define RW_SA_OF_LAST_AMP_OR_SMP 0x2803
-#define RW_PHYSICAL_DROP_NUMBER 0x3B02
-#define RW_UPSTREAM_NEIGHBOR_ADDRESS 0x3E03
-#define RW_PRODUCT_INSTANCE_ID 0x4B09
-
-#define RW_TRC_STATUS_BLOCK 0x5412
-
-#define RW_MAC_ERROR_COUNTERS_NO_CLEAR 0x8006
-#define RW_MAC_ERROR_COUNTER_CLEAR 0x7A06
-#define RW_CONFIG_REGISTER_0 0xA001
-#define RW_CONFIG_REGISTER_1 0xA101
-#define RW_PRESCALE_TIMER_THRESHOLD 0xA201
-#define RW_TPT_THRESHOLD 0xA301
-#define RW_TQP_THRESHOLD 0xA401
-#define RW_TNT_THRESHOLD 0xA501
-#define RW_TBT_THRESHOLD 0xA601
-#define RW_TSM_THRESHOLD 0xA701
-#define RW_TAM_THRESHOLD 0xA801
-#define RW_TBR_THRESHOLD 0xA901
-#define RW_TER_THRESHOLD 0xAA01
-#define RW_TGT_THRESHOLD 0xAB01
-#define RW_THT_THRESHOLD 0xAC01
-#define RW_TRR_THRESHOLD 0xAD01
-#define RW_TVX_THRESHOLD 0xAE01
-#define RW_INDIVIDUAL_MAC_ADDRESS 0xB003
-
-#define RW_INDIVIDUAL_GROUP_ADDRESS 0xB303 /* all of group addr */
-#define RW_INDIVIDUAL_GROUP_ADDR_WORD_0 0xB301 /* 1st word of group addr */
-#define RW_INDIVIDUAL_GROUP_ADDR 0xB402 /* 2nd-3rd word of group addr */
-#define RW_FUNCTIONAL_ADDRESS 0xB603 /* all of functional addr */
-#define RW_FUNCTIONAL_ADDR_WORD_0 0xB601 /* 1st word of func addr */
-#define RW_FUNCTIONAL_ADDR 0xB702 /* 2nd-3rd word func addr */
-
-#define RW_BIT_SIGNIFICANT_GROUP_ADDR 0xB902
-#define RW_SOURCE_RING_BRIDGE_NUMBER 0xBB01
-#define RW_TARGET_RING_NUMBER 0xBC01
-
-#define RW_HIC_INTERRUPT_MASK 0xC601
-
-#define SOURCE_ROUTING_SPANNING_BITS 0x00C0 /* Spanning Tree Frames */
-#define SOURCE_ROUTING_EXPLORER_BIT 0x0040 /* Explorer and Single Route */
-
- /* write */
-
-#define CSR_MSK_ALL 0x80 // Bic 587 Only
-#define CSR_MSKTINT 0x20
-#define CSR_MSKCBUSY 0x10
-#define CSR_CLRTINT 0x08
-#define CSR_CLRCBUSY 0x04
-#define CSR_WCSS 0x02
-#define CSR_CA 0x01
-
- /* read */
-
-#define CSR_TINT 0x20
-#define CSR_CINT 0x10
-#define CSR_TSTAT 0x08
-#define CSR_CSTAT 0x04
-#define CSR_FAULT 0x02
-#define CSR_CBUSY 0x01
-
-#define LAAR_MEM16ENB 0x80
-#define Zws16 0x20
-
-#define IRR_IEN 0x80
-#define Zws8 0x01
-
-#define IMCCR_EIL 0x04
-
-typedef struct {
- __u8 ac; /* Access Control */
- __u8 fc; /* Frame Control */
- __u8 da[6]; /* Dest Addr */
- __u8 sa[6]; /* Source Addr */
-
- __u16 vl; /* Vector Length */
- __u8 dc_sc; /* Dest/Source Class */
- __u8 vc; /* Vector Code */
- } MAC_HEADER;
-
-#define MAX_SUB_VECTOR_INFO (RX_DATA_BUFFER_SIZE - sizeof(MAC_HEADER) - 2)
-
-typedef struct
- {
- __u8 svl; /* Sub-vector Length */
- __u8 svi; /* Sub-vector Code */
- __u8 svv[MAX_SUB_VECTOR_INFO]; /* Sub-vector Info */
- } MAC_SUB_VECTOR;
-
-#endif /* __KERNEL__ */
-#endif /* __LINUX_SMCTR_H */
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
deleted file mode 100644
index b5e0855e4b39..000000000000
--- a/drivers/net/tokenring/tms380tr.c
+++ /dev/null
@@ -1,2306 +0,0 @@
-/*
- * tms380tr.c: A network driver library for Texas Instruments TMS380-based
- * Token Ring Adapters.
- *
- * Originally sktr.c: Written 1997 by Christoph Goos
- *
- * A fine result of the Linux Systems Network Architecture Project.
- * http://www.vanheusden.com/sna/
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * The following modules are currently available for card support:
- * - tmspci (Generic PCI card support)
- * - abyss (Madge PCI support)
- * - tmsisa (SysKonnect TR4/16 ISA)
- *
- * Sources:
- * - The hardware related parts of this driver are take from
- * the SysKonnect Token Ring driver for Windows NT.
- * - I used the IBM Token Ring driver 'ibmtr.c' as a base for this
- * driver, as well as the 'skeleton.c' driver by Donald Becker.
- * - Also various other drivers in the linux source tree were taken
- * as samples for some tasks.
- * - TI TMS380 Second-Generation Token Ring User's Guide
- * - TI datasheets for respective chips
- * - David Hein at Texas Instruments
- * - Various Madge employees
- *
- * Maintainer(s):
- * JS Jay Schulist jschlst@samba.org
- * CG Christoph Goos cgoos@syskonnect.de
- * AF Adam Fritzler
- * MLP Mike Phillips phillim@amtrak.com
- * JF Jochen Friedrich jochen@scram.de
- *
- * Modification History:
- * 29-Aug-97 CG Created
- * 04-Apr-98 CG Fixed problems caused by tok_timer_check
- * 10-Apr-98 CG Fixed lockups at cable disconnection
- * 27-May-98 JS Formated to Linux Kernel Format
- * 31-May-98 JS Hacked in PCI support
- * 16-Jun-98 JS Modulized for multiple cards with one driver
- * Sep-99 AF Renamed to tms380tr (supports more than SK's)
- * 23-Sep-99 AF Added Compaq and Thomas-Conrad PCI support
- * Fixed a bug causing double copies on PCI
- * Fixed for new multicast stuff (2.2/2.3)
- * 25-Sep-99 AF Uped TPL_NUM from 3 to 9
- * Removed extraneous 'No free TPL'
- * 22-Dec-99 AF Added Madge PCI Mk2 support and generalized
- * parts of the initilization procedure.
- * 30-Dec-99 AF Turned tms380tr into a library ala 8390.
- * Madge support is provided in the abyss module
- * Generic PCI support is in the tmspci module.
- * 30-Nov-00 JF Updated PCI code to support IO MMU via
- * pci_map_static(). Alpha uses this MMU for ISA
- * as well.
- * 14-Jan-01 JF Fix DMA on ifdown/ifup sequences. Some
- * cleanup.
- * 13-Jan-02 JF Add spinlock to fix race condition.
- * 09-Nov-02 JF Fixed printks to not SPAM the console during
- * normal operation.
- * 30-Dec-02 JF Removed incorrect __init from
- * tms380tr_init_card.
- * 22-Jul-05 JF Converted to dma-mapping.
- *
- * To do:
- * 1. Multi/Broadcast packet handling (this may have fixed itself)
- * 2. Write a sktrisa module that includes the old ISA support (done)
- * 3. Allow modules to load their own microcode
- * 4. Speed up the BUD process -- freezing the kernel for 3+sec is
- * quite unacceptable.
- * 5. Still a few remaining stalls when the cable is unplugged.
- */
-
-#ifdef MODULE
-static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, Adam Fritzler\n";
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/time.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/trdevice.h>
-#include <linux/firmware.h>
-#include <linux/bitops.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-
-#include "tms380tr.h" /* Our Stuff */
-
-/* Use 0 for production, 1 for verification, 2 for debug, and
- * 3 for very verbose debug.
- */
-#ifndef TMS380TR_DEBUG
-#define TMS380TR_DEBUG 0
-#endif
-static unsigned int tms380tr_debug = TMS380TR_DEBUG;
-
-/* Index to functions, as function prototypes.
- * Alphabetical by function name.
- */
-
-/* "A" */
-/* "B" */
-static int tms380tr_bringup_diags(struct net_device *dev);
-/* "C" */
-static void tms380tr_cancel_tx_queue(struct net_local* tp);
-static int tms380tr_chipset_init(struct net_device *dev);
-static void tms380tr_chk_irq(struct net_device *dev);
-static void tms380tr_chk_outstanding_cmds(struct net_device *dev);
-static void tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr);
-static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType);
-int tms380tr_close(struct net_device *dev);
-static void tms380tr_cmd_status_irq(struct net_device *dev);
-/* "D" */
-static void tms380tr_disable_interrupts(struct net_device *dev);
-#if TMS380TR_DEBUG > 0
-static void tms380tr_dump(unsigned char *Data, int length);
-#endif
-/* "E" */
-static void tms380tr_enable_interrupts(struct net_device *dev);
-static void tms380tr_exec_cmd(struct net_device *dev, unsigned short Command);
-static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue);
-/* "F" */
-/* "G" */
-static struct net_device_stats *tms380tr_get_stats(struct net_device *dev);
-/* "H" */
-static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-/* "I" */
-static int tms380tr_init_adapter(struct net_device *dev);
-static void tms380tr_init_ipb(struct net_local *tp);
-static void tms380tr_init_net_local(struct net_device *dev);
-static void tms380tr_init_opb(struct net_device *dev);
-/* "M" */
-/* "O" */
-int tms380tr_open(struct net_device *dev);
-static void tms380tr_open_adapter(struct net_device *dev);
-/* "P" */
-/* "R" */
-static void tms380tr_rcv_status_irq(struct net_device *dev);
-static int tms380tr_read_ptr(struct net_device *dev);
-static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data,
- unsigned short Address, int Length);
-static int tms380tr_reset_adapter(struct net_device *dev);
-static void tms380tr_reset_interrupt(struct net_device *dev);
-static void tms380tr_ring_status_irq(struct net_device *dev);
-/* "S" */
-static netdev_tx_t tms380tr_send_packet(struct sk_buff *skb,
- struct net_device *dev);
-static void tms380tr_set_multicast_list(struct net_device *dev);
-static int tms380tr_set_mac_address(struct net_device *dev, void *addr);
-/* "T" */
-static void tms380tr_timer_chk(unsigned long data);
-static void tms380tr_timer_end_wait(unsigned long data);
-static void tms380tr_tx_status_irq(struct net_device *dev);
-/* "U" */
-static void tms380tr_update_rcv_stats(struct net_local *tp,
- unsigned char DataPtr[], unsigned int Length);
-/* "W" */
-void tms380tr_wait(unsigned long time);
-static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status);
-static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status);
-
-#define SIFREADB(reg) \
- (((struct net_local *)netdev_priv(dev))->sifreadb(dev, reg))
-#define SIFWRITEB(val, reg) \
- (((struct net_local *)netdev_priv(dev))->sifwriteb(dev, val, reg))
-#define SIFREADW(reg) \
- (((struct net_local *)netdev_priv(dev))->sifreadw(dev, reg))
-#define SIFWRITEW(val, reg) \
- (((struct net_local *)netdev_priv(dev))->sifwritew(dev, val, reg))
-
-
-
-#if 0 /* TMS380TR_DEBUG > 0 */
-static int madgemc_sifprobe(struct net_device *dev)
-{
- unsigned char old, chk1, chk2;
-
- old = SIFREADB(SIFADR); /* Get the old SIFADR value */
-
- chk1 = 0; /* Begin with check value 0 */
- do {
- madgemc_setregpage(dev, 0);
- /* Write new SIFADR value */
- SIFWRITEB(chk1, SIFADR);
- chk2 = SIFREADB(SIFADR);
- if (chk2 != chk1)
- return -1;
-
- madgemc_setregpage(dev, 1);
- /* Read, invert and write */
- chk2 = SIFREADB(SIFADD);
- if (chk2 != chk1)
- return -1;
-
- madgemc_setregpage(dev, 0);
- chk2 ^= 0x0FE;
- SIFWRITEB(chk2, SIFADR);
-
- /* Read, invert and compare */
- madgemc_setregpage(dev, 1);
- chk2 = SIFREADB(SIFADD);
- madgemc_setregpage(dev, 0);
- chk2 ^= 0x0FE;
-
- if(chk1 != chk2)
- return -1; /* No adapter */
- chk1 -= 2;
- } while(chk1 != 0); /* Repeat 128 times (all byte values) */
-
- madgemc_setregpage(dev, 0); /* sanity */
- /* Restore the SIFADR value */
- SIFWRITEB(old, SIFADR);
-
- return 0;
-}
-#endif
-
-/*
- * Open/initialize the board. This is called sometime after
- * booting when the 'ifconfig' program is run.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is non-reboot way to recover if something goes wrong.
- */
-int tms380tr_open(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- /* init the spinlock */
- spin_lock_init(&tp->lock);
- init_timer(&tp->timer);
-
- /* Reset the hardware here. Don't forget to set the station address. */
-
-#if defined(CONFIG_ISA) && defined(CONFIG_ISA_DMA_API)
- if(dev->dma > 0)
- {
- unsigned long flags=claim_dma_lock();
- disable_dma(dev->dma);
- set_dma_mode(dev->dma, DMA_MODE_CASCADE);
- enable_dma(dev->dma);
- release_dma_lock(flags);
- }
-#endif
-
- err = tms380tr_chipset_init(dev);
- if(err)
- {
- printk(KERN_INFO "%s: Chipset initialization error\n",
- dev->name);
- return -1;
- }
-
- tp->timer.expires = jiffies + 30*HZ;
- tp->timer.function = tms380tr_timer_end_wait;
- tp->timer.data = (unsigned long)dev;
- add_timer(&tp->timer);
-
- printk(KERN_DEBUG "%s: Adapter RAM size: %dK\n",
- dev->name, tms380tr_read_ptr(dev));
-
- tms380tr_enable_interrupts(dev);
- tms380tr_open_adapter(dev);
-
- netif_start_queue(dev);
-
- /* Wait for interrupt from hardware. If interrupt does not come,
- * there will be a timeout from the timer.
- */
- tp->Sleeping = 1;
- interruptible_sleep_on(&tp->wait_for_tok_int);
- del_timer(&tp->timer);
-
- /* If AdapterVirtOpenFlag is 1, the adapter is now open for use */
- if(tp->AdapterVirtOpenFlag == 0)
- {
- tms380tr_disable_interrupts(dev);
- return -1;
- }
-
- tp->StartTime = jiffies;
-
- /* Start function control timer */
- tp->timer.expires = jiffies + 2*HZ;
- tp->timer.function = tms380tr_timer_chk;
- tp->timer.data = (unsigned long)dev;
- add_timer(&tp->timer);
-
- return 0;
-}
-
-/*
- * Timeout function while waiting for event
- */
-static void tms380tr_timer_end_wait(unsigned long data)
-{
- struct net_device *dev = (struct net_device*)data;
- struct net_local *tp = netdev_priv(dev);
-
- if(tp->Sleeping)
- {
- tp->Sleeping = 0;
- wake_up_interruptible(&tp->wait_for_tok_int);
- }
-}
-
-/*
- * Initialize the chipset
- */
-static int tms380tr_chipset_init(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int err;
-
- tms380tr_init_ipb(tp);
- tms380tr_init_opb(dev);
- tms380tr_init_net_local(dev);
-
- if(tms380tr_debug > 3)
- printk(KERN_DEBUG "%s: Resetting adapter...\n", dev->name);
- err = tms380tr_reset_adapter(dev);
- if(err < 0)
- return -1;
-
- if(tms380tr_debug > 3)
- printk(KERN_DEBUG "%s: Bringup diags...\n", dev->name);
- err = tms380tr_bringup_diags(dev);
- if(err < 0)
- return -1;
-
- if(tms380tr_debug > 3)
- printk(KERN_DEBUG "%s: Init adapter...\n", dev->name);
- err = tms380tr_init_adapter(dev);
- if(err < 0)
- return -1;
-
- if(tms380tr_debug > 3)
- printk(KERN_DEBUG "%s: Done!\n", dev->name);
- return 0;
-}
-
-/*
- * Initializes the net_local structure.
- */
-static void tms380tr_init_net_local(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- int i;
- dma_addr_t dmabuf;
-
- tp->scb.CMD = 0;
- tp->scb.Parm[0] = 0;
- tp->scb.Parm[1] = 0;
-
- tp->ssb.STS = 0;
- tp->ssb.Parm[0] = 0;
- tp->ssb.Parm[1] = 0;
- tp->ssb.Parm[2] = 0;
-
- tp->CMDqueue = 0;
-
- tp->AdapterOpenFlag = 0;
- tp->AdapterVirtOpenFlag = 0;
- tp->ScbInUse = 0;
- tp->OpenCommandIssued = 0;
- tp->ReOpenInProgress = 0;
- tp->HaltInProgress = 0;
- tp->TransmitHaltScheduled = 0;
- tp->LobeWireFaultLogged = 0;
- tp->LastOpenStatus = 0;
- tp->MaxPacketSize = DEFAULT_PACKET_SIZE;
-
- /* Create circular chain of transmit lists */
- for (i = 0; i < TPL_NUM; i++)
- {
- tp->Tpl[i].NextTPLAddr = htonl(((char *)(&tp->Tpl[(i+1) % TPL_NUM]) - (char *)tp) + tp->dmabuffer); /* DMA buffer may be MMU driven */
- tp->Tpl[i].Status = 0;
- tp->Tpl[i].FrameSize = 0;
- tp->Tpl[i].FragList[0].DataCount = 0;
- tp->Tpl[i].FragList[0].DataAddr = 0;
- tp->Tpl[i].NextTPLPtr = &tp->Tpl[(i+1) % TPL_NUM];
- tp->Tpl[i].MData = NULL;
- tp->Tpl[i].TPLIndex = i;
- tp->Tpl[i].DMABuff = 0;
- tp->Tpl[i].BusyFlag = 0;
- }
-
- tp->TplFree = tp->TplBusy = &tp->Tpl[0];
-
- /* Create circular chain of receive lists */
- for (i = 0; i < RPL_NUM; i++)
- {
- tp->Rpl[i].NextRPLAddr = htonl(((char *)(&tp->Rpl[(i+1) % RPL_NUM]) - (char *)tp) + tp->dmabuffer); /* DMA buffer may be MMU driven */
- tp->Rpl[i].Status = (RX_VALID | RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ);
- tp->Rpl[i].FrameSize = 0;
- tp->Rpl[i].FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize);
-
- /* Alloc skb and point adapter to data area */
- tp->Rpl[i].Skb = dev_alloc_skb(tp->MaxPacketSize);
- tp->Rpl[i].DMABuff = 0;
-
- /* skb == NULL ? then use local buffer */
- if(tp->Rpl[i].Skb == NULL)
- {
- tp->Rpl[i].SkbStat = SKB_UNAVAILABLE;
- tp->Rpl[i].FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[i] - (char *)tp) + tp->dmabuffer);
- tp->Rpl[i].MData = tp->LocalRxBuffers[i];
- }
- else /* SKB != NULL */
- {
- tp->Rpl[i].Skb->dev = dev;
- skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize);
-
- /* data unreachable for DMA ? then use local buffer */
- dmabuf = dma_map_single(tp->pdev, tp->Rpl[i].Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE);
- if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit))
- {
- tp->Rpl[i].SkbStat = SKB_DATA_COPY;
- tp->Rpl[i].FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[i] - (char *)tp) + tp->dmabuffer);
- tp->Rpl[i].MData = tp->LocalRxBuffers[i];
- }
- else /* DMA directly in skb->data */
- {
- tp->Rpl[i].SkbStat = SKB_DMA_DIRECT;
- tp->Rpl[i].FragList[0].DataAddr = htonl(dmabuf);
- tp->Rpl[i].MData = tp->Rpl[i].Skb->data;
- tp->Rpl[i].DMABuff = dmabuf;
- }
- }
-
- tp->Rpl[i].NextRPLPtr = &tp->Rpl[(i+1) % RPL_NUM];
- tp->Rpl[i].RPLIndex = i;
- }
-
- tp->RplHead = &tp->Rpl[0];
- tp->RplTail = &tp->Rpl[RPL_NUM-1];
- tp->RplTail->Status = (RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ);
-}
-
-/*
- * Initializes the initialisation parameter block.
- */
-static void tms380tr_init_ipb(struct net_local *tp)
-{
- tp->ipb.Init_Options = BURST_MODE;
- tp->ipb.CMD_Status_IV = 0;
- tp->ipb.TX_IV = 0;
- tp->ipb.RX_IV = 0;
- tp->ipb.Ring_Status_IV = 0;
- tp->ipb.SCB_Clear_IV = 0;
- tp->ipb.Adapter_CHK_IV = 0;
- tp->ipb.RX_Burst_Size = BURST_SIZE;
- tp->ipb.TX_Burst_Size = BURST_SIZE;
- tp->ipb.DMA_Abort_Thrhld = DMA_RETRIES;
- tp->ipb.SCB_Addr = 0;
- tp->ipb.SSB_Addr = 0;
-}
-
-/*
- * Initializes the open parameter block.
- */
-static void tms380tr_init_opb(struct net_device *dev)
-{
- struct net_local *tp;
- unsigned long Addr;
- unsigned short RplSize = RPL_SIZE;
- unsigned short TplSize = TPL_SIZE;
- unsigned short BufferSize = BUFFER_SIZE;
- int i;
-
- tp = netdev_priv(dev);
-
- tp->ocpl.OPENOptions = 0;
- tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION;
- tp->ocpl.FullDuplex = 0;
- tp->ocpl.FullDuplex |= OPEN_FULL_DUPLEX_OFF;
-
- /*
- * Set node address
- *
- * We go ahead and put it in the OPB even though on
- * most of the generic adapters this isn't required.
- * Its simpler this way. -- ASF
- */
- for (i=0;i<6;i++)
- tp->ocpl.NodeAddr[i] = ((unsigned char *)dev->dev_addr)[i];
-
- tp->ocpl.GroupAddr = 0;
- tp->ocpl.FunctAddr = 0;
- tp->ocpl.RxListSize = cpu_to_be16((unsigned short)RplSize);
- tp->ocpl.TxListSize = cpu_to_be16((unsigned short)TplSize);
- tp->ocpl.BufSize = cpu_to_be16((unsigned short)BufferSize);
- tp->ocpl.Reserved = 0;
- tp->ocpl.TXBufMin = TX_BUF_MIN;
- tp->ocpl.TXBufMax = TX_BUF_MAX;
-
- Addr = htonl(((char *)tp->ProductID - (char *)tp) + tp->dmabuffer);
-
- tp->ocpl.ProdIDAddr[0] = LOWORD(Addr);
- tp->ocpl.ProdIDAddr[1] = HIWORD(Addr);
-}
-
-/*
- * Send OPEN command to adapter
- */
-static void tms380tr_open_adapter(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- if(tp->OpenCommandIssued)
- return;
-
- tp->OpenCommandIssued = 1;
- tms380tr_exec_cmd(dev, OC_OPEN);
-}
-
-/*
- * Clear the adapter's interrupt flag. Clear system interrupt enable
- * (SINTEN): disable adapter to system interrupts.
- */
-static void tms380tr_disable_interrupts(struct net_device *dev)
-{
- SIFWRITEB(0, SIFACL);
-}
-
-/*
- * Set the adapter's interrupt flag. Set system interrupt enable
- * (SINTEN): enable adapter to system interrupts.
- */
-static void tms380tr_enable_interrupts(struct net_device *dev)
-{
- SIFWRITEB(ACL_SINTEN, SIFACL);
-}
-
-/*
- * Put command in command queue, try to execute it.
- */
-static void tms380tr_exec_cmd(struct net_device *dev, unsigned short Command)
-{
- struct net_local *tp = netdev_priv(dev);
-
- tp->CMDqueue |= Command;
- tms380tr_chk_outstanding_cmds(dev);
-}
-
-static void tms380tr_timeout(struct net_device *dev)
-{
- /*
- * If we get here, some higher level has decided we are broken.
- * There should really be a "kick me" function call instead.
- *
- * Resetting the token ring adapter takes a long time so just
- * fake transmission time and go on trying. Our own timeout
- * routine is in tms380tr_timer_chk()
- */
- dev->trans_start = jiffies; /* prevent tx timeout */
- netif_wake_queue(dev);
-}
-
-/*
- * Gets skb from system, queues it and checks if it can be sent
- */
-static netdev_tx_t tms380tr_send_packet(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- netdev_tx_t rc;
-
- rc = tms380tr_hardware_send_packet(skb, dev);
- if(tp->TplFree->NextTPLPtr->BusyFlag)
- netif_stop_queue(dev);
- return rc;
-}
-
-/*
- * Move frames into adapter tx queue
- */
-static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb,
- struct net_device *dev)
-{
- TPL *tpl;
- short length;
- unsigned char *buf;
- unsigned long flags;
- int i;
- dma_addr_t dmabuf, newbuf;
- struct net_local *tp = netdev_priv(dev);
-
- /* Try to get a free TPL from the chain.
- *
- * NOTE: We *must* always leave one unused TPL in the chain,
- * because otherwise the adapter might send frames twice.
- */
- spin_lock_irqsave(&tp->lock, flags);
- if(tp->TplFree->NextTPLPtr->BusyFlag) { /* No free TPL */
- if (tms380tr_debug > 0)
- printk(KERN_DEBUG "%s: No free TPL\n", dev->name);
- spin_unlock_irqrestore(&tp->lock, flags);
- return NETDEV_TX_BUSY;
- }
-
- dmabuf = 0;
-
- /* Is buffer reachable for Busmaster-DMA? */
-
- length = skb->len;
- dmabuf = dma_map_single(tp->pdev, skb->data, length, DMA_TO_DEVICE);
- if(tp->dmalimit && (dmabuf + length > tp->dmalimit)) {
- /* Copy frame to local buffer */
- dma_unmap_single(tp->pdev, dmabuf, length, DMA_TO_DEVICE);
- dmabuf = 0;
- i = tp->TplFree->TPLIndex;
- buf = tp->LocalTxBuffers[i];
- skb_copy_from_linear_data(skb, buf, length);
- newbuf = ((char *)buf - (char *)tp) + tp->dmabuffer;
- }
- else {
- /* Send direct from skb->data */
- newbuf = dmabuf;
- buf = skb->data;
- }
- /* Source address in packet? */
- tms380tr_chk_src_addr(buf, dev->dev_addr);
- tp->LastSendTime = jiffies;
- tpl = tp->TplFree; /* Get the "free" TPL */
- tpl->BusyFlag = 1; /* Mark TPL as busy */
- tp->TplFree = tpl->NextTPLPtr;
-
- /* Save the skb for delayed return of skb to system */
- tpl->Skb = skb;
- tpl->DMABuff = dmabuf;
- tpl->FragList[0].DataCount = cpu_to_be16((unsigned short)length);
- tpl->FragList[0].DataAddr = htonl(newbuf);
-
- /* Write the data length in the transmit list. */
- tpl->FrameSize = cpu_to_be16((unsigned short)length);
- tpl->MData = buf;
-
- /* Transmit the frame and set the status values. */
- tms380tr_write_tpl_status(tpl, TX_VALID | TX_START_FRAME
- | TX_END_FRAME | TX_PASS_SRC_ADDR
- | TX_FRAME_IRQ);
-
- /* Let adapter send the frame. */
- tms380tr_exec_sifcmd(dev, CMD_TX_VALID);
- spin_unlock_irqrestore(&tp->lock, flags);
-
- return NETDEV_TX_OK;
-}
-
-/*
- * Write the given value to the 'Status' field of the specified TPL.
- * NOTE: This function should be used whenever the status of any TPL must be
- * modified by the driver, because the compiler may otherwise change the
- * order of instructions such that writing the TPL status may be executed at
- * an undesirable time. When this function is used, the status is always
- * written when the function is called.
- */
-static void tms380tr_write_tpl_status(TPL *tpl, unsigned int Status)
-{
- tpl->Status = Status;
-}
-
-static void tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr)
-{
- unsigned char SRBit;
-
- if((((unsigned long)frame[8]) & ~0x80) != 0) /* Compare 4 bytes */
- return;
- if((unsigned short)frame[12] != 0) /* Compare 2 bytes */
- return;
-
- SRBit = frame[8] & 0x80;
- memcpy(&frame[8], hw_addr, 6);
- frame[8] |= SRBit;
-}
-
-/*
- * The timer routine: Check if adapter still open and working, reopen if not.
- */
-static void tms380tr_timer_chk(unsigned long data)
-{
- struct net_device *dev = (struct net_device*)data;
- struct net_local *tp = netdev_priv(dev);
-
- if(tp->HaltInProgress)
- return;
-
- tms380tr_chk_outstanding_cmds(dev);
- if(time_before(tp->LastSendTime + SEND_TIMEOUT, jiffies) &&
- (tp->TplFree != tp->TplBusy))
- {
- /* Anything to send, but stalled too long */
- tp->LastSendTime = jiffies;
- tms380tr_exec_cmd(dev, OC_CLOSE); /* Does reopen automatically */
- }
-
- tp->timer.expires = jiffies + 2*HZ;
- add_timer(&tp->timer);
-
- if(tp->AdapterOpenFlag || tp->ReOpenInProgress)
- return;
- tp->ReOpenInProgress = 1;
- tms380tr_open_adapter(dev);
-}
-
-/*
- * The typical workload of the driver: Handle the network interface interrupts.
- */
-irqreturn_t tms380tr_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct net_local *tp;
- unsigned short irq_type;
- int handled = 0;
-
- tp = netdev_priv(dev);
-
- irq_type = SIFREADW(SIFSTS);
-
- while(irq_type & STS_SYSTEM_IRQ) {
- handled = 1;
- irq_type &= STS_IRQ_MASK;
-
- if(!tms380tr_chk_ssb(tp, irq_type)) {
- printk(KERN_DEBUG "%s: DATA LATE occurred\n", dev->name);
- break;
- }
-
- switch(irq_type) {
- case STS_IRQ_RECEIVE_STATUS:
- tms380tr_reset_interrupt(dev);
- tms380tr_rcv_status_irq(dev);
- break;
-
- case STS_IRQ_TRANSMIT_STATUS:
- /* Check if TRANSMIT.HALT command is complete */
- if(tp->ssb.Parm[0] & COMMAND_COMPLETE) {
- tp->TransmitCommandActive = 0;
- tp->TransmitHaltScheduled = 0;
-
- /* Issue a new transmit command. */
- tms380tr_exec_cmd(dev, OC_TRANSMIT);
- }
-
- tms380tr_reset_interrupt(dev);
- tms380tr_tx_status_irq(dev);
- break;
-
- case STS_IRQ_COMMAND_STATUS:
- /* The SSB contains status of last command
- * other than receive/transmit.
- */
- tms380tr_cmd_status_irq(dev);
- break;
-
- case STS_IRQ_SCB_CLEAR:
- /* The SCB is free for another command. */
- tp->ScbInUse = 0;
- tms380tr_chk_outstanding_cmds(dev);
- break;
-
- case STS_IRQ_RING_STATUS:
- tms380tr_ring_status_irq(dev);
- break;
-
- case STS_IRQ_ADAPTER_CHECK:
- tms380tr_chk_irq(dev);
- break;
-
- case STS_IRQ_LLC_STATUS:
- printk(KERN_DEBUG "tms380tr: unexpected LLC status IRQ\n");
- break;
-
- case STS_IRQ_TIMER:
- printk(KERN_DEBUG "tms380tr: unexpected Timer IRQ\n");
- break;
-
- case STS_IRQ_RECEIVE_PENDING:
- printk(KERN_DEBUG "tms380tr: unexpected Receive Pending IRQ\n");
- break;
-
- default:
- printk(KERN_DEBUG "Unknown Token Ring IRQ (0x%04x)\n", irq_type);
- break;
- }
-
- /* Reset system interrupt if not already done. */
- if(irq_type != STS_IRQ_TRANSMIT_STATUS &&
- irq_type != STS_IRQ_RECEIVE_STATUS) {
- tms380tr_reset_interrupt(dev);
- }
-
- irq_type = SIFREADW(SIFSTS);
- }
-
- return IRQ_RETVAL(handled);
-}
-
-/*
- * Reset the INTERRUPT SYSTEM bit and issue SSB CLEAR command.
- */
-static void tms380tr_reset_interrupt(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- SSB *ssb = &tp->ssb;
-
- /*
- * [Workaround for "Data Late"]
- * Set all fields of the SSB to well-defined values so we can
- * check if the adapter has written the SSB.
- */
-
- ssb->STS = (unsigned short) -1;
- ssb->Parm[0] = (unsigned short) -1;
- ssb->Parm[1] = (unsigned short) -1;
- ssb->Parm[2] = (unsigned short) -1;
-
- /* Free SSB by issuing SSB_CLEAR command after reading IRQ code
- * and clear STS_SYSTEM_IRQ bit: enable adapter for further interrupts.
- */
- tms380tr_exec_sifcmd(dev, CMD_SSB_CLEAR | CMD_CLEAR_SYSTEM_IRQ);
-}
-
-/*
- * Check if the SSB has actually been written by the adapter.
- */
-static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType)
-{
- SSB *ssb = &tp->ssb; /* The address of the SSB. */
-
- /* C 0 1 2 INTERRUPT CODE
- * - - - - --------------
- * 1 1 1 1 TRANSMIT STATUS
- * 1 1 1 1 RECEIVE STATUS
- * 1 ? ? 0 COMMAND STATUS
- * 0 0 0 0 SCB CLEAR
- * 1 1 0 0 RING STATUS
- * 0 0 0 0 ADAPTER CHECK
- *
- * 0 = SSB field not affected by interrupt
- * 1 = SSB field is affected by interrupt
- *
- * C = SSB ADDRESS +0: COMMAND
- * 0 = SSB ADDRESS +2: STATUS 0
- * 1 = SSB ADDRESS +4: STATUS 1
- * 2 = SSB ADDRESS +6: STATUS 2
- */
-
- /* Check if this interrupt does use the SSB. */
-
- if(IrqType != STS_IRQ_TRANSMIT_STATUS &&
- IrqType != STS_IRQ_RECEIVE_STATUS &&
- IrqType != STS_IRQ_COMMAND_STATUS &&
- IrqType != STS_IRQ_RING_STATUS)
- {
- return 1; /* SSB not involved. */
- }
-
- /* Note: All fields of the SSB have been set to all ones (-1) after it
- * has last been used by the software (see DriverIsr()).
- *
- * Check if the affected SSB fields are still unchanged.
- */
-
- if(ssb->STS == (unsigned short) -1)
- return 0; /* Command field not yet available. */
- if(IrqType == STS_IRQ_COMMAND_STATUS)
- return 1; /* Status fields not always affected. */
- if(ssb->Parm[0] == (unsigned short) -1)
- return 0; /* Status 1 field not yet available. */
- if(IrqType == STS_IRQ_RING_STATUS)
- return 1; /* Status 2 & 3 fields not affected. */
-
- /* Note: At this point, the interrupt is either TRANSMIT or RECEIVE. */
- if(ssb->Parm[1] == (unsigned short) -1)
- return 0; /* Status 2 field not yet available. */
- if(ssb->Parm[2] == (unsigned short) -1)
- return 0; /* Status 3 field not yet available. */
-
- return 1; /* All SSB fields have been written by the adapter. */
-}
-
-/*
- * Evaluates the command results status in the SSB status field.
- */
-static void tms380tr_cmd_status_irq(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned short ssb_cmd, ssb_parm_0;
- unsigned short ssb_parm_1;
- char *open_err = "Open error -";
- char *code_err = "Open code -";
-
- /* Copy the ssb values to local variables */
- ssb_cmd = tp->ssb.STS;
- ssb_parm_0 = tp->ssb.Parm[0];
- ssb_parm_1 = tp->ssb.Parm[1];
-
- if(ssb_cmd == OPEN)
- {
- tp->Sleeping = 0;
- if(!tp->ReOpenInProgress)
- wake_up_interruptible(&tp->wait_for_tok_int);
-
- tp->OpenCommandIssued = 0;
- tp->ScbInUse = 0;
-
- if((ssb_parm_0 & 0x00FF) == GOOD_COMPLETION)
- {
- /* Success, the adapter is open. */
- tp->LobeWireFaultLogged = 0;
- tp->AdapterOpenFlag = 1;
- tp->AdapterVirtOpenFlag = 1;
- tp->TransmitCommandActive = 0;
- tms380tr_exec_cmd(dev, OC_TRANSMIT);
- tms380tr_exec_cmd(dev, OC_RECEIVE);
-
- if(tp->ReOpenInProgress)
- tp->ReOpenInProgress = 0;
-
- return;
- }
- else /* The adapter did not open. */
- {
- if(ssb_parm_0 & NODE_ADDR_ERROR)
- printk(KERN_INFO "%s: Node address error\n",
- dev->name);
- if(ssb_parm_0 & LIST_SIZE_ERROR)
- printk(KERN_INFO "%s: List size error\n",
- dev->name);
- if(ssb_parm_0 & BUF_SIZE_ERROR)
- printk(KERN_INFO "%s: Buffer size error\n",
- dev->name);
- if(ssb_parm_0 & TX_BUF_COUNT_ERROR)
- printk(KERN_INFO "%s: Tx buffer count error\n",
- dev->name);
- if(ssb_parm_0 & INVALID_OPEN_OPTION)
- printk(KERN_INFO "%s: Invalid open option\n",
- dev->name);
- if(ssb_parm_0 & OPEN_ERROR)
- {
- /* Show the open phase. */
- switch(ssb_parm_0 & OPEN_PHASES_MASK)
- {
- case LOBE_MEDIA_TEST:
- if(!tp->LobeWireFaultLogged)
- {
- tp->LobeWireFaultLogged = 1;
- printk(KERN_INFO "%s: %s Lobe wire fault (check cable !).\n", dev->name, open_err);
- }
- tp->ReOpenInProgress = 1;
- tp->AdapterOpenFlag = 0;
- tp->AdapterVirtOpenFlag = 1;
- tms380tr_open_adapter(dev);
- return;
-
- case PHYSICAL_INSERTION:
- printk(KERN_INFO "%s: %s Physical insertion.\n", dev->name, open_err);
- break;
-
- case ADDRESS_VERIFICATION:
- printk(KERN_INFO "%s: %s Address verification.\n", dev->name, open_err);
- break;
-
- case PARTICIPATION_IN_RING_POLL:
- printk(KERN_INFO "%s: %s Participation in ring poll.\n", dev->name, open_err);
- break;
-
- case REQUEST_INITIALISATION:
- printk(KERN_INFO "%s: %s Request initialisation.\n", dev->name, open_err);
- break;
-
- case FULLDUPLEX_CHECK:
- printk(KERN_INFO "%s: %s Full duplex check.\n", dev->name, open_err);
- break;
-
- default:
- printk(KERN_INFO "%s: %s Unknown open phase\n", dev->name, open_err);
- break;
- }
-
- /* Show the open errors. */
- switch(ssb_parm_0 & OPEN_ERROR_CODES_MASK)
- {
- case OPEN_FUNCTION_FAILURE:
- printk(KERN_INFO "%s: %s OPEN_FUNCTION_FAILURE", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_FUNCTION_FAILURE;
- break;
-
- case OPEN_SIGNAL_LOSS:
- printk(KERN_INFO "%s: %s OPEN_SIGNAL_LOSS\n", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_SIGNAL_LOSS;
- break;
-
- case OPEN_TIMEOUT:
- printk(KERN_INFO "%s: %s OPEN_TIMEOUT\n", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_TIMEOUT;
- break;
-
- case OPEN_RING_FAILURE:
- printk(KERN_INFO "%s: %s OPEN_RING_FAILURE\n", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_RING_FAILURE;
- break;
-
- case OPEN_RING_BEACONING:
- printk(KERN_INFO "%s: %s OPEN_RING_BEACONING\n", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_RING_BEACONING;
- break;
-
- case OPEN_DUPLICATE_NODEADDR:
- printk(KERN_INFO "%s: %s OPEN_DUPLICATE_NODEADDR\n", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_DUPLICATE_NODEADDR;
- break;
-
- case OPEN_REQUEST_INIT:
- printk(KERN_INFO "%s: %s OPEN_REQUEST_INIT\n", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_REQUEST_INIT;
- break;
-
- case OPEN_REMOVE_RECEIVED:
- printk(KERN_INFO "%s: %s OPEN_REMOVE_RECEIVED", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_REMOVE_RECEIVED;
- break;
-
- case OPEN_FULLDUPLEX_SET:
- printk(KERN_INFO "%s: %s OPEN_FULLDUPLEX_SET\n", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_FULLDUPLEX_SET;
- break;
-
- default:
- printk(KERN_INFO "%s: %s Unknown open err code", dev->name, code_err);
- tp->LastOpenStatus =
- OPEN_FUNCTION_FAILURE;
- break;
- }
- }
-
- tp->AdapterOpenFlag = 0;
- tp->AdapterVirtOpenFlag = 0;
-
- return;
- }
- }
- else
- {
- if(ssb_cmd != READ_ERROR_LOG)
- return;
-
- /* Add values from the error log table to the MAC
- * statistics counters and update the errorlogtable
- * memory.
- */
- tp->MacStat.line_errors += tp->errorlogtable.Line_Error;
- tp->MacStat.burst_errors += tp->errorlogtable.Burst_Error;
- tp->MacStat.A_C_errors += tp->errorlogtable.ARI_FCI_Error;
- tp->MacStat.lost_frames += tp->errorlogtable.Lost_Frame_Error;
- tp->MacStat.recv_congest_count += tp->errorlogtable.Rx_Congest_Error;
- tp->MacStat.rx_errors += tp->errorlogtable.Rx_Congest_Error;
- tp->MacStat.frame_copied_errors += tp->errorlogtable.Frame_Copied_Error;
- tp->MacStat.token_errors += tp->errorlogtable.Token_Error;
- tp->MacStat.dummy1 += tp->errorlogtable.DMA_Bus_Error;
- tp->MacStat.dummy1 += tp->errorlogtable.DMA_Parity_Error;
- tp->MacStat.abort_delimiters += tp->errorlogtable.AbortDelimeters;
- tp->MacStat.frequency_errors += tp->errorlogtable.Frequency_Error;
- tp->MacStat.internal_errors += tp->errorlogtable.Internal_Error;
- }
-}
-
-/*
- * The inverse routine to tms380tr_open().
- */
-int tms380tr_close(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- netif_stop_queue(dev);
-
- del_timer(&tp->timer);
-
- /* Flush the Tx and disable Rx here. */
-
- tp->HaltInProgress = 1;
- tms380tr_exec_cmd(dev, OC_CLOSE);
- tp->timer.expires = jiffies + 1*HZ;
- tp->timer.function = tms380tr_timer_end_wait;
- tp->timer.data = (unsigned long)dev;
- add_timer(&tp->timer);
-
- tms380tr_enable_interrupts(dev);
-
- tp->Sleeping = 1;
- interruptible_sleep_on(&tp->wait_for_tok_int);
- tp->TransmitCommandActive = 0;
-
- del_timer(&tp->timer);
- tms380tr_disable_interrupts(dev);
-
-#if defined(CONFIG_ISA) && defined(CONFIG_ISA_DMA_API)
- if(dev->dma > 0)
- {
- unsigned long flags=claim_dma_lock();
- disable_dma(dev->dma);
- release_dma_lock(flags);
- }
-#endif
-
- SIFWRITEW(0xFF00, SIFCMD);
-#if 0
- if(dev->dma > 0) /* what the? */
- SIFWRITEB(0xff, POSREG);
-#endif
- tms380tr_cancel_tx_queue(tp);
-
- return 0;
-}
-
-/*
- * Get the current statistics. This may be called with the card open
- * or closed.
- */
-static struct net_device_stats *tms380tr_get_stats(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- return (struct net_device_stats *)&tp->MacStat;
-}
-
-/*
- * Set or clear the multicast filter for this adapter.
- */
-static void tms380tr_set_multicast_list(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned int OpenOptions;
-
- OpenOptions = tp->ocpl.OPENOptions &
- ~(PASS_ADAPTER_MAC_FRAMES
- | PASS_ATTENTION_FRAMES
- | PASS_BEACON_MAC_FRAMES
- | COPY_ALL_MAC_FRAMES
- | COPY_ALL_NON_MAC_FRAMES);
-
- tp->ocpl.FunctAddr = 0;
-
- if(dev->flags & IFF_PROMISC)
- /* Enable promiscuous mode */
- OpenOptions |= COPY_ALL_NON_MAC_FRAMES |
- COPY_ALL_MAC_FRAMES;
- else
- {
- if(dev->flags & IFF_ALLMULTI)
- {
- /* Disable promiscuous mode, use normal mode. */
- tp->ocpl.FunctAddr = 0xFFFFFFFF;
- }
- else
- {
- struct netdev_hw_addr *ha;
-
- netdev_for_each_mc_addr(ha, dev) {
- ((char *)(&tp->ocpl.FunctAddr))[0] |=
- ha->addr[2];
- ((char *)(&tp->ocpl.FunctAddr))[1] |=
- ha->addr[3];
- ((char *)(&tp->ocpl.FunctAddr))[2] |=
- ha->addr[4];
- ((char *)(&tp->ocpl.FunctAddr))[3] |=
- ha->addr[5];
- }
- }
- tms380tr_exec_cmd(dev, OC_SET_FUNCT_ADDR);
- }
-
- tp->ocpl.OPENOptions = OpenOptions;
- tms380tr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS);
-}
-
-/*
- * Wait for some time (microseconds)
- */
-void tms380tr_wait(unsigned long time)
-{
-#if 0
- long tmp;
-
- tmp = jiffies + time/(1000000/HZ);
- do {
- tmp = schedule_timeout_interruptible(tmp);
- } while(time_after(tmp, jiffies));
-#else
- mdelay(time / 1000);
-#endif
-}
-
-/*
- * Write a command value to the SIFCMD register
- */
-static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue)
-{
- unsigned short cmd;
- unsigned short SifStsValue;
- unsigned long loop_counter;
-
- WriteValue = ((WriteValue ^ CMD_SYSTEM_IRQ) | CMD_INTERRUPT_ADAPTER);
- cmd = (unsigned short)WriteValue;
- loop_counter = 0,5 * 800000;
- do {
- SifStsValue = SIFREADW(SIFSTS);
- } while((SifStsValue & CMD_INTERRUPT_ADAPTER) && loop_counter--);
- SIFWRITEW(cmd, SIFCMD);
-}
-
-/*
- * Processes adapter hardware reset, halts adapter and downloads firmware,
- * clears the halt bit.
- */
-static int tms380tr_reset_adapter(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned short *fw_ptr;
- unsigned short count, c, count2;
- const struct firmware *fw_entry = NULL;
-
- if (request_firmware(&fw_entry, "tms380tr.bin", tp->pdev) != 0) {
- printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n",
- dev->name, "tms380tr.bin");
- return -1;
- }
-
- fw_ptr = (unsigned short *)fw_entry->data;
- count2 = fw_entry->size / 2;
-
- /* Hardware adapter reset */
- SIFWRITEW(ACL_ARESET, SIFACL);
- tms380tr_wait(40);
-
- c = SIFREADW(SIFACL);
- tms380tr_wait(20);
-
- if(dev->dma == 0) /* For PCI adapters */
- {
- c &= ~(ACL_NSELOUT0 | ACL_NSELOUT1); /* Clear bits */
- if(tp->setnselout)
- c |= (*tp->setnselout)(dev);
- }
-
- /* In case a command is pending - forget it */
- tp->ScbInUse = 0;
-
- c &= ~ACL_ARESET; /* Clear adapter reset bit */
- c |= ACL_CPHALT; /* Halt adapter CPU, allow download */
- c |= ACL_BOOT;
- c |= ACL_SINTEN;
- c &= ~ACL_PSDMAEN; /* Clear pseudo dma bit */
- SIFWRITEW(c, SIFACL);
- tms380tr_wait(40);
-
- count = 0;
- /* Download firmware via DIO interface: */
- do {
- if (count2 < 3) continue;
-
- /* Download first address part */
- SIFWRITEW(*fw_ptr, SIFADX);
- fw_ptr++;
- count2--;
- /* Download second address part */
- SIFWRITEW(*fw_ptr, SIFADD);
- fw_ptr++;
- count2--;
-
- if((count = *fw_ptr) != 0) /* Load loop counter */
- {
- fw_ptr++; /* Download block data */
- count2--;
- if (count > count2) continue;
-
- for(; count > 0; count--)
- {
- SIFWRITEW(*fw_ptr, SIFINC);
- fw_ptr++;
- count2--;
- }
- }
- else /* Stop, if last block downloaded */
- {
- c = SIFREADW(SIFACL);
- c &= (~ACL_CPHALT | ACL_SINTEN);
-
- /* Clear CPHALT and start BUD */
- SIFWRITEW(c, SIFACL);
- release_firmware(fw_entry);
- return 1;
- }
- } while(count == 0);
-
- release_firmware(fw_entry);
- printk(KERN_INFO "%s: Adapter Download Failed\n", dev->name);
- return -1;
-}
-
-MODULE_FIRMWARE("tms380tr.bin");
-
-/*
- * Starts bring up diagnostics of token ring adapter and evaluates
- * diagnostic results.
- */
-static int tms380tr_bringup_diags(struct net_device *dev)
-{
- int loop_cnt, retry_cnt;
- unsigned short Status;
-
- tms380tr_wait(HALF_SECOND);
- tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET);
- tms380tr_wait(HALF_SECOND);
-
- retry_cnt = BUD_MAX_RETRIES; /* maximal number of retrys */
-
- do {
- retry_cnt--;
- if(tms380tr_debug > 3)
- printk(KERN_DEBUG "BUD-Status: ");
- loop_cnt = BUD_MAX_LOOPCNT; /* maximum: three seconds*/
- do { /* Inspect BUD results */
- loop_cnt--;
- tms380tr_wait(HALF_SECOND);
- Status = SIFREADW(SIFSTS);
- Status &= STS_MASK;
-
- if(tms380tr_debug > 3)
- printk(KERN_DEBUG " %04X\n", Status);
- /* BUD successfully completed */
- if(Status == STS_INITIALIZE)
- return 1;
- /* Unrecoverable hardware error, BUD not completed? */
- } while((loop_cnt > 0) && ((Status & (STS_ERROR | STS_TEST))
- != (STS_ERROR | STS_TEST)));
-
- /* Error preventing completion of BUD */
- if(retry_cnt > 0)
- {
- printk(KERN_INFO "%s: Adapter Software Reset.\n",
- dev->name);
- tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET);
- tms380tr_wait(HALF_SECOND);
- }
- } while(retry_cnt > 0);
-
- Status = SIFREADW(SIFSTS);
-
- printk(KERN_INFO "%s: Hardware error\n", dev->name);
- /* Hardware error occurred! */
- Status &= 0x001f;
- if (Status & 0x0010)
- printk(KERN_INFO "%s: BUD Error: Timeout\n", dev->name);
- else if ((Status & 0x000f) > 6)
- printk(KERN_INFO "%s: BUD Error: Illegal Failure\n", dev->name);
- else
- printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f);
-
- return -1;
-}
-
-/*
- * Copy initialisation data to adapter memory, beginning at address
- * 1:0A00; Starting DMA test and evaluating result bits.
- */
-static int tms380tr_init_adapter(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- const unsigned char SCB_Test[6] = {0x00, 0x00, 0xC1, 0xE2, 0xD4, 0x8B};
- const unsigned char SSB_Test[8] = {0xFF, 0xFF, 0xD1, 0xD7,
- 0xC5, 0xD9, 0xC3, 0xD4};
- void *ptr = (void *)&tp->ipb;
- unsigned short *ipb_ptr = (unsigned short *)ptr;
- unsigned char *cb_ptr = (unsigned char *) &tp->scb;
- unsigned char *sb_ptr = (unsigned char *) &tp->ssb;
- unsigned short Status;
- int i, loop_cnt, retry_cnt;
-
- /* Normalize: byte order low/high, word order high/low! (only IPB!) */
- tp->ipb.SCB_Addr = SWAPW(((char *)&tp->scb - (char *)tp) + tp->dmabuffer);
- tp->ipb.SSB_Addr = SWAPW(((char *)&tp->ssb - (char *)tp) + tp->dmabuffer);
-
- if(tms380tr_debug > 3)
- {
- printk(KERN_DEBUG "%s: buffer (real): %lx\n", dev->name, (long) &tp->scb);
- printk(KERN_DEBUG "%s: buffer (virt): %lx\n", dev->name, (long) ((char *)&tp->scb - (char *)tp) + (long) tp->dmabuffer);
- printk(KERN_DEBUG "%s: buffer (DMA) : %lx\n", dev->name, (long) tp->dmabuffer);
- printk(KERN_DEBUG "%s: buffer (tp) : %lx\n", dev->name, (long) tp);
- }
- /* Maximum: three initialization retries */
- retry_cnt = INIT_MAX_RETRIES;
-
- do {
- retry_cnt--;
-
- /* Transfer initialization block */
- SIFWRITEW(0x0001, SIFADX);
-
- /* To address 0001:0A00 of adapter RAM */
- SIFWRITEW(0x0A00, SIFADD);
-
- /* Write 11 words to adapter RAM */
- for(i = 0; i < 11; i++)
- SIFWRITEW(ipb_ptr[i], SIFINC);
-
- /* Execute SCB adapter command */
- tms380tr_exec_sifcmd(dev, CMD_EXECUTE);
-
- loop_cnt = INIT_MAX_LOOPCNT; /* Maximum: 11 seconds */
-
- /* While remaining retries, no error and not completed */
- do {
- Status = 0;
- loop_cnt--;
- tms380tr_wait(HALF_SECOND);
-
- /* Mask interesting status bits */
- Status = SIFREADW(SIFSTS);
- Status &= STS_MASK;
- } while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0) &&
- ((Status & STS_ERROR) == 0) && (loop_cnt != 0));
-
- if((Status & (STS_INITIALIZE | STS_ERROR | STS_TEST)) == 0)
- {
- /* Initialization completed without error */
- i = 0;
- do { /* Test if contents of SCB is valid */
- if(SCB_Test[i] != *(cb_ptr + i))
- {
- printk(KERN_INFO "%s: DMA failed\n", dev->name);
- /* DMA data error: wrong data in SCB */
- return -1;
- }
- i++;
- } while(i < 6);
-
- i = 0;
- do { /* Test if contents of SSB is valid */
- if(SSB_Test[i] != *(sb_ptr + i))
- /* DMA data error: wrong data in SSB */
- return -1;
- i++;
- } while (i < 8);
-
- return 1; /* Adapter successfully initialized */
- }
- else
- {
- if((Status & STS_ERROR) != 0)
- {
- /* Initialization error occurred */
- Status = SIFREADW(SIFSTS);
- Status &= STS_ERROR_MASK;
- /* ShowInitialisationErrorCode(Status); */
- printk(KERN_INFO "%s: Status error: %d\n", dev->name, Status);
- return -1; /* Unrecoverable error */
- }
- else
- {
- if(retry_cnt > 0)
- {
- /* Reset adapter and try init again */
- tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET);
- tms380tr_wait(HALF_SECOND);
- }
- }
- }
- } while(retry_cnt > 0);
-
- printk(KERN_INFO "%s: Retry exceeded\n", dev->name);
- return -1;
-}
-
-/*
- * Check for outstanding commands in command queue and tries to execute
- * command immediately. Corresponding command flag in command queue is cleared.
- */
-static void tms380tr_chk_outstanding_cmds(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned long Addr = 0;
-
- if(tp->CMDqueue == 0)
- return; /* No command execution */
-
- /* If SCB in use: no command */
- if(tp->ScbInUse == 1)
- return;
-
- /* Check if adapter is opened, avoiding COMMAND_REJECT
- * interrupt by the adapter!
- */
- if (tp->AdapterOpenFlag == 0) {
- if (tp->CMDqueue & OC_OPEN) {
- /* Execute OPEN command */
- tp->CMDqueue ^= OC_OPEN;
-
- Addr = htonl(((char *)&tp->ocpl - (char *)tp) + tp->dmabuffer);
- tp->scb.Parm[0] = LOWORD(Addr);
- tp->scb.Parm[1] = HIWORD(Addr);
- tp->scb.CMD = OPEN;
- } else
- /* No OPEN command queued, but adapter closed. Note:
- * We'll try to re-open the adapter in DriverPoll()
- */
- return; /* No adapter command issued */
- } else {
- /* Adapter is open; evaluate command queue: try to execute
- * outstanding commands (depending on priority!) CLOSE
- * command queued
- */
- if (tp->CMDqueue & OC_CLOSE) {
- tp->CMDqueue ^= OC_CLOSE;
- tp->AdapterOpenFlag = 0;
- tp->scb.Parm[0] = 0; /* Parm[0], Parm[1] are ignored */
- tp->scb.Parm[1] = 0; /* but should be set to zero! */
- tp->scb.CMD = CLOSE;
- if(!tp->HaltInProgress)
- tp->CMDqueue |= OC_OPEN; /* re-open adapter */
- else
- tp->CMDqueue = 0; /* no more commands */
- } else if (tp->CMDqueue & OC_RECEIVE) {
- tp->CMDqueue ^= OC_RECEIVE;
- Addr = htonl(((char *)tp->RplHead - (char *)tp) + tp->dmabuffer);
- tp->scb.Parm[0] = LOWORD(Addr);
- tp->scb.Parm[1] = HIWORD(Addr);
- tp->scb.CMD = RECEIVE;
- } else if (tp->CMDqueue & OC_TRANSMIT_HALT) {
- /* NOTE: TRANSMIT.HALT must be checked
- * before TRANSMIT.
- */
- tp->CMDqueue ^= OC_TRANSMIT_HALT;
- tp->scb.CMD = TRANSMIT_HALT;
-
- /* Parm[0] and Parm[1] are ignored
- * but should be set to zero!
- */
- tp->scb.Parm[0] = 0;
- tp->scb.Parm[1] = 0;
- } else if (tp->CMDqueue & OC_TRANSMIT) {
- /* NOTE: TRANSMIT must be
- * checked after TRANSMIT.HALT
- */
- if (tp->TransmitCommandActive) {
- if (!tp->TransmitHaltScheduled) {
- tp->TransmitHaltScheduled = 1;
- tms380tr_exec_cmd(dev, OC_TRANSMIT_HALT);
- }
- tp->TransmitCommandActive = 0;
- return;
- }
-
- tp->CMDqueue ^= OC_TRANSMIT;
- tms380tr_cancel_tx_queue(tp);
- Addr = htonl(((char *)tp->TplBusy - (char *)tp) + tp->dmabuffer);
- tp->scb.Parm[0] = LOWORD(Addr);
- tp->scb.Parm[1] = HIWORD(Addr);
- tp->scb.CMD = TRANSMIT;
- tp->TransmitCommandActive = 1;
- } else if (tp->CMDqueue & OC_MODIFY_OPEN_PARMS) {
- tp->CMDqueue ^= OC_MODIFY_OPEN_PARMS;
- tp->scb.Parm[0] = tp->ocpl.OPENOptions; /* new OPEN options*/
- tp->scb.Parm[0] |= ENABLE_FULL_DUPLEX_SELECTION;
- tp->scb.Parm[1] = 0; /* is ignored but should be zero */
- tp->scb.CMD = MODIFY_OPEN_PARMS;
- } else if (tp->CMDqueue & OC_SET_FUNCT_ADDR) {
- tp->CMDqueue ^= OC_SET_FUNCT_ADDR;
- tp->scb.Parm[0] = LOWORD(tp->ocpl.FunctAddr);
- tp->scb.Parm[1] = HIWORD(tp->ocpl.FunctAddr);
- tp->scb.CMD = SET_FUNCT_ADDR;
- } else if (tp->CMDqueue & OC_SET_GROUP_ADDR) {
- tp->CMDqueue ^= OC_SET_GROUP_ADDR;
- tp->scb.Parm[0] = LOWORD(tp->ocpl.GroupAddr);
- tp->scb.Parm[1] = HIWORD(tp->ocpl.GroupAddr);
- tp->scb.CMD = SET_GROUP_ADDR;
- } else if (tp->CMDqueue & OC_READ_ERROR_LOG) {
- tp->CMDqueue ^= OC_READ_ERROR_LOG;
- Addr = htonl(((char *)&tp->errorlogtable - (char *)tp) + tp->dmabuffer);
- tp->scb.Parm[0] = LOWORD(Addr);
- tp->scb.Parm[1] = HIWORD(Addr);
- tp->scb.CMD = READ_ERROR_LOG;
- } else {
- printk(KERN_WARNING "CheckForOutstandingCommand: unknown Command\n");
- tp->CMDqueue = 0;
- return;
- }
- }
-
- tp->ScbInUse = 1; /* Set semaphore: SCB in use. */
-
- /* Execute SCB and generate IRQ when done. */
- tms380tr_exec_sifcmd(dev, CMD_EXECUTE | CMD_SCB_REQUEST);
-}
-
-/*
- * IRQ conditions: signal loss on the ring, transmit or receive of beacon
- * frames (disabled if bit 1 of OPEN option is set); report error MAC
- * frame transmit (disabled if bit 2 of OPEN option is set); open or short
- * circuit fault on the lobe is detected; remove MAC frame received;
- * error counter overflow (255); opened adapter is the only station in ring.
- * After some of the IRQs the adapter is closed!
- */
-static void tms380tr_ring_status_irq(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
-
- tp->CurrentRingStatus = be16_to_cpu((unsigned short)tp->ssb.Parm[0]);
-
- /* First: fill up statistics */
- if(tp->ssb.Parm[0] & SIGNAL_LOSS)
- {
- printk(KERN_INFO "%s: Signal Loss\n", dev->name);
- tp->MacStat.line_errors++;
- }
-
- /* Adapter is closed, but initialized */
- if(tp->ssb.Parm[0] & LOBE_WIRE_FAULT)
- {
- printk(KERN_INFO "%s: Lobe Wire Fault, Reopen Adapter\n",
- dev->name);
- tp->MacStat.line_errors++;
- }
-
- if(tp->ssb.Parm[0] & RING_RECOVERY)
- printk(KERN_INFO "%s: Ring Recovery\n", dev->name);
-
- /* Counter overflow: read error log */
- if(tp->ssb.Parm[0] & COUNTER_OVERFLOW)
- {
- printk(KERN_INFO "%s: Counter Overflow\n", dev->name);
- tms380tr_exec_cmd(dev, OC_READ_ERROR_LOG);
- }
-
- /* Adapter is closed, but initialized */
- if(tp->ssb.Parm[0] & REMOVE_RECEIVED)
- printk(KERN_INFO "%s: Remove Received, Reopen Adapter\n",
- dev->name);
-
- /* Adapter is closed, but initialized */
- if(tp->ssb.Parm[0] & AUTO_REMOVAL_ERROR)
- printk(KERN_INFO "%s: Auto Removal Error, Reopen Adapter\n",
- dev->name);
-
- if(tp->ssb.Parm[0] & HARD_ERROR)
- printk(KERN_INFO "%s: Hard Error\n", dev->name);
-
- if(tp->ssb.Parm[0] & SOFT_ERROR)
- printk(KERN_INFO "%s: Soft Error\n", dev->name);
-
- if(tp->ssb.Parm[0] & TRANSMIT_BEACON)
- printk(KERN_INFO "%s: Transmit Beacon\n", dev->name);
-
- if(tp->ssb.Parm[0] & SINGLE_STATION)
- printk(KERN_INFO "%s: Single Station\n", dev->name);
-
- /* Check if adapter has been closed */
- if(tp->ssb.Parm[0] & ADAPTER_CLOSED)
- {
- printk(KERN_INFO "%s: Adapter closed (Reopening),"
- "CurrentRingStat %x\n",
- dev->name, tp->CurrentRingStatus);
- tp->AdapterOpenFlag = 0;
- tms380tr_open_adapter(dev);
- }
-}
-
-/*
- * Issued if adapter has encountered an unrecoverable hardware
- * or software error.
- */
-static void tms380tr_chk_irq(struct net_device *dev)
-{
- int i;
- unsigned short AdapterCheckBlock[4];
- struct net_local *tp = netdev_priv(dev);
-
- tp->AdapterOpenFlag = 0; /* Adapter closed now */
-
- /* Page number of adapter memory */
- SIFWRITEW(0x0001, SIFADX);
- /* Address offset */
- SIFWRITEW(CHECKADDR, SIFADR);
-
- /* Reading 8 byte adapter check block. */
- for(i = 0; i < 4; i++)
- AdapterCheckBlock[i] = SIFREADW(SIFINC);
-
- if(tms380tr_debug > 3)
- {
- printk(KERN_DEBUG "%s: AdapterCheckBlock: ", dev->name);
- for (i = 0; i < 4; i++)
- printk("%04X", AdapterCheckBlock[i]);
- printk("\n");
- }
-
- switch(AdapterCheckBlock[0])
- {
- case DIO_PARITY:
- printk(KERN_INFO "%s: DIO parity error\n", dev->name);
- break;
-
- case DMA_READ_ABORT:
- printk(KERN_INFO "%s DMA read operation aborted:\n",
- dev->name);
- switch (AdapterCheckBlock[1])
- {
- case 0:
- printk(KERN_INFO "Timeout\n");
- printk(KERN_INFO "Address: %04X %04X\n",
- AdapterCheckBlock[2],
- AdapterCheckBlock[3]);
- break;
-
- case 1:
- printk(KERN_INFO "Parity error\n");
- printk(KERN_INFO "Address: %04X %04X\n",
- AdapterCheckBlock[2],
- AdapterCheckBlock[3]);
- break;
-
- case 2:
- printk(KERN_INFO "Bus error\n");
- printk(KERN_INFO "Address: %04X %04X\n",
- AdapterCheckBlock[2],
- AdapterCheckBlock[3]);
- break;
-
- default:
- printk(KERN_INFO "Unknown error.\n");
- break;
- }
- break;
-
- case DMA_WRITE_ABORT:
- printk(KERN_INFO "%s: DMA write operation aborted:\n",
- dev->name);
- switch (AdapterCheckBlock[1])
- {
- case 0:
- printk(KERN_INFO "Timeout\n");
- printk(KERN_INFO "Address: %04X %04X\n",
- AdapterCheckBlock[2],
- AdapterCheckBlock[3]);
- break;
-
- case 1:
- printk(KERN_INFO "Parity error\n");
- printk(KERN_INFO "Address: %04X %04X\n",
- AdapterCheckBlock[2],
- AdapterCheckBlock[3]);
- break;
-
- case 2:
- printk(KERN_INFO "Bus error\n");
- printk(KERN_INFO "Address: %04X %04X\n",
- AdapterCheckBlock[2],
- AdapterCheckBlock[3]);
- break;
-
- default:
- printk(KERN_INFO "Unknown error.\n");
- break;
- }
- break;
-
- case ILLEGAL_OP_CODE:
- printk(KERN_INFO "%s: Illegal operation code in firmware\n",
- dev->name);
- /* Parm[0-3]: adapter internal register R13-R15 */
- break;
-
- case PARITY_ERRORS:
- printk(KERN_INFO "%s: Adapter internal bus parity error\n",
- dev->name);
- /* Parm[0-3]: adapter internal register R13-R15 */
- break;
-
- case RAM_DATA_ERROR:
- printk(KERN_INFO "%s: RAM data error\n", dev->name);
- /* Parm[0-1]: MSW/LSW address of RAM location. */
- break;
-
- case RAM_PARITY_ERROR:
- printk(KERN_INFO "%s: RAM parity error\n", dev->name);
- /* Parm[0-1]: MSW/LSW address of RAM location. */
- break;
-
- case RING_UNDERRUN:
- printk(KERN_INFO "%s: Internal DMA underrun detected\n",
- dev->name);
- break;
-
- case INVALID_IRQ:
- printk(KERN_INFO "%s: Unrecognized interrupt detected\n",
- dev->name);
- /* Parm[0-3]: adapter internal register R13-R15 */
- break;
-
- case INVALID_ERROR_IRQ:
- printk(KERN_INFO "%s: Unrecognized error interrupt detected\n",
- dev->name);
- /* Parm[0-3]: adapter internal register R13-R15 */
- break;
-
- case INVALID_XOP:
- printk(KERN_INFO "%s: Unrecognized XOP request detected\n",
- dev->name);
- /* Parm[0-3]: adapter internal register R13-R15 */
- break;
-
- default:
- printk(KERN_INFO "%s: Unknown status", dev->name);
- break;
- }
-
- if(tms380tr_chipset_init(dev) == 1)
- {
- /* Restart of firmware successful */
- tp->AdapterOpenFlag = 1;
- }
-}
-
-/*
- * Internal adapter pointer to RAM data are copied from adapter into
- * host system.
- */
-static int tms380tr_read_ptr(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned short adapterram;
-
- tms380tr_read_ram(dev, (unsigned char *)&tp->intptrs.BurnedInAddrPtr,
- ADAPTER_INT_PTRS, 16);
- tms380tr_read_ram(dev, (unsigned char *)&adapterram,
- cpu_to_be16((unsigned short)tp->intptrs.AdapterRAMPtr), 2);
- return be16_to_cpu(adapterram);
-}
-
-/*
- * Reads a number of bytes from adapter to system memory.
- */
-static void tms380tr_read_ram(struct net_device *dev, unsigned char *Data,
- unsigned short Address, int Length)
-{
- int i;
- unsigned short old_sifadx, old_sifadr, InWord;
-
- /* Save the current values */
- old_sifadx = SIFREADW(SIFADX);
- old_sifadr = SIFREADW(SIFADR);
-
- /* Page number of adapter memory */
- SIFWRITEW(0x0001, SIFADX);
- /* Address offset in adapter RAM */
- SIFWRITEW(Address, SIFADR);
-
- /* Copy len byte from adapter memory to system data area. */
- i = 0;
- for(;;)
- {
- InWord = SIFREADW(SIFINC);
-
- *(Data + i) = HIBYTE(InWord); /* Write first byte */
- if(++i == Length) /* All is done break */
- break;
-
- *(Data + i) = LOBYTE(InWord); /* Write second byte */
- if (++i == Length) /* All is done break */
- break;
- }
-
- /* Restore original values */
- SIFWRITEW(old_sifadx, SIFADX);
- SIFWRITEW(old_sifadr, SIFADR);
-}
-
-/*
- * Cancel all queued packets in the transmission queue.
- */
-static void tms380tr_cancel_tx_queue(struct net_local* tp)
-{
- TPL *tpl;
-
- /*
- * NOTE: There must not be an active TRANSMIT command pending, when
- * this function is called.
- */
- if(tp->TransmitCommandActive)
- return;
-
- for(;;)
- {
- tpl = tp->TplBusy;
- if(!tpl->BusyFlag)
- break;
- /* "Remove" TPL from busy list. */
- tp->TplBusy = tpl->NextTPLPtr;
- tms380tr_write_tpl_status(tpl, 0); /* Clear VALID bit */
- tpl->BusyFlag = 0; /* "free" TPL */
-
- printk(KERN_INFO "Cancel tx (%08lXh).\n", (unsigned long)tpl);
- if (tpl->DMABuff)
- dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE);
- dev_kfree_skb_any(tpl->Skb);
- }
-}
-
-/*
- * This function is called whenever a transmit interrupt is generated by the
- * adapter. For a command complete interrupt, it is checked if we have to
- * issue a new transmit command or not.
- */
-static void tms380tr_tx_status_irq(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned char HighByte, HighAc, LowAc;
- TPL *tpl;
-
- /* NOTE: At this point the SSB from TRANSMIT STATUS is no longer
- * available, because the CLEAR SSB command has already been issued.
- *
- * Process all complete transmissions.
- */
-
- for(;;)
- {
- tpl = tp->TplBusy;
- if(!tpl->BusyFlag || (tpl->Status
- & (TX_VALID | TX_FRAME_COMPLETE))
- != TX_FRAME_COMPLETE)
- {
- break;
- }
-
- /* "Remove" TPL from busy list. */
- tp->TplBusy = tpl->NextTPLPtr ;
-
- /* Check the transmit status field only for directed frames*/
- if(DIRECTED_FRAME(tpl) && (tpl->Status & TX_ERROR) == 0)
- {
- HighByte = GET_TRANSMIT_STATUS_HIGH_BYTE(tpl->Status);
- HighAc = GET_FRAME_STATUS_HIGH_AC(HighByte);
- LowAc = GET_FRAME_STATUS_LOW_AC(HighByte);
-
- if((HighAc != LowAc) || (HighAc == AC_NOT_RECOGNIZED))
- {
- printk(KERN_DEBUG "%s: (DA=%08lX not recognized)\n",
- dev->name,
- *(unsigned long *)&tpl->MData[2+2]);
- }
- else
- {
- if(tms380tr_debug > 3)
- printk(KERN_DEBUG "%s: Directed frame tx'd\n",
- dev->name);
- }
- }
- else
- {
- if(!DIRECTED_FRAME(tpl))
- {
- if(tms380tr_debug > 3)
- printk(KERN_DEBUG "%s: Broadcast frame tx'd\n",
- dev->name);
- }
- }
-
- tp->MacStat.tx_packets++;
- if (tpl->DMABuff)
- dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE);
- dev_kfree_skb_irq(tpl->Skb);
- tpl->BusyFlag = 0; /* "free" TPL */
- }
-
- if(!tp->TplFree->NextTPLPtr->BusyFlag)
- netif_wake_queue(dev);
-}
-
-/*
- * Called if a frame receive interrupt is generated by the adapter.
- * Check if the frame is valid and indicate it to system.
- */
-static void tms380tr_rcv_status_irq(struct net_device *dev)
-{
- struct net_local *tp = netdev_priv(dev);
- unsigned char *ReceiveDataPtr;
- struct sk_buff *skb;
- unsigned int Length, Length2;
- RPL *rpl;
- RPL *SaveHead;
- dma_addr_t dmabuf;
-
- /* NOTE: At this point the SSB from RECEIVE STATUS is no longer
- * available, because the CLEAR SSB command has already been issued.
- *
- * Process all complete receives.
- */
-
- for(;;)
- {
- rpl = tp->RplHead;
- if(rpl->Status & RX_VALID)
- break; /* RPL still in use by adapter */
-
- /* Forward RPLHead pointer to next list. */
- SaveHead = tp->RplHead;
- tp->RplHead = rpl->NextRPLPtr;
-
- /* Get the frame size (Byte swap for Intel).
- * Do this early (see workaround comment below)
- */
- Length = be16_to_cpu(rpl->FrameSize);
-
- /* Check if the Frame_Start, Frame_End and
- * Frame_Complete bits are set.
- */
- if((rpl->Status & VALID_SINGLE_BUFFER_FRAME)
- == VALID_SINGLE_BUFFER_FRAME)
- {
- ReceiveDataPtr = rpl->MData;
-
- /* Workaround for delayed write of FrameSize on ISA
- * (FrameSize is false but valid-bit is reset)
- * Frame size is set to zero when the RPL is freed.
- * Length2 is there because there have also been
- * cases where the FrameSize was partially written
- */
- Length2 = be16_to_cpu(rpl->FrameSize);
-
- if(Length == 0 || Length != Length2)
- {
- tp->RplHead = SaveHead;
- break; /* Return to tms380tr_interrupt */
- }
- tms380tr_update_rcv_stats(tp,ReceiveDataPtr,Length);
-
- if(tms380tr_debug > 3)
- printk(KERN_DEBUG "%s: Packet Length %04X (%d)\n",
- dev->name, Length, Length);
-
- /* Indicate the received frame to system the
- * adapter does the Source-Routing padding for
- * us. See: OpenOptions in tms380tr_init_opb()
- */
- skb = rpl->Skb;
- if(rpl->SkbStat == SKB_UNAVAILABLE)
- {
- /* Try again to allocate skb */
- skb = dev_alloc_skb(tp->MaxPacketSize);
- if(skb == NULL)
- {
- /* Update Stats ?? */
- }
- else
- {
- skb_put(skb, tp->MaxPacketSize);
- rpl->SkbStat = SKB_DATA_COPY;
- ReceiveDataPtr = rpl->MData;
- }
- }
-
- if(skb && (rpl->SkbStat == SKB_DATA_COPY ||
- rpl->SkbStat == SKB_DMA_DIRECT))
- {
- if(rpl->SkbStat == SKB_DATA_COPY)
- skb_copy_to_linear_data(skb, ReceiveDataPtr,
- Length);
-
- /* Deliver frame to system */
- rpl->Skb = NULL;
- skb_trim(skb,Length);
- skb->protocol = tr_type_trans(skb,dev);
- netif_rx(skb);
- }
- }
- else /* Invalid frame */
- {
- if(rpl->Skb != NULL)
- dev_kfree_skb_irq(rpl->Skb);
-
- /* Skip list. */
- if(rpl->Status & RX_START_FRAME)
- /* Frame start bit is set -> overflow. */
- tp->MacStat.rx_errors++;
- }
- if (rpl->DMABuff)
- dma_unmap_single(tp->pdev, rpl->DMABuff, tp->MaxPacketSize, DMA_TO_DEVICE);
- rpl->DMABuff = 0;
-
- /* Allocate new skb for rpl */
- rpl->Skb = dev_alloc_skb(tp->MaxPacketSize);
- /* skb == NULL ? then use local buffer */
- if(rpl->Skb == NULL)
- {
- rpl->SkbStat = SKB_UNAVAILABLE;
- rpl->FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[rpl->RPLIndex] - (char *)tp) + tp->dmabuffer);
- rpl->MData = tp->LocalRxBuffers[rpl->RPLIndex];
- }
- else /* skb != NULL */
- {
- rpl->Skb->dev = dev;
- skb_put(rpl->Skb, tp->MaxPacketSize);
-
- /* Data unreachable for DMA ? then use local buffer */
- dmabuf = dma_map_single(tp->pdev, rpl->Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE);
- if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit))
- {
- rpl->SkbStat = SKB_DATA_COPY;
- rpl->FragList[0].DataAddr = htonl(((char *)tp->LocalRxBuffers[rpl->RPLIndex] - (char *)tp) + tp->dmabuffer);
- rpl->MData = tp->LocalRxBuffers[rpl->RPLIndex];
- }
- else
- {
- /* DMA directly in skb->data */
- rpl->SkbStat = SKB_DMA_DIRECT;
- rpl->FragList[0].DataAddr = htonl(dmabuf);
- rpl->MData = rpl->Skb->data;
- rpl->DMABuff = dmabuf;
- }
- }
-
- rpl->FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize);
- rpl->FrameSize = 0;
-
- /* Pass the last RPL back to the adapter */
- tp->RplTail->FrameSize = 0;
-
- /* Reset the CSTAT field in the list. */
- tms380tr_write_rpl_status(tp->RplTail, RX_VALID | RX_FRAME_IRQ);
-
- /* Current RPL becomes last one in list. */
- tp->RplTail = tp->RplTail->NextRPLPtr;
-
- /* Inform adapter about RPL valid. */
- tms380tr_exec_sifcmd(dev, CMD_RX_VALID);
- }
-}
-
-/*
- * This function should be used whenever the status of any RPL must be
- * modified by the driver, because the compiler may otherwise change the
- * order of instructions such that writing the RPL status may be executed
- * at an undesirable time. When this function is used, the status is
- * always written when the function is called.
- */
-static void tms380tr_write_rpl_status(RPL *rpl, unsigned int Status)
-{
- rpl->Status = Status;
-}
-
-/*
- * The function updates the statistic counters in mac->MacStat.
- * It differtiates between directed and broadcast/multicast ( ==functional)
- * frames.
- */
-static void tms380tr_update_rcv_stats(struct net_local *tp, unsigned char DataPtr[],
- unsigned int Length)
-{
- tp->MacStat.rx_packets++;
- tp->MacStat.rx_bytes += Length;
-
- /* Test functional bit */
- if(DataPtr[2] & GROUP_BIT)
- tp->MacStat.multicast++;
-}
-
-static int tms380tr_set_mac_address(struct net_device *dev, void *addr)
-{
- struct net_local *tp = netdev_priv(dev);
- struct sockaddr *saddr = addr;
-
- if (tp->AdapterOpenFlag || tp->AdapterVirtOpenFlag) {
- printk(KERN_WARNING "%s: Cannot set MAC/LAA address while card is open\n", dev->name);
- return -EIO;
- }
- memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len);
- return 0;
-}
-
-#if TMS380TR_DEBUG > 0
-/*
- * Dump Packet (data)
- */
-static void tms380tr_dump(unsigned char *Data, int length)
-{
- int i, j;
-
- for (i = 0, j = 0; i < length / 8; i++, j += 8)
- {
- printk(KERN_DEBUG "%02x %02x %02x %02x %02x %02x %02x %02x\n",
- Data[j+0],Data[j+1],Data[j+2],Data[j+3],
- Data[j+4],Data[j+5],Data[j+6],Data[j+7]);
- }
-}
-#endif
-
-void tmsdev_term(struct net_device *dev)
-{
- struct net_local *tp;
-
- tp = netdev_priv(dev);
- dma_unmap_single(tp->pdev, tp->dmabuffer, sizeof(struct net_local),
- DMA_BIDIRECTIONAL);
-}
-
-const struct net_device_ops tms380tr_netdev_ops = {
- .ndo_open = tms380tr_open,
- .ndo_stop = tms380tr_close,
- .ndo_start_xmit = tms380tr_send_packet,
- .ndo_tx_timeout = tms380tr_timeout,
- .ndo_get_stats = tms380tr_get_stats,
- .ndo_set_rx_mode = tms380tr_set_multicast_list,
- .ndo_set_mac_address = tms380tr_set_mac_address,
-};
-EXPORT_SYMBOL(tms380tr_netdev_ops);
-
-int tmsdev_init(struct net_device *dev, struct device *pdev)
-{
- struct net_local *tms_local;
-
- memset(netdev_priv(dev), 0, sizeof(struct net_local));
- tms_local = netdev_priv(dev);
- init_waitqueue_head(&tms_local->wait_for_tok_int);
- if (pdev->dma_mask)
- tms_local->dmalimit = *pdev->dma_mask;
- else
- return -ENOMEM;
- tms_local->pdev = pdev;
- tms_local->dmabuffer = dma_map_single(pdev, (void *)tms_local,
- sizeof(struct net_local), DMA_BIDIRECTIONAL);
- if (tms_local->dmabuffer + sizeof(struct net_local) >
- tms_local->dmalimit)
- {
- printk(KERN_INFO "%s: Memory not accessible for DMA\n",
- dev->name);
- tmsdev_term(dev);
- return -ENOMEM;
- }
-
- dev->netdev_ops = &tms380tr_netdev_ops;
- dev->watchdog_timeo = HZ;
-
- return 0;
-}
-
-EXPORT_SYMBOL(tms380tr_open);
-EXPORT_SYMBOL(tms380tr_close);
-EXPORT_SYMBOL(tms380tr_interrupt);
-EXPORT_SYMBOL(tmsdev_init);
-EXPORT_SYMBOL(tmsdev_term);
-EXPORT_SYMBOL(tms380tr_wait);
-
-#ifdef MODULE
-
-static struct module *TMS380_module = NULL;
-
-int init_module(void)
-{
- printk(KERN_DEBUG "%s", version);
-
- TMS380_module = &__this_module;
- return 0;
-}
-
-void cleanup_module(void)
-{
- TMS380_module = NULL;
-}
-#endif
-
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/net/tokenring/tms380tr.h b/drivers/net/tokenring/tms380tr.h
deleted file mode 100644
index e5a617c586c2..000000000000
--- a/drivers/net/tokenring/tms380tr.h
+++ /dev/null
@@ -1,1141 +0,0 @@
-/*
- * tms380tr.h: TI TMS380 Token Ring driver for Linux
- *
- * Authors:
- * - Christoph Goos <cgoos@syskonnect.de>
- * - Adam Fritzler
- */
-
-#ifndef __LINUX_TMS380TR_H
-#define __LINUX_TMS380TR_H
-
-#ifdef __KERNEL__
-
-#include <linux/interrupt.h>
-
-/* module prototypes */
-extern const struct net_device_ops tms380tr_netdev_ops;
-int tms380tr_open(struct net_device *dev);
-int tms380tr_close(struct net_device *dev);
-irqreturn_t tms380tr_interrupt(int irq, void *dev_id);
-int tmsdev_init(struct net_device *dev, struct device *pdev);
-void tmsdev_term(struct net_device *dev);
-void tms380tr_wait(unsigned long time);
-
-#define TMS380TR_MAX_ADAPTERS 7
-
-#define SEND_TIMEOUT 10*HZ
-
-#define TR_RCF_LONGEST_FRAME_MASK 0x0070
-#define TR_RCF_FRAME4K 0x0030
-
-/*------------------------------------------------------------------*/
-/* Bit order for adapter communication with DMA */
-/* -------------------------------------------------------------- */
-/* Bit 8 | 9| 10| 11|| 12| 13| 14| 15|| 0| 1| 2| 3|| 4| 5| 6| 7| */
-/* -------------------------------------------------------------- */
-/* The bytes in a word must be byte swapped. Also, if a double */
-/* word is used for storage, then the words, as well as the bytes, */
-/* must be swapped. */
-/* Bit order for adapter communication with DIO */
-/* -------------------------------------------------------------- */
-/* Bit 0 | 1| 2| 3|| 4| 5| 6| 7|| 8| 9| 10| 11|| 12| 13| 14| 15| */
-/* -------------------------------------------------------------- */
-/*------------------------------------------------------------------*/
-
-/* Swap words of a long. */
-#define SWAPW(x) (((x) << 16) | ((x) >> 16))
-
-/* Get the low byte of a word. */
-#define LOBYTE(w) ((unsigned char)(w))
-
-/* Get the high byte of a word. */
-#define HIBYTE(w) ((unsigned char)((unsigned short)(w) >> 8))
-
-/* Get the low word of a long. */
-#define LOWORD(l) ((unsigned short)(l))
-
-/* Get the high word of a long. */
-#define HIWORD(l) ((unsigned short)((unsigned long)(l) >> 16))
-
-
-
-/* Token ring adapter I/O addresses for normal mode. */
-
-/*
- * The SIF registers. Common to all adapters.
- */
-/* Basic SIF (SRSX = 0) */
-#define SIFDAT 0x00 /* SIF/DMA data. */
-#define SIFINC 0x02 /* IO Word data with auto increment. */
-#define SIFINH 0x03 /* IO Byte data with auto increment. */
-#define SIFADR 0x04 /* SIF/DMA Address. */
-#define SIFCMD 0x06 /* SIF Command. */
-#define SIFSTS 0x06 /* SIF Status. */
-
-/* "Extended" SIF (SRSX = 1) */
-#define SIFACL 0x08 /* SIF Adapter Control Register. */
-#define SIFADD 0x0a /* SIF/DMA Address. -- 0x0a */
-#define SIFADX 0x0c /* 0x0c */
-#define DMALEN 0x0e /* SIF DMA length. -- 0x0e */
-
-/*
- * POS Registers. Only for ISA Adapters.
- */
-#define POSREG 0x10 /* Adapter Program Option Select (POS)
- * Register: base IO address + 16 byte.
- */
-#define POSREG_2 24L /* only for TR4/16+ adapter
- * base IO address + 24 byte. -- 0x18
- */
-
-/* SIFCMD command codes (high-low) */
-#define CMD_INTERRUPT_ADAPTER 0x8000 /* Cause internal adapter interrupt */
-#define CMD_ADAPTER_RESET 0x4000 /* Hardware reset of adapter */
-#define CMD_SSB_CLEAR 0x2000 /* Acknowledge to adapter to
- * system interrupts.
- */
-#define CMD_EXECUTE 0x1000 /* Execute SCB command */
-#define CMD_SCB_REQUEST 0x0800 /* Request adapter to interrupt
- * system when SCB is available for
- * another command.
- */
-#define CMD_RX_CONTINUE 0x0400 /* Continue receive after odd pointer
- * stop. (odd pointer receive method)
- */
-#define CMD_RX_VALID 0x0200 /* Now actual RPL is valid. */
-#define CMD_TX_VALID 0x0100 /* Now actual TPL is valid. (valid
- * bit receive/transmit method)
- */
-#define CMD_SYSTEM_IRQ 0x0080 /* Adapter-to-attached-system
- * interrupt is reset.
- */
-#define CMD_CLEAR_SYSTEM_IRQ 0x0080 /* Clear SYSTEM_INTERRUPT bit.
- * (write: 1=ignore, 0=reset)
- */
-#define EXEC_SOFT_RESET 0xFF00 /* adapter soft reset. (restart
- * adapter after hardware reset)
- */
-
-
-/* ACL commands (high-low) */
-#define ACL_SWHLDA 0x0800 /* Software hold acknowledge. */
-#define ACL_SWDDIR 0x0400 /* Data transfer direction. */
-#define ACL_SWHRQ 0x0200 /* Pseudo DMA operation. */
-#define ACL_PSDMAEN 0x0100 /* Enable pseudo system DMA. */
-#define ACL_ARESET 0x0080 /* Adapter hardware reset command.
- * (held in reset condition as
- * long as bit is set)
- */
-#define ACL_CPHALT 0x0040 /* Communication processor halt.
- * (can only be set while ACL_ARESET
- * bit is set; prevents adapter
- * processor from executing code while
- * downloading firmware)
- */
-#define ACL_BOOT 0x0020
-#define ACL_SINTEN 0x0008 /* System interrupt enable/disable
- * (1/0): can be written if ACL_ARESET
- * is zero.
- */
-#define ACL_PEN 0x0004
-
-#define ACL_NSELOUT0 0x0002
-#define ACL_NSELOUT1 0x0001 /* NSELOUTx have a card-specific
- * meaning for setting ring speed.
- */
-
-#define PS_DMA_MASK (ACL_SWHRQ | ACL_PSDMAEN)
-
-
-/* SIFSTS register return codes (high-low) */
-#define STS_SYSTEM_IRQ 0x0080 /* Adapter-to-attached-system
- * interrupt is valid.
- */
-#define STS_INITIALIZE 0x0040 /* INITIALIZE status. (ready to
- * initialize)
- */
-#define STS_TEST 0x0020 /* TEST status. (BUD not completed) */
-#define STS_ERROR 0x0010 /* ERROR status. (unrecoverable
- * HW error occurred)
- */
-#define STS_MASK 0x00F0 /* Mask interesting status bits. */
-#define STS_ERROR_MASK 0x000F /* Get Error Code by masking the
- * interrupt code bits.
- */
-#define ADAPTER_INT_PTRS 0x0A00 /* Address offset of adapter internal
- * pointers 01:0a00 (high-low) have to
- * be read after init and before open.
- */
-
-
-/* Interrupt Codes (only MAC IRQs) */
-#define STS_IRQ_ADAPTER_CHECK 0x0000 /* unrecoverable hardware or
- * software error.
- */
-#define STS_IRQ_RING_STATUS 0x0004 /* SSB is updated with ring status. */
-#define STS_IRQ_LLC_STATUS 0x0005 /* Not used in MAC-only microcode */
-#define STS_IRQ_SCB_CLEAR 0x0006 /* SCB clear, following an
- * SCB_REQUEST IRQ.
- */
-#define STS_IRQ_TIMER 0x0007 /* Not normally used in MAC ucode */
-#define STS_IRQ_COMMAND_STATUS 0x0008 /* SSB is updated with command
- * status.
- */
-#define STS_IRQ_RECEIVE_STATUS 0x000A /* SSB is updated with receive
- * status.
- */
-#define STS_IRQ_TRANSMIT_STATUS 0x000C /* SSB is updated with transmit
- * status
- */
-#define STS_IRQ_RECEIVE_PENDING 0x000E /* Not used in MAC-only microcode */
-#define STS_IRQ_MASK 0x000F /* = STS_ERROR_MASK. */
-
-
-/* TRANSMIT_STATUS completion code: (SSB.Parm[0]) */
-#define COMMAND_COMPLETE 0x0080 /* TRANSMIT command completed
- * (avoid this!) issue another transmit
- * to send additional frames.
- */
-#define FRAME_COMPLETE 0x0040 /* Frame has been transmitted;
- * INTERRUPT_FRAME bit was set in the
- * CSTAT request; indication of possibly
- * more than one frame transmissions!
- * SSB.Parm[0-1]: 32 bit pointer to
- * TPL of last frame.
- */
-#define LIST_ERROR 0x0020 /* Error in one of the TPLs that
- * compose the frame; TRANSMIT
- * terminated; Parm[1-2]: 32bit pointer
- * to TPL which starts the error
- * frame; error details in bits 8-13.
- * (14?)
- */
-#define FRAME_SIZE_ERROR 0x8000 /* FRAME_SIZE does not equal the sum of
- * the valid DATA_COUNT fields;
- * FRAME_SIZE less than header plus
- * information field. (15 bytes +
- * routing field) Or if FRAME_SIZE
- * was specified as zero in one list.
- */
-#define TX_THRESHOLD 0x4000 /* FRAME_SIZE greater than (BUFFER_SIZE
- * - 9) * TX_BUF_MAX.
- */
-#define ODD_ADDRESS 0x2000 /* Odd forward pointer value is
- * read on a list without END_FRAME
- * indication.
- */
-#define FRAME_ERROR 0x1000 /* START_FRAME bit (not) anticipated,
- * but (not) set.
- */
-#define ACCESS_PRIORITY_ERROR 0x0800 /* Access priority requested has not
- * been allowed.
- */
-#define UNENABLED_MAC_FRAME 0x0400 /* MAC frame has source class of zero
- * or MAC frame PCF ATTN field is
- * greater than one.
- */
-#define ILLEGAL_FRAME_FORMAT 0x0200 /* Bit 0 or FC field was set to one. */
-
-
-/*
- * Since we need to support some functions even if the adapter is in a
- * CLOSED state, we have a (pseudo-) command queue which holds commands
- * that are outstandig to be executed.
- *
- * Each time a command completes, an interrupt occurs and the next
- * command is executed. The command queue is actually a simple word with
- * a bit for each outstandig command. Therefore the commands will not be
- * executed in the order they have been queued.
- *
- * The following defines the command code bits and the command queue:
- */
-#define OC_OPEN 0x0001 /* OPEN command */
-#define OC_TRANSMIT 0x0002 /* TRANSMIT command */
-#define OC_TRANSMIT_HALT 0x0004 /* TRANSMIT_HALT command */
-#define OC_RECEIVE 0x0008 /* RECEIVE command */
-#define OC_CLOSE 0x0010 /* CLOSE command */
-#define OC_SET_GROUP_ADDR 0x0020 /* SET_GROUP_ADDR command */
-#define OC_SET_FUNCT_ADDR 0x0040 /* SET_FUNCT_ADDR command */
-#define OC_READ_ERROR_LOG 0x0080 /* READ_ERROR_LOG command */
-#define OC_READ_ADAPTER 0x0100 /* READ_ADAPTER command */
-#define OC_MODIFY_OPEN_PARMS 0x0400 /* MODIFY_OPEN_PARMS command */
-#define OC_RESTORE_OPEN_PARMS 0x0800 /* RESTORE_OPEN_PARMS command */
-#define OC_SET_FIRST_16_GROUP 0x1000 /* SET_FIRST_16_GROUP command */
-#define OC_SET_BRIDGE_PARMS 0x2000 /* SET_BRIDGE_PARMS command */
-#define OC_CONFIG_BRIDGE_PARMS 0x4000 /* CONFIG_BRIDGE_PARMS command */
-
-#define OPEN 0x0300 /* C: open command. S: completion. */
-#define TRANSMIT 0x0400 /* C: transmit command. S: completion
- * status. (reject: COMMAND_REJECT if
- * adapter not opened, TRANSMIT already
- * issued or address passed in the SCB
- * not word aligned)
- */
-#define TRANSMIT_HALT 0x0500 /* C: interrupt TX TPL chain; if no
- * TRANSMIT command issued, the command
- * is ignored (completion with TRANSMIT
- * status (0x0400)!)
- */
-#define RECEIVE 0x0600 /* C: receive command. S: completion
- * status. (reject: COMMAND_REJECT if
- * adapter not opened, RECEIVE already
- * issued or address passed in the SCB
- * not word aligned)
- */
-#define CLOSE 0x0700 /* C: close adapter. S: completion.
- * (COMMAND_REJECT if adapter not open)
- */
-#define SET_GROUP_ADDR 0x0800 /* C: alter adapter group address after
- * OPEN. S: completion. (COMMAND_REJECT
- * if adapter not open)
- */
-#define SET_FUNCT_ADDR 0x0900 /* C: alter adapter functional address
- * after OPEN. S: completion.
- * (COMMAND_REJECT if adapter not open)
- */
-#define READ_ERROR_LOG 0x0A00 /* C: read adapter error counters.
- * S: completion. (command ignored
- * if adapter not open!)
- */
-#define READ_ADAPTER 0x0B00 /* C: read data from adapter memory.
- * (important: after init and before
- * open!) S: completion. (ADAPTER_CHECK
- * interrupt if undefined storage area
- * read)
- */
-#define MODIFY_OPEN_PARMS 0x0D00 /* C: modify some adapter operational
- * parameters. (bit correspondend to
- * WRAP_INTERFACE is ignored)
- * S: completion. (reject:
- * COMMAND_REJECT)
- */
-#define RESTORE_OPEN_PARMS 0x0E00 /* C: modify some adapter operational
- * parameters. (bit correspondend
- * to WRAP_INTERFACE is ignored)
- * S: completion. (reject:
- * COMMAND_REJECT)
- */
-#define SET_FIRST_16_GROUP 0x0F00 /* C: alter the first two bytes in
- * adapter group address.
- * S: completion. (reject:
- * COMMAND_REJECT)
- */
-#define SET_BRIDGE_PARMS 0x1000 /* C: values and conditions for the
- * adapter hardware to use when frames
- * are copied for forwarding.
- * S: completion. (reject:
- * COMMAND_REJECT)
- */
-#define CONFIG_BRIDGE_PARMS 0x1100 /* C: ..
- * S: completion. (reject:
- * COMMAND_REJECT)
- */
-
-#define SPEED_4 4
-#define SPEED_16 16 /* Default transmission speed */
-
-
-/* Initialization Parameter Block (IPB); word alignment necessary! */
-#define BURST_SIZE 0x0018 /* Default burst size */
-#define BURST_MODE 0x9F00 /* Burst mode enable */
-#define DMA_RETRIES 0x0505 /* Magic DMA retry number... */
-
-#define CYCLE_TIME 3 /* Default AT-bus cycle time: 500 ns
- * (later adapter version: fix cycle time!)
- */
-#define LINE_SPEED_BIT 0x80
-
-/* Macro definition for the wait function. */
-#define ONE_SECOND_TICKS 1000000
-#define HALF_SECOND (ONE_SECOND_TICKS / 2)
-#define ONE_SECOND (ONE_SECOND_TICKS)
-#define TWO_SECONDS (ONE_SECOND_TICKS * 2)
-#define THREE_SECONDS (ONE_SECOND_TICKS * 3)
-#define FOUR_SECONDS (ONE_SECOND_TICKS * 4)
-#define FIVE_SECONDS (ONE_SECOND_TICKS * 5)
-
-#define BUFFER_SIZE 2048 /* Buffers on Adapter */
-
-#pragma pack(1)
-typedef struct {
- unsigned short Init_Options; /* Initialize with burst mode;
- * LLC disabled. (MAC only)
- */
-
- /* Interrupt vectors the adapter places on attached system bus. */
- u_int8_t CMD_Status_IV; /* Interrupt vector: command status. */
- u_int8_t TX_IV; /* Interrupt vector: transmit. */
- u_int8_t RX_IV; /* Interrupt vector: receive. */
- u_int8_t Ring_Status_IV; /* Interrupt vector: ring status. */
- u_int8_t SCB_Clear_IV; /* Interrupt vector: SCB clear. */
- u_int8_t Adapter_CHK_IV; /* Interrupt vector: adapter check. */
-
- u_int16_t RX_Burst_Size; /* Max. number of transfer cycles. */
- u_int16_t TX_Burst_Size; /* During DMA burst; even value! */
- u_int16_t DMA_Abort_Thrhld; /* Number of DMA retries. */
-
- u_int32_t SCB_Addr; /* SCB address: even, word aligned, high-low */
- u_int32_t SSB_Addr; /* SSB address: even, word aligned, high-low */
-} IPB, *IPB_Ptr;
-#pragma pack()
-
-/*
- * OPEN Command Parameter List (OCPL) (can be reused, if the adapter has to
- * be reopened)
- */
-#define BUFFER_SIZE 2048 /* Buffers on Adapter. */
-#define TPL_SIZE 8+6*TX_FRAG_NUM /* Depending on fragments per TPL. */
-#define RPL_SIZE 14 /* (with TI firmware v2.26 handling
- * up to nine fragments possible)
- */
-#define TX_BUF_MIN 20 /* ??? (Stephan: calculation with */
-#define TX_BUF_MAX 40 /* BUFFER_SIZE and MAX_FRAME_SIZE) ???
- */
-#define DISABLE_EARLY_TOKEN_RELEASE 0x1000
-
-/* OPEN Options (high-low) */
-#define WRAP_INTERFACE 0x0080 /* Inserting omitted for test
- * purposes; transmit data appears
- * as receive data. (useful for
- * testing; change: CLOSE necessary)
- */
-#define DISABLE_HARD_ERROR 0x0040 /* On HARD_ERROR & TRANSMIT_BEACON
- * no RING.STATUS interrupt.
- */
-#define DISABLE_SOFT_ERROR 0x0020 /* On SOFT_ERROR, no RING.STATUS
- * interrupt.
- */
-#define PASS_ADAPTER_MAC_FRAMES 0x0010 /* Passing unsupported MAC frames
- * to system.
- */
-#define PASS_ATTENTION_FRAMES 0x0008 /* All changed attention MAC frames are
- * passed to the system.
- */
-#define PAD_ROUTING_FIELD 0x0004 /* Routing field is padded to 18
- * bytes.
- */
-#define FRAME_HOLD 0x0002 /*Adapter waits for entire frame before
- * initiating DMA transfer; otherwise:
- * DMA transfer initiation if internal
- * buffer filled.
- */
-#define CONTENDER 0x0001 /* Adapter participates in the monitor
- * contention process.
- */
-#define PASS_BEACON_MAC_FRAMES 0x8000 /* Adapter passes beacon MAC frames
- * to the system.
- */
-#define EARLY_TOKEN_RELEASE 0x1000 /* Only valid in 16 Mbps operation;
- * 0 = ETR. (no effect in 4 Mbps
- * operation)
- */
-#define COPY_ALL_MAC_FRAMES 0x0400 /* All MAC frames are copied to
- * the system. (after OPEN: duplicate
- * address test (DAT) MAC frame is
- * first received frame copied to the
- * system)
- */
-#define COPY_ALL_NON_MAC_FRAMES 0x0200 /* All non MAC frames are copied to
- * the system.
- */
-#define PASS_FIRST_BUF_ONLY 0x0100 /* Passes only first internal buffer
- * of each received frame; FrameSize
- * of RPLs must contain internal
- * BUFFER_SIZE bits for promiscuous mode.
- */
-#define ENABLE_FULL_DUPLEX_SELECTION 0x2000
- /* Enable the use of full-duplex
- * settings with bits in byte 22 in
- * ocpl. (new feature in firmware
- * version 3.09)
- */
-
-/* Full-duplex settings */
-#define OPEN_FULL_DUPLEX_OFF 0x0000
-#define OPEN_FULL_DUPLEX_ON 0x00c0
-#define OPEN_FULL_DUPLEX_AUTO 0x0080
-
-#define PROD_ID_SIZE 18 /* Length of product ID. */
-
-#define TX_FRAG_NUM 3 /* Number of fragments used in one TPL. */
-#define TX_MORE_FRAGMENTS 0x8000 /* Bit set in DataCount to indicate more
- * fragments following.
- */
-
-/* XXX is there some better way to do this? */
-#define ISA_MAX_ADDRESS 0x00ffffff
-#define PCI_MAX_ADDRESS 0xffffffff
-
-#pragma pack(1)
-typedef struct {
- u_int16_t OPENOptions;
- u_int8_t NodeAddr[6]; /* Adapter node address; use ROM
- * address
- */
- u_int32_t GroupAddr; /* Multicast: high order
- * bytes = 0xC000
- */
- u_int32_t FunctAddr; /* High order bytes = 0xC000 */
- __be16 RxListSize; /* RPL size: 0 (=26), 14, 20 or
- * 26 bytes read by the adapter.
- * (Depending on the number of
- * fragments/list)
- */
- __be16 TxListSize; /* TPL size */
- __be16 BufSize; /* Is automatically rounded up to the
- * nearest nK boundary.
- */
- u_int16_t FullDuplex;
- u_int16_t Reserved;
- u_int8_t TXBufMin; /* Number of adapter buffers reserved
- * for transmission a minimum of 2
- * buffers must be allocated.
- */
- u_int8_t TXBufMax; /* Maximum number of adapter buffers
- * for transmit; a minimum of 2 buffers
- * must be available for receive.
- * Default: 6
- */
- u_int16_t ProdIDAddr[2];/* Pointer to product ID. */
-} OPB, *OPB_Ptr;
-#pragma pack()
-
-/*
- * SCB: adapter commands enabled by the host system started by writing
- * CMD_INTERRUPT_ADAPTER | CMD_EXECUTE (|SCB_REQUEST) to the SIFCMD IO
- * register. (special case: | CMD_SYSTEM_IRQ for initialization)
- */
-#pragma pack(1)
-typedef struct {
- u_int16_t CMD; /* Command code */
- u_int16_t Parm[2]; /* Pointer to Command Parameter Block */
-} SCB; /* System Command Block (32 bit physical address; big endian)*/
-#pragma pack()
-
-/*
- * SSB: adapter command return status can be evaluated after COMMAND_STATUS
- * adapter to system interrupt after reading SSB, the availability of the SSB
- * has to be told the adapter by writing CMD_INTERRUPT_ADAPTER | CMD_SSB_CLEAR
- * in the SIFCMD IO register.
- */
-#pragma pack(1)
-typedef struct {
- u_int16_t STS; /* Status code */
- u_int16_t Parm[3]; /* Parameter or pointer to Status Parameter
- * Block.
- */
-} SSB; /* System Status Block (big endian - physical address) */
-#pragma pack()
-
-typedef struct {
- unsigned short BurnedInAddrPtr; /* Pointer to adapter burned in
- * address. (BIA)
- */
- unsigned short SoftwareLevelPtr;/* Pointer to software level data. */
- unsigned short AdapterAddrPtr; /* Pointer to adapter addresses. */
- unsigned short AdapterParmsPtr; /* Pointer to adapter parameters. */
- unsigned short MACBufferPtr; /* Pointer to MAC buffer. (internal) */
- unsigned short LLCCountersPtr; /* Pointer to LLC counters. */
- unsigned short SpeedFlagPtr; /* Pointer to data rate flag.
- * (4/16 Mbps)
- */
- unsigned short AdapterRAMPtr; /* Pointer to adapter RAM found. (KB) */
-} INTPTRS; /* Adapter internal pointers */
-
-#pragma pack(1)
-typedef struct {
- u_int8_t Line_Error; /* Line error: code violation in
- * frame or in a token, or FCS error.
- */
- u_int8_t Internal_Error; /* IBM specific. (Reserved_1) */
- u_int8_t Burst_Error;
- u_int8_t ARI_FCI_Error; /* ARI/FCI bit zero in AMP or
- * SMP MAC frame.
- */
- u_int8_t AbortDelimeters; /* IBM specific. (Reserved_2) */
- u_int8_t Reserved_3;
- u_int8_t Lost_Frame_Error; /* Receive of end of transmitted
- * frame failed.
- */
- u_int8_t Rx_Congest_Error; /* Adapter in repeat mode has not
- * enough buffer space to copy incoming
- * frame.
- */
- u_int8_t Frame_Copied_Error; /* ARI bit not zero in frame
- * addressed to adapter.
- */
- u_int8_t Frequency_Error; /* IBM specific. (Reserved_4) */
- u_int8_t Token_Error; /* (active only in monitor station) */
- u_int8_t Reserved_5;
- u_int8_t DMA_Bus_Error; /* DMA bus errors not exceeding the
- * abort thresholds.
- */
- u_int8_t DMA_Parity_Error; /* DMA parity errors not exceeding
- * the abort thresholds.
- */
-} ERRORTAB; /* Adapter error counters */
-#pragma pack()
-
-
-/*--------------------- Send and Receive definitions -------------------*/
-#pragma pack(1)
-typedef struct {
- __be16 DataCount; /* Value 0, even and odd values are
- * permitted; value is unaltered most
- * significant bit set: following
- * fragments last fragment: most
- * significant bit is not evaluated.
- * (???)
- */
- __be32 DataAddr; /* Pointer to frame data fragment;
- * even or odd.
- */
-} Fragment;
-#pragma pack()
-
-#define MAX_FRAG_NUMBERS 9 /* Maximal number of fragments possible to use
- * in one RPL/TPL. (depending on TI firmware
- * version)
- */
-
-/*
- * AC (1), FC (1), Dst (6), Src (6), RIF (18), Data (4472) = 4504
- * The packet size can be one of the follows: 548, 1502, 2084, 4504, 8176,
- * 11439, 17832. Refer to TMS380 Second Generation Token Ring User's Guide
- * Page 2-27.
- */
-#define HEADER_SIZE (1 + 1 + 6 + 6)
-#define SRC_SIZE 18
-#define MIN_DATA_SIZE 516
-#define DEFAULT_DATA_SIZE 4472
-#define MAX_DATA_SIZE 17800
-
-#define DEFAULT_PACKET_SIZE (HEADER_SIZE + SRC_SIZE + DEFAULT_DATA_SIZE)
-#define MIN_PACKET_SIZE (HEADER_SIZE + SRC_SIZE + MIN_DATA_SIZE)
-#define MAX_PACKET_SIZE (HEADER_SIZE + SRC_SIZE + MAX_DATA_SIZE)
-
-/*
- * Macros to deal with the frame status field.
- */
-#define AC_NOT_RECOGNIZED 0x00
-#define GROUP_BIT 0x80
-#define GET_TRANSMIT_STATUS_HIGH_BYTE(Ts) ((unsigned char)((Ts) >> 8))
-#define GET_FRAME_STATUS_HIGH_AC(Fs) ((unsigned char)(((Fs) & 0xC0) >> 6))
-#define GET_FRAME_STATUS_LOW_AC(Fs) ((unsigned char)(((Fs) & 0x0C) >> 2))
-#define DIRECTED_FRAME(Context) (!((Context)->MData[2] & GROUP_BIT))
-
-
-/*--------------------- Send Functions ---------------------------------*/
-/* define TX_CSTAT _REQUEST (R) and _COMPLETE (C) values (high-low) */
-
-#define TX_VALID 0x0080 /* R: set via TRANSMIT.VALID interrupt.
- * C: always reset to zero!
- */
-#define TX_FRAME_COMPLETE 0x0040 /* R: must be reset to zero.
- * C: set to one.
- */
-#define TX_START_FRAME 0x0020 /* R: start of a frame: 1
- * C: unchanged.
- */
-#define TX_END_FRAME 0x0010 /* R: end of a frame: 1
- * C: unchanged.
- */
-#define TX_FRAME_IRQ 0x0008 /* R: request interrupt generation
- * after transmission.
- * C: unchanged.
- */
-#define TX_ERROR 0x0004 /* R: reserved.
- * C: set to one if Error occurred.
- */
-#define TX_INTERFRAME_WAIT 0x0004
-#define TX_PASS_CRC 0x0002 /* R: set if CRC value is already
- * calculated. (valid only in
- * FRAME_START TPL)
- * C: unchanged.
- */
-#define TX_PASS_SRC_ADDR 0x0001 /* R: adapter uses explicit frame
- * source address and does not overwrite
- * with the adapter node address.
- * (valid only in FRAME_START TPL)
- *
- * C: unchanged.
- */
-#define TX_STRIP_FS 0xFF00 /* R: reserved.
- * C: if no Transmission Error,
- * field contains copy of FS byte after
- * stripping of frame.
- */
-
-/*
- * Structure of Transmit Parameter Lists (TPLs) (only one frame every TPL,
- * but possibly multiple TPLs for one frame) the length of the TPLs has to be
- * initialized in the OPL. (OPEN parameter list)
- */
-#define TPL_NUM 3 /* Number of Transmit Parameter Lists.
- * !! MUST BE >= 3 !!
- */
-
-#pragma pack(1)
-typedef struct s_TPL TPL;
-
-struct s_TPL { /* Transmit Parameter List (align on even word boundaries) */
- __be32 NextTPLAddr; /* Pointer to next TPL in chain; if
- * pointer is odd: this is the last
- * TPL. Pointing to itself can cause
- * problems!
- */
- volatile u_int16_t Status; /* Initialized by the adapter:
- * CSTAT_REQUEST important: update least
- * significant bit first! Set by the
- * adapter: CSTAT_COMPLETE status.
- */
- __be16 FrameSize; /* Number of bytes to be transmitted
- * as a frame including AC/FC,
- * Destination, Source, Routing field
- * not including CRC, FS, End Delimiter
- * (valid only if START_FRAME bit in
- * CSTAT nonzero) must not be zero in
- * any list; maximum value: (BUFFER_SIZE
- * - 8) * TX_BUF_MAX sum of DataCount
- * values in FragmentList must equal
- * Frame_Size value in START_FRAME TPL!
- * frame data fragment list.
- */
-
- /* TPL/RPL size in OPEN parameter list depending on maximal
- * numbers of fragments used in one parameter list.
- */
- Fragment FragList[TX_FRAG_NUM]; /* Maximum: nine frame fragments in one
- * TPL actual version of firmware: 9
- * fragments possible.
- */
-#pragma pack()
-
- /* Special proprietary data and precalculations */
-
- TPL *NextTPLPtr; /* Pointer to next TPL in chain. */
- unsigned char *MData;
- struct sk_buff *Skb;
- unsigned char TPLIndex;
- volatile unsigned char BusyFlag;/* Flag: TPL busy? */
- dma_addr_t DMABuff; /* DMA IO bus address from dma_map */
-};
-
-/* ---------------------Receive Functions-------------------------------*
- * define RECEIVE_CSTAT_REQUEST (R) and RECEIVE_CSTAT_COMPLETE (C) values.
- * (high-low)
- */
-#define RX_VALID 0x0080 /* R: set; tell adapter with
- * RECEIVE.VALID interrupt.
- * C: reset to zero.
- */
-#define RX_FRAME_COMPLETE 0x0040 /* R: must be reset to zero,
- * C: set to one.
- */
-#define RX_START_FRAME 0x0020 /* R: must be reset to zero.
- * C: set to one on the list.
- */
-#define RX_END_FRAME 0x0010 /* R: must be reset to zero.
- * C: set to one on the list
- * that ends the frame.
- */
-#define RX_FRAME_IRQ 0x0008 /* R: request interrupt generation
- * after receive.
- * C: unchanged.
- */
-#define RX_INTERFRAME_WAIT 0x0004 /* R: after receiving a frame:
- * interrupt and wait for a
- * RECEIVE.CONTINUE.
- * C: unchanged.
- */
-#define RX_PASS_CRC 0x0002 /* R: if set, the adapter includes
- * the CRC in data passed. (last four
- * bytes; valid only if FRAME_START is
- * set)
- * C: set, if CRC is included in
- * received data.
- */
-#define RX_PASS_SRC_ADDR 0x0001 /* R: adapter uses explicit frame
- * source address and does not
- * overwrite with the adapter node
- * address. (valid only if FRAME_START
- * is set)
- * C: unchanged.
- */
-#define RX_RECEIVE_FS 0xFC00 /* R: reserved; must be reset to zero.
- * C: on lists with START_FRAME, field
- * contains frame status field from
- * received frame; otherwise cleared.
- */
-#define RX_ADDR_MATCH 0x0300 /* R: reserved; must be reset to zero.
- * C: address match code mask.
- */
-#define RX_STATUS_MASK 0x00FF /* Mask for receive status bits. */
-
-#define RX_INTERN_ADDR_MATCH 0x0100 /* C: internally address match. */
-#define RX_EXTERN_ADDR_MATCH 0x0200 /* C: externally matched via
- * XMATCH/XFAIL interface.
- */
-#define RX_INTEXT_ADDR_MATCH 0x0300 /* C: internally and externally
- * matched.
- */
-#define RX_READY (RX_VALID | RX_FRAME_IRQ) /* Ready for receive. */
-
-/* Constants for Command Status Interrupt.
- * COMMAND_REJECT status field bit functions (SSB.Parm[0])
- */
-#define ILLEGAL_COMMAND 0x0080 /* Set if an unknown command
- * is issued to the adapter
- */
-#define ADDRESS_ERROR 0x0040 /* Set if any address field in
- * the SCB is odd. (not word aligned)
- */
-#define ADAPTER_OPEN 0x0020 /* Command issued illegal with
- * open adapter.
- */
-#define ADAPTER_CLOSE 0x0010 /* Command issued illegal with
- * closed adapter.
- */
-#define SAME_COMMAND 0x0008 /* Command issued with same command
- * already executing.
- */
-
-/* OPEN_COMPLETION values (SSB.Parm[0], MSB) */
-#define NODE_ADDR_ERROR 0x0040 /* Wrong address or BIA read
- * zero address.
- */
-#define LIST_SIZE_ERROR 0x0020 /* If List_Size value not in 0,
- * 14, 20, 26.
- */
-#define BUF_SIZE_ERROR 0x0010 /* Not enough available memory for
- * two buffers.
- */
-#define TX_BUF_COUNT_ERROR 0x0004 /* Remaining receive buffers less than
- * two.
- */
-#define OPEN_ERROR 0x0002 /* Error during ring insertion; more
- * information in bits 8-15.
- */
-
-/* Standard return codes */
-#define GOOD_COMPLETION 0x0080 /* =OPEN_SUCCESSFULL */
-#define INVALID_OPEN_OPTION 0x0001 /* OPEN options are not supported by
- * the adapter.
- */
-
-/* OPEN phases; details of OPEN_ERROR (SSB.Parm[0], LSB) */
-#define OPEN_PHASES_MASK 0xF000 /* Check only the bits 8-11. */
-#define LOBE_MEDIA_TEST 0x1000
-#define PHYSICAL_INSERTION 0x2000
-#define ADDRESS_VERIFICATION 0x3000
-#define PARTICIPATION_IN_RING_POLL 0x4000
-#define REQUEST_INITIALISATION 0x5000
-#define FULLDUPLEX_CHECK 0x6000
-
-/* OPEN error codes; details of OPEN_ERROR (SSB.Parm[0], LSB) */
-#define OPEN_ERROR_CODES_MASK 0x0F00 /* Check only the bits 12-15. */
-#define OPEN_FUNCTION_FAILURE 0x0100 /* Unable to transmit to itself or
- * frames received before insertion.
- */
-#define OPEN_SIGNAL_LOSS 0x0200 /* Signal loss condition detected at
- * receiver.
- */
-#define OPEN_TIMEOUT 0x0500 /* Insertion timer expired before
- * logical insertion.
- */
-#define OPEN_RING_FAILURE 0x0600 /* Unable to receive own ring purge
- * MAC frames.
- */
-#define OPEN_RING_BEACONING 0x0700 /* Beacon MAC frame received after
- * ring insertion.
- */
-#define OPEN_DUPLICATE_NODEADDR 0x0800 /* Other station in ring found
- * with the same address.
- */
-#define OPEN_REQUEST_INIT 0x0900 /* RPS present but does not respond. */
-#define OPEN_REMOVE_RECEIVED 0x0A00 /* Adapter received a remove adapter
- * MAC frame.
- */
-#define OPEN_FULLDUPLEX_SET 0x0D00 /* Got this with full duplex on when
- * trying to connect to a normal ring.
- */
-
-/* SET_BRIDGE_PARMS return codes: */
-#define BRIDGE_INVALID_MAX_LEN 0x4000 /* MAX_ROUTING_FIELD_LENGTH odd,
- * less than 6 or > 30.
- */
-#define BRIDGE_INVALID_SRC_RING 0x2000 /* SOURCE_RING number zero, too large
- * or = TARGET_RING.
- */
-#define BRIDGE_INVALID_TRG_RING 0x1000 /* TARGET_RING number zero, too large
- * or = SOURCE_RING.
- */
-#define BRIDGE_INVALID_BRDGE_NO 0x0800 /* BRIDGE_NUMBER too large. */
-#define BRIDGE_INVALID_OPTIONS 0x0400 /* Invalid bridge options. */
-#define BRIDGE_DIAGS_FAILED 0x0200 /* Diagnostics of TMS380SRA failed. */
-#define BRIDGE_NO_SRA 0x0100 /* The TMS380SRA does not exist in HW
- * configuration.
- */
-
-/*
- * Bring Up Diagnostics error codes.
- */
-#define BUD_INITIAL_ERROR 0x0
-#define BUD_CHECKSUM_ERROR 0x1
-#define BUD_ADAPTER_RAM_ERROR 0x2
-#define BUD_INSTRUCTION_ERROR 0x3
-#define BUD_CONTEXT_ERROR 0x4
-#define BUD_PROTOCOL_ERROR 0x5
-#define BUD_INTERFACE_ERROR 0x6
-
-/* BUD constants */
-#define BUD_MAX_RETRIES 3
-#define BUD_MAX_LOOPCNT 6
-#define BUD_TIMEOUT 3000
-
-/* Initialization constants */
-#define INIT_MAX_RETRIES 3 /* Maximum three retries. */
-#define INIT_MAX_LOOPCNT 22 /* Maximum loop counts. */
-
-/* RING STATUS field values (high/low) */
-#define SIGNAL_LOSS 0x0080 /* Loss of signal on the ring
- * detected.
- */
-#define HARD_ERROR 0x0040 /* Transmitting or receiving beacon
- * frames.
- */
-#define SOFT_ERROR 0x0020 /* Report error MAC frame
- * transmitted.
- */
-#define TRANSMIT_BEACON 0x0010 /* Transmitting beacon frames on the
- * ring.
- */
-#define LOBE_WIRE_FAULT 0x0008 /* Open or short circuit in the
- * cable to concentrator; adapter
- * closed.
- */
-#define AUTO_REMOVAL_ERROR 0x0004 /* Lobe wrap test failed, deinserted;
- * adapter closed.
- */
-#define REMOVE_RECEIVED 0x0001 /* Received a remove ring station MAC
- * MAC frame request; adapter closed.
- */
-#define COUNTER_OVERFLOW 0x8000 /* Overflow of one of the adapters
- * error counters; READ.ERROR.LOG.
- */
-#define SINGLE_STATION 0x4000 /* Adapter is the only station on the
- * ring.
- */
-#define RING_RECOVERY 0x2000 /* Claim token MAC frames on the ring;
- * reset after ring purge frame.
- */
-
-#define ADAPTER_CLOSED (LOBE_WIRE_FAULT | AUTO_REMOVAL_ERROR |\
- REMOVE_RECEIVED)
-
-/* Adapter_check_block.Status field bit assignments: */
-#define DIO_PARITY 0x8000 /* Adapter detects bad parity
- * through direct I/O access.
- */
-#define DMA_READ_ABORT 0x4000 /* Aborting DMA read operation
- * from system Parm[0]: 0=timeout,
- * 1=parity error, 2=bus error;
- * Parm[1]: 32 bit pointer to host
- * system address at failure.
- */
-#define DMA_WRITE_ABORT 0x2000 /* Aborting DMA write operation
- * to system. (parameters analogous to
- * DMA_READ_ABORT)
- */
-#define ILLEGAL_OP_CODE 0x1000 /* Illegal operation code in the
- * the adapters firmware Parm[0]-2:
- * communications processor registers
- * R13-R15.
- */
-#define PARITY_ERRORS 0x0800 /* Adapter detects internal bus
- * parity error.
- */
-#define RAM_DATA_ERROR 0x0080 /* Valid only during RAM testing;
- * RAM data error Parm[0-1]: 32 bit
- * pointer to RAM location.
- */
-#define RAM_PARITY_ERROR 0x0040 /* Valid only during RAM testing;
- * RAM parity error Parm[0-1]: 32 bit
- * pointer to RAM location.
- */
-#define RING_UNDERRUN 0x0020 /* Internal DMA underrun when
- * transmitting onto ring.
- */
-#define INVALID_IRQ 0x0008 /* Unrecognized interrupt generated
- * internal to adapter Parm[0-2]:
- * adapter register R13-R15.
- */
-#define INVALID_ERROR_IRQ 0x0004 /* Unrecognized error interrupt
- * generated Parm[0-2]: adapter register
- * R13-R15.
- */
-#define INVALID_XOP 0x0002 /* Unrecognized XOP request in
- * communication processor Parm[0-2]:
- * adapter register R13-R15.
- */
-#define CHECKADDR 0x05E0 /* Adapter check status information
- * address offset.
- */
-#define ROM_PAGE_0 0x0000 /* Adapter ROM page 0. */
-
-/*
- * RECEIVE.STATUS interrupt result SSB values: (high-low)
- * (RECEIVE_COMPLETE field bit definitions in SSB.Parm[0])
- */
-#define RX_COMPLETE 0x0080 /* SSB.Parm[0]; SSB.Parm[1]: 32
- * bit pointer to last RPL.
- */
-#define RX_SUSPENDED 0x0040 /* SSB.Parm[0]; SSB.Parm[1]: 32
- * bit pointer to RPL with odd
- * forward pointer.
- */
-
-/* Valid receive CSTAT: */
-#define RX_FRAME_CONTROL_BITS (RX_VALID | RX_START_FRAME | RX_END_FRAME | \
- RX_FRAME_COMPLETE)
-#define VALID_SINGLE_BUFFER_FRAME (RX_START_FRAME | RX_END_FRAME | \
- RX_FRAME_COMPLETE)
-
-typedef enum SKB_STAT SKB_STAT;
-enum SKB_STAT {
- SKB_UNAVAILABLE,
- SKB_DMA_DIRECT,
- SKB_DATA_COPY
-};
-
-/* Receive Parameter List (RPL) The length of the RPLs has to be initialized
- * in the OPL. (OPEN parameter list)
- */
-#define RPL_NUM 3
-
-#define RX_FRAG_NUM 1 /* Maximal number of used fragments in one RPL.
- * (up to firmware v2.24: 3, now: up to 9)
- */
-
-#pragma pack(1)
-typedef struct s_RPL RPL;
-struct s_RPL { /* Receive Parameter List */
- __be32 NextRPLAddr; /* Pointer to next RPL in chain
- * (normalized = physical 32 bit
- * address) if pointer is odd: this
- * is last RPL. Pointing to itself can
- * cause problems!
- */
- volatile u_int16_t Status; /* Set by creation of Receive Parameter
- * List RECEIVE_CSTAT_COMPLETE set by
- * adapter in lists that start or end
- * a frame.
- */
- volatile __be16 FrameSize; /* Number of bytes received as a
- * frame including AC/FC, Destination,
- * Source, Routing field not including
- * CRC, FS (Frame Status), End Delimiter
- * (valid only if START_FRAME bit in
- * CSTAT nonzero) must not be zero in
- * any list; maximum value: (BUFFER_SIZE
- * - 8) * TX_BUF_MAX sum of DataCount
- * values in FragmentList must equal
- * Frame_Size value in START_FRAME TPL!
- * frame data fragment list
- */
-
- /* TPL/RPL size in OPEN parameter list depending on maximal numbers
- * of fragments used in one parameter list.
- */
- Fragment FragList[RX_FRAG_NUM]; /* Maximum: nine frame fragments in
- * one TPL. Actual version of firmware:
- * 9 fragments possible.
- */
-#pragma pack()
-
- /* Special proprietary data and precalculations. */
- RPL *NextRPLPtr; /* Logical pointer to next RPL in chain. */
- unsigned char *MData;
- struct sk_buff *Skb;
- SKB_STAT SkbStat;
- int RPLIndex;
- dma_addr_t DMABuff; /* DMA IO bus address from dma_map */
-};
-
-/* Information that need to be kept for each board. */
-typedef struct net_local {
-#pragma pack(1)
- IPB ipb; /* Initialization Parameter Block. */
- SCB scb; /* System Command Block: system to adapter
- * communication.
- */
- SSB ssb; /* System Status Block: adapter to system
- * communication.
- */
- OPB ocpl; /* Open Options Parameter Block. */
-
- ERRORTAB errorlogtable; /* Adapter statistic error counters.
- * (read from adapter memory)
- */
- unsigned char ProductID[PROD_ID_SIZE + 1]; /* Product ID */
-#pragma pack()
-
- TPL Tpl[TPL_NUM];
- TPL *TplFree;
- TPL *TplBusy;
- unsigned char LocalTxBuffers[TPL_NUM][DEFAULT_PACKET_SIZE];
-
- RPL Rpl[RPL_NUM];
- RPL *RplHead;
- RPL *RplTail;
- unsigned char LocalRxBuffers[RPL_NUM][DEFAULT_PACKET_SIZE];
-
- struct device *pdev;
- int DataRate;
- unsigned char ScbInUse;
- unsigned short CMDqueue;
-
- unsigned long AdapterOpenFlag:1;
- unsigned long AdapterVirtOpenFlag:1;
- unsigned long OpenCommandIssued:1;
- unsigned long TransmitCommandActive:1;
- unsigned long TransmitHaltScheduled:1;
- unsigned long HaltInProgress:1;
- unsigned long LobeWireFaultLogged:1;
- unsigned long ReOpenInProgress:1;
- unsigned long Sleeping:1;
-
- unsigned long LastOpenStatus;
- unsigned short CurrentRingStatus;
- unsigned long MaxPacketSize;
-
- unsigned long StartTime;
- unsigned long LastSendTime;
-
- struct tr_statistics MacStat; /* MAC statistics structure */
-
- unsigned long dmalimit; /* the max DMA address (ie, ISA) */
- dma_addr_t dmabuffer; /* the DMA bus address corresponding to
- priv. Might be different from virt_to_bus()
- for architectures with IO MMU (Alpha) */
-
- struct timer_list timer;
-
- wait_queue_head_t wait_for_tok_int;
-
- INTPTRS intptrs; /* Internal adapter pointer. Must be read
- * before OPEN command.
- */
- unsigned short (*setnselout)(struct net_device *);
- unsigned short (*sifreadb)(struct net_device *, unsigned short);
- void (*sifwriteb)(struct net_device *, unsigned short, unsigned short);
- unsigned short (*sifreadw)(struct net_device *, unsigned short);
- void (*sifwritew)(struct net_device *, unsigned short, unsigned short);
-
- spinlock_t lock; /* SMP protection */
- void *tmspriv;
-} NET_LOCAL;
-
-#endif /* __KERNEL__ */
-#endif /* __LINUX_TMS380TR_H */
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
deleted file mode 100644
index 90f3fa44a151..000000000000
--- a/drivers/net/tokenring/tmspci.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * tmspci.c: A generic network driver for TMS380-based PCI token ring cards.
- *
- * Written 1999 by Adam Fritzler
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * This driver module supports the following cards:
- * - SysKonnect TR4/16(+) PCI (SK-4590)
- * - SysKonnect TR4/16 PCI (SK-4591)
- * - Compaq TR 4/16 PCI
- * - Thomas-Conrad TC4048 4/16 PCI
- * - 3Com 3C339 Token Link Velocity
- *
- * Maintainer(s):
- * AF Adam Fritzler
- *
- * Modification History:
- * 30-Dec-99 AF Split off from the tms380tr driver.
- * 22-Jan-00 AF Updated to use indirect read/writes
- * 23-Nov-00 JG New PCI API, cleanups
- *
- * TODO:
- * 1. See if we can use MMIO instead of port accesses
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "tms380tr.h"
-
-static char version[] __devinitdata =
-"tmspci.c: v1.02 23/11/2000 by Adam Fritzler\n";
-
-#define TMS_PCI_IO_EXTENT 32
-
-struct card_info {
- unsigned char nselout[2]; /* NSELOUT vals for 4mb([0]) and 16mb([1]) */
- char *name;
-};
-
-static struct card_info card_info_table[] = {
- { {0x03, 0x01}, "Compaq 4/16 TR PCI"},
- { {0x03, 0x01}, "SK NET TR 4/16 PCI"},
- { {0x03, 0x01}, "Thomas-Conrad TC4048 PCI 4/16"},
- { {0x03, 0x01}, "3Com Token Link Velocity"},
-};
-
-static DEFINE_PCI_DEVICE_TABLE(tmspci_pci_tbl) = {
- { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
- { PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
- { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, tmspci_pci_tbl);
-
-MODULE_LICENSE("GPL");
-
-static void tms_pci_read_eeprom(struct net_device *dev);
-static unsigned short tms_pci_setnselout_pins(struct net_device *dev);
-
-static unsigned short tms_pci_sifreadb(struct net_device *dev, unsigned short reg)
-{
- return inb(dev->base_addr + reg);
-}
-
-static unsigned short tms_pci_sifreadw(struct net_device *dev, unsigned short reg)
-{
- return inw(dev->base_addr + reg);
-}
-
-static void tms_pci_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- outb(val, dev->base_addr + reg);
-}
-
-static void tms_pci_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
-{
- outw(val, dev->base_addr + reg);
-}
-
-static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- static int versionprinted;
- struct net_device *dev;
- struct net_local *tp;
- int ret;
- unsigned int pci_irq_line;
- unsigned long pci_ioaddr;
- struct card_info *cardinfo = &card_info_table[ent->driver_data];
-
- if (versionprinted++ == 0)
- printk("%s", version);
-
- if (pci_enable_device(pdev))
- return -EIO;
-
- /* Remove I/O space marker in bit 0. */
- pci_irq_line = pdev->irq;
- pci_ioaddr = pci_resource_start (pdev, 0);
-
- /* At this point we have found a valid card. */
- dev = alloc_trdev(sizeof(struct net_local));
- if (!dev)
- return -ENOMEM;
-
- if (!request_region(pci_ioaddr, TMS_PCI_IO_EXTENT, dev->name)) {
- ret = -EBUSY;
- goto err_out_trdev;
- }
-
- dev->base_addr = pci_ioaddr;
- dev->irq = pci_irq_line;
- dev->dma = 0;
-
- dev_info(&pdev->dev, "%s\n", cardinfo->name);
- dev_info(&pdev->dev, " IO: %#4lx IRQ: %d\n", dev->base_addr, dev->irq);
-
- tms_pci_read_eeprom(dev);
-
- dev_info(&pdev->dev, " Ring Station Address: %pM\n", dev->dev_addr);
-
- ret = tmsdev_init(dev, &pdev->dev);
- if (ret) {
- dev_info(&pdev->dev, "unable to get memory for dev->priv.\n");
- goto err_out_region;
- }
-
- tp = netdev_priv(dev);
- tp->setnselout = tms_pci_setnselout_pins;
-
- tp->sifreadb = tms_pci_sifreadb;
- tp->sifreadw = tms_pci_sifreadw;
- tp->sifwriteb = tms_pci_sifwriteb;
- tp->sifwritew = tms_pci_sifwritew;
-
- memcpy(tp->ProductID, cardinfo->name, PROD_ID_SIZE + 1);
-
- tp->tmspriv = cardinfo;
-
- dev->netdev_ops = &tms380tr_netdev_ops;
-
- ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED,
- dev->name, dev);
- if (ret)
- goto err_out_tmsdev;
-
- pci_set_drvdata(pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- ret = register_netdev(dev);
- if (ret)
- goto err_out_irq;
-
- return 0;
-
-err_out_irq:
- free_irq(pdev->irq, dev);
-err_out_tmsdev:
- pci_set_drvdata(pdev, NULL);
- tmsdev_term(dev);
-err_out_region:
- release_region(pci_ioaddr, TMS_PCI_IO_EXTENT);
-err_out_trdev:
- free_netdev(dev);
- return ret;
-}
-
-/*
- * Reads MAC address from adapter RAM, which should've read it from
- * the onboard ROM.
- *
- * Calling this on a board that does not support it can be a very
- * dangerous thing. The Madge board, for instance, will lock your
- * machine hard when this is called. Luckily, its supported in a
- * separate driver. --ASF
- */
-static void tms_pci_read_eeprom(struct net_device *dev)
-{
- int i;
-
- /* Address: 0000:0000 */
- tms_pci_sifwritew(dev, 0, SIFADX);
- tms_pci_sifwritew(dev, 0, SIFADR);
-
- /* Read six byte MAC address data */
- dev->addr_len = 6;
- for(i = 0; i < 6; i++)
- dev->dev_addr[i] = tms_pci_sifreadw(dev, SIFINC) >> 8;
-}
-
-static unsigned short tms_pci_setnselout_pins(struct net_device *dev)
-{
- unsigned short val = 0;
- struct net_local *tp = netdev_priv(dev);
- struct card_info *cardinfo = tp->tmspriv;
-
- if(tp->DataRate == SPEED_4)
- val |= cardinfo->nselout[0]; /* Set 4Mbps */
- else
- val |= cardinfo->nselout[1]; /* Set 16Mbps */
- return val;
-}
-
-static void __devexit tms_pci_detach (struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- BUG_ON(!dev);
- unregister_netdev(dev);
- release_region(dev->base_addr, TMS_PCI_IO_EXTENT);
- free_irq(dev->irq, dev);
- tmsdev_term(dev);
- free_netdev(dev);
- pci_set_drvdata(pdev, NULL);
-}
-
-static struct pci_driver tms_pci_driver = {
- .name = "tmspci",
- .id_table = tmspci_pci_tbl,
- .probe = tms_pci_attach,
- .remove = __devexit_p(tms_pci_detach),
-};
-
-module_pci_driver(tms_pci_driver);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index bb8c72c79c6f..987aeefbc774 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -313,7 +313,7 @@ static int run_filter(struct tap_filter *filter, const struct sk_buff *skb)
/* Exact match */
for (i = 0; i < filter->count; i++)
- if (!compare_ether_addr(eh->h_dest, filter->addr[i]))
+ if (ether_addr_equal(eh->h_dest, filter->addr[i]))
return 1;
/* Inexact match (multicast only) */
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 00880edba048..fffee6aee8bb 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -485,6 +485,8 @@ static const struct driver_info wwan_info = {
/*-------------------------------------------------------------------------*/
#define HUAWEI_VENDOR_ID 0x12D1
+#define NOVATEL_VENDOR_ID 0x1410
+#define ZTE_VENDOR_ID 0x19D2
static const struct usb_device_id products [] = {
/*
@@ -602,6 +604,76 @@ static const struct usb_device_id products [] = {
* because of bugs/quirks in a given product (like Zaurus, above).
*/
{
+ /* Novatel USB551L */
+ /* This match must come *before* the generic CDC-ETHER match so that
+ * we get FLAG_WWAN set on the device, since it's descriptors are
+ * generic CDC-ETHER.
+ */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = NOVATEL_VENDOR_ID,
+ .idProduct = 0xB001,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
+ /* ZTE (Vodafone) K3805-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1003,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
+ /* ZTE (Vodafone) K3806-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1015,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
+ /* ZTE (Vodafone) K4510-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1173,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
+ /* ZTE (Vodafone) K3770-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1177,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
+ /* ZTE (Vodafone) K3772-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_PRODUCT
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = ZTE_VENDOR_ID,
+ .idProduct = 0x1181,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
+ .bInterfaceProtocol = USB_CDC_PROTO_NONE,
+ .driver_info = (unsigned long)&wwan_info,
+}, {
USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long) &cdc_info,
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index d316503b35d4..63cfd0b2c31a 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -356,10 +356,19 @@ static const struct driver_info qmi_wwan_gobi = {
};
/* ZTE suck at making USB descriptors */
+static const struct driver_info qmi_wwan_force_int1 = {
+ .description = "Qualcomm WWAN/QMI device",
+ .flags = FLAG_WWAN,
+ .bind = qmi_wwan_bind_shared,
+ .unbind = qmi_wwan_unbind_shared,
+ .manage_power = qmi_wwan_manage_power,
+ .data = BIT(1), /* interface whitelist bitmap */
+};
+
static const struct driver_info qmi_wwan_force_int4 = {
- .description = "Qualcomm Gobi wwan/QMI device",
+ .description = "Qualcomm WWAN/QMI device",
.flags = FLAG_WWAN,
- .bind = qmi_wwan_bind_gobi,
+ .bind = qmi_wwan_bind_shared,
.unbind = qmi_wwan_unbind_shared,
.manage_power = qmi_wwan_manage_power,
.data = BIT(4), /* interface whitelist bitmap */
@@ -401,6 +410,14 @@ static const struct usb_device_id products[] = {
.bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */
.driver_info = (unsigned long)&qmi_wwan_info,
},
+ { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */
+ .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = HUAWEI_VENDOR_ID,
+ .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 56, /* NOTE: This is the *slave* interface of the CDC Union! */
+ .driver_info = (unsigned long)&qmi_wwan_info,
+ },
{ /* Huawei E392, E398 and possibly others in "Windows mode"
* using a combined control and data interface without any CDC
* functional descriptors
@@ -430,6 +447,15 @@ static const struct usb_device_id products[] = {
.bInterfaceProtocol = 0xff,
.driver_info = (unsigned long)&qmi_wwan_force_int4,
},
+ { /* ZTE (Vodafone) K3520-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x19d2,
+ .idProduct = 0x0055,
+ .bInterfaceClass = 0xff,
+ .bInterfaceSubClass = 0xff,
+ .bInterfaceProtocol = 0xff,
+ .driver_info = (unsigned long)&qmi_wwan_force_int1,
+ },
{ /* ZTE (Vodafone) K3565-Z */
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x19d2,
@@ -457,6 +483,15 @@ static const struct usb_device_id products[] = {
.bInterfaceProtocol = 0xff,
.driver_info = (unsigned long)&qmi_wwan_force_int4,
},
+ { /* ZTE (Vodafone) K3765-Z */
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x19d2,
+ .idProduct = 0x2002,
+ .bInterfaceClass = 0xff,
+ .bInterfaceSubClass = 0xff,
+ .bInterfaceProtocol = 0xff,
+ .driver_info = (unsigned long)&qmi_wwan_force_int4,
+ },
{ /* ZTE (Vodafone) K4505-Z */
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x19d2,
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index c8f1b5b3aff3..0d746b3fdef1 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -77,7 +77,9 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
if (dev->driver_info->indication) {
dev->driver_info->indication(dev, msg, buflen);
} else {
- switch (msg->status) {
+ u32 status = le32_to_cpu(msg->status);
+
+ switch (status) {
case RNDIS_STATUS_MEDIA_CONNECT:
dev_info(udev, "rndis media connect\n");
break;
@@ -85,8 +87,7 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
dev_info(udev, "rndis media disconnect\n");
break;
default:
- dev_info(udev, "rndis indication: 0x%08x\n",
- le32_to_cpu(msg->status));
+ dev_info(udev, "rndis indication: 0x%08x\n", status);
}
}
}
@@ -109,16 +110,17 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
int retval;
int partial;
unsigned count;
- __le32 rsp;
- u32 xid = 0, msg_len, request_id;
+ u32 xid = 0, msg_len, request_id, msg_type, rsp,
+ status;
/* REVISIT when this gets called from contexts other than probe() or
* disconnect(): either serialize, or dispatch responses on xid
*/
+ msg_type = le32_to_cpu(buf->msg_type);
+
/* Issue the request; xid is unique, don't bother byteswapping it */
- if (likely(buf->msg_type != RNDIS_MSG_HALT &&
- buf->msg_type != RNDIS_MSG_RESET)) {
+ if (likely(msg_type != RNDIS_MSG_HALT && msg_type != RNDIS_MSG_RESET)) {
xid = dev->xid++;
if (!xid)
xid = dev->xid++;
@@ -149,7 +151,7 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
}
/* Poll the control channel; the request probably completed immediately */
- rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
+ rsp = le32_to_cpu(buf->msg_type) | RNDIS_MSG_COMPLETION;
for (count = 0; count < 10; count++) {
memset(buf, 0, CONTROL_BUFFER_SIZE);
retval = usb_control_msg(dev->udev,
@@ -160,35 +162,36 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
buf, buflen,
RNDIS_CONTROL_TIMEOUT_MS);
if (likely(retval >= 8)) {
+ msg_type = le32_to_cpu(buf->msg_type);
msg_len = le32_to_cpu(buf->msg_len);
+ status = le32_to_cpu(buf->status);
request_id = (__force u32) buf->request_id;
- if (likely(buf->msg_type == rsp)) {
+ if (likely(msg_type == rsp)) {
if (likely(request_id == xid)) {
if (unlikely(rsp == RNDIS_MSG_RESET_C))
return 0;
- if (likely(RNDIS_STATUS_SUCCESS
- == buf->status))
+ if (likely(RNDIS_STATUS_SUCCESS ==
+ status))
return 0;
dev_dbg(&info->control->dev,
"rndis reply status %08x\n",
- le32_to_cpu(buf->status));
+ status);
return -EL3RST;
}
dev_dbg(&info->control->dev,
"rndis reply id %d expected %d\n",
request_id, xid);
/* then likely retry */
- } else switch (buf->msg_type) {
- case RNDIS_MSG_INDICATE: /* fault/event */
+ } else switch (msg_type) {
+ case RNDIS_MSG_INDICATE: /* fault/event */
rndis_msg_indicate(dev, (void *)buf, buflen);
-
break;
- case RNDIS_MSG_KEEPALIVE: { /* ping */
+ case RNDIS_MSG_KEEPALIVE: { /* ping */
struct rndis_keepalive_c *msg = (void *)buf;
- msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
+ msg->msg_type = cpu_to_le32(RNDIS_MSG_KEEPALIVE_C);
msg->msg_len = cpu_to_le32(sizeof *msg);
- msg->status = RNDIS_STATUS_SUCCESS;
+ msg->status = cpu_to_le32(RNDIS_STATUS_SUCCESS);
retval = usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, 0),
USB_CDC_SEND_ENCAPSULATED_COMMAND,
@@ -236,7 +239,7 @@ EXPORT_SYMBOL_GPL(rndis_command);
* ActiveSync 4.1 Windows driver.
*/
static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
- void *buf, __le32 oid, u32 in_len,
+ void *buf, u32 oid, u32 in_len,
void **reply, int *reply_len)
{
int retval;
@@ -251,9 +254,9 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
u.buf = buf;
memset(u.get, 0, sizeof *u.get + in_len);
- u.get->msg_type = RNDIS_MSG_QUERY;
+ u.get->msg_type = cpu_to_le32(RNDIS_MSG_QUERY);
u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len);
- u.get->oid = oid;
+ u.get->oid = cpu_to_le32(oid);
u.get->len = cpu_to_le32(in_len);
u.get->offset = cpu_to_le32(20);
@@ -324,7 +327,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
if (retval < 0)
goto fail;
- u.init->msg_type = RNDIS_MSG_INIT;
+ u.init->msg_type = cpu_to_le32(RNDIS_MSG_INIT);
u.init->msg_len = cpu_to_le32(sizeof *u.init);
u.init->major_version = cpu_to_le32(1);
u.init->minor_version = cpu_to_le32(0);
@@ -395,22 +398,23 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
/* Check physical medium */
phym = NULL;
reply_len = sizeof *phym;
- retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM,
- 0, (void **) &phym, &reply_len);
+ retval = rndis_query(dev, intf, u.buf,
+ RNDIS_OID_GEN_PHYSICAL_MEDIUM,
+ 0, (void **) &phym, &reply_len);
if (retval != 0 || !phym) {
/* OID is optional so don't fail here. */
- phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED;
+ phym_unspec = cpu_to_le32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED);
phym = &phym_unspec;
}
if ((flags & FLAG_RNDIS_PHYM_WIRELESS) &&
- *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
+ le32_to_cpup(phym) != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
netif_dbg(dev, probe, dev->net,
"driver requires wireless physical medium, but device is not\n");
retval = -ENODEV;
goto halt_fail_and_release;
}
if ((flags & FLAG_RNDIS_PHYM_NOT_WIRELESS) &&
- *phym == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
+ le32_to_cpup(phym) == RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
netif_dbg(dev, probe, dev->net,
"driver requires non-wireless physical medium, but device is wireless.\n");
retval = -ENODEV;
@@ -419,8 +423,9 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
/* Get designated host ethernet address */
reply_len = ETH_ALEN;
- retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS,
- 48, (void **) &bp, &reply_len);
+ retval = rndis_query(dev, intf, u.buf,
+ RNDIS_OID_802_3_PERMANENT_ADDRESS,
+ 48, (void **) &bp, &reply_len);
if (unlikely(retval< 0)) {
dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
goto halt_fail_and_release;
@@ -430,12 +435,12 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
/* set a nonzero filter to enable data transfers */
memset(u.set, 0, sizeof *u.set);
- u.set->msg_type = RNDIS_MSG_SET;
+ u.set->msg_type = cpu_to_le32(RNDIS_MSG_SET);
u.set->msg_len = cpu_to_le32(4 + sizeof *u.set);
- u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
+ u.set->oid = cpu_to_le32(RNDIS_OID_GEN_CURRENT_PACKET_FILTER);
u.set->len = cpu_to_le32(4);
u.set->offset = cpu_to_le32((sizeof *u.set) - 8);
- *(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
+ *(__le32 *)(u.buf + sizeof *u.set) = cpu_to_le32(RNDIS_DEFAULT_FILTER);
retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
if (unlikely(retval < 0)) {
@@ -450,7 +455,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
halt_fail_and_release:
memset(u.halt, 0, sizeof *u.halt);
- u.halt->msg_type = RNDIS_MSG_HALT;
+ u.halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT);
u.halt->msg_len = cpu_to_le32(sizeof *u.halt);
(void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE);
fail_and_release:
@@ -475,7 +480,7 @@ void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
/* try to clear any rndis state/activity (no i/o from stack!) */
halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
if (halt) {
- halt->msg_type = RNDIS_MSG_HALT;
+ halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT);
halt->msg_len = cpu_to_le32(sizeof *halt);
(void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE);
kfree(halt);
@@ -494,16 +499,16 @@ int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
while (likely(skb->len)) {
struct rndis_data_hdr *hdr = (void *)skb->data;
struct sk_buff *skb2;
- u32 msg_len, data_offset, data_len;
+ u32 msg_type, msg_len, data_offset, data_len;
+ msg_type = le32_to_cpu(hdr->msg_type);
msg_len = le32_to_cpu(hdr->msg_len);
data_offset = le32_to_cpu(hdr->data_offset);
data_len = le32_to_cpu(hdr->data_len);
/* don't choke if we see oob, per-packet data, etc */
- if (unlikely(hdr->msg_type != RNDIS_MSG_PACKET ||
- skb->len < msg_len ||
- (data_offset + data_len + 8) > msg_len)) {
+ if (unlikely(msg_type != RNDIS_MSG_PACKET || skb->len < msg_len
+ || (data_offset + data_len + 8) > msg_len)) {
dev->net->stats.rx_frame_errors++;
netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n",
le32_to_cpu(hdr->msg_type),
@@ -569,7 +574,7 @@ rndis_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
fill:
hdr = (void *) __skb_push(skb, sizeof *hdr);
memset(hdr, 0, sizeof *hdr);
- hdr->msg_type = RNDIS_MSG_PACKET;
+ hdr->msg_type = cpu_to_le32(RNDIS_MSG_PACKET);
hdr->msg_len = cpu_to_le32(skb->len);
hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8);
hdr->data_len = cpu_to_le32(len);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 80b837c88f0d..9f58330f1312 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -282,17 +282,32 @@ int usbnet_change_mtu (struct net_device *net, int new_mtu)
}
EXPORT_SYMBOL_GPL(usbnet_change_mtu);
+/* The caller must hold list->lock */
+static void __usbnet_queue_skb(struct sk_buff_head *list,
+ struct sk_buff *newsk, enum skb_state state)
+{
+ struct skb_data *entry = (struct skb_data *) newsk->cb;
+
+ __skb_queue_tail(list, newsk);
+ entry->state = state;
+}
+
/*-------------------------------------------------------------------------*/
/* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from
* completion callbacks. 2.5 should have fixed those bugs...
*/
-static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list)
+static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb,
+ struct sk_buff_head *list, enum skb_state state)
{
unsigned long flags;
+ enum skb_state old_state;
+ struct skb_data *entry = (struct skb_data *) skb->cb;
spin_lock_irqsave(&list->lock, flags);
+ old_state = entry->state;
+ entry->state = state;
__skb_unlink(skb, list);
spin_unlock(&list->lock);
spin_lock(&dev->done.lock);
@@ -300,6 +315,7 @@ static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_hea
if (dev->done.qlen == 1)
tasklet_schedule(&dev->bh);
spin_unlock_irqrestore(&dev->done.lock, flags);
+ return old_state;
}
/* some work can't be done in tasklets, so we use keventd
@@ -340,7 +356,6 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
entry = (struct skb_data *) skb->cb;
entry->urb = urb;
entry->dev = dev;
- entry->state = rx_start;
entry->length = 0;
usb_fill_bulk_urb (urb, dev->udev, dev->in,
@@ -372,7 +387,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
tasklet_schedule (&dev->bh);
break;
case 0:
- __skb_queue_tail (&dev->rxq, skb);
+ __usbnet_queue_skb(&dev->rxq, skb, rx_start);
}
} else {
netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
@@ -423,16 +438,17 @@ static void rx_complete (struct urb *urb)
struct skb_data *entry = (struct skb_data *) skb->cb;
struct usbnet *dev = entry->dev;
int urb_status = urb->status;
+ enum skb_state state;
skb_put (skb, urb->actual_length);
- entry->state = rx_done;
+ state = rx_done;
entry->urb = NULL;
switch (urb_status) {
/* success */
case 0:
if (skb->len < dev->net->hard_header_len) {
- entry->state = rx_cleanup;
+ state = rx_cleanup;
dev->net->stats.rx_errors++;
dev->net->stats.rx_length_errors++;
netif_dbg(dev, rx_err, dev->net,
@@ -471,7 +487,7 @@ static void rx_complete (struct urb *urb)
"rx throttle %d\n", urb_status);
}
block:
- entry->state = rx_cleanup;
+ state = rx_cleanup;
entry->urb = urb;
urb = NULL;
break;
@@ -482,17 +498,18 @@ block:
// FALLTHROUGH
default:
- entry->state = rx_cleanup;
+ state = rx_cleanup;
dev->net->stats.rx_errors++;
netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status);
break;
}
- defer_bh(dev, skb, &dev->rxq);
+ state = defer_bh(dev, skb, &dev->rxq, state);
if (urb) {
if (netif_running (dev->net) &&
- !test_bit (EVENT_RX_HALT, &dev->flags)) {
+ !test_bit (EVENT_RX_HALT, &dev->flags) &&
+ state != unlink_start) {
rx_submit (dev, urb, GFP_ATOMIC);
usb_mark_last_busy(dev->udev);
return;
@@ -579,16 +596,23 @@ EXPORT_SYMBOL_GPL(usbnet_purge_paused_rxq);
static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
{
unsigned long flags;
- struct sk_buff *skb, *skbnext;
+ struct sk_buff *skb;
int count = 0;
spin_lock_irqsave (&q->lock, flags);
- skb_queue_walk_safe(q, skb, skbnext) {
+ while (!skb_queue_empty(q)) {
struct skb_data *entry;
struct urb *urb;
int retval;
- entry = (struct skb_data *) skb->cb;
+ skb_queue_walk(q, skb) {
+ entry = (struct skb_data *) skb->cb;
+ if (entry->state != unlink_start)
+ goto found;
+ }
+ break;
+found:
+ entry->state = unlink_start;
urb = entry->urb;
/*
@@ -1040,8 +1064,7 @@ static void tx_complete (struct urb *urb)
}
usb_autopm_put_interface_async(dev->intf);
- entry->state = tx_done;
- defer_bh(dev, skb, &dev->txq);
+ (void) defer_bh(dev, skb, &dev->txq, tx_done);
}
/*-------------------------------------------------------------------------*/
@@ -1097,7 +1120,6 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
entry = (struct skb_data *) skb->cb;
entry->urb = urb;
entry->dev = dev;
- entry->state = tx_start;
entry->length = length;
usb_fill_bulk_urb (urb, dev->udev, dev->out,
@@ -1156,7 +1178,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
break;
case 0:
net->trans_start = jiffies;
- __skb_queue_tail (&dev->txq, skb);
+ __usbnet_queue_skb(&dev->txq, skb, tx_start);
if (dev->txq.qlen >= TX_QLEN (dev))
netif_stop_queue (net);
}
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index fa58c7869954..9ce6995e8d08 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -501,7 +501,9 @@ static void virtnet_napi_enable(struct virtnet_info *vi)
* We synchronize against interrupts via NAPI_STATE_SCHED */
if (napi_schedule_prep(&vi->napi)) {
virtqueue_disable_cb(vi->rvq);
+ local_bh_disable();
__napi_schedule(&vi->napi);
+ local_bh_enable();
}
}
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 3036c0bab056..3df0146b797e 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1751,7 +1751,7 @@ static void at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* following workaround is necessary. If the TX frame is an
* authentication frame extract the bssid and send the CMD_JOIN. */
if (mgmt->frame_control & cpu_to_le16(IEEE80211_STYPE_AUTH)) {
- if (compare_ether_addr(priv->bssid, mgmt->bssid)) {
+ if (!ether_addr_equal(priv->bssid, mgmt->bssid)) {
memcpy(priv->bssid, mgmt->bssid, ETH_ALEN);
ieee80211_queue_work(hw, &priv->work_join_bssid);
dev_kfree_skb_any(skb);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 49e3b19cf781..0ba81a66061f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -462,7 +462,7 @@ void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
}
if (iter_data->need_set_hw_addr && iter_data->hw_macaddr)
- if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0)
+ if (ether_addr_equal(iter_data->hw_macaddr, mac))
iter_data->need_set_hw_addr = false;
if (!iter_data->any_assoc) {
@@ -1170,7 +1170,7 @@ ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb,
if (ieee80211_is_beacon(mgmt->frame_control) &&
le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
- compare_ether_addr(mgmt->bssid, common->curbssid) == 0) {
+ ether_addr_equal(mgmt->bssid, common->curbssid)) {
/*
* Received an IBSS beacon with the same BSSID. Hardware *must*
* have updated the local TSF. We have to work around various
@@ -1234,7 +1234,7 @@ ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi)
/* only beacons from our BSSID */
if (!ieee80211_is_beacon(mgmt->frame_control) ||
- compare_ether_addr(mgmt->bssid, common->curbssid) != 0)
+ !ether_addr_equal(mgmt->bssid, common->curbssid))
return;
ewma_add(&ah->ah_beacon_rssi_avg, rssi);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 544e5490ca2e..e1fcc68124dc 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1833,7 +1833,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
if (ieee80211_is_beacon(hdr->frame_control)) {
RX_STAT_INC(rx_beacons);
if (!is_zero_ether_addr(common->curbssid) &&
- !compare_ether_addr(hdr->addr3, common->curbssid))
+ ether_addr_equal(hdr->addr3, common->curbssid))
rs.is_mybeacon = true;
else
rs.is_mybeacon = false;
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index dc99030ea8b6..84b22eec7abd 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -538,7 +538,7 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
return;
/* and only beacons from the associated BSSID, please */
- if (compare_ether_addr(hdr->addr3, ar->common.curbssid) ||
+ if (!ether_addr_equal(hdr->addr3, ar->common.curbssid) ||
!ar->common.curaid)
return;
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index c4955d25a19a..02e057923236 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -77,8 +77,8 @@ static struct libipw_frag_entry *libipw_frag_cache_find(struct
if (entry->skb != NULL && entry->seq == seq &&
(entry->last_frag + 1 == frag || frag == -1) &&
- !compare_ether_addr(entry->src_addr, src) &&
- !compare_ether_addr(entry->dst_addr, dst))
+ ether_addr_equal(entry->src_addr, src) &&
+ ether_addr_equal(entry->dst_addr, dst))
return entry;
}
@@ -245,12 +245,12 @@ static int libipw_is_eapol_frame(struct libipw_device *ieee,
/* check that the frame is unicast frame to us */
if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
IEEE80211_FCTL_TODS &&
- !compare_ether_addr(hdr->addr1, dev->dev_addr) &&
- !compare_ether_addr(hdr->addr3, dev->dev_addr)) {
+ ether_addr_equal(hdr->addr1, dev->dev_addr) &&
+ ether_addr_equal(hdr->addr3, dev->dev_addr)) {
/* ToDS frame with own addr BSSID and DA */
} else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
IEEE80211_FCTL_FROMDS &&
- !compare_ether_addr(hdr->addr1, dev->dev_addr)) {
+ ether_addr_equal(hdr->addr1, dev->dev_addr)) {
/* FromDS frame with own addr as DA */
} else
return 0;
@@ -523,8 +523,8 @@ int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,
if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
(fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_FROMDS && ieee->stadev
- && !compare_ether_addr(hdr->addr2, ieee->assoc_ap_addr)) {
+ IEEE80211_FCTL_FROMDS && ieee->stadev &&
+ ether_addr_equal(hdr->addr2, ieee->assoc_ap_addr)) {
/* Frame from BSSID of the AP for which we are a client */
skb->dev = dev = ieee->stadev;
stats = hostap_get_stats(dev);
@@ -1468,7 +1468,7 @@ static inline int is_same_network(struct libipw_network *src,
* as one network */
return ((src->ssid_len == dst->ssid_len) &&
(src->channel == dst->channel) &&
- !compare_ether_addr(src->bssid, dst->bssid) &&
+ ether_addr_equal(src->bssid, dst->bssid) &&
!memcmp(src->ssid, dst->ssid, src->ssid_len));
}
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index b25c01be0d90..87e539894330 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -453,10 +453,10 @@ il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header)
switch (il->iw_mode) {
case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */
/* packets to our IBSS update information */
- return !compare_ether_addr(header->addr3, il->bssid);
+ return ether_addr_equal(header->addr3, il->bssid);
case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */
/* packets to our IBSS update information */
- return !compare_ether_addr(header->addr2, il->bssid);
+ return ether_addr_equal(header->addr2, il->bssid);
default:
return 1;
}
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index f2baf94f069c..509301a5e7e2 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -2565,7 +2565,7 @@ il4965_find_station(struct il_priv *il, const u8 *addr)
spin_lock_irqsave(&il->sta_lock, flags);
for (i = start; i < il->hw_params.max_stations; i++)
if (il->stations[i].used &&
- (!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) {
+ ether_addr_equal(il->stations[i].sta.sta.addr, addr)) {
ret = i;
goto out;
}
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index eaf249452e51..cbf2dc18341f 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -1896,8 +1896,8 @@ il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap,
sta_id = il->hw_params.bcast_id;
else
for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) {
- if (!compare_ether_addr
- (il->stations[i].sta.sta.addr, addr)) {
+ if (ether_addr_equal(il->stations[i].sta.sta.addr,
+ addr)) {
sta_id = i;
break;
}
@@ -1926,7 +1926,7 @@ il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap,
if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) &&
(il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) &&
- !compare_ether_addr(il->stations[sta_id].sta.sta.addr, addr)) {
+ ether_addr_equal(il->stations[sta_id].sta.sta.addr, addr)) {
D_ASSOC("STA %d (%pM) already added, not adding again.\n",
sta_id, addr);
return sta_id;
@@ -3744,10 +3744,10 @@ il_full_rxon_required(struct il_priv *il)
/* These items are only settable from the full RXON command */
CHK(!il_is_associated(il));
- CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
- CHK(compare_ether_addr(staging->node_addr, active->node_addr));
- CHK(compare_ether_addr
- (staging->wlap_bssid_addr, active->wlap_bssid_addr));
+ CHK(!ether_addr_equal(staging->bssid_addr, active->bssid_addr));
+ CHK(!ether_addr_equal(staging->node_addr, active->node_addr));
+ CHK(!ether_addr_equal(staging->wlap_bssid_addr,
+ active->wlap_bssid_addr));
CHK_NEQ(staging->dev_type, active->dev_type);
CHK_NEQ(staging->channel, active->channel);
CHK_NEQ(staging->air_propagation, active->air_propagation);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 5b80467a5bb1..403de96f9747 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -759,7 +759,12 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
IWL_ERR(priv, "alloc_skb failed\n");
return;
}
- hdrlen = min_t(unsigned int, len, skb_tailroom(skb));
+ /* If frame is small enough to fit in skb->head, pull it completely.
+ * If not, only pull ieee80211_hdr so that splice() or TCP coalesce
+ * are more efficient.
+ */
+ hdrlen = (len <= skb_tailroom(skb)) ? len : sizeof(*hdr);
+
memcpy(skb_put(skb, hdrlen), hdr, hdrlen);
fraglen = len - hdrlen;
@@ -780,8 +785,8 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
*/
if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) {
for_each_context(priv, ctx) {
- if (compare_ether_addr(hdr->addr3,
- ctx->active.bssid_addr))
+ if (!ether_addr_equal(hdr->addr3,
+ ctx->active.bssid_addr))
continue;
iwlagn_lift_passive_no_rx(priv);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 89ccddcf0230..0a3aa7c83003 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -885,10 +885,10 @@ int iwl_full_rxon_required(struct iwl_priv *priv,
/* These items are only settable from the full RXON command */
CHK(!iwl_is_associated_ctx(ctx));
- CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
- CHK(compare_ether_addr(staging->node_addr, active->node_addr));
- CHK(compare_ether_addr(staging->wlap_bssid_addr,
- active->wlap_bssid_addr));
+ CHK(!ether_addr_equal(staging->bssid_addr, active->bssid_addr));
+ CHK(!ether_addr_equal(staging->node_addr, active->node_addr));
+ CHK(!ether_addr_equal(staging->wlap_bssid_addr,
+ active->wlap_bssid_addr));
CHK_NEQ(staging->dev_type, active->dev_type);
CHK_NEQ(staging->channel, active->channel);
CHK_NEQ(staging->air_propagation, active->air_propagation);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 67e6f1d2a08b..b31584e87bc7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -322,8 +322,8 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
sta_id = ctx->bcast_sta_id;
else
for (i = IWL_STA_ID; i < IWLAGN_STATION_COUNT; i++) {
- if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
- addr)) {
+ if (ether_addr_equal(priv->stations[i].sta.sta.addr,
+ addr)) {
sta_id = i;
break;
}
@@ -353,7 +353,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) &&
- !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
+ ether_addr_equal(priv->stations[sta_id].sta.sta.addr, addr)) {
IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not "
"adding again.\n", sta_id, addr);
return sta_id;
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index e30cc32f8279..cf7bdc66f822 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1235,7 +1235,7 @@ mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
{
return priv->capture_beacon &&
ieee80211_is_beacon(wh->frame_control) &&
- !compare_ether_addr(wh->addr3, priv->capture_bssid);
+ ether_addr_equal(wh->addr3, priv->capture_bssid);
}
static inline void mwl8k_save_beacon(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 7c8f118c2b09..82a1cac920bd 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -308,7 +308,7 @@ static void p54_pspoll_workaround(struct p54_common *priv, struct sk_buff *skb)
return;
/* only consider beacons from the associated BSSID */
- if (compare_ether_addr(hdr->addr3, priv->bssid))
+ if (!ether_addr_equal(hdr->addr3, priv->bssid))
return;
tim = p54_find_ie(skb, WLAN_EID_TIM);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 8b2226262524..f11953b26024 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -88,49 +88,6 @@ module_param_named(workaround_interval, modparam_workaround_interval,
MODULE_PARM_DESC(workaround_interval,
"set stall workaround interval in msecs (0=disabled) (default: 0)");
-
-/* various RNDIS OID defs */
-#define OID_GEN_LINK_SPEED cpu_to_le32(0x00010107)
-#define OID_GEN_RNDIS_CONFIG_PARAMETER cpu_to_le32(0x0001021b)
-
-#define OID_GEN_XMIT_OK cpu_to_le32(0x00020101)
-#define OID_GEN_RCV_OK cpu_to_le32(0x00020102)
-#define OID_GEN_XMIT_ERROR cpu_to_le32(0x00020103)
-#define OID_GEN_RCV_ERROR cpu_to_le32(0x00020104)
-#define OID_GEN_RCV_NO_BUFFER cpu_to_le32(0x00020105)
-
-#define OID_802_3_CURRENT_ADDRESS cpu_to_le32(0x01010102)
-#define OID_802_3_MULTICAST_LIST cpu_to_le32(0x01010103)
-#define OID_802_3_MAXIMUM_LIST_SIZE cpu_to_le32(0x01010104)
-
-#define OID_802_11_BSSID cpu_to_le32(0x0d010101)
-#define OID_802_11_SSID cpu_to_le32(0x0d010102)
-#define OID_802_11_INFRASTRUCTURE_MODE cpu_to_le32(0x0d010108)
-#define OID_802_11_ADD_WEP cpu_to_le32(0x0d010113)
-#define OID_802_11_REMOVE_WEP cpu_to_le32(0x0d010114)
-#define OID_802_11_DISASSOCIATE cpu_to_le32(0x0d010115)
-#define OID_802_11_AUTHENTICATION_MODE cpu_to_le32(0x0d010118)
-#define OID_802_11_PRIVACY_FILTER cpu_to_le32(0x0d010119)
-#define OID_802_11_BSSID_LIST_SCAN cpu_to_le32(0x0d01011a)
-#define OID_802_11_ENCRYPTION_STATUS cpu_to_le32(0x0d01011b)
-#define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d)
-#define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e)
-#define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f)
-#define OID_802_11_CAPABILITY cpu_to_le32(0x0d010122)
-#define OID_802_11_PMKID cpu_to_le32(0x0d010123)
-#define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203)
-#define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204)
-#define OID_802_11_TX_POWER_LEVEL cpu_to_le32(0x0d010205)
-#define OID_802_11_RSSI cpu_to_le32(0x0d010206)
-#define OID_802_11_RSSI_TRIGGER cpu_to_le32(0x0d010207)
-#define OID_802_11_FRAGMENTATION_THRESHOLD cpu_to_le32(0x0d010209)
-#define OID_802_11_RTS_THRESHOLD cpu_to_le32(0x0d01020a)
-#define OID_802_11_SUPPORTED_RATES cpu_to_le32(0x0d01020e)
-#define OID_802_11_CONFIGURATION cpu_to_le32(0x0d010211)
-#define OID_802_11_POWER_MODE cpu_to_le32(0x0d010216)
-#define OID_802_11_BSSID_LIST cpu_to_le32(0x0d010217)
-
-
/* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */
#define WL_NOISE -96 /* typical noise level in dBm */
#define WL_SIGMAX -32 /* typical maximum signal level in dBm */
@@ -149,12 +106,6 @@ MODULE_PARM_DESC(workaround_interval,
#define BCM4320_DEFAULT_TXPOWER_DBM_50 10
#define BCM4320_DEFAULT_TXPOWER_DBM_25 7
-
-/* codes for "status" field of completion messages */
-#define RNDIS_STATUS_ADAPTER_NOT_READY cpu_to_le32(0xc0010011)
-#define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012)
-
-
/* Known device types */
#define RNDIS_UNKNOWN 0
#define RNDIS_BCM4320A 1
@@ -515,7 +466,7 @@ struct rndis_wlan_private {
int infra_mode;
bool connected;
u8 bssid[ETH_ALEN];
- __le32 current_command_oid;
+ u32 current_command_oid;
/* encryption stuff */
u8 encr_tx_key_index;
@@ -666,63 +617,63 @@ static int rndis_akm_suite_to_key_mgmt(u32 akm_suite)
}
#ifdef DEBUG
-static const char *oid_to_string(__le32 oid)
+static const char *oid_to_string(u32 oid)
{
switch (oid) {
#define OID_STR(oid) case oid: return(#oid)
/* from rndis_host.h */
- OID_STR(OID_802_3_PERMANENT_ADDRESS);
- OID_STR(OID_GEN_MAXIMUM_FRAME_SIZE);
- OID_STR(OID_GEN_CURRENT_PACKET_FILTER);
- OID_STR(OID_GEN_PHYSICAL_MEDIUM);
+ OID_STR(RNDIS_OID_802_3_PERMANENT_ADDRESS);
+ OID_STR(RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE);
+ OID_STR(RNDIS_OID_GEN_CURRENT_PACKET_FILTER);
+ OID_STR(RNDIS_OID_GEN_PHYSICAL_MEDIUM);
/* from rndis_wlan.c */
- OID_STR(OID_GEN_LINK_SPEED);
- OID_STR(OID_GEN_RNDIS_CONFIG_PARAMETER);
-
- OID_STR(OID_GEN_XMIT_OK);
- OID_STR(OID_GEN_RCV_OK);
- OID_STR(OID_GEN_XMIT_ERROR);
- OID_STR(OID_GEN_RCV_ERROR);
- OID_STR(OID_GEN_RCV_NO_BUFFER);
-
- OID_STR(OID_802_3_CURRENT_ADDRESS);
- OID_STR(OID_802_3_MULTICAST_LIST);
- OID_STR(OID_802_3_MAXIMUM_LIST_SIZE);
-
- OID_STR(OID_802_11_BSSID);
- OID_STR(OID_802_11_SSID);
- OID_STR(OID_802_11_INFRASTRUCTURE_MODE);
- OID_STR(OID_802_11_ADD_WEP);
- OID_STR(OID_802_11_REMOVE_WEP);
- OID_STR(OID_802_11_DISASSOCIATE);
- OID_STR(OID_802_11_AUTHENTICATION_MODE);
- OID_STR(OID_802_11_PRIVACY_FILTER);
- OID_STR(OID_802_11_BSSID_LIST_SCAN);
- OID_STR(OID_802_11_ENCRYPTION_STATUS);
- OID_STR(OID_802_11_ADD_KEY);
- OID_STR(OID_802_11_REMOVE_KEY);
- OID_STR(OID_802_11_ASSOCIATION_INFORMATION);
- OID_STR(OID_802_11_CAPABILITY);
- OID_STR(OID_802_11_PMKID);
- OID_STR(OID_802_11_NETWORK_TYPES_SUPPORTED);
- OID_STR(OID_802_11_NETWORK_TYPE_IN_USE);
- OID_STR(OID_802_11_TX_POWER_LEVEL);
- OID_STR(OID_802_11_RSSI);
- OID_STR(OID_802_11_RSSI_TRIGGER);
- OID_STR(OID_802_11_FRAGMENTATION_THRESHOLD);
- OID_STR(OID_802_11_RTS_THRESHOLD);
- OID_STR(OID_802_11_SUPPORTED_RATES);
- OID_STR(OID_802_11_CONFIGURATION);
- OID_STR(OID_802_11_POWER_MODE);
- OID_STR(OID_802_11_BSSID_LIST);
+ OID_STR(RNDIS_OID_GEN_LINK_SPEED);
+ OID_STR(RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER);
+
+ OID_STR(RNDIS_OID_GEN_XMIT_OK);
+ OID_STR(RNDIS_OID_GEN_RCV_OK);
+ OID_STR(RNDIS_OID_GEN_XMIT_ERROR);
+ OID_STR(RNDIS_OID_GEN_RCV_ERROR);
+ OID_STR(RNDIS_OID_GEN_RCV_NO_BUFFER);
+
+ OID_STR(RNDIS_OID_802_3_CURRENT_ADDRESS);
+ OID_STR(RNDIS_OID_802_3_MULTICAST_LIST);
+ OID_STR(RNDIS_OID_802_3_MAXIMUM_LIST_SIZE);
+
+ OID_STR(RNDIS_OID_802_11_BSSID);
+ OID_STR(RNDIS_OID_802_11_SSID);
+ OID_STR(RNDIS_OID_802_11_INFRASTRUCTURE_MODE);
+ OID_STR(RNDIS_OID_802_11_ADD_WEP);
+ OID_STR(RNDIS_OID_802_11_REMOVE_WEP);
+ OID_STR(RNDIS_OID_802_11_DISASSOCIATE);
+ OID_STR(RNDIS_OID_802_11_AUTHENTICATION_MODE);
+ OID_STR(RNDIS_OID_802_11_PRIVACY_FILTER);
+ OID_STR(RNDIS_OID_802_11_BSSID_LIST_SCAN);
+ OID_STR(RNDIS_OID_802_11_ENCRYPTION_STATUS);
+ OID_STR(RNDIS_OID_802_11_ADD_KEY);
+ OID_STR(RNDIS_OID_802_11_REMOVE_KEY);
+ OID_STR(RNDIS_OID_802_11_ASSOCIATION_INFORMATION);
+ OID_STR(RNDIS_OID_802_11_CAPABILITY);
+ OID_STR(RNDIS_OID_802_11_PMKID);
+ OID_STR(RNDIS_OID_802_11_NETWORK_TYPES_SUPPORTED);
+ OID_STR(RNDIS_OID_802_11_NETWORK_TYPE_IN_USE);
+ OID_STR(RNDIS_OID_802_11_TX_POWER_LEVEL);
+ OID_STR(RNDIS_OID_802_11_RSSI);
+ OID_STR(RNDIS_OID_802_11_RSSI_TRIGGER);
+ OID_STR(RNDIS_OID_802_11_FRAGMENTATION_THRESHOLD);
+ OID_STR(RNDIS_OID_802_11_RTS_THRESHOLD);
+ OID_STR(RNDIS_OID_802_11_SUPPORTED_RATES);
+ OID_STR(RNDIS_OID_802_11_CONFIGURATION);
+ OID_STR(RNDIS_OID_802_11_POWER_MODE);
+ OID_STR(RNDIS_OID_802_11_BSSID_LIST);
#undef OID_STR
}
return "?";
}
#else
-static const char *oid_to_string(__le32 oid)
+static const char *oid_to_string(u32 oid)
{
return "?";
}
@@ -732,7 +683,7 @@ static const char *oid_to_string(__le32 oid)
static int rndis_error_status(__le32 rndis_status)
{
int ret = -EINVAL;
- switch (rndis_status) {
+ switch (le32_to_cpu(rndis_status)) {
case RNDIS_STATUS_SUCCESS:
ret = 0;
break;
@@ -751,7 +702,7 @@ static int rndis_error_status(__le32 rndis_status)
return ret;
}
-static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
+static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
union {
@@ -778,9 +729,9 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
mutex_lock(&priv->command_lock);
memset(u.get, 0, sizeof *u.get);
- u.get->msg_type = RNDIS_MSG_QUERY;
+ u.get->msg_type = cpu_to_le32(RNDIS_MSG_QUERY);
u.get->msg_len = cpu_to_le32(sizeof *u.get);
- u.get->oid = oid;
+ u.get->oid = cpu_to_le32(oid);
priv->current_command_oid = oid;
ret = rndis_command(dev, u.header, buflen);
@@ -835,7 +786,7 @@ exit_unlock:
return ret;
}
-static int rndis_set_oid(struct usbnet *dev, __le32 oid, const void *data,
+static int rndis_set_oid(struct usbnet *dev, u32 oid, const void *data,
int len)
{
struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
@@ -862,9 +813,9 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, const void *data,
mutex_lock(&priv->command_lock);
memset(u.set, 0, sizeof *u.set);
- u.set->msg_type = RNDIS_MSG_SET;
+ u.set->msg_type = cpu_to_le32(RNDIS_MSG_SET);
u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len);
- u.set->oid = oid;
+ u.set->oid = cpu_to_le32(oid);
u.set->len = cpu_to_le32(len);
u.set->offset = cpu_to_le32(sizeof(*u.set) - 8);
u.set->handle = cpu_to_le32(0);
@@ -904,7 +855,7 @@ static int rndis_reset(struct usbnet *usbdev)
reset = (void *)priv->command_buffer;
memset(reset, 0, sizeof(*reset));
- reset->msg_type = RNDIS_MSG_RESET;
+ reset->msg_type = cpu_to_le32(RNDIS_MSG_RESET);
reset->msg_len = cpu_to_le32(sizeof(*reset));
priv->current_command_oid = 0;
ret = rndis_command(usbdev, (void *)reset, CONTROL_BUFFER_SIZE);
@@ -990,7 +941,7 @@ static int rndis_set_config_parameter(struct usbnet *dev, char *param,
}
#endif
- ret = rndis_set_oid(dev, OID_GEN_RNDIS_CONFIG_PARAMETER,
+ ret = rndis_set_oid(dev, RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER,
infobuf, info_len);
if (ret != 0)
netdev_dbg(dev->net, "setting rndis config parameter failed, %d\n",
@@ -1027,9 +978,9 @@ static int rndis_start_bssid_list_scan(struct usbnet *usbdev)
{
__le32 tmp;
- /* Note: OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */
+ /* Note: RNDIS_OID_802_11_BSSID_LIST_SCAN clears internal BSS list. */
tmp = cpu_to_le32(1);
- return rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+ return rndis_set_oid(usbdev, RNDIS_OID_802_11_BSSID_LIST_SCAN, &tmp,
sizeof(tmp));
}
@@ -1038,7 +989,8 @@ static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
int ret;
- ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
+ ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_SSID,
+ ssid, sizeof(*ssid));
if (ret < 0) {
netdev_warn(usbdev->net, "setting SSID failed (%08X)\n", ret);
return ret;
@@ -1055,7 +1007,8 @@ static int set_bssid(struct usbnet *usbdev, const u8 *bssid)
{
int ret;
- ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
+ ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_BSSID,
+ bssid, ETH_ALEN);
if (ret < 0) {
netdev_warn(usbdev->net, "setting BSSID[%pM] failed (%08X)\n",
bssid, ret);
@@ -1079,7 +1032,8 @@ static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
int ret, len;
len = ETH_ALEN;
- ret = rndis_query_oid(usbdev, OID_802_11_BSSID, bssid, &len);
+ ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_BSSID,
+ bssid, &len);
if (ret != 0)
memset(bssid, 0, ETH_ALEN);
@@ -1090,8 +1044,9 @@ static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
static int get_association_info(struct usbnet *usbdev,
struct ndis_80211_assoc_info *info, int len)
{
- return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION,
- info, &len);
+ return rndis_query_oid(usbdev,
+ RNDIS_OID_802_11_ASSOCIATION_INFORMATION,
+ info, &len);
}
static bool is_associated(struct usbnet *usbdev)
@@ -1115,7 +1070,9 @@ static int disassociate(struct usbnet *usbdev, bool reset_ssid)
int i, ret = 0;
if (priv->radio_on) {
- ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0);
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_DISASSOCIATE,
+ NULL, 0);
if (ret == 0) {
priv->radio_on = false;
netdev_dbg(usbdev->net, "%s(): radio_on = false\n",
@@ -1177,8 +1134,9 @@ static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version,
return -ENOTSUPP;
tmp = cpu_to_le32(auth_mode);
- ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
- sizeof(tmp));
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_AUTHENTICATION_MODE,
+ &tmp, sizeof(tmp));
if (ret != 0) {
netdev_warn(usbdev->net, "setting auth mode failed (%08X)\n",
ret);
@@ -1204,8 +1162,9 @@ static int set_priv_filter(struct usbnet *usbdev)
else
tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL);
- return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp,
- sizeof(tmp));
+ return rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_PRIVACY_FILTER, &tmp,
+ sizeof(tmp));
}
static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
@@ -1230,8 +1189,9 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
encr_mode = NDIS_80211_ENCR_DISABLED;
tmp = cpu_to_le32(encr_mode);
- ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
- sizeof(tmp));
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_ENCRYPTION_STATUS, &tmp,
+ sizeof(tmp));
if (ret != 0) {
netdev_warn(usbdev->net, "setting encr mode failed (%08X)\n",
ret);
@@ -1251,8 +1211,9 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
__func__, priv->infra_mode);
tmp = cpu_to_le32(mode);
- ret = rndis_set_oid(usbdev, OID_802_11_INFRASTRUCTURE_MODE, &tmp,
- sizeof(tmp));
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_INFRASTRUCTURE_MODE,
+ &tmp, sizeof(tmp));
if (ret != 0) {
netdev_warn(usbdev->net, "setting infra mode failed (%08X)\n",
ret);
@@ -1278,8 +1239,9 @@ static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold)
rts_threshold = 2347;
tmp = cpu_to_le32(rts_threshold);
- return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp,
- sizeof(tmp));
+ return rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_RTS_THRESHOLD,
+ &tmp, sizeof(tmp));
}
static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold)
@@ -1292,8 +1254,9 @@ static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold)
frag_threshold = 2346;
tmp = cpu_to_le32(frag_threshold);
- return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
- sizeof(tmp));
+ return rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_FRAGMENTATION_THRESHOLD,
+ &tmp, sizeof(tmp));
}
static void set_default_iw_params(struct usbnet *usbdev)
@@ -1329,7 +1292,9 @@ static int set_channel(struct usbnet *usbdev, int channel)
dsconfig = ieee80211_dsss_chan_to_freq(channel) * 1000;
len = sizeof(config);
- ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
+ ret = rndis_query_oid(usbdev,
+ RNDIS_OID_802_11_CONFIGURATION,
+ &config, &len);
if (ret < 0) {
netdev_dbg(usbdev->net, "%s(): querying configuration failed\n",
__func__);
@@ -1337,8 +1302,9 @@ static int set_channel(struct usbnet *usbdev, int channel)
}
config.ds_config = cpu_to_le32(dsconfig);
- ret = rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
- sizeof(config));
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_CONFIGURATION,
+ &config, sizeof(config));
netdev_dbg(usbdev->net, "%s(): %d -> %d\n", __func__, channel, ret);
@@ -1355,8 +1321,10 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev,
/* Get channel and beacon interval */
len = sizeof(config);
- ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
- netdev_dbg(usbdev->net, "%s(): OID_802_11_CONFIGURATION -> %d\n",
+ ret = rndis_query_oid(usbdev,
+ RNDIS_OID_802_11_CONFIGURATION,
+ &config, &len);
+ netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_CONFIGURATION -> %d\n",
__func__, ret);
if (ret < 0)
return NULL;
@@ -1409,8 +1377,9 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
ret);
}
- ret = rndis_set_oid(usbdev, OID_802_11_ADD_WEP, &ndis_key,
- sizeof(ndis_key));
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_ADD_WEP, &ndis_key,
+ sizeof(ndis_key));
if (ret != 0) {
netdev_warn(usbdev->net, "adding encryption key %d failed (%08X)\n",
index + 1, ret);
@@ -1500,9 +1469,10 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
get_bssid(usbdev, ndis_key.bssid);
}
- ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
- le32_to_cpu(ndis_key.size));
- netdev_dbg(usbdev->net, "%s(): OID_802_11_ADD_KEY -> %08X\n",
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_ADD_KEY, &ndis_key,
+ le32_to_cpu(ndis_key.size));
+ netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_ADD_KEY -> %08X\n",
__func__, ret);
if (ret != 0)
return ret;
@@ -1590,14 +1560,16 @@ static int remove_key(struct usbnet *usbdev, u8 index, const u8 *bssid)
memset(remove_key.bssid, 0xff,
sizeof(remove_key.bssid));
- ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_KEY, &remove_key,
- sizeof(remove_key));
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_REMOVE_KEY,
+ &remove_key, sizeof(remove_key));
if (ret != 0)
return ret;
} else {
keyindex = cpu_to_le32(index);
- ret = rndis_set_oid(usbdev, OID_802_11_REMOVE_WEP, &keyindex,
- sizeof(keyindex));
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_REMOVE_WEP,
+ &keyindex, sizeof(keyindex));
if (ret != 0) {
netdev_warn(usbdev->net,
"removing encryption key %d failed (%08X)\n",
@@ -1622,14 +1594,14 @@ static void set_multicast_list(struct usbnet *usbdev)
char *mc_addrs = NULL;
int mc_count;
- basefilter = filter = RNDIS_PACKET_TYPE_DIRECTED |
- RNDIS_PACKET_TYPE_BROADCAST;
+ basefilter = filter = cpu_to_le32(RNDIS_PACKET_TYPE_DIRECTED |
+ RNDIS_PACKET_TYPE_BROADCAST);
if (usbdev->net->flags & IFF_PROMISC) {
- filter |= RNDIS_PACKET_TYPE_PROMISCUOUS |
- RNDIS_PACKET_TYPE_ALL_LOCAL;
+ filter |= cpu_to_le32(RNDIS_PACKET_TYPE_PROMISCUOUS |
+ RNDIS_PACKET_TYPE_ALL_LOCAL);
} else if (usbdev->net->flags & IFF_ALLMULTI) {
- filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+ filter |= cpu_to_le32(RNDIS_PACKET_TYPE_ALL_MULTICAST);
}
if (filter != basefilter)
@@ -1642,7 +1614,7 @@ static void set_multicast_list(struct usbnet *usbdev)
netif_addr_lock_bh(usbdev->net);
mc_count = netdev_mc_count(usbdev->net);
if (mc_count > priv->multicast_size) {
- filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+ filter |= cpu_to_le32(RNDIS_PACKET_TYPE_ALL_MULTICAST);
} else if (mc_count) {
int i = 0;
@@ -1665,27 +1637,28 @@ static void set_multicast_list(struct usbnet *usbdev)
goto set_filter;
if (mc_count) {
- ret = rndis_set_oid(usbdev, OID_802_3_MULTICAST_LIST, mc_addrs,
- mc_count * ETH_ALEN);
+ ret = rndis_set_oid(usbdev,
+ RNDIS_OID_802_3_MULTICAST_LIST,
+ mc_addrs, mc_count * ETH_ALEN);
kfree(mc_addrs);
if (ret == 0)
- filter |= RNDIS_PACKET_TYPE_MULTICAST;
+ filter |= cpu_to_le32(RNDIS_PACKET_TYPE_MULTICAST);
else
- filter |= RNDIS_PACKET_TYPE_ALL_MULTICAST;
+ filter |= cpu_to_le32(RNDIS_PACKET_TYPE_ALL_MULTICAST);
- netdev_dbg(usbdev->net, "OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n",
+ netdev_dbg(usbdev->net, "RNDIS_OID_802_3_MULTICAST_LIST(%d, max: %d) -> %d\n",
mc_count, priv->multicast_size, ret);
}
set_filter:
- ret = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
+ ret = rndis_set_oid(usbdev, RNDIS_OID_GEN_CURRENT_PACKET_FILTER, &filter,
sizeof(filter));
if (ret < 0) {
netdev_warn(usbdev->net, "couldn't set packet filter: %08x\n",
le32_to_cpu(filter));
}
- netdev_dbg(usbdev->net, "OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d\n",
+ netdev_dbg(usbdev->net, "RNDIS_OID_GEN_CURRENT_PACKET_FILTER(%08x) -> %d\n",
le32_to_cpu(filter), ret);
}
@@ -1744,9 +1717,10 @@ static struct ndis_80211_pmkid *get_device_pmkids(struct usbnet *usbdev)
pmkids->length = cpu_to_le32(len);
pmkids->bssid_info_count = cpu_to_le32(max_pmkids);
- ret = rndis_query_oid(usbdev, OID_802_11_PMKID, pmkids, &len);
+ ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_PMKID,
+ pmkids, &len);
if (ret < 0) {
- netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d)"
+ netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_PMKID(%d, %d)"
" -> %d\n", __func__, len, max_pmkids, ret);
kfree(pmkids);
@@ -1772,10 +1746,10 @@ static int set_device_pmkids(struct usbnet *usbdev,
debug_print_pmkids(usbdev, pmkids, __func__);
- ret = rndis_set_oid(usbdev, OID_802_11_PMKID, pmkids,
- le32_to_cpu(pmkids->length));
+ ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_PMKID, pmkids,
+ le32_to_cpu(pmkids->length));
if (ret < 0) {
- netdev_dbg(usbdev->net, "%s(): OID_802_11_PMKID(%d, %d) -> %d"
+ netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_PMKID(%d, %d) -> %d"
"\n", __func__, len, num_pmkids, ret);
}
@@ -1797,8 +1771,8 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev,
count = max_pmkids;
for (i = 0; i < count; i++)
- if (!compare_ether_addr(pmkids->bssid_info[i].bssid,
- pmksa->bssid))
+ if (ether_addr_equal(pmkids->bssid_info[i].bssid,
+ pmksa->bssid))
break;
/* pmkid not found */
@@ -1839,8 +1813,8 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev,
/* update with new pmkid */
for (i = 0; i < count; i++) {
- if (compare_ether_addr(pmkids->bssid_info[i].bssid,
- pmksa->bssid))
+ if (!ether_addr_equal(pmkids->bssid_info[i].bssid,
+ pmksa->bssid))
continue;
memcpy(pmkids->bssid_info[i].pmkid, pmksa->pmkid,
@@ -2109,7 +2083,8 @@ resize_buf:
* resizing until it won't get any bigger.
*/
new_len = len;
- ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &new_len);
+ ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_BSSID_LIST,
+ buf, &new_len);
if (ret != 0 || new_len < sizeof(struct ndis_80211_bssid_list_ex))
goto out;
@@ -2135,7 +2110,7 @@ resize_buf:
while (check_bssid_list_item(bssid, bssid_len, buf, len)) {
if (rndis_bss_info_update(usbdev, bssid) && match_bssid &&
matched) {
- if (compare_ether_addr(bssid->mac, match_bssid))
+ if (!ether_addr_equal(bssid->mac, match_bssid))
*matched = true;
}
@@ -2497,14 +2472,15 @@ static void rndis_fill_station_info(struct usbnet *usbdev,
memset(sinfo, 0, sizeof(*sinfo));
len = sizeof(linkspeed);
- ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &linkspeed, &len);
+ ret = rndis_query_oid(usbdev, RNDIS_OID_GEN_LINK_SPEED, &linkspeed, &len);
if (ret == 0) {
sinfo->txrate.legacy = le32_to_cpu(linkspeed) / 1000;
sinfo->filled |= STATION_INFO_TX_BITRATE;
}
len = sizeof(rssi);
- ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
+ ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_RSSI,
+ &rssi, &len);
if (ret == 0) {
sinfo->signal = level_to_qual(le32_to_cpu(rssi));
sinfo->filled |= STATION_INFO_SIGNAL;
@@ -2517,7 +2493,7 @@ static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
struct usbnet *usbdev = priv->usbdev;
- if (compare_ether_addr(priv->bssid, mac))
+ if (!ether_addr_equal(priv->bssid, mac))
return -ENOENT;
rndis_fill_station_info(usbdev, sinfo);
@@ -2610,7 +2586,8 @@ static int rndis_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
pmkid.length = cpu_to_le32(sizeof(pmkid));
pmkid.bssid_info_count = cpu_to_le32(0);
- return rndis_set_oid(usbdev, OID_802_11_PMKID, &pmkid, sizeof(pmkid));
+ return rndis_set_oid(usbdev, RNDIS_OID_802_11_PMKID,
+ &pmkid, sizeof(pmkid));
}
static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
@@ -2640,9 +2617,10 @@ static int rndis_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
priv->power_mode = power_mode;
mode = cpu_to_le32(power_mode);
- ret = rndis_set_oid(usbdev, OID_802_11_POWER_MODE, &mode, sizeof(mode));
+ ret = rndis_set_oid(usbdev, RNDIS_OID_802_11_POWER_MODE,
+ &mode, sizeof(mode));
- netdev_dbg(usbdev->net, "%s(): OID_802_11_POWER_MODE -> %d\n",
+ netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_POWER_MODE -> %d\n",
__func__, ret);
return ret;
@@ -2679,10 +2657,11 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
/* Get signal quality, in case of error use rssi=0 and ignore error. */
len = sizeof(rssi);
rssi = 0;
- ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
+ ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_RSSI,
+ &rssi, &len);
signal = level_to_qual(le32_to_cpu(rssi));
- netdev_dbg(usbdev->net, "%s(): OID_802_11_RSSI -> %d, "
+ netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_RSSI -> %d, "
"rssi:%d, qual: %d\n", __func__, ret, le32_to_cpu(rssi),
level_to_qual(le32_to_cpu(rssi)));
@@ -2706,8 +2685,9 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid,
/* Get SSID, in case of error, use zero length SSID and ignore error. */
len = sizeof(ssid);
memset(&ssid, 0, sizeof(ssid));
- ret = rndis_query_oid(usbdev, OID_802_11_SSID, &ssid, &len);
- netdev_dbg(usbdev->net, "%s(): OID_802_11_SSID -> %d, len: %d, ssid: "
+ ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_SSID,
+ &ssid, &len);
+ netdev_dbg(usbdev->net, "%s(): RNDIS_OID_802_11_SSID -> %d, len: %d, ssid: "
"'%.32s'\n", __func__, ret,
le32_to_cpu(ssid.length), ssid.essid);
@@ -2829,7 +2809,7 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
* NDIS spec says: "If the device is associated, but the associated
* BSSID is not in its BSSID scan list, then the driver must add an
* entry for the BSSID at the end of the data that it returns in
- * response to query of OID_802_11_BSSID_LIST."
+ * response to query of RNDIS_OID_802_11_BSSID_LIST."
*
* NOTE: Seems to be true for BCM4320b variant, but not BCM4320a.
*/
@@ -3081,15 +3061,15 @@ static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
struct rndis_indicate *msg = ind;
- switch (msg->status) {
+ switch (le32_to_cpu(msg->status)) {
case RNDIS_STATUS_MEDIA_CONNECT:
- if (priv->current_command_oid == OID_802_11_ADD_KEY) {
- /* OID_802_11_ADD_KEY causes sometimes extra
+ if (priv->current_command_oid == RNDIS_OID_802_11_ADD_KEY) {
+ /* RNDIS_OID_802_11_ADD_KEY causes sometimes extra
* "media connect" indications which confuses driver
* and userspace to think that device is
* roaming/reassociating when it isn't.
*/
- netdev_dbg(usbdev->net, "ignored OID_802_11_ADD_KEY triggered 'media connect'\n");
+ netdev_dbg(usbdev->net, "ignored RNDIS_OID_802_11_ADD_KEY triggered 'media connect'\n");
return;
}
@@ -3134,8 +3114,9 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy)
/* determine supported modes */
len = sizeof(networks_supported);
- retval = rndis_query_oid(usbdev, OID_802_11_NETWORK_TYPES_SUPPORTED,
- &networks_supported, &len);
+ retval = rndis_query_oid(usbdev,
+ RNDIS_OID_802_11_NETWORK_TYPES_SUPPORTED,
+ &networks_supported, &len);
if (retval >= 0) {
n = le32_to_cpu(networks_supported.num_items);
if (n > 8)
@@ -3159,9 +3140,11 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev, struct wiphy *wiphy)
/* get device 802.11 capabilities, number of PMKIDs */
caps = (struct ndis_80211_capability *)caps_buf;
len = sizeof(caps_buf);
- retval = rndis_query_oid(usbdev, OID_802_11_CAPABILITY, caps, &len);
+ retval = rndis_query_oid(usbdev,
+ RNDIS_OID_802_11_CAPABILITY,
+ caps, &len);
if (retval >= 0) {
- netdev_dbg(usbdev->net, "OID_802_11_CAPABILITY -> len %d, "
+ netdev_dbg(usbdev->net, "RNDIS_OID_802_11_CAPABILITY -> len %d, "
"ver %d, pmkids %d, auth-encr-pairs %d\n",
le32_to_cpu(caps->length),
le32_to_cpu(caps->version),
@@ -3233,13 +3216,14 @@ static void rndis_device_poller(struct work_struct *work)
}
len = sizeof(rssi);
- ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
+ ret = rndis_query_oid(usbdev, RNDIS_OID_802_11_RSSI,
+ &rssi, &len);
if (ret == 0) {
priv->last_qual = level_to_qual(le32_to_cpu(rssi));
rndis_do_cqm(usbdev, le32_to_cpu(rssi));
}
- netdev_dbg(usbdev->net, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n",
+ netdev_dbg(usbdev->net, "dev-poller: RNDIS_OID_802_11_RSSI -> %d, rssi:%d, qual: %d\n",
ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi)));
/* Workaround transfer stalls on poor quality links.
@@ -3261,15 +3245,18 @@ static void rndis_device_poller(struct work_struct *work)
* working.
*/
tmp = cpu_to_le32(1);
- rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
- sizeof(tmp));
+ rndis_set_oid(usbdev,
+ RNDIS_OID_802_11_BSSID_LIST_SCAN,
+ &tmp, sizeof(tmp));
len = CONTROL_BUFFER_SIZE;
buf = kmalloc(len, GFP_KERNEL);
if (!buf)
goto end;
- rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
+ rndis_query_oid(usbdev,
+ RNDIS_OID_802_11_BSSID_LIST,
+ buf, &len);
kfree(buf);
}
@@ -3451,13 +3438,15 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
*/
usbdev->net->netdev_ops = &rndis_wlan_netdev_ops;
- tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
- retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
- sizeof(tmp));
+ tmp = cpu_to_le32(RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST);
+ retval = rndis_set_oid(usbdev,
+ RNDIS_OID_GEN_CURRENT_PACKET_FILTER,
+ &tmp, sizeof(tmp));
len = sizeof(tmp);
- retval = rndis_query_oid(usbdev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp,
- &len);
+ retval = rndis_query_oid(usbdev,
+ RNDIS_OID_802_3_MAXIMUM_LIST_SIZE,
+ &tmp, &len);
priv->multicast_size = le32_to_cpu(tmp);
if (retval < 0 || priv->multicast_size < 0)
priv->multicast_size = 0;
@@ -3587,7 +3576,7 @@ static int rndis_wlan_stop(struct usbnet *usbdev)
/* Set current packet filter zero to block receiving data packets from
device. */
filter = 0;
- rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
+ rndis_set_oid(usbdev, RNDIS_OID_GEN_CURRENT_PACKET_FILTER, &filter,
sizeof(filter));
return retval;
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index e54488db0e10..f4c852c6749b 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -1460,7 +1460,7 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
return;
/* and only beacons from the associated BSSID, please */
- if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+ if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
return;
if (rtl_find_221_ie(hw, data, len))
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index 5b9c3b5e8c92..5ae26647f340 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -480,7 +480,7 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
return;
/* and only beacons from the associated BSSID, please */
- if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+ if (!ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
return;
rtlpriv->psc.last_beacon = jiffies;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index 37b13636a778..3af874e69595 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -508,14 +508,14 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
packet_matchbssid =
((IEEE80211_FTYPE_CTL != type) &&
- (!compare_ether_addr(mac->bssid,
- (c_fc & IEEE80211_FCTL_TODS) ?
- hdr->addr1 : (c_fc & IEEE80211_FCTL_FROMDS) ?
- hdr->addr2 : hdr->addr3)) &&
+ ether_addr_equal(mac->bssid,
+ (c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
+ (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
+ hdr->addr3) &&
(!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
packet_toself = packet_matchbssid &&
- (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+ ether_addr_equal(praddr, rtlefuse->dev_addr);
if (ieee80211_is_beacon(fc))
packet_beacon = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
index 025bdc2eba44..7e91c76582ec 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
@@ -1099,14 +1099,14 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw,
praddr = hdr->addr1;
packet_matchbssid =
((IEEE80211_FTYPE_CTL != type) &&
- (!compare_ether_addr(mac->bssid,
- (cpu_fc & IEEE80211_FCTL_TODS) ?
- hdr->addr1 : (cpu_fc & IEEE80211_FCTL_FROMDS) ?
- hdr->addr2 : hdr->addr3)) &&
+ ether_addr_equal(mac->bssid,
+ (cpu_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
+ (cpu_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
+ hdr->addr3) &&
(!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
packet_toself = packet_matchbssid &&
- (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+ ether_addr_equal(praddr, rtlefuse->dev_addr);
if (ieee80211_is_beacon(fc))
packet_beacon = true;
_rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
index a7f6126e2f86..1666ef7fd87b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
@@ -466,12 +466,13 @@ static void _rtl92de_translate_rx_signal_stuff(struct ieee80211_hw *hw,
type = WLAN_FC_GET_TYPE(fc);
praddr = hdr->addr1;
packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
- (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ?
- hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ?
- hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) &&
- (!pstats->crc) && (!pstats->icv));
+ ether_addr_equal(mac->bssid,
+ (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
+ (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
+ hdr->addr3) &&
+ (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
packet_toself = packet_matchbssid &&
- (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+ ether_addr_equal(praddr, rtlefuse->dev_addr);
if (ieee80211_is_beacon(fc))
packet_beacon = true;
_rtl92de_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index 2fd3d13b7ced..812b5858f14a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -492,13 +492,14 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
praddr = hdr->addr1;
packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
- (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ?
- hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ?
- hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) &&
- (!pstats->crc) && (!pstats->icv));
+ ether_addr_equal(mac->bssid,
+ (cfc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
+ (cfc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
+ hdr->addr3) &&
+ (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
packet_toself = packet_matchbssid &&
- (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+ ether_addr_equal(praddr, rtlefuse->dev_addr);
if (ieee80211_is_beacon(fc))
packet_beacon = true;