]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
Merge tag 'ipvs2-for-v4.4' of https://git.kernel.org/pub/scm/linux/kernel/git/horms...
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 24 Sep 2015 23:37:21 +0000 (01:37 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 24 Sep 2015 23:38:58 +0000 (01:38 +0200)
Simon Horman says:

====================
Second Round of IPVS Updates for v4.4

please consider these bug fixes and extensive clean-ups of IPVS
from Eric Biederman for v4.4.

His excellent description of the changes, which is part of an even larger
set of clean-up work, is as follows:

  I am gradually working my way through the netfilter stack passing struct
  down into the netfilter hooks and from the netfilter hooks and from there
  down into the functions that actually care.  This removes the need for
  netfilter functions to guess how to figure out how to compute which
  network namespace they are in and instead provides a simple and reliable
  method to do so.

  The cleanups stand on their own but this is part of a larger effort to
  have routes with an output device that is not in the current network
  namespace.

  The IPVS code has been a bit more of a challenge than most.  Just passing
  struct net through to where it is needed did not feel clean to me.  The
  practical issue is that the ipvs code in most places actually wants
  struct netns_ipvs and not struct net.

  So as part of this process I have turned the relationship between struct
  net and the structs netns_ipvs, ip_vs_conn_param, ip_vs_conn, and
  ip_vs_service inside out.  I have modified the ipvs functions to take a
  struct netns_ipvs not a struct net.  The net is code with fewer
  conversions from one type of structure to another.  I did wind up adding
  a struct netns_ipvs parameter to quite a few functions that did not have
  it before so I could pass the structure down from the netfilter hooks to
  where it is actually needed to avoid guessing.

  I have broken up the work in a bunch of small patches so there is at
  least a chance and reviewing that each step I took is correct.  The
  series compiles at each step so bisecting it should not be a problem if
  something weird comes up.

  The first two changes in this series are actually bug fixes.  The first
  is a compile fix for a bug in sctp that came in, in the last round of
  ipvs changes merged into nf-next.  The second fixes an older bug where in
  pathological circumstances the wrong network namespace could be used when
  a proc file is written to.

  The rest of the patchset is a bunch of boring changes getting pushing
  struct netns_ipvs (and by extension ipvs->net) where it needs to be.
  Either by replacing struct net pointers or adding new struct netns_ipvs
  pointers.  With a handful of other minor cleanups (like removing
  skb_net).

I have decided include the bug fixes in this pull request. Patch one
relates to a bug that was added to nf-next recently and is thus not
applicable to nf . Patch two could arguably be promoted to a fix for v4.3
and stable though it does not appear to be severe enough to warrant that
course of action; let me know if you would like me to reconsider.
====================

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
68 files changed:
Documentation/networking/switchdev.txt
MAINTAINERS
drivers/net/arcnet/arc-rawmode.c
drivers/net/arcnet/arc-rimi.c
drivers/net/arcnet/arcdevice.h [new file with mode: 0644]
drivers/net/arcnet/arcnet.c
drivers/net/arcnet/capmode.c
drivers/net/arcnet/com20020-isa.c
drivers/net/arcnet/com20020-pci.c
drivers/net/arcnet/com20020.c
drivers/net/arcnet/com20020.h [new file with mode: 0644]
drivers/net/arcnet/com20020_cs.c
drivers/net/arcnet/com9026.h [new file with mode: 0644]
drivers/net/arcnet/com90io.c
drivers/net/arcnet/com90xx.c
drivers/net/arcnet/rfc1051.c
drivers/net/arcnet/rfc1201.c
drivers/net/ethernet/ethoc.c
drivers/net/ethernet/intel/e1000/e1000_hw.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/fm10k/fm10k.h
drivers/net/ethernet/intel/fm10k/fm10k_ethtool.c
drivers/net/ethernet/intel/fm10k/fm10k_iov.c
drivers/net/ethernet/intel/fm10k/fm10k_main.c
drivers/net/ethernet/intel/fm10k/fm10k_mbx.c
drivers/net/ethernet/intel/fm10k/fm10k_pci.c
drivers/net/ethernet/intel/fm10k/fm10k_type.h
drivers/net/ethernet/intel/igbvf/netdev.c
drivers/net/ethernet/intel/ixgbe/ixgbe.h
drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/rocker/rocker.c
drivers/net/ethernet/ti/davinci_emac.c
drivers/net/ethernet/xilinx/ll_temac_mdio.c
drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
drivers/net/usb/cdc_mbim.c
drivers/net/vmxnet3/vmxnet3_ethtool.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/wireless/mac80211_hwsim.c
include/linux/arcdevice.h [deleted file]
include/linux/com20020.h [deleted file]
include/linux/if_bridge.h
include/net/addrconf.h
include/net/ethoc.h
include/net/genetlink.h
include/net/ndisc.h
include/uapi/linux/if_arcnet.h
net/bridge/br_device.c
net/bridge/br_fdb.c
net/core/filter.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv6/addrconf.c
net/ipv6/ndisc.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/netlink/genetlink.c
net/openvswitch/datapath.c
net/sched/cls_bpf.c

index 476df0496686d50b16fa73126cc4fdf52ac004f7..67e43ee7840a1018fc9f9a5a78134dd043bde0ab 100644 (file)
@@ -239,20 +239,20 @@ The driver should initialize the attributes to the hardware defaults.
 FDB Ageing
 ^^^^^^^^^^
 
-There are two FDB ageing models supported: 1) ageing by the device, and 2)
-ageing by the kernel.  Ageing by the device is preferred if many FDB entries
-are supported.  The driver calls call_switchdev_notifiers(SWITCHDEV_FDB_DEL,
-...) to age out the FDB entry.  In this model, ageing by the kernel should be
-turned off.  XXX: how to turn off ageing in kernel on a per-port basis or
-otherwise prevent the kernel from ageing out the FDB entry?
-
-In the kernel ageing model, the standard bridge ageing mechanism is used to age
-out stale FDB entries.  To keep an FDB entry "alive", the driver should refresh
-the FDB entry by calling call_switchdev_notifiers(SWITCHDEV_FDB_ADD, ...).  The
+The bridge will skip ageing FDB entries marked with NTF_EXT_LEARNED and it is
+the responsibility of the port driver/device to age out these entries.  If the
+port device supports ageing, when the FDB entry expires, it will notify the
+driver which in turn will notify the bridge with SWITCHDEV_FDB_DEL.  If the
+device does not support ageing, the driver can simulate ageing using a
+garbage collection timer to monitor FBD entries.  Expired entries will be
+notified to the bridge using SWITCHDEV_FDB_DEL.  See rocker driver for
+example of driver running ageing timer.
+
+To keep an NTF_EXT_LEARNED entry "alive", the driver should refresh the FDB
+entry by calling call_switchdev_notifiers(SWITCHDEV_FDB_ADD, ...).  The
 notification will reset the FDB entry's last-used time to now.  The driver
 should rate limit refresh notifications, for example, no more than once a
-second.  If the FDB entry expires, fdb_delete is called to remove entry from
-the device.
+second.  (The last-used time is visible using the bridge -s fdb option).
 
 STP State Change on Port
 ^^^^^^^^^^^^^^^^^^^^^^^^
index 310da4295c7026e27698e9f8b980adcc1893b774..c978a257f4aac02b58b83823c0dcd10dfa4c3d89 100644 (file)
@@ -7292,7 +7292,6 @@ S:        Odd Fixes
 F:     drivers/net/
 F:     include/linux/if_*
 F:     include/linux/netdevice.h
-F:     include/linux/arcdevice.h
 F:     include/linux/etherdevice.h
 F:     include/linux/fcdevice.h
 F:     include/linux/fddidevice.h
index 705e6ce2eb90b9debb4e635af396ddfdbb53a594..d78f30186642e299d803fa98fa6fd8001b2d831b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - "raw mode" packet encapsulation (no soft headers)
- * 
+ *
  * Written 1994-1999 by Avery Pennarun.
  * Derived from skeleton.c by Donald Becker.
  *
@@ -24,6 +24,8 @@
  * **********************
  */
 
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/gfp.h>
 #include <linux/init.h>
 #include <net/arp.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/arcdevice.h>
-
-#define VERSION "arcnet: raw mode (`r') encapsulation support loaded.\n"
-
-
-static void rx(struct net_device *dev, int bufnum,
-              struct archdr *pkthdr, int length);
-static int build_header(struct sk_buff *skb, struct net_device *dev,
-                       unsigned short type, uint8_t daddr);
-static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
-                     int bufnum);
-
-static struct ArcProto rawmode_proto =
-{
-       .suffix         = 'r',
-       .mtu            = XMTU,
-       .rx             = rx,
-       .build_header   = build_header,
-       .prepare_tx     = prepare_tx,
-       .continue_tx    = NULL,
-       .ack_tx         = NULL
-};
-
-
-static int __init arcnet_raw_init(void)
-{
-       int count;
-
-       printk(VERSION);
-
-       for (count = 0; count < 256; count++)
-               if (arc_proto_map[count] == arc_proto_default)
-                       arc_proto_map[count] = &rawmode_proto;
-
-       /* for raw mode, we only set the bcast proto if there's no better one */
-       if (arc_bcast_proto == arc_proto_default)
-               arc_bcast_proto = &rawmode_proto;
-
-       arc_proto_default = &rawmode_proto;
-       return 0;
-}
-
-static void __exit arcnet_raw_exit(void)
-{
-       arcnet_unregister_proto(&rawmode_proto);
-}
-
-module_init(arcnet_raw_init);
-module_exit(arcnet_raw_exit);
-
-MODULE_LICENSE("GPL");
-
+#include "arcdevice.h"
 
 /* packet receiver */
 static void rx(struct net_device *dev, int bufnum,
@@ -93,7 +44,7 @@ static void rx(struct net_device *dev, int bufnum,
        struct archdr *pkt = pkthdr;
        int ofs;
 
-       BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);
+       arc_printk(D_DURING, dev, "it's a raw packet (length=%d)\n", length);
 
        if (length > MTU)
                ofs = 512 - length;
@@ -101,15 +52,14 @@ static void rx(struct net_device *dev, int bufnum,
                ofs = 256 - length;
 
        skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
-       if (skb == NULL) {
-               BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
+       if (!skb) {
                dev->stats.rx_dropped++;
                return;
        }
        skb_put(skb, length + ARC_HDR_SIZE);
        skb->dev = dev;
 
-       pkt = (struct archdr *) skb->data;
+       pkt = (struct archdr *)skb->data;
 
        skb_reset_mac_header(skb);
        skb_pull(skb, ARC_HDR_SIZE);
@@ -121,38 +71,35 @@ static void rx(struct net_device *dev, int bufnum,
                                      pkt->soft.raw + sizeof(pkt->soft),
                                      length - sizeof(pkt->soft));
 
-       BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
+       if (BUGLVL(D_SKB))
+               arcnet_dump_skb(dev, skb, "rx");
 
        skb->protocol = cpu_to_be16(ETH_P_ARCNET);
        netif_rx(skb);
 }
 
-
-/*
- * Create the ARCnet hard/soft headers for raw mode.
+/* Create the ARCnet hard/soft headers for raw mode.
  * There aren't any soft headers in raw mode - not even the protocol id.
  */
 static int build_header(struct sk_buff *skb, struct net_device *dev,
                        unsigned short type, uint8_t daddr)
 {
        int hdr_size = ARC_HDR_SIZE;
-       struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
+       struct archdr *pkt = (struct archdr *)skb_push(skb, hdr_size);
 
-       /*
-        * Set the source hardware address.
+       /* Set the source hardware address.
         *
         * This is pretty pointless for most purposes, but it can help in
-        * debugging.  ARCnet does not allow us to change the source address in
-        * the actual packet sent)
+        * debugging.  ARCnet does not allow us to change the source address
+        * in the actual packet sent.
         */
        pkt->hard.source = *dev->dev_addr;
 
        /* see linux/net/ethernet/eth.c to see where I got the following */
 
        if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
-               /* 
-                * FIXME: fill in the last byte of the dest ipaddr here to better
-                * comply with RFC1051 in "noarp" mode.
+               /* FIXME: fill in the last byte of the dest ipaddr here
+                * to better comply with RFC1051 in "noarp" mode.
                 */
                pkt->hard.dest = 0;
                return hdr_size;
@@ -163,7 +110,6 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
        return hdr_size;        /* success */
 }
 
-
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum)
 {
@@ -171,15 +117,16 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
        struct arc_hardware *hard = &pkt->hard;
        int ofs;
 
-       BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
-              lp->next_tx, lp->cur_tx, bufnum);
+       arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
+                  lp->next_tx, lp->cur_tx, bufnum);
 
-       length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
+       /* hard header is not included in packet length */
+       length -= ARC_HDR_SIZE;
 
        if (length > XMTU) {
                /* should never happen! other people already check for this. */
-               BUGMSG(D_NORMAL, "Bug!  prepare_tx with size %d (> %d)\n",
-                      length, XMTU);
+               arc_printk(D_NORMAL, dev, "Bug!  prepare_tx with size %d (> %d)\n",
+                          length, XMTU);
                length = XMTU;
        }
        if (length >= MinTU) {
@@ -188,11 +135,12 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
        } else if (length > MTU) {
                hard->offset[0] = 0;
                hard->offset[1] = ofs = 512 - length - 3;
-       } else
+       } else {
                hard->offset[0] = ofs = 256 - length;
+       }
 
-       BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n",
-              length,ofs);
+       arc_printk(D_DURING, dev, "prepare_tx: length=%d ofs=%d\n",
+                  length, ofs);
 
        lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
        lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
@@ -201,3 +149,41 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 
        return 1;               /* done */
 }
+
+static struct ArcProto rawmode_proto = {
+       .suffix         = 'r',
+       .mtu            = XMTU,
+       .rx             = rx,
+       .build_header   = build_header,
+       .prepare_tx     = prepare_tx,
+       .continue_tx    = NULL,
+       .ack_tx         = NULL
+};
+
+static int __init arcnet_raw_init(void)
+{
+       int count;
+
+       pr_info("raw mode (`r') encapsulation support loaded\n");
+
+       for (count = 0; count < 256; count++)
+               if (arc_proto_map[count] == arc_proto_default)
+                       arc_proto_map[count] = &rawmode_proto;
+
+       /* for raw mode, we only set the bcast proto if there's no better one */
+       if (arc_bcast_proto == arc_proto_default)
+               arc_bcast_proto = &rawmode_proto;
+
+       arc_proto_default = &rawmode_proto;
+       return 0;
+}
+
+static void __exit arcnet_raw_exit(void)
+{
+       arcnet_unregister_proto(&rawmode_proto);
+}
+
+module_init(arcnet_raw_init);
+module_exit(arcnet_raw_exit);
+
+MODULE_LICENSE("GPL");
index b8b4c7ba884f0c2ed9499e1ede4a20ad1df4f732..a07e24970be4216f16df473c80dab72b516ab11c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - "RIM I" (entirely mem-mapped) cards
- * 
+ *
  * Written 1994-1999 by Avery Pennarun.
  * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
  * Derived from skeleton.c by Donald Becker.
@@ -24,6 +24,9 @@
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/bootmem.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/io.h>
-#include <linux/arcdevice.h>
-
-
-#define VERSION "arcnet: RIM I (entirely mem-mapped) support\n"
+#include <linux/io.h>
 
+#include "arcdevice.h"
+#include "com9026.h"
 
 /* Internal function declarations */
 
@@ -50,66 +51,46 @@ static void arcrimi_setmask(struct net_device *dev, int mask);
 static int arcrimi_reset(struct net_device *dev, int really_reset);
 static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
                                 void *buf, int count);
-static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
-                                  void *buf, int count);
+static void arcrimi_copy_from_card(struct net_device *dev, int bufnum,
+                                  int offset, void *buf, int count);
 
 /* Handy defines for ARCnet specific stuff */
 
 /* Amount of I/O memory used by the card */
-#define BUFFER_SIZE (512)
-#define MIRROR_SIZE (BUFFER_SIZE*4)
+#define BUFFER_SIZE    (512)
+#define MIRROR_SIZE    (BUFFER_SIZE * 4)
 
-/* COM 9026 controller chip --> ARCnet register addresses */
-#define _INTMASK (ioaddr+0)    /* writable */
-#define _STATUS  (ioaddr+0)    /* readable */
-#define _COMMAND (ioaddr+1)    /* writable, returns random vals on read (?) */
-#define _RESET  (ioaddr+8)     /* software reset (on read) */
-#define _MEMDATA  (ioaddr+12)  /* Data port for IO-mapped memory */
-#define _ADDR_HI  (ioaddr+15)  /* Control registers for said */
-#define _ADDR_LO  (ioaddr+14)
-#define _CONFIG  (ioaddr+2)    /* Configuration register */
-
-#undef ASTATUS
-#undef ACOMMAND
-#undef AINTMASK
-
-#define ASTATUS()      readb(_STATUS)
-#define ACOMMAND(cmd)  writeb((cmd),_COMMAND)
-#define AINTMASK(msk)  writeb((msk),_INTMASK)
-#define SETCONF()      writeb(lp->config,_CONFIG)
-
-
-/*
- * We cannot probe for a RIM I card; one reason is I don't know how to reset
+/* We cannot probe for a RIM I card; one reason is I don't know how to reset
  * them.  In fact, we can't even get their node ID automatically.  So, we
  * need to be passed a specific shmem address, IRQ, and node ID.
  */
 static int __init arcrimi_probe(struct net_device *dev)
 {
-       BUGLVL(D_NORMAL) printk(VERSION);
-       BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n");
-
-       BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n",
-              dev->dev_addr[0], dev->mem_start, dev->irq);
+       if (BUGLVL(D_NORMAL)) {
+               pr_info("%s\n", "RIM I (entirely mem-mapped) support");
+               pr_info("E-mail me if you actually test the RIM I driver, please!\n");
+               pr_info("Given: node %02Xh, shmem %lXh, irq %d\n",
+                       dev->dev_addr[0], dev->mem_start, dev->irq);
+       }
 
        if (dev->mem_start <= 0 || dev->irq <= 0) {
-               BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you "
-                      "must specify the shmem and irq!\n");
+               if (BUGLVL(D_NORMAL))
+                       pr_err("No autoprobe for RIM I; you must specify the shmem and irq!\n");
                return -ENODEV;
        }
        if (dev->dev_addr[0] == 0) {
-               BUGLVL(D_NORMAL) printk("You need to specify your card's station "
-                      "ID!\n");
+               if (BUGLVL(D_NORMAL))
+                       pr_err("You need to specify your card's station ID!\n");
                return -ENODEV;
        }
-       /*
-        * Grab the memory region at mem_start for MIRROR_SIZE bytes.
+       /* Grab the memory region at mem_start for MIRROR_SIZE bytes.
         * Later in arcrimi_found() the real size will be determined
         * and this reserve will be released and the correct size
         * will be taken.
         */
        if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) {
-               BUGLVL(D_NORMAL) printk("Card memory already allocated\n");
+               if (BUGLVL(D_NORMAL))
+                       pr_notice("Card memory already allocated\n");
                return -ENODEV;
        }
        return arcrimi_found(dev);
@@ -125,7 +106,7 @@ static int check_mirror(unsigned long addr, size_t size)
 
        p = ioremap(addr, size);
        if (p) {
-               if (readb(p) == TESTvalue)
+               if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue)
                        res = 1;
                else
                        res = 0;
@@ -136,9 +117,8 @@ static int check_mirror(unsigned long addr, size_t size)
        return res;
 }
 
-/*
- * Set up the struct net_device associated with this card.  Called after
- * probing succeeds.
+/* Set up the struct net_device associated with this card.
+ * Called after probing succeeds.
  */
 static int __init arcrimi_found(struct net_device *dev)
 {
@@ -151,7 +131,7 @@ static int __init arcrimi_found(struct net_device *dev)
        p = ioremap(dev->mem_start, MIRROR_SIZE);
        if (!p) {
                release_mem_region(dev->mem_start, MIRROR_SIZE);
-               BUGMSG(D_NORMAL, "Can't ioremap\n");
+               arc_printk(D_NORMAL, dev, "Can't ioremap\n");
                return -ENODEV;
        }
 
@@ -159,13 +139,14 @@ static int __init arcrimi_found(struct net_device *dev)
        if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (RIM I)", dev)) {
                iounmap(p);
                release_mem_region(dev->mem_start, MIRROR_SIZE);
-               BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
+               arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", dev->irq);
                return -ENODEV;
        }
 
        shmem = dev->mem_start;
-       writeb(TESTvalue, p);
-       writeb(dev->dev_addr[0], p + 1);        /* actually the node ID */
+       arcnet_writeb(TESTvalue, p, COM9026_REG_W_INTMASK);
+       arcnet_writeb(TESTvalue, p, COM9026_REG_W_COMMAND);
+                                       /* actually the station/node ID */
 
        /* find the real shared memory start/end points, including mirrors */
 
@@ -174,7 +155,7 @@ static int __init arcrimi_found(struct net_device *dev)
         * 2k (or there are no mirrors at all) but on some, it's 4k.
         */
        mirror_size = MIRROR_SIZE;
-       if (readb(p) == TESTvalue &&
+       if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue &&
            check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 &&
            check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
                mirror_size = 2 * MIRROR_SIZE;
@@ -204,8 +185,7 @@ static int __init arcrimi_found(struct net_device *dev)
        lp->hw.copy_to_card = arcrimi_copy_to_card;
        lp->hw.copy_from_card = arcrimi_copy_from_card;
 
-       /*
-        * re-reserve the memory region - arcrimi_probe() alloced this reqion
+       /* re-reserve the memory region - arcrimi_probe() alloced this reqion
         * but didn't know the real size.  Free that region and then re-get
         * with the correct size.  There is a VERY slim chance this could
         * fail.
@@ -215,24 +195,25 @@ static int __init arcrimi_found(struct net_device *dev)
        if (!request_mem_region(dev->mem_start,
                                dev->mem_end - dev->mem_start + 1,
                                "arcnet (90xx)")) {
-               BUGMSG(D_NORMAL, "Card memory already allocated\n");
+               arc_printk(D_NORMAL, dev, "Card memory already allocated\n");
                goto err_free_irq;
        }
 
-       lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+       lp->mem_start = ioremap(dev->mem_start,
+                               dev->mem_end - dev->mem_start + 1);
        if (!lp->mem_start) {
-               BUGMSG(D_NORMAL, "Can't remap device memory!\n");
+               arc_printk(D_NORMAL, dev, "Can't remap device memory!\n");
                goto err_release_mem;
        }
 
        /* get and check the station ID from offset 1 in shmem */
-       dev->dev_addr[0] = readb(lp->mem_start + 1);
+       dev->dev_addr[0] = arcnet_readb(lp->mem_start, COM9026_REG_R_STATION);
 
-       BUGMSG(D_NORMAL, "ARCnet RIM I: station %02Xh found at IRQ %d, "
-              "ShMem %lXh (%ld*%d bytes).\n",
-              dev->dev_addr[0],
-              dev->irq, dev->mem_start,
-        (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
+       arc_printk(D_NORMAL, dev, "ARCnet RIM I: station %02Xh found at IRQ %d, ShMem %lXh (%ld*%d bytes)\n",
+                  dev->dev_addr[0],
+                  dev->irq, dev->mem_start,
+                  (dev->mem_end - dev->mem_start + 1) / mirror_size,
+                  mirror_size);
 
        err = register_netdev(dev);
        if (err)
@@ -249,9 +230,7 @@ err_free_irq:
        return -EIO;
 }
 
-
-/*
- * Do a hardware reset on the card, and set up necessary registers.
+/* Do a hardware reset on the card, and set up necessary registers.
  *
  * This should be called as little as possible, because it disrupts the
  * token on the network (causes a RECON) and requires a significant delay.
@@ -263,17 +242,19 @@ static int arcrimi_reset(struct net_device *dev, int really_reset)
        struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->mem_start + 0x800;
 
-       BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
+       arc_printk(D_INIT, dev, "Resetting %s (status=%02Xh)\n",
+                  dev->name, arcnet_readb(ioaddr, COM9026_REG_R_STATUS));
 
        if (really_reset) {
-               writeb(TESTvalue, ioaddr - 0x800);      /* fake reset */
+               arcnet_writeb(TESTvalue, ioaddr, -0x800);       /* fake reset */
                return 0;
        }
-       ACOMMAND(CFLAGScmd | RESETclear);       /* clear flags & end reset */
-       ACOMMAND(CFLAGScmd | CONFIGclear);
+       /* clear flags & end reset */
+       arcnet_writeb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND);
+       arcnet_writeb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND);
 
        /* enable extended (512-byte) packets */
-       ACOMMAND(CONFIGcmd | EXTconf);
+       arcnet_writeb(CONFIGcmd | EXTconf, ioaddr, COM9026_REG_W_COMMAND);
 
        /* done!  return success. */
        return 0;
@@ -284,7 +265,7 @@ static void arcrimi_setmask(struct net_device *dev, int mask)
        struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->mem_start + 0x800;
 
-       AINTMASK(mask);
+       arcnet_writeb(mask, ioaddr, COM9026_REG_W_INTMASK);
 }
 
 static int arcrimi_status(struct net_device *dev)
@@ -292,7 +273,7 @@ static int arcrimi_status(struct net_device *dev)
        struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->mem_start + 0x800;
 
-       return ASTATUS();
+       return arcnet_readb(ioaddr, COM9026_REG_R_STATUS);
 }
 
 static void arcrimi_command(struct net_device *dev, int cmd)
@@ -300,7 +281,7 @@ static void arcrimi_command(struct net_device *dev, int cmd)
        struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->mem_start + 0x800;
 
-       ACOMMAND(cmd);
+       arcnet_writeb(cmd, ioaddr, COM9026_REG_W_COMMAND);
 }
 
 static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
@@ -308,16 +289,17 @@ static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
 {
        struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
-       TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
-}
 
+       TIME(dev, "memcpy_toio", count, memcpy_toio(memaddr, buf, count));
+}
 
-static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
-                                  void *buf, int count)
+static void arcrimi_copy_from_card(struct net_device *dev, int bufnum,
+                                  int offset, void *buf, int count)
 {
        struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
-       TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
+
+       TIME(dev, "memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
 }
 
 static int node;
@@ -374,12 +356,13 @@ static void __exit arc_rimi_exit(void)
 static int __init arcrimi_setup(char *s)
 {
        int ints[8];
+
        s = get_options(s, 8, ints);
        if (!ints[0])
                return 1;
        switch (ints[0]) {
        default:                /* ERROR */
-               printk("arcrimi: Too many arguments.\n");
+               pr_err("Too many arguments\n");
        case 3:         /* Node ID */
                node = ints[3];
        case 2:         /* IRQ */
diff --git a/drivers/net/arcnet/arcdevice.h b/drivers/net/arcnet/arcdevice.h
new file mode 100644 (file)
index 0000000..d7fdea1
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ * INET         An implementation of the TCP/IP protocol suite for the LINUX
+ *              operating system.  NET  is implemented using the  BSD Socket
+ *              interface as the means of communication with the user level.
+ *
+ *              Definitions used by the ARCnet driver.
+ *
+ * Authors:     Avery Pennarun and David Woodhouse
+ *
+ *              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.
+ *
+ */
+#ifndef _LINUX_ARCDEVICE_H
+#define _LINUX_ARCDEVICE_H
+
+#include <asm/timex.h>
+#include <linux/if_arcnet.h>
+
+#ifdef __KERNEL__
+#include  <linux/irqreturn.h>
+
+/*
+ * RECON_THRESHOLD is the maximum number of RECON messages to receive
+ * within one minute before printing a "cabling problem" warning. The
+ * default value should be fine.
+ *
+ * After that, a "cabling restored" message will be printed on the next IRQ
+ * if no RECON messages have been received for 10 seconds.
+ *
+ * Do not define RECON_THRESHOLD at all if you want to disable this feature.
+ */
+#define RECON_THRESHOLD 30
+
+/*
+ * Define this to the minimum "timeout" value.  If a transmit takes longer
+ * than TX_TIMEOUT jiffies, Linux will abort the TX and retry.  On a large
+ * network, or one with heavy network traffic, this timeout may need to be
+ * increased.  The larger it is, though, the longer it will be between
+ * necessary transmits - don't set this too high.
+ */
+#define TX_TIMEOUT (HZ * 200 / 1000)
+
+/* Display warnings about the driver being an ALPHA version. */
+#undef ALPHA_WARNING
+
+/*
+ * Debugging bitflags: each option can be enabled individually.
+ *
+ * Note: only debug flags included in the ARCNET_DEBUG_MAX define will
+ *   actually be available.  GCC will (at least, GCC 2.7.0 will) notice
+ *   lines using a BUGLVL not in ARCNET_DEBUG_MAX and automatically optimize
+ *   them out.
+ */
+#define D_NORMAL       1       /* important operational info             */
+#define D_EXTRA                2       /* useful, but non-vital information      */
+#define        D_INIT          4       /* show init/probe messages               */
+#define D_INIT_REASONS 8       /* show reasons for discarding probes     */
+#define D_RECON                32      /* print a message whenever token is lost */
+#define D_PROTO                64      /* debug auto-protocol support            */
+/* debug levels below give LOTS of output during normal operation! */
+#define D_DURING       128     /* trace operations (including irq's)     */
+#define D_TX           256     /* show tx packets                        */
+#define D_RX           512     /* show rx packets                        */
+#define D_SKB          1024    /* show skb's                             */
+#define D_SKB_SIZE     2048    /* show skb sizes                         */
+#define D_TIMING       4096    /* show time needed to copy buffers to card */
+#define D_DEBUG         8192    /* Very detailed debug line for line */
+
+#ifndef ARCNET_DEBUG_MAX
+#define ARCNET_DEBUG_MAX (127) /* change to ~0 if you want detailed debugging */
+#endif
+
+#ifndef ARCNET_DEBUG
+#define ARCNET_DEBUG (D_NORMAL | D_EXTRA)
+#endif
+extern int arcnet_debug;
+
+#define BUGLVL(x)      ((x) & ARCNET_DEBUG_MAX & arcnet_debug)
+
+/* macros to simplify debug checking */
+#define arc_printk(x, dev, fmt, ...)                                   \
+do {                                                                   \
+       if (BUGLVL(x)) {                                                \
+               if ((x) == D_NORMAL)                                    \
+                       netdev_warn(dev, fmt, ##__VA_ARGS__);           \
+               else if ((x) < D_DURING)                                \
+                       netdev_info(dev, fmt, ##__VA_ARGS__);           \
+               else                                                    \
+                       netdev_dbg(dev, fmt, ##__VA_ARGS__);            \
+       }                                                               \
+} while (0)
+
+#define arc_cont(x, fmt, ...)                                          \
+do {                                                                   \
+       if (BUGLVL(x))                                                  \
+               pr_cont(fmt, ##__VA_ARGS__);                            \
+} while (0)
+
+/* see how long a function call takes to run, expressed in CPU cycles */
+#define TIME(dev, name, bytes, call)                                   \
+do {                                                                   \
+       if (BUGLVL(D_TIMING)) {                                         \
+               unsigned long _x, _y;                                   \
+               _x = get_cycles();                                      \
+               call;                                                   \
+               _y = get_cycles();                                      \
+               arc_printk(D_TIMING, dev,                               \
+                          "%s: %d bytes in %lu cycles == %lu Kbytes/100Mcycle\n", \
+                          name, bytes, _y - _x,                        \
+                          100000000 / 1024 * bytes / (_y - _x + 1));   \
+       } else {                                                        \
+               call;                                                   \
+       }                                                               \
+} while (0)
+
+/*
+ * Time needed to reset the card - in ms (milliseconds).  This works on my
+ * SMC PC100.  I can't find a reference that tells me just how long I
+ * should wait.
+ */
+#define RESETtime (300)
+
+/*
+ * These are the max/min lengths of packet payload, not including the
+ * arc_hardware header, but definitely including the soft header.
+ *
+ * Note: packet sizes 254, 255, 256 are impossible because of the way
+ * ARCnet registers work  That's why RFC1201 defines "exception" packets.
+ * In non-RFC1201 protocols, we have to just tack some extra bytes on the
+ * end.
+ */
+#define MTU    253             /* normal packet max size */
+#define MinTU  257             /* extended packet min size */
+#define XMTU   508             /* extended packet max size */
+
+/* status/interrupt mask bit fields */
+#define TXFREEflag     0x01    /* transmitter available */
+#define TXACKflag       0x02   /* transmitted msg. ackd */
+#define RECONflag       0x04   /* network reconfigured */
+#define TESTflag        0x08   /* test flag */
+#define EXCNAKflag      0x08    /* excesive nak flag */
+#define RESETflag       0x10   /* power-on-reset */
+#define RES1flag        0x20   /* reserved - usually set by jumper */
+#define RES2flag        0x40   /* reserved - usually set by jumper */
+#define NORXflag        0x80   /* receiver inhibited */
+
+/* Flags used for IO-mapped memory operations */
+#define AUTOINCflag     0x40   /* Increase location with each access */
+#define IOMAPflag       0x02   /* (for 90xx) Use IO mapped memory, not mmap */
+#define ENABLE16flag    0x80   /* (for 90xx) Enable 16-bit mode */
+
+/* in the command register, the following bits have these meanings:
+ *                0-2     command
+ *                3-4     page number (for enable rcv/xmt command)
+ *                 7      receive broadcasts
+ */
+#define NOTXcmd         0x01   /* disable transmitter */
+#define NORXcmd         0x02   /* disable receiver */
+#define TXcmd           0x03   /* enable transmitter */
+#define RXcmd           0x04   /* enable receiver */
+#define CONFIGcmd       0x05   /* define configuration */
+#define CFLAGScmd       0x06   /* clear flags */
+#define TESTcmd         0x07   /* load test flags */
+#define STARTIOcmd      0x18   /* start internal operation */
+
+/* flags for "clear flags" command */
+#define RESETclear      0x08   /* power-on-reset */
+#define CONFIGclear     0x10   /* system reconfigured */
+
+#define EXCNAKclear     0x0E    /* Clear and acknowledge the excive nak bit */
+
+/* flags for "load test flags" command */
+#define TESTload        0x08   /* test flag (diagnostic) */
+
+/* byte deposited into first address of buffers on reset */
+#define TESTvalue       0321   /* that's octal for 0xD1 :) */
+
+/* for "enable receiver" command */
+#define RXbcasts        0x80   /* receive broadcasts */
+
+/* flags for "define configuration" command */
+#define NORMALconf      0x00   /* 1-249 byte packets */
+#define EXTconf         0x08   /* 250-504 byte packets */
+
+/* card feature flags, set during auto-detection.
+ * (currently only used by com20020pci)
+ */
+#define ARC_IS_5MBIT    1   /* card default speed is 5MBit */
+#define ARC_CAN_10MBIT  2   /* card uses COM20022, supporting 10MBit,
+                                but default is 2.5MBit. */
+
+/* information needed to define an encapsulation driver */
+struct ArcProto {
+       char suffix;            /* a for RFC1201, e for ether-encap, etc. */
+       int mtu;                /* largest possible packet */
+       int is_ip;              /* This is a ip plugin - not a raw thing */
+
+       void (*rx)(struct net_device *dev, int bufnum,
+                  struct archdr *pkthdr, int length);
+       int (*build_header)(struct sk_buff *skb, struct net_device *dev,
+                           unsigned short ethproto, uint8_t daddr);
+
+       /* these functions return '1' if the skb can now be freed */
+       int (*prepare_tx)(struct net_device *dev, struct archdr *pkt,
+                         int length, int bufnum);
+       int (*continue_tx)(struct net_device *dev, int bufnum);
+       int (*ack_tx)(struct net_device *dev, int acked);
+};
+
+extern struct ArcProto *arc_proto_map[256], *arc_proto_default,
+       *arc_bcast_proto, *arc_raw_proto;
+
+/*
+ * "Incoming" is information needed for each address that could be sending
+ * to us.  Mostly for partially-received split packets.
+ */
+struct Incoming {
+       struct sk_buff *skb;    /* packet data buffer             */
+       __be16 sequence;        /* sequence number of assembly    */
+       uint8_t lastpacket,     /* number of last packet (from 1) */
+               numpackets;     /* number of packets in split     */
+};
+
+/* only needed for RFC1201 */
+struct Outgoing {
+       struct ArcProto *proto; /* protocol driver that owns this:
+                                *   if NULL, no packet is pending.
+                                */
+       struct sk_buff *skb;    /* buffer from upper levels */
+       struct archdr *pkt;     /* a pointer into the skb */
+       uint16_t length,        /* bytes total */
+               dataleft,       /* bytes left */
+               segnum,         /* segment being sent */
+               numsegs;        /* number of segments */
+};
+
+struct arcnet_local {
+       uint8_t config,         /* current value of CONFIG register */
+               timeout,        /* Extended timeout for COM20020 */
+               backplane,      /* Backplane flag for COM20020 */
+               clockp,         /* COM20020 clock divider */
+               clockm,         /* COM20020 clock multiplier flag */
+               setup,          /* Contents of setup1 register */
+               setup2,         /* Contents of setup2 register */
+               intmask;        /* current value of INTMASK register */
+       uint8_t default_proto[256];     /* default encap to use for each host */
+       int     cur_tx,         /* buffer used by current transmit, or -1 */
+               next_tx,        /* buffer where a packet is ready to send */
+               cur_rx;         /* current receive buffer */
+       int     lastload_dest,  /* can last loaded packet be acked? */
+               lasttrans_dest; /* can last TX'd packet be acked? */
+       int     timed_out;      /* need to process TX timeout and drop packet */
+       unsigned long last_timeout;     /* time of last reported timeout */
+       char *card_name;        /* card ident string */
+       int card_flags;         /* special card features */
+
+       /* On preemtive and SMB a lock is needed */
+       spinlock_t lock;
+
+       /*
+        * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of
+        * which can be used for either sending or receiving.  The new dynamic
+        * buffer management routines use a simple circular queue of available
+        * buffers, and take them as they're needed.  This way, we simplify
+        * situations in which we (for example) want to pre-load a transmit
+        * buffer, or start receiving while we copy a received packet to
+        * memory.
+        *
+        * The rules: only the interrupt handler is allowed to _add_ buffers to
+        * the queue; thus, this doesn't require a lock.  Both the interrupt
+        * handler and the transmit function will want to _remove_ buffers, so
+        * we need to handle the situation where they try to do it at the same
+        * time.
+        *
+        * If next_buf == first_free_buf, the queue is empty.  Since there are
+        * only four possible buffers, the queue should never be full.
+        */
+       atomic_t buf_lock;
+       int buf_queue[5];
+       int next_buf, first_free_buf;
+
+       /* network "reconfiguration" handling */
+       unsigned long first_recon; /* time of "first" RECON message to count */
+       unsigned long last_recon;  /* time of most recent RECON */
+       int num_recons;         /* number of RECONs between first and last. */
+       int network_down;       /* do we think the network is down? */
+
+       int excnak_pending;    /* We just got an excesive nak interrupt */
+
+       struct {
+               uint16_t sequence;      /* sequence number (incs with each packet) */
+               __be16 aborted_seq;
+
+               struct Incoming incoming[256];  /* one from each address */
+       } rfc1201;
+
+       /* really only used by rfc1201, but we'll pretend it's not */
+       struct Outgoing outgoing;       /* packet currently being sent */
+
+       /* hardware-specific functions */
+       struct {
+               struct module *owner;
+               void (*command)(struct net_device *dev, int cmd);
+               int (*status)(struct net_device *dev);
+               void (*intmask)(struct net_device *dev, int mask);
+               int (*reset)(struct net_device *dev, int really_reset);
+               void (*open)(struct net_device *dev);
+               void (*close)(struct net_device *dev);
+
+               void (*copy_to_card)(struct net_device *dev, int bufnum,
+                                    int offset, void *buf, int count);
+               void (*copy_from_card)(struct net_device *dev, int bufnum,
+                                      int offset, void *buf, int count);
+       } hw;
+
+       void __iomem *mem_start;        /* pointer to ioremap'ed MMIO */
+};
+
+#if ARCNET_DEBUG_MAX & D_SKB
+void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc);
+#else
+static inline
+void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc)
+{
+}
+#endif
+
+void arcnet_unregister_proto(struct ArcProto *proto);
+irqreturn_t arcnet_interrupt(int irq, void *dev_id);
+struct net_device *alloc_arcdev(const char *name);
+
+int arcnet_open(struct net_device *dev);
+int arcnet_close(struct net_device *dev);
+netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
+                              struct net_device *dev);
+void arcnet_timeout(struct net_device *dev);
+
+/* I/O equivalents */
+
+#ifdef CONFIG_SA1100_CT6001
+#define BUS_ALIGN  2  /* 8 bit device on a 16 bit bus - needs padding */
+#else
+#define BUS_ALIGN  1
+#endif
+
+/* addr and offset allow register like names to define the actual IO  address.
+ * A configuration option multiplies the offset for alignment.
+ */
+#define arcnet_inb(addr, offset)                                       \
+       inb((addr) + BUS_ALIGN * (offset))
+#define arcnet_outb(value, addr, offset)                               \
+       outb(value, (addr) + BUS_ALIGN * (offset))
+
+#define arcnet_insb(addr, offset, buffer, count)                       \
+       insb((addr) + BUS_ALIGN * (offset), buffer, count)
+#define arcnet_outsb(addr, offset, buffer, count)                      \
+       outsb((addr) + BUS_ALIGN * (offset), buffer, count)
+
+#define arcnet_readb(addr, offset)                                     \
+       readb((addr) + (offset))
+#define arcnet_writeb(value, addr, offset)                             \
+       writeb(value, (addr) + (offset))
+
+#endif                         /* __KERNEL__ */
+#endif                         /* _LINUX_ARCDEVICE_H */
index 10f71c732b5995c9121acf41724848f49994b49f..2158e985a0e7b8cb37e31e28c1cdb5009a23e1ab 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - device-independent routines
- * 
+ *
  * Written 1997 by David Woodhouse.
  * Written 1994-1999 by Avery Pennarun.
  * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
  * modified by SRC, incorporated herein by reference.
  *
  * **********************
- * 
+ *
  * The change log is now in a file called ChangeLog in this directory.
  *
  * Sources:
  *  - Crynwr arcnet.com/arcether.com packet drivers.
- *  - arcnet.c v0.00 dated 1/1/94 and apparently by 
+ *  - arcnet.c v0.00 dated 1/1/94 and apparently by
  *     Donald Becker - it didn't work :)
  *  - skeleton.c v0.05 dated 11/16/93 by Donald Becker
  *     (from Linux Kernel 1.1.45)
@@ -41,7 +41,7 @@
  *     <jojo@repas.de>
  */
 
-#define VERSION "arcnet: v3.94 BETA 2007/02/08 - by Avery Pennarun et al.\n"
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/if_arp.h>
 #include <net/arp.h>
 #include <linux/init.h>
-#include <linux/arcdevice.h>
 #include <linux/jiffies.h>
 
+#include "arcdevice.h"
+#include "com9026.h"
+
 /* "do nothing" functions for protocol drivers */
 static void null_rx(struct net_device *dev, int bufnum,
                    struct archdr *pkthdr, int length);
@@ -63,17 +65,24 @@ static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
 
 static void arcnet_rx(struct net_device *dev, int bufnum);
 
-/*
- * one ArcProto per possible proto ID.  None of the elements of
+/* one ArcProto per possible proto ID.  None of the elements of
  * arc_proto_map are allowed to be NULL; they will get set to
  * arc_proto_default instead.  It also must not be NULL; if you would like
  * to set it to NULL, set it to &arc_proto_null instead.
  */
- struct ArcProto *arc_proto_map[256], *arc_proto_default,
-   *arc_bcast_proto, *arc_raw_proto;
+struct ArcProto *arc_proto_map[256];
+EXPORT_SYMBOL(arc_proto_map);
 
-static struct ArcProto arc_proto_null =
-{
+struct ArcProto *arc_proto_default;
+EXPORT_SYMBOL(arc_proto_default);
+
+struct ArcProto *arc_bcast_proto;
+EXPORT_SYMBOL(arc_bcast_proto);
+
+struct ArcProto *arc_raw_proto;
+EXPORT_SYMBOL(arc_raw_proto);
+
+static struct ArcProto arc_proto_null = {
        .suffix         = '?',
        .mtu            = XMTU,
        .is_ip          = 0,
@@ -86,19 +95,7 @@ static struct ArcProto arc_proto_null =
 
 /* Exported function prototypes */
 int arcnet_debug = ARCNET_DEBUG;
-
-EXPORT_SYMBOL(arc_proto_map);
-EXPORT_SYMBOL(arc_proto_default);
-EXPORT_SYMBOL(arc_bcast_proto);
-EXPORT_SYMBOL(arc_raw_proto);
-EXPORT_SYMBOL(arcnet_unregister_proto);
 EXPORT_SYMBOL(arcnet_debug);
-EXPORT_SYMBOL(alloc_arcdev);
-EXPORT_SYMBOL(arcnet_interrupt);
-EXPORT_SYMBOL(arcnet_open);
-EXPORT_SYMBOL(arcnet_close);
-EXPORT_SYMBOL(arcnet_send_packet);
-EXPORT_SYMBOL(arcnet_timeout);
 
 /* Internal function prototypes */
 static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
@@ -116,29 +113,20 @@ static int __init arcnet_init(void)
 
        arcnet_debug = debug;
 
-       printk("arcnet loaded.\n");
-
-#ifdef ALPHA_WARNING
-       BUGLVL(D_EXTRA) {
-               printk("arcnet: ***\n"
-               "arcnet: * Read arcnet.txt for important release notes!\n"
-                      "arcnet: *\n"
-                      "arcnet: * This is an ALPHA version! (Last stable release: v3.02)  E-mail\n"
-                      "arcnet: * me if you have any questions, comments, or bug reports.\n"
-                      "arcnet: ***\n");
-       }
-#endif
+       pr_info("arcnet loaded\n");
 
        /* initialize the protocol map */
        arc_raw_proto = arc_proto_default = arc_bcast_proto = &arc_proto_null;
        for (count = 0; count < 256; count++)
                arc_proto_map[count] = arc_proto_default;
 
-       BUGLVL(D_DURING)
-           printk("arcnet: struct sizes: %Zd %Zd %Zd %Zd %Zd\n",
-                sizeof(struct arc_hardware), sizeof(struct arc_rfc1201),
-               sizeof(struct arc_rfc1051), sizeof(struct arc_eth_encap),
-                  sizeof(struct archdr));
+       if (BUGLVL(D_DURING))
+               pr_info("struct sizes: %Zd %Zd %Zd %Zd %Zd\n",
+                       sizeof(struct arc_hardware),
+                       sizeof(struct arc_rfc1201),
+                       sizeof(struct arc_rfc1051),
+                       sizeof(struct arc_eth_encap),
+                       sizeof(struct archdr));
 
        return 0;
 }
@@ -150,9 +138,7 @@ static void __exit arcnet_exit(void)
 module_init(arcnet_init);
 module_exit(arcnet_exit);
 
-/*
- * Dump the contents of an sk_buff
- */
+/* Dump the contents of an sk_buff */
 #if ARCNET_DEBUG_MAX & D_SKB
 void arcnet_dump_skb(struct net_device *dev,
                     struct sk_buff *skb, char *desc)
@@ -164,14 +150,10 @@ void arcnet_dump_skb(struct net_device *dev,
        print_hex_dump(KERN_DEBUG, hdr, DUMP_PREFIX_OFFSET,
                       16, 1, skb->data, skb->len, true);
 }
-
 EXPORT_SYMBOL(arcnet_dump_skb);
 #endif
 
-
-/*
- * Dump the contents of an ARCnet buffer
- */
+/* Dump the contents of an ARCnet buffer */
 #if (ARCNET_DEBUG_MAX & (D_RX | D_TX))
 static void arcnet_dump_packet(struct net_device *dev, int bufnum,
                               char *desc, int take_arcnet_lock)
@@ -183,12 +165,13 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum,
        char hdr[32];
 
        /* hw.copy_from_card expects IRQ context so take the IRQ lock
-          to keep it single threaded */
-       if(take_arcnet_lock)
+        * to keep it single threaded
+        */
+       if (take_arcnet_lock)
                spin_lock_irqsave(&lp->lock, flags);
 
        lp->hw.copy_from_card(dev, bufnum, 0, buf, 512);
-       if(take_arcnet_lock)
+       if (take_arcnet_lock)
                spin_unlock_irqrestore(&lp->lock, flags);
 
        /* if the offset[0] byte is nonzero, this is a 256-byte packet */
@@ -202,13 +185,11 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum,
 
 #else
 
-#define arcnet_dump_packet(dev, bufnum, desc,take_arcnet_lock) do { } while (0)
+#define arcnet_dump_packet(dev, bufnum, desc, take_arcnet_lock) do { } while (0)
 
 #endif
 
-
-/*
- * Unregister a protocol driver from the arc_proto_map.  Protocol drivers
+/* Unregister a protocol driver from the arc_proto_map.  Protocol drivers
  * are responsible for registering themselves, but the unregister routine
  * is pretty generic so we'll do it here.
  */
@@ -228,12 +209,11 @@ void arcnet_unregister_proto(struct ArcProto *proto)
                        arc_proto_map[count] = arc_proto_default;
        }
 }
+EXPORT_SYMBOL(arcnet_unregister_proto);
 
-
-/*
- * Add a buffer to the queue.  Only the interrupt handler is allowed to do
+/* Add a buffer to the queue.  Only the interrupt handler is allowed to do
  * this, unless interrupts are disabled.
- * 
+ *
  * Note: we don't check for a full queue, since there aren't enough buffers
  * to more than fill it.
  */
@@ -245,19 +225,17 @@ static void release_arcbuf(struct net_device *dev, int bufnum)
        lp->buf_queue[lp->first_free_buf++] = bufnum;
        lp->first_free_buf %= 5;
 
-       BUGLVL(D_DURING) {
-               BUGMSG(D_DURING, "release_arcbuf: freed #%d; buffer queue is now: ",
-                      bufnum);
-               for (i = lp->next_buf; i != lp->first_free_buf; i = (i+1) % 5)
-                       BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
-               BUGMSG2(D_DURING, "\n");
+       if (BUGLVL(D_DURING)) {
+               arc_printk(D_DURING, dev, "release_arcbuf: freed #%d; buffer queue is now: ",
+                          bufnum);
+               for (i = lp->next_buf; i != lp->first_free_buf; i = (i + 1) % 5)
+                       arc_cont(D_DURING, "#%d ", lp->buf_queue[i]);
+               arc_cont(D_DURING, "\n");
        }
 }
 
-
-/*
- * Get a buffer from the queue.  If this returns -1, there are no buffers
- * available.
+/* Get a buffer from the queue.
+ * If this returns -1, there are no buffers available.
  */
 static int get_arcbuf(struct net_device *dev)
 {
@@ -266,34 +244,32 @@ static int get_arcbuf(struct net_device *dev)
 
        if (!atomic_dec_and_test(&lp->buf_lock)) {
                /* already in this function */
-               BUGMSG(D_NORMAL, "get_arcbuf: overlap (%d)!\n",
-                      lp->buf_lock.counter);
-       }
-       else {                  /* we can continue */
+               arc_printk(D_NORMAL, dev, "get_arcbuf: overlap (%d)!\n",
+                          lp->buf_lock.counter);
+       } else {                        /* we can continue */
                if (lp->next_buf >= 5)
                        lp->next_buf -= 5;
 
-               if (lp->next_buf == lp->first_free_buf)
-                       BUGMSG(D_NORMAL, "get_arcbuf: BUG: no buffers are available??\n");
-               else {
+               if (lp->next_buf == lp->first_free_buf) {
+                       arc_printk(D_NORMAL, dev, "get_arcbuf: BUG: no buffers are available??\n");
+               else {
                        buf = lp->buf_queue[lp->next_buf++];
                        lp->next_buf %= 5;
                }
        }
 
-
-       BUGLVL(D_DURING) {
-               BUGMSG(D_DURING, "get_arcbuf: got #%d; buffer queue is now: ", buf);
-               for (i = lp->next_buf; i != lp->first_free_buf; i = (i+1) % 5)
-                       BUGMSG2(D_DURING, "#%d ", lp->buf_queue[i]);
-               BUGMSG2(D_DURING, "\n");
+       if (BUGLVL(D_DURING)) {
+               arc_printk(D_DURING, dev, "get_arcbuf: got #%d; buffer queue is now: ",
+                          buf);
+               for (i = lp->next_buf; i != lp->first_free_buf; i = (i + 1) % 5)
+                       arc_cont(D_DURING, "#%d ", lp->buf_queue[i]);
+               arc_cont(D_DURING, "\n");
        }
 
        atomic_inc(&lp->buf_lock);
        return buf;
 }
 
-
 static int choose_mtu(void)
 {
        int count, mtu = 65535;
@@ -336,7 +312,6 @@ static void arcdev_setup(struct net_device *dev)
 
        /* New-style flags. */
        dev->flags = IFF_BROADCAST;
-
 }
 
 struct net_device *alloc_arcdev(const char *name)
@@ -346,16 +321,17 @@ struct net_device *alloc_arcdev(const char *name)
        dev = alloc_netdev(sizeof(struct arcnet_local),
                           name && *name ? name : "arc%d", NET_NAME_UNKNOWN,
                           arcdev_setup);
-       if(dev) {
+       if (dev) {
                struct arcnet_local *lp = netdev_priv(dev);
+
                spin_lock_init(&lp->lock);
        }
 
        return dev;
 }
+EXPORT_SYMBOL(alloc_arcdev);
 
-/*
- * Open/initialize the board.  This is called sometime after booting when
+/* 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
@@ -367,34 +343,33 @@ int arcnet_open(struct net_device *dev)
        struct arcnet_local *lp = netdev_priv(dev);
        int count, newmtu, error;
 
-       BUGMSG(D_INIT,"opened.");
+       arc_printk(D_INIT, dev, "opened.");
 
        if (!try_module_get(lp->hw.owner))
                return -ENODEV;
 
-       BUGLVL(D_PROTO) {
-               BUGMSG(D_PROTO, "protocol map (default is '%c'): ",
-                      arc_proto_default->suffix);
+       if (BUGLVL(D_PROTO)) {
+               arc_printk(D_PROTO, dev, "protocol map (default is '%c'): ",
+                          arc_proto_default->suffix);
                for (count = 0; count < 256; count++)
-                       BUGMSG2(D_PROTO, "%c", arc_proto_map[count]->suffix);
-               BUGMSG2(D_PROTO, "\n");
+                       arc_cont(D_PROTO, "%c", arc_proto_map[count]->suffix);
+               arc_cont(D_PROTO, "\n");
        }
 
-
-       BUGMSG(D_INIT, "arcnet_open: resetting card.\n");
+       arc_printk(D_INIT, dev, "arcnet_open: resetting card.\n");
 
        /* try to put the card in a defined state - if it fails the first
         * time, actually reset it.
         */
        error = -ENODEV;
-       if (ARCRESET(0) && ARCRESET(1))
+       if (lp->hw.reset(dev, 0) && lp->hw.reset(dev, 1))
                goto out_module_put;
 
        newmtu = choose_mtu();
        if (newmtu < dev->mtu)
                dev->mtu = newmtu;
 
-       BUGMSG(D_INIT, "arcnet_open: mtu: %d.\n", dev->mtu);
+       arc_printk(D_INIT, dev, "arcnet_open: mtu: %d.\n", dev->mtu);
 
        /* autodetect the encapsulation for each host. */
        memset(lp->default_proto, 0, sizeof(lp->default_proto));
@@ -425,30 +400,28 @@ int arcnet_open(struct net_device *dev)
                lp->hw.open(dev);
 
        if (dev->dev_addr[0] == 0)
-               BUGMSG(D_NORMAL, "WARNING!  Station address 00 is reserved "
-                      "for broadcasts!\n");
+               arc_printk(D_NORMAL, dev, "WARNING!  Station address 00 is reserved for broadcasts!\n");
        else if (dev->dev_addr[0] == 255)
-               BUGMSG(D_NORMAL, "WARNING!  Station address FF may confuse "
-                      "DOS networking programs!\n");
+               arc_printk(D_NORMAL, dev, "WARNING!  Station address FF may confuse DOS networking programs!\n");
 
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
-       if (ASTATUS() & RESETflag) {
-               BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
-               ACOMMAND(CFLAGScmd | RESETclear);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
+       if (lp->hw.status(dev) & RESETflag) {
+               arc_printk(D_DEBUG, dev, "%s: %d: %s\n",
+                          __FILE__, __LINE__, __func__);
+               lp->hw.command(dev, CFLAGScmd | RESETclear);
        }
 
-
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
        /* make sure we're ready to receive IRQ's. */
-       AINTMASK(0);
+       lp->hw.intmask(dev, 0);
        udelay(1);              /* give it time to set the mask before
                                 * we reset it again. (may not even be
                                 * necessary)
                                 */
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
        lp->intmask = NORXflag | RECONflag;
-       AINTMASK(lp->intmask);
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
+       lp->hw.intmask(dev, lp->intmask);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
 
        netif_start_queue(dev);
 
@@ -458,7 +431,7 @@ int arcnet_open(struct net_device *dev)
        module_put(lp->hw.owner);
        return error;
 }
-
+EXPORT_SYMBOL(arcnet_open);
 
 /* The inverse routine to arcnet_open - shuts down the card. */
 int arcnet_close(struct net_device *dev)
@@ -468,9 +441,9 @@ int arcnet_close(struct net_device *dev)
        netif_stop_queue(dev);
 
        /* flush TX and disable RX */
-       AINTMASK(0);
-       ACOMMAND(NOTXcmd);      /* stop transmit */
-       ACOMMAND(NORXcmd);      /* disable receive */
+       lp->hw.intmask(dev, 0);
+       lp->hw.command(dev, NOTXcmd);   /* stop transmit */
+       lp->hw.command(dev, NORXcmd);   /* disable receive */
        mdelay(1);
 
        /* shut down the card */
@@ -478,7 +451,7 @@ int arcnet_close(struct net_device *dev)
        module_put(lp->hw.owner);
        return 0;
 }
-
+EXPORT_SYMBOL(arcnet_close);
 
 static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
                         unsigned short type, const void *daddr,
@@ -488,48 +461,44 @@ static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
        uint8_t _daddr, proto_num;
        struct ArcProto *proto;
 
-       BUGMSG(D_DURING,
-           "create header from %d to %d; protocol %d (%Xh); size %u.\n",
-              saddr ? *(uint8_t *) saddr : -1,
-              daddr ? *(uint8_t *) daddr : -1,
-              type, type, len);
-
-       if (skb->len!=0 && len != skb->len)
-               BUGMSG(D_NORMAL, "arcnet_header: Yikes!  skb->len(%d) != len(%d)!\n",
-                      skb->len, len);
-
-
-       /* Type is host order - ? */
-       if(type == ETH_P_ARCNET) {
-               proto = arc_raw_proto;
-               BUGMSG(D_DEBUG, "arc_raw_proto used. proto='%c'\n",proto->suffix);
-               _daddr = daddr ? *(uint8_t *) daddr : 0;
-       }
-       else if (!daddr) {
-               /*
-                * if the dest addr isn't provided, we can't choose an encapsulation!
-                * Store the packet type (eg. ETH_P_IP) for now, and we'll push on a
-                * real header when we do rebuild_header.
-                */
-               *(uint16_t *) skb_push(skb, 2) = type;
-               /*
-                * XXX: Why not use skb->mac_len?
+       arc_printk(D_DURING, dev,
+                  "create header from %d to %d; protocol %d (%Xh); size %u.\n",
+                  saddr ? *(uint8_t *)saddr : -1,
+                  daddr ? *(uint8_t *)daddr : -1,
+                  type, type, len);
+
+       if (skb->len != 0 && len != skb->len)
+               arc_printk(D_NORMAL, dev, "arcnet_header: Yikes!  skb->len(%d) != len(%d)!\n",
+                          skb->len, len);
+
+       /* Type is host order - ? */
+       if (type == ETH_P_ARCNET) {
+               proto = arc_raw_proto;
+               arc_printk(D_DEBUG, dev, "arc_raw_proto used. proto='%c'\n",
+                          proto->suffix);
+               _daddr = daddr ? *(uint8_t *)daddr : 0;
+       } else if (!daddr) {
+               /* if the dest addr isn't provided, we can't choose an
+                * encapsulation!  Store the packet type (eg. ETH_P_IP)
+                * for now, and we'll push on a real header when we do
+                * rebuild_header.
                 */
+               *(uint16_t *)skb_push(skb, 2) = type;
+               /* XXX: Why not use skb->mac_len? */
                if (skb->network_header - skb->mac_header != 2)
-                       BUGMSG(D_NORMAL, "arcnet_header: Yikes!  diff (%d) is not 2!\n",
-                              (int)(skb->network_header - skb->mac_header));
+                       arc_printk(D_NORMAL, dev, "arcnet_header: Yikes!  diff (%u) is not 2!\n",
+                                  skb->network_header - skb->mac_header);
                return -2;      /* return error -- can't transmit yet! */
-       }
-       else {
+       } else {
                /* otherwise, we can just add the header as usual. */
-               _daddr = *(uint8_t *) daddr;
+               _daddr = *(uint8_t *)daddr;
                proto_num = lp->default_proto[_daddr];
                proto = arc_proto_map[proto_num];
-               BUGMSG(D_DURING, "building header for %02Xh using protocol '%c'\n",
-                      proto_num, proto->suffix);
+               arc_printk(D_DURING, dev, "building header for %02Xh using protocol '%c'\n",
+                          proto_num, proto->suffix);
                if (proto == &arc_proto_null && arc_bcast_proto != proto) {
-                       BUGMSG(D_DURING, "actually, let's use '%c' instead.\n",
-                              arc_bcast_proto->suffix);
+                       arc_printk(D_DURING, dev, "actually, let's use '%c' instead.\n",
+                                  arc_bcast_proto->suffix);
                        proto = arc_bcast_proto;
                }
        }
@@ -538,7 +507,7 @@ static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
 
 /* Called by the kernel in order to transmit a packet. */
 netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
-                                    struct net_device *dev)
+                              struct net_device *dev)
 {
        struct arcnet_local *lp = netdev_priv(dev);
        struct archdr *pkt;
@@ -548,21 +517,22 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
        unsigned long flags;
        int freeskb, retval;
 
-       BUGMSG(D_DURING,
-              "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n",
-              ASTATUS(), lp->cur_tx, lp->next_tx, skb->len,skb->protocol);
+       arc_printk(D_DURING, dev,
+                  "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n",
+                  lp->hw.status(dev), lp->cur_tx, lp->next_tx, skb->len, skb->protocol);
 
-       pkt = (struct archdr *) skb->data;
+       pkt = (struct archdr *)skb->data;
        soft = &pkt->soft.rfc1201;
        proto = arc_proto_map[soft->proto];
 
-       BUGMSG(D_SKB_SIZE, "skb: transmitting %d bytes to %02X\n",
-               skb->len, pkt->hard.dest);
-       BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "tx");
+       arc_printk(D_SKB_SIZE, dev, "skb: transmitting %d bytes to %02X\n",
+                  skb->len, pkt->hard.dest);
+       if (BUGLVL(D_SKB))
+               arcnet_dump_skb(dev, skb, "tx");
 
        /* fits in one packet? */
        if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx) {
-               BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n");
+               arc_printk(D_NORMAL, dev, "fixme: packet too large: compensating badly!\n");
                dev_kfree_skb(skb);
                return NETDEV_TX_OK;    /* don't try again */
        }
@@ -571,17 +541,18 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
        netif_stop_queue(dev);
 
        spin_lock_irqsave(&lp->lock, flags);
-       AINTMASK(0);
-       if(lp->next_tx == -1)
+       lp->hw.intmask(dev, 0);
+       if (lp->next_tx == -1)
                txbuf = get_arcbuf(dev);
-       else {
+       else
                txbuf = -1;
-       }
+
        if (txbuf != -1) {
                if (proto->prepare_tx(dev, pkt, skb->len, txbuf) &&
                    !proto->ack_tx) {
                        /* done right away and we don't want to acknowledge
-                          the package later - forget about it now */
+                        *  the package later - forget about it now
+                        */
                        dev->stats.tx_bytes += skb->len;
                        freeskb = 1;
                } else {
@@ -594,9 +565,9 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
 
                        if (proto->continue_tx &&
                            proto->continue_tx(dev, txbuf)) {
-                         BUGMSG(D_NORMAL,
-                                "bug! continue_tx finished the first time! "
-                                "(proto='%c')\n", proto->suffix);
+                               arc_printk(D_NORMAL, dev,
+                                          "bug! continue_tx finished the first time! (proto='%c')\n",
+                                          proto->suffix);
                        }
                }
                retval = NETDEV_TX_OK;
@@ -606,61 +577,62 @@ netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
                freeskb = 0;
        }
 
-       BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
+       arc_printk(D_DEBUG, dev, "%s: %d: %s, status: %x\n",
+                  __FILE__, __LINE__, __func__, lp->hw.status(dev));
        /* make sure we didn't ignore a TX IRQ while we were in here */
-       AINTMASK(0);
+       lp->hw.intmask(dev, 0);
 
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
-       lp->intmask |= TXFREEflag|EXCNAKflag;
-       AINTMASK(lp->intmask);
-       BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
+       lp->intmask |= TXFREEflag | EXCNAKflag;
+       lp->hw.intmask(dev, lp->intmask);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s, status: %x\n",
+                  __FILE__, __LINE__, __func__, lp->hw.status(dev));
 
        spin_unlock_irqrestore(&lp->lock, flags);
-       if (freeskb) {
+       if (freeskb)
                dev_kfree_skb(skb);
-       }
+
        return retval;          /* no need to try again */
 }
+EXPORT_SYMBOL(arcnet_send_packet);
 
-
-/*
- * Actually start transmitting a packet that was loaded into a buffer
+/* Actually start transmitting a packet that was loaded into a buffer
  * by prepare_tx.  This should _only_ be called by the interrupt handler.
  */
 static int go_tx(struct net_device *dev)
 {
        struct arcnet_local *lp = netdev_priv(dev);
 
-       BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n",
-              ASTATUS(), lp->intmask, lp->next_tx, lp->cur_tx);
+       arc_printk(D_DURING, dev, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n",
+                  lp->hw.status(dev), lp->intmask, lp->next_tx, lp->cur_tx);
 
        if (lp->cur_tx != -1 || lp->next_tx == -1)
                return 0;
 
-       BUGLVL(D_TX) arcnet_dump_packet(dev, lp->next_tx, "go_tx", 0);
+       if (BUGLVL(D_TX))
+               arcnet_dump_packet(dev, lp->next_tx, "go_tx", 0);
 
        lp->cur_tx = lp->next_tx;
        lp->next_tx = -1;
 
        /* start sending */
-       ACOMMAND(TXcmd | (lp->cur_tx << 3));
+       lp->hw.command(dev, TXcmd | (lp->cur_tx << 3));
 
        dev->stats.tx_packets++;
        lp->lasttrans_dest = lp->lastload_dest;
        lp->lastload_dest = 0;
        lp->excnak_pending = 0;
-       lp->intmask |= TXFREEflag|EXCNAKflag;
+       lp->intmask |= TXFREEflag | EXCNAKflag;
 
        return 1;
 }
 
-
 /* Called by the kernel when transmit times out */
 void arcnet_timeout(struct net_device *dev)
 {
        unsigned long flags;
        struct arcnet_local *lp = netdev_priv(dev);
-       int status = ASTATUS();
+       int status = lp->hw.status(dev);
        char *msg;
 
        spin_lock_irqsave(&lp->lock, flags);
@@ -670,30 +642,29 @@ void arcnet_timeout(struct net_device *dev)
                msg = "";
                dev->stats.tx_aborted_errors++;
                lp->timed_out = 1;
-               ACOMMAND(NOTXcmd | (lp->cur_tx << 3));
+               lp->hw.command(dev, NOTXcmd | (lp->cur_tx << 3));
        }
        dev->stats.tx_errors++;
 
        /* make sure we didn't miss a TX or a EXC NAK IRQ */
-       AINTMASK(0);
-       lp->intmask |= TXFREEflag|EXCNAKflag;
-       AINTMASK(lp->intmask);
-       
+       lp->hw.intmask(dev, 0);
+       lp->intmask |= TXFREEflag | EXCNAKflag;
+       lp->hw.intmask(dev, lp->intmask);
+
        spin_unlock_irqrestore(&lp->lock, flags);
 
-       if (time_after(jiffies, lp->last_timeout + 10*HZ)) {
-               BUGMSG(D_EXTRA, "tx timed out%s (status=%Xh, intmask=%Xh, dest=%02Xh)\n",
-                      msg, status, lp->intmask, lp->lasttrans_dest);
+       if (time_after(jiffies, lp->last_timeout + 10 * HZ)) {
+               arc_printk(D_EXTRA, dev, "tx timed out%s (status=%Xh, intmask=%Xh, dest=%02Xh)\n",
+                          msg, status, lp->intmask, lp->lasttrans_dest);
                lp->last_timeout = jiffies;
        }
 
        if (lp->cur_tx == -1)
                netif_wake_queue(dev);
 }
+EXPORT_SYMBOL(arcnet_timeout);
 
-
-/*
- * The typical workload of the driver: Handle the network interface
+/* The typical workload of the driver: Handle the network interface
  * interrupts. Establish which device needs attention, and call the correct
  * chipset interrupt handler.
  */
@@ -704,125 +675,125 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
        int recbuf, status, diagstatus, didsomething, boguscount;
        int retval = IRQ_NONE;
 
-       BUGMSG(D_DURING, "\n");
+       arc_printk(D_DURING, dev, "\n");
 
-       BUGMSG(D_DURING, "in arcnet_interrupt\n");
+       arc_printk(D_DURING, dev, "in arcnet_interrupt\n");
 
        lp = netdev_priv(dev);
        BUG_ON(!lp);
-               
+
        spin_lock(&lp->lock);
 
-       /*
-        * RESET flag was enabled - if device is not running, we must clear it right
-        * away (but nothing else).
+       /* RESET flag was enabled - if device is not running, we must
+        * clear it right away (but nothing else).
         */
        if (!netif_running(dev)) {
-               if (ASTATUS() & RESETflag)
-                       ACOMMAND(CFLAGScmd | RESETclear);
-               AINTMASK(0);
+               if (lp->hw.status(dev) & RESETflag)
+                       lp->hw.command(dev, CFLAGScmd | RESETclear);
+               lp->hw.intmask(dev, 0);
                spin_unlock(&lp->lock);
                return retval;
        }
 
-       BUGMSG(D_DURING, "in arcnet_inthandler (status=%Xh, intmask=%Xh)\n",
-              ASTATUS(), lp->intmask);
+       arc_printk(D_DURING, dev, "in arcnet_inthandler (status=%Xh, intmask=%Xh)\n",
+                  lp->hw.status(dev), lp->intmask);
 
        boguscount = 5;
        do {
-               status = ASTATUS();
-                diagstatus = (status >> 8) & 0xFF;
+               status = lp->hw.status(dev);
+               diagstatus = (status >> 8) & 0xFF;
 
-               BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n",
-                       __FILE__,__LINE__,__func__,status);
+               arc_printk(D_DEBUG, dev, "%s: %d: %s: status=%x\n",
+                          __FILE__, __LINE__, __func__, status);
                didsomething = 0;
 
-               /*
-                * RESET flag was enabled - card is resetting and if RX is
+               /* RESET flag was enabled - card is resetting and if RX is
                 * disabled, it's NOT because we just got a packet.
-                * 
-                * The card is in an undefined state.  Clear it out and start over.
+                *
+                * The card is in an undefined state.
+                * Clear it out and start over.
                 */
                if (status & RESETflag) {
-                       BUGMSG(D_NORMAL, "spurious reset (status=%Xh)\n", status);
+                       arc_printk(D_NORMAL, dev, "spurious reset (status=%Xh)\n",
+                                  status);
                        arcnet_close(dev);
                        arcnet_open(dev);
 
                        /* get out of the interrupt handler! */
                        break;
                }
-               /* 
-                * RX is inhibited - we must have received something. Prepare to
-                * receive into the next buffer.
-                * 
-                * We don't actually copy the received packet from the card until
-                * after the transmit handler runs (and possibly launches the next
-                * tx); this should improve latency slightly if we get both types
-                * of interrupts at once. 
+               /* RX is inhibited - we must have received something.
+                * Prepare to receive into the next buffer.
+                *
+                * We don't actually copy the received packet from the card
+                * until after the transmit handler runs (and possibly
+                * launches the next tx); this should improve latency slightly
+                * if we get both types of interrupts at once.
                 */
                recbuf = -1;
                if (status & lp->intmask & NORXflag) {
                        recbuf = lp->cur_rx;
-                       BUGMSG(D_DURING, "Buffer #%d: receive irq (status=%Xh)\n",
-                              recbuf, status);
+                       arc_printk(D_DURING, dev, "Buffer #%d: receive irq (status=%Xh)\n",
+                                  recbuf, status);
 
                        lp->cur_rx = get_arcbuf(dev);
                        if (lp->cur_rx != -1) {
-                               BUGMSG(D_DURING, "enabling receive to buffer #%d\n",
-                                      lp->cur_rx);
-                               ACOMMAND(RXcmd | (lp->cur_rx << 3) | RXbcasts);
+                               arc_printk(D_DURING, dev, "enabling receive to buffer #%d\n",
+                                          lp->cur_rx);
+                               lp->hw.command(dev, RXcmd | (lp->cur_rx << 3) | RXbcasts);
                        }
                        didsomething++;
                }
 
-               if((diagstatus & EXCNAKflag)) {
-                       BUGMSG(D_DURING, "EXCNAK IRQ (diagstat=%Xh)\n",
-                              diagstatus);
+               if ((diagstatus & EXCNAKflag)) {
+                       arc_printk(D_DURING, dev, "EXCNAK IRQ (diagstat=%Xh)\n",
+                                  diagstatus);
 
-                        ACOMMAND(NOTXcmd);      /* disable transmit */
-                        lp->excnak_pending = 1;
+                       lp->hw.command(dev, NOTXcmd);      /* disable transmit */
+                       lp->excnak_pending = 1;
 
-                        ACOMMAND(EXCNAKclear);
+                       lp->hw.command(dev, EXCNAKclear);
                        lp->intmask &= ~(EXCNAKflag);
-                        didsomething++;
-                }
-
+                       didsomething++;
+               }
 
                /* a transmit finished, and we're interested in it. */
                if ((status & lp->intmask & TXFREEflag) || lp->timed_out) {
-                       lp->intmask &= ~(TXFREEflag|EXCNAKflag);
+                       lp->intmask &= ~(TXFREEflag | EXCNAKflag);
 
-                       BUGMSG(D_DURING, "TX IRQ (stat=%Xh)\n", status);
+                       arc_printk(D_DURING, dev, "TX IRQ (stat=%Xh)\n",
+                                  status);
 
                        if (lp->cur_tx != -1 && !lp->timed_out) {
-                               if(!(status & TXACKflag)) {
+                               if (!(status & TXACKflag)) {
                                        if (lp->lasttrans_dest != 0) {
-                                               BUGMSG(D_EXTRA,
-                                                      "transmit was not acknowledged! "
-                                                      "(status=%Xh, dest=%02Xh)\n",
-                                                      status, lp->lasttrans_dest);
+                                               arc_printk(D_EXTRA, dev,
+                                                          "transmit was not acknowledged! (status=%Xh, dest=%02Xh)\n",
+                                                          status,
+                                                          lp->lasttrans_dest);
                                                dev->stats.tx_errors++;
                                                dev->stats.tx_carrier_errors++;
                                        } else {
-                                               BUGMSG(D_DURING,
-                                                      "broadcast was not acknowledged; that's normal "
-                                                      "(status=%Xh, dest=%02Xh)\n",
-                                                      status, lp->lasttrans_dest);
+                                               arc_printk(D_DURING, dev,
+                                                          "broadcast was not acknowledged; that's normal (status=%Xh, dest=%02Xh)\n",
+                                                          status,
+                                                          lp->lasttrans_dest);
                                        }
                                }
 
                                if (lp->outgoing.proto &&
                                    lp->outgoing.proto->ack_tx) {
-                                 int ackstatus;
-                                 if(status & TXACKflag)
-                                    ackstatus=2;
-                                  else if(lp->excnak_pending)
-                                    ackstatus=1;
-                                  else
-                                    ackstatus=0;
-
-                                  lp->outgoing.proto
-                                    ->ack_tx(dev, ackstatus);
+                                       int ackstatus;
+
+                                       if (status & TXACKflag)
+                                               ackstatus = 2;
+                                       else if (lp->excnak_pending)
+                                               ackstatus = 1;
+                                       else
+                                               ackstatus = 0;
+
+                                       lp->outgoing.proto
+                                               ->ack_tx(dev, ackstatus);
                                }
                        }
                        if (lp->cur_tx != -1)
@@ -836,17 +807,18 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
                        go_tx(dev);
 
                        /* continue a split packet, if any */
-                       if (lp->outgoing.proto && lp->outgoing.proto->continue_tx) {
+                       if (lp->outgoing.proto &&
+                           lp->outgoing.proto->continue_tx) {
                                int txbuf = get_arcbuf(dev);
+
                                if (txbuf != -1) {
                                        if (lp->outgoing.proto->continue_tx(dev, txbuf)) {
                                                /* that was the last segment */
                                                dev->stats.tx_bytes += lp->outgoing.skb->len;
-                                               if(!lp->outgoing.proto->ack_tx)
-                                                 {
-                                                   dev_kfree_skb_irq(lp->outgoing.skb);
-                                                   lp->outgoing.proto = NULL;
-                                                 }
+                                               if (!lp->outgoing.proto->ack_tx) {
+                                                       dev_kfree_skb_irq(lp->outgoing.skb);
+                                                       lp->outgoing.proto = NULL;
+                                               }
                                        }
                                        lp->next_tx = txbuf;
                                }
@@ -857,7 +829,8 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
                }
                /* now process the received packet, if any */
                if (recbuf != -1) {
-                       BUGLVL(D_RX) arcnet_dump_packet(dev, recbuf, "rx irq", 0);
+                       if (BUGLVL(D_RX))
+                               arcnet_dump_packet(dev, recbuf, "rx irq", 0);
 
                        arcnet_rx(dev, recbuf);
                        release_arcbuf(dev, recbuf);
@@ -865,32 +838,32 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
                        didsomething++;
                }
                if (status & lp->intmask & RECONflag) {
-                       ACOMMAND(CFLAGScmd | CONFIGclear);
+                       lp->hw.command(dev, CFLAGScmd | CONFIGclear);
                        dev->stats.tx_carrier_errors++;
 
-                       BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
-                              status);
+                       arc_printk(D_RECON, dev, "Network reconfiguration detected (status=%Xh)\n",
+                                  status);
                        /* MYRECON bit is at bit 7 of diagstatus */
-                       if(diagstatus & 0x80)
-                               BUGMSG(D_RECON,"Put out that recon myself\n");
+                       if (diagstatus & 0x80)
+                               arc_printk(D_RECON, dev, "Put out that recon myself\n");
 
                        /* is the RECON info empty or old? */
                        if (!lp->first_recon || !lp->last_recon ||
                            time_after(jiffies, lp->last_recon + HZ * 10)) {
                                if (lp->network_down)
-                                       BUGMSG(D_NORMAL, "reconfiguration detected: cabling restored?\n");
+                                       arc_printk(D_NORMAL, dev, "reconfiguration detected: cabling restored?\n");
                                lp->first_recon = lp->last_recon = jiffies;
                                lp->num_recons = lp->network_down = 0;
 
-                               BUGMSG(D_DURING, "recon: clearing counters.\n");
+                               arc_printk(D_DURING, dev, "recon: clearing counters.\n");
                        } else {        /* add to current RECON counter */
                                lp->last_recon = jiffies;
                                lp->num_recons++;
 
-                               BUGMSG(D_DURING, "recon: counter=%d, time=%lds, net=%d\n",
-                                      lp->num_recons,
-                                (lp->last_recon - lp->first_recon) / HZ,
-                                      lp->network_down);
+                               arc_printk(D_DURING, dev, "recon: counter=%d, time=%lds, net=%d\n",
+                                          lp->num_recons,
+                                          (lp->last_recon - lp->first_recon) / HZ,
+                                          lp->network_down);
 
                                /* if network is marked up;
                                 * and first_recon and last_recon are 60+ apart;
@@ -902,46 +875,44 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
                                    (lp->last_recon - lp->first_recon) <= HZ * 60 &&
                                    lp->num_recons >= RECON_THRESHOLD) {
                                        lp->network_down = 1;
-                                       BUGMSG(D_NORMAL, "many reconfigurations detected: cabling problem?\n");
+                                       arc_printk(D_NORMAL, dev, "many reconfigurations detected: cabling problem?\n");
                                } else if (!lp->network_down &&
                                           lp->last_recon - lp->first_recon > HZ * 60) {
-                                       /* reset counters if we've gone for over a minute. */
+                                       /* reset counters if we've gone for
+                                        *  over a minute.
+                                        */
                                        lp->first_recon = lp->last_recon;
                                        lp->num_recons = 1;
                                }
                        }
                } else if (lp->network_down &&
-                               time_after(jiffies, lp->last_recon + HZ * 10)) {
+                          time_after(jiffies, lp->last_recon + HZ * 10)) {
                        if (lp->network_down)
-                               BUGMSG(D_NORMAL, "cabling restored?\n");
+                               arc_printk(D_NORMAL, dev, "cabling restored?\n");
                        lp->first_recon = lp->last_recon = 0;
                        lp->num_recons = lp->network_down = 0;
 
-                       BUGMSG(D_DURING, "not recon: clearing counters anyway.\n");
+                       arc_printk(D_DURING, dev, "not recon: clearing counters anyway.\n");
                }
 
-               if(didsomething) {
+               if (didsomething)
                        retval |= IRQ_HANDLED;
-               }
-       }
-       while (--boguscount && didsomething);
-
-       BUGMSG(D_DURING, "arcnet_interrupt complete (status=%Xh, count=%d)\n",
-              ASTATUS(), boguscount);
-       BUGMSG(D_DURING, "\n");
+       } while (--boguscount && didsomething);
 
+       arc_printk(D_DURING, dev, "arcnet_interrupt complete (status=%Xh, count=%d)\n",
+                  lp->hw.status(dev), boguscount);
+       arc_printk(D_DURING, dev, "\n");
 
-       AINTMASK(0);
+       lp->hw.intmask(dev, 0);
        udelay(1);
-       AINTMASK(lp->intmask);
-       
+       lp->hw.intmask(dev, lp->intmask);
+
        spin_unlock(&lp->lock);
        return retval;
 }
+EXPORT_SYMBOL(arcnet_interrupt);
 
-
-/*
- * This is a generic packet receiver that calls arcnet??_rx depending on the
+/* This is a generic packet receiver that calls arcnet??_rx depending on the
  * protocol ID found.
  */
 static void arcnet_rx(struct net_device *dev, int bufnum)
@@ -963,32 +934,31 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
        }
 
        /* get the full header, if possible */
-       if (sizeof(pkt.soft) <= length)
+       if (sizeof(pkt.soft) <= length) {
                lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(pkt.soft));
-       else {
+       else {
                memset(&pkt.soft, 0, sizeof(pkt.soft));
                lp->hw.copy_from_card(dev, bufnum, ofs, soft, length);
        }
 
-       BUGMSG(D_DURING, "Buffer #%d: received packet from %02Xh to %02Xh "
-              "(%d+4 bytes)\n",
-              bufnum, pkt.hard.source, pkt.hard.dest, length);
+       arc_printk(D_DURING, dev, "Buffer #%d: received packet from %02Xh to %02Xh (%d+4 bytes)\n",
+                  bufnum, pkt.hard.source, pkt.hard.dest, length);
 
        dev->stats.rx_packets++;
        dev->stats.rx_bytes += length + ARC_HDR_SIZE;
 
        /* call the right receiver for the protocol */
        if (arc_proto_map[soft->proto]->is_ip) {
-               BUGLVL(D_PROTO) {
+               if (BUGLVL(D_PROTO)) {
                        struct ArcProto
                        *oldp = arc_proto_map[lp->default_proto[pkt.hard.source]],
                        *newp = arc_proto_map[soft->proto];
 
                        if (oldp != newp) {
-                               BUGMSG(D_PROTO,
-                                      "got protocol %02Xh; encap for host %02Xh is now '%c'"
-                                      " (was '%c')\n", soft->proto, pkt.hard.source,
-                                      newp->suffix, oldp->suffix);
+                               arc_printk(D_PROTO, dev,
+                                          "got protocol %02Xh; encap for host %02Xh is now '%c' (was '%c')\n",
+                                          soft->proto, pkt.hard.source,
+                                          newp->suffix, oldp->suffix);
                        }
                }
 
@@ -1002,30 +972,27 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
        arc_proto_map[soft->proto]->rx(dev, bufnum, &pkt, length);
 }
 
-
 static void null_rx(struct net_device *dev, int bufnum,
                    struct archdr *pkthdr, int length)
 {
-       BUGMSG(D_PROTO,
-       "rx: don't know how to deal with proto %02Xh from host %02Xh.\n",
-              pkthdr->soft.rfc1201.proto, pkthdr->hard.source);
+       arc_printk(D_PROTO, dev,
+                  "rx: don't know how to deal with proto %02Xh from host %02Xh.\n",
+                  pkthdr->soft.rfc1201.proto, pkthdr->hard.source);
 }
 
-
 static int null_build_header(struct sk_buff *skb, struct net_device *dev,
                             unsigned short type, uint8_t daddr)
 {
        struct arcnet_local *lp = netdev_priv(dev);
 
-       BUGMSG(D_PROTO,
-              "tx: can't build header for encap %02Xh; load a protocol driver.\n",
-              lp->default_proto[daddr]);
+       arc_printk(D_PROTO, dev,
+                  "tx: can't build header for encap %02Xh; load a protocol driver.\n",
+                  lp->default_proto[daddr]);
 
        /* always fails */
        return 0;
 }
 
-
 /* the "do nothing" prepare_tx function warns that there's nothing to do. */
 static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
                           int length, int bufnum)
@@ -1033,7 +1000,7 @@ static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
        struct arcnet_local *lp = netdev_priv(dev);
        struct arc_hardware newpkt;
 
-       BUGMSG(D_PROTO, "tx: no encap for this host; load a protocol driver.\n");
+       arc_printk(D_PROTO, dev, "tx: no encap for this host; load a protocol driver.\n");
 
        /* send a packet to myself -- will never get received, of course */
        newpkt.source = newpkt.dest = dev->dev_addr[0];
index 42fce91b71fc9c613fa894e910ceecd4fd9eb037..2056878fb087d6d3bc3bf6564220065f30322283 100644 (file)
@@ -26,6 +26,8 @@
  * **********************
  */
 
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/gfp.h>
 #include <linux/init.h>
@@ -33,9 +35,8 @@
 #include <net/arp.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/arcdevice.h>
 
-#define VERSION "arcnet: cap mode (`c') encapsulation support loaded.\n"
+#include "arcdevice.h"
 
 /* packet receiver */
 static void rx(struct net_device *dev, int bufnum,
@@ -47,7 +48,8 @@ static void rx(struct net_device *dev, int bufnum,
        char *pktbuf, *pkthdrbuf;
        int ofs;
 
-       BUGMSG(D_DURING, "it's a raw(cap) packet (length=%d)\n", length);
+       arc_printk(D_DURING, dev, "it's a raw(cap) packet (length=%d)\n",
+                  length);
 
        if (length >= MinTU)
                ofs = 512 - length;
@@ -55,8 +57,7 @@ static void rx(struct net_device *dev, int bufnum,
                ofs = 256 - length;
 
        skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
-       if (skb == NULL) {
-               BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
+       if (!skb) {
                dev->stats.rx_dropped++;
                return;
        }
@@ -66,17 +67,17 @@ static void rx(struct net_device *dev, int bufnum,
        pkt = (struct archdr *)skb_mac_header(skb);
        skb_pull(skb, ARC_HDR_SIZE);
 
-       /* up to sizeof(pkt->soft) has already been copied from the card */
-       /* squeeze in an int for the cap encapsulation */
-
-       /* use these variables to be sure we count in bytes, not in
-          sizeof(struct archdr) */
-       pktbuf=(char*)pkt;
-       pkthdrbuf=(char*)pkthdr;
-       memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto));
-       memcpy(pktbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto)+sizeof(int),
-              pkthdrbuf+ARC_HDR_SIZE+sizeof(pkt->soft.cap.proto),
-              sizeof(struct archdr)-ARC_HDR_SIZE-sizeof(pkt->soft.cap.proto));
+       /* up to sizeof(pkt->soft) has already been copied from the card
+        * squeeze in an int for the cap encapsulation
+        * use these variables to be sure we count in bytes, not in
+        * sizeof(struct archdr)
+        */
+       pktbuf = (char *)pkt;
+       pkthdrbuf = (char *)pkthdr;
+       memcpy(pktbuf, pkthdrbuf, ARC_HDR_SIZE + sizeof(pkt->soft.cap.proto));
+       memcpy(pktbuf + ARC_HDR_SIZE + sizeof(pkt->soft.cap.proto) + sizeof(int),
+              pkthdrbuf + ARC_HDR_SIZE + sizeof(pkt->soft.cap.proto),
+              sizeof(struct archdr) - ARC_HDR_SIZE - sizeof(pkt->soft.cap.proto));
 
        if (length > sizeof(pkt->soft))
                lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
@@ -84,15 +85,14 @@ static void rx(struct net_device *dev, int bufnum,
                                      + sizeof(int),
                                      length - sizeof(pkt->soft));
 
-       BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
+       if (BUGLVL(D_SKB))
+               arcnet_dump_skb(dev, skb, "rx");
 
        skb->protocol = cpu_to_be16(ETH_P_ARCNET);
        netif_rx(skb);
 }
 
-
-/*
- * Create the ARCnet hard/soft headers for cap mode.
+/* Create the ARCnet hard/soft headers for cap mode.
  * There aren't any soft headers in cap mode - not even the protocol id.
  */
 static int build_header(struct sk_buff *skb,
@@ -101,12 +101,12 @@ static int build_header(struct sk_buff *skb,
                        uint8_t daddr)
 {
        int hdr_size = ARC_HDR_SIZE;
-       struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
+       struct archdr *pkt = (struct archdr *)skb_push(skb, hdr_size);
 
-       BUGMSG(D_PROTO, "Preparing header for cap packet %x.\n",
-              *((int*)&pkt->soft.cap.cookie[0]));
-       /*
-        * Set the source hardware address.
+       arc_printk(D_PROTO, dev, "Preparing header for cap packet %x.\n",
+                  *((int *)&pkt->soft.cap.cookie[0]));
+
+       /* Set the source hardware address.
         *
         * This is pretty pointless for most purposes, but it can help in
         * debugging.  ARCnet does not allow us to change the source address in
@@ -117,9 +117,8 @@ static int build_header(struct sk_buff *skb,
        /* see linux/net/ethernet/eth.c to see where I got the following */
 
        if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
-               /*
-                * FIXME: fill in the last byte of the dest ipaddr here to better
-                * comply with RFC1051 in "noarp" mode.
+               /* FIXME: fill in the last byte of the dest ipaddr here to
+                * better comply with RFC1051 in "noarp" mode.
                 */
                pkt->hard.dest = 0;
                return hdr_size;
@@ -130,7 +129,6 @@ static int build_header(struct sk_buff *skb,
        return hdr_size;        /* success */
 }
 
-
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum)
 {
@@ -138,22 +136,21 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
        struct arc_hardware *hard = &pkt->hard;
        int ofs;
 
-
        /* hard header is not included in packet length */
        length -= ARC_HDR_SIZE;
        /* And neither is the cookie field */
        length -= sizeof(int);
 
-       BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
-              lp->next_tx, lp->cur_tx, bufnum);
+       arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
+                  lp->next_tx, lp->cur_tx, bufnum);
 
-       BUGMSG(D_PROTO, "Sending for cap packet %x.\n",
-              *((int*)&pkt->soft.cap.cookie[0]));
+       arc_printk(D_PROTO, dev, "Sending for cap packet %x.\n",
+                  *((int *)&pkt->soft.cap.cookie[0]));
 
        if (length > XMTU) {
                /* should never happen! other people already check for this. */
-               BUGMSG(D_NORMAL, "Bug!  prepare_tx with size %d (> %d)\n",
-                      length, XMTU);
+               arc_printk(D_NORMAL, dev, "Bug!  prepare_tx with size %d (> %d)\n",
+                          length, XMTU);
                length = XMTU;
        }
        if (length > MinTU) {
@@ -162,11 +159,12 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
        } else if (length > MTU) {
                hard->offset[0] = 0;
                hard->offset[1] = ofs = 512 - length - 3;
-       } else
+       } else {
                hard->offset[0] = ofs = 256 - length;
+       }
 
-       BUGMSG(D_DURING, "prepare_tx: length=%d ofs=%d\n",
-              length,ofs);
+       arc_printk(D_DURING, dev, "prepare_tx: length=%d ofs=%d\n",
+                  length, ofs);
 
        /* Copy the arcnet-header + the protocol byte down: */
        lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
@@ -174,9 +172,10 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                            sizeof(pkt->soft.cap.proto));
 
        /* Skip the extra integer we have written into it as a cookie
-          but write the rest of the message: */
-       lp->hw.copy_to_card(dev, bufnum, ofs+1,
-                           ((unsigned char*)&pkt->soft.cap.mes),length-1);
+        * but write the rest of the message:
+        */
+       lp->hw.copy_to_card(dev, bufnum, ofs + 1,
+                           ((unsigned char *)&pkt->soft.cap.mes), length - 1);
 
        lp->lastload_dest = hard->dest;
 
@@ -188,21 +187,20 @@ static int ack_tx(struct net_device *dev, int acked)
        struct arcnet_local *lp = netdev_priv(dev);
        struct sk_buff *ackskb;
        struct archdr *ackpkt;
-       int length=sizeof(struct arc_cap);
+       int length = sizeof(struct arc_cap);
 
-       BUGMSG(D_DURING, "capmode: ack_tx: protocol: %x: result: %d\n",
-               lp->outgoing.skb->protocol, acked);
+       arc_printk(D_DURING, dev, "capmode: ack_tx: protocol: %x: result: %d\n",
+                  lp->outgoing.skb->protocol, acked);
 
-       BUGLVL(D_SKB) arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx");
+       if (BUGLVL(D_SKB))
+               arcnet_dump_skb(dev, lp->outgoing.skb, "ack_tx");
 
        /* Now alloc a skb to send back up through the layers: */
-       ackskb = alloc_skb(length + ARC_HDR_SIZE , GFP_ATOMIC);
-       if (ackskb == NULL) {
-               BUGMSG(D_NORMAL, "Memory squeeze, can't acknowledge.\n");
+       ackskb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
+       if (!ackskb)
                goto free_outskb;
-       }
 
-       skb_put(ackskb, length + ARC_HDR_SIZE );
+       skb_put(ackskb, length + ARC_HDR_SIZE);
        ackskb->dev = dev;
 
        skb_reset_mac_header(ackskb);
@@ -212,39 +210,40 @@ static int ack_tx(struct net_device *dev, int acked)
        skb_copy_from_linear_data(lp->outgoing.skb, ackpkt,
                                  ARC_HDR_SIZE + sizeof(struct arc_cap));
        ackpkt->soft.cap.proto = 0; /* using protocol 0 for acknowledge */
-       ackpkt->soft.cap.mes.ack=acked;
+       ackpkt->soft.cap.mes.ack = acked;
 
-       BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n",
-                       *((int*)&ackpkt->soft.cap.cookie[0]));
+       arc_printk(D_PROTO, dev, "Ackknowledge for cap packet %x.\n",
+                  *((int *)&ackpkt->soft.cap.cookie[0]));
 
        ackskb->protocol = cpu_to_be16(ETH_P_ARCNET);
 
-       BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
+       if (BUGLVL(D_SKB))
+               arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
        netif_rx(ackskb);
 
 free_outskb:
        dev_kfree_skb_irq(lp->outgoing.skb);
-       lp->outgoing.proto = NULL; /* We are always finished when in this protocol */
+       lp->outgoing.proto = NULL;
+                       /* We are always finished when in this protocol */
 
        return 0;
 }
 
-static struct ArcProto capmode_proto =
-{
-       'r',
-       XMTU,
-       0,
-       rx,
-       build_header,
-       prepare_tx,
-       NULL,
-       ack_tx
+static struct ArcProto capmode_proto = {
+       .suffix         = 'r',
+       .mtu            = XMTU,
+       .rx             = rx,
+       .build_header   = build_header,
+       .prepare_tx     = prepare_tx,
+       .ack_tx         = ack_tx
 };
 
-static void arcnet_cap_init(void)
+static int __init capmode_module_init(void)
 {
        int count;
 
+       pr_info("cap mode (`c') encapsulation support loaded\n");
+
        for (count = 1; count <= 8; count++)
                if (arc_proto_map[count] == arc_proto_default)
                        arc_proto_map[count] = &capmode_proto;
@@ -255,12 +254,7 @@ static void arcnet_cap_init(void)
 
        arc_proto_default = &capmode_proto;
        arc_raw_proto = &capmode_proto;
-}
 
-static int __init capmode_module_init(void)
-{
-       printk(VERSION);
-       arcnet_cap_init();
        return 0;
 }
 
index 45c61a2c5fbd8345ee592768b9693b2360048e7e..b9e9931353b22a727066eaef790dec1f63d3fd5f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - COM20020 chipset support
- * 
+ *
  * Written 1997 by David Woodhouse.
  * Written 1994-1999 by Avery Pennarun.
  * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
@@ -25,6 +25,9 @@
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/bootmem.h>
-#include <linux/arcdevice.h>
-#include <linux/com20020.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
-#define VERSION "arcnet: COM20020 ISA support (by David Woodhouse et al.)\n"
+#include "arcdevice.h"
+#include "com20020.h"
 
-
-/*
- * We cannot (yet) probe for an IO mapped card, although we can check that
+/* We cannot (yet) probe for an IO mapped card, although we can check that
  * it's where we were told it was, and even do autoirq.
  */
 static int __init com20020isa_probe(struct net_device *dev)
@@ -55,21 +54,21 @@ static int __init com20020isa_probe(struct net_device *dev)
        struct arcnet_local *lp = netdev_priv(dev);
        int err;
 
-       BUGLVL(D_NORMAL) printk(VERSION);
+       if (BUGLVL(D_NORMAL))
+               pr_info("%s\n", "COM20020 ISA support (by David Woodhouse et al.)");
 
        ioaddr = dev->base_addr;
        if (!ioaddr) {
-               BUGMSG(D_NORMAL, "No autoprobe (yet) for IO mapped cards; you "
-                      "must specify the base address!\n");
+               arc_printk(D_NORMAL, dev, "No autoprobe (yet) for IO mapped cards; you must specify the base address!\n");
                return -ENODEV;
        }
        if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) {
-               BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n",
-                      ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
+               arc_printk(D_NORMAL, dev, "IO region %xh-%xh already allocated.\n",
+                          ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
                return -ENXIO;
        }
-       if (ASTATUS() == 0xFF) {
-               BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr);
+       if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
+               arc_printk(D_NORMAL, dev, "IO address %x empty\n", ioaddr);
                err = -ENODEV;
                goto out;
        }
@@ -83,23 +82,24 @@ static int __init com20020isa_probe(struct net_device *dev)
                 * card has just reset and the NORXflag is on until
                 * we tell it to start receiving.
                 */
-               BUGMSG(D_INIT_REASONS, "intmask was %02Xh\n", inb(_INTMASK));
-               outb(0, _INTMASK);
+               arc_printk(D_INIT_REASONS, dev, "intmask was %02Xh\n",
+                          arcnet_inb(ioaddr, COM20020_REG_R_STATUS));
+               arcnet_outb(0, ioaddr, COM20020_REG_W_INTMASK);
                airqmask = probe_irq_on();
-               outb(NORXflag, _INTMASK);
+               arcnet_outb(NORXflag, ioaddr, COM20020_REG_W_INTMASK);
                udelay(1);
-               outb(0, _INTMASK);
+               arcnet_outb(0, ioaddr, COM20020_REG_W_INTMASK);
                dev->irq = probe_irq_off(airqmask);
 
                if ((int)dev->irq <= 0) {
-                       BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed first time\n");
+                       arc_printk(D_INIT_REASONS, dev, "Autoprobe IRQ failed first time\n");
                        airqmask = probe_irq_on();
-                       outb(NORXflag, _INTMASK);
+                       arcnet_outb(NORXflag, ioaddr, COM20020_REG_W_INTMASK);
                        udelay(5);
-                       outb(0, _INTMASK);
+                       arcnet_outb(0, ioaddr, COM20020_REG_W_INTMASK);
                        dev->irq = probe_irq_off(airqmask);
                        if ((int)dev->irq <= 0) {
-                               BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n");
+                               arc_printk(D_NORMAL, dev, "Autoprobe IRQ failed.\n");
                                err = -ENODEV;
                                goto out;
                        }
@@ -107,7 +107,9 @@ static int __init com20020isa_probe(struct net_device *dev)
        }
 
        lp->card_name = "ISA COM20020";
-       if ((err = com20020_found(dev, 0)) != 0)
+
+       err = com20020_found(dev, 0);
+       if (err != 0)
                goto out;
 
        return 0;
@@ -194,7 +196,7 @@ static int __init com20020isa_setup(char *s)
 
        switch (ints[0]) {
        default:                /* ERROR */
-               printk("com90xx: Too many arguments.\n");
+               pr_info("Too many arguments\n");
        case 6:         /* Timeout */
                timeout = ints[6];
        case 5:         /* CKP value */
index 96edc1346124eb95b29c863f53359ae327348e2d..a12bf83be7502dd6e4262907a45dc05efb090b80 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Linux ARCnet driver - COM20020 PCI support
  * Contemporary Controls PCI20 and SOHARD SH-ARC PCI
- * 
+ *
  * Written 1994-1999 by Avery Pennarun,
  *    based on an ISA version by David Woodhouse.
  * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
@@ -26,6 +26,9 @@
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
-#include <linux/arcdevice.h>
-#include <linux/com20020.h>
 #include <linux/list.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
-
-
-#define VERSION "arcnet: COM20020 PCI support\n"
+#include "arcdevice.h"
+#include "com20020.h"
 
 /* Module parameters */
 
@@ -64,7 +64,8 @@ MODULE_LICENSE("GPL");
 
 static void com20020pci_remove(struct pci_dev *pdev);
 
-static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int com20020pci_probe(struct pci_dev *pdev,
+                            const struct pci_device_id *id)
 {
        struct com20020_pci_card_info *ci;
        struct net_device *dev;
@@ -86,7 +87,6 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 
        INIT_LIST_HEAD(&priv->list_dev);
 
-
        for (i = 0; i < ci->devcount; i++) {
                struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i];
                struct com20020_dev *card;
@@ -101,13 +101,13 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 
                lp = netdev_priv(dev);
 
-               BUGMSG(D_NORMAL, "%s Controls\n", ci->name);
+               arc_printk(D_NORMAL, dev, "%s Controls\n", ci->name);
                ioaddr = pci_resource_start(pdev, cm->bar) + cm->offset;
 
                r = devm_request_region(&pdev->dev, ioaddr, cm->size,
                                        "com20020-pci");
                if (!r) {
-                       pr_err("IO region %xh-%xh already allocated.\n",
+                       pr_err("IO region %xh-%xh already allocated\n",
                               ioaddr, ioaddr + cm->size - 1);
                        ret = -EBUSY;
                        goto out_port;
@@ -117,8 +117,8 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
                 * ARCNET controller needs
                 * this access to detect bustype
                 */
-               outb(0x00, ioaddr + 1);
-               inb(ioaddr + 1);
+               arcnet_outb(0x00, ioaddr, COM20020_REG_W_COMMAND);
+               arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT);
 
                dev->base_addr = ioaddr;
                dev->dev_addr[0] = node;
@@ -131,7 +131,7 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
                lp->timeout = timeout;
                lp->hw.owner = THIS_MODULE;
 
-               if (ASTATUS() == 0xFF) {
+               if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
                        pr_err("IO address %Xh is empty!\n", ioaddr);
                        ret = -EIO;
                        goto out_port;
@@ -143,10 +143,8 @@ static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 
                card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
                                    GFP_KERNEL);
-               if (!card) {
-                       pr_err("%s out of memory!\n", __func__);
+               if (!card)
                        return -ENOMEM;
-               }
 
                card->index = i;
                card->pci_priv = priv;
@@ -190,7 +188,11 @@ static struct com20020_pci_card_info card_info_10mbit = {
        .name = "ARC-PCI",
        .devcount = 1,
        .chan_map_tbl = {
-               { 2, 0x00, 0x08 },
+               {
+                       .bar = 2,
+                       .offset = 0x00,
+                       .size = 0x08,
+               },
        },
        .flags = ARC_CAN_10MBIT,
 };
@@ -199,7 +201,11 @@ static struct com20020_pci_card_info card_info_5mbit = {
        .name = "ARC-PCI",
        .devcount = 1,
        .chan_map_tbl = {
-               { 2, 0x00, 0x08 },
+               {
+                       .bar = 2,
+                       .offset = 0x00,
+                       .size = 0x08,
+               },
        },
        .flags = ARC_IS_5MBIT,
 };
@@ -209,7 +215,11 @@ static struct com20020_pci_card_info card_info_sohard = {
        .devcount = 1,
        /* SOHARD needs PCI base addr 4 */
        .chan_map_tbl = {
-               {4, 0x00, 0x08},
+               {
+                       .bar = 4,
+                       .offset = 0x00,
+                       .size = 0x08
+               },
        },
        .flags = ARC_CAN_10MBIT,
 };
@@ -218,7 +228,11 @@ static struct com20020_pci_card_info card_info_eae_arc1 = {
        .name = "EAE PLX-PCI ARC1",
        .devcount = 1,
        .chan_map_tbl = {
-               { 2, 0x00, 0x08 },
+               {
+                       .bar = 2,
+                       .offset = 0x00,
+                       .size = 0x08,
+               },
        },
        .flags = ARC_CAN_10MBIT,
 };
@@ -227,8 +241,15 @@ static struct com20020_pci_card_info card_info_eae_ma1 = {
        .name = "EAE PLX-PCI MA1",
        .devcount = 2,
        .chan_map_tbl = {
-               { 2, 0x00, 0x08 },
-               { 2, 0x08, 0x08 }
+               {
+                       .bar = 2,
+                       .offset = 0x00,
+                       .size = 0x08,
+               }, {
+                       .bar = 2,
+                       .offset = 0x08,
+                       .size = 0x08,
+               }
        },
        .flags = ARC_CAN_10MBIT,
 };
@@ -404,7 +425,8 @@ static struct pci_driver com20020pci_driver = {
 
 static int __init com20020pci_init(void)
 {
-       BUGLVL(D_NORMAL) printk(VERSION);
+       if (BUGLVL(D_NORMAL))
+               pr_info("%s\n", "COM20020 PCI support");
        return pci_register_driver(&com20020pci_driver);
 }
 
index 1a8437842fbca819efeca443433c9ab82bc3236f..c82f323a8c2b8fecd0f1c6a33d253db176088df5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - COM20020 chipset support
- * 
+ *
  * Written 1997 by David Woodhouse.
  * Written 1994-1999 by Avery Pennarun.
  * Written 1999 by Martin Mares <mj@ucw.cz>.
@@ -25,6 +25,9 @@
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/arcdevice.h>
-#include <linux/com20020.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
+#include "arcdevice.h"
+#include "com20020.h"
 
-#define VERSION "arcnet: COM20020 chipset support (by David Woodhouse et al.)\n"
-
-static char *clockrates[] =
-{"10 Mb/s", "Reserved", "5 Mb/s",
- "2.5 Mb/s", "1.25Mb/s", "625 Kb/s", "312.5 Kb/s",
- "156.25 Kb/s", "Reserved", "Reserved", "Reserved"};
+static const char * const clockrates[] = {
+       "XXXXXXX", "XXXXXXXX", "XXXXXX", "2.5 Mb/s",
+       "1.25Mb/s", "625 Kb/s", "312.5 Kb/s", "156.25 Kb/s",
+       "Reserved", "Reserved", "Reserved"
+};
 
 static void com20020_command(struct net_device *dev, int command);
 static int com20020_status(struct net_device *dev);
@@ -63,35 +65,38 @@ static void com20020_copy_from_card(struct net_device *dev, int bufnum,
        int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;
 
        /* set up the address register */
-       outb((ofs >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
-       outb(ofs & 0xff, _ADDR_LO);
+       arcnet_outb((ofs >> 8) | RDDATAflag | AUTOINCflag,
+                   ioaddr, COM20020_REG_W_ADDR_HI);
+       arcnet_outb(ofs & 0xff, ioaddr, COM20020_REG_W_ADDR_LO);
 
        /* copy the data */
-       TIME("insb", count, insb(_MEMDATA, buf, count));
+       TIME(dev, "insb", count,
+            arcnet_insb(ioaddr, COM20020_REG_RW_MEMDATA, buf, count));
 }
 
-
 static void com20020_copy_to_card(struct net_device *dev, int bufnum,
                                  int offset, void *buf, int count)
 {
        int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;
 
        /* set up the address register */
-       outb((ofs >> 8) | AUTOINCflag, _ADDR_HI);
-       outb(ofs & 0xff, _ADDR_LO);
+       arcnet_outb((ofs >> 8) | AUTOINCflag, ioaddr, COM20020_REG_W_ADDR_HI);
+       arcnet_outb(ofs & 0xff, ioaddr, COM20020_REG_W_ADDR_LO);
 
        /* copy the data */
-       TIME("outsb", count, outsb(_MEMDATA, buf, count));
+       TIME(dev, "outsb", count,
+            arcnet_outsb(ioaddr, COM20020_REG_RW_MEMDATA, buf, count));
 }
 
-
 /* Reset the card and check some basic stuff during the detection stage. */
 int com20020_check(struct net_device *dev)
 {
        int ioaddr = dev->base_addr, status;
        struct arcnet_local *lp = netdev_priv(dev);
 
-       ARCRESET0;
+       arcnet_outb(XTOcfg(3) | RESETcfg, ioaddr, COM20020_REG_W_CONFIG);
+       udelay(5);
+       arcnet_outb(XTOcfg(3), ioaddr, COM20020_REG_W_CONFIG);
        mdelay(RESETtime);
 
        lp->setup = lp->clockm ? 0 : (lp->clockp << 1);
@@ -101,49 +106,51 @@ int com20020_check(struct net_device *dev)
        /* Enable P1Mode for backplane mode */
        lp->setup = lp->setup | P1MODE;
 
-       SET_SUBADR(SUB_SETUP1);
-       outb(lp->setup, _XREG);
+       com20020_set_subaddress(lp, ioaddr, SUB_SETUP1);
+       arcnet_outb(lp->setup, ioaddr, COM20020_REG_W_XREG);
+
+       if (lp->clockm != 0) {
+               com20020_set_subaddress(lp, ioaddr, SUB_SETUP2);
+               arcnet_outb(lp->setup2, ioaddr, COM20020_REG_W_XREG);
 
-       if (lp->clockm != 0)
-       {
-               SET_SUBADR(SUB_SETUP2);
-               outb(lp->setup2, _XREG);
-       
                /* must now write the magic "restart operation" command */
                mdelay(1);
-               outb(0x18, _COMMAND);
+               arcnet_outb(STARTIOcmd, ioaddr, COM20020_REG_W_COMMAND);
        }
 
-       lp->config = 0x21 | (lp->timeout << 3) | (lp->backplane << 2);
+       lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE;
        /* set node ID to 0x42 (but transmitter is disabled, so it's okay) */
-       SETCONF;
-       outb(0x42, ioaddr + BUS_ALIGN*7);
+       arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
+       arcnet_outb(0x42, ioaddr, COM20020_REG_W_XREG);
 
-       status = ASTATUS();
+       status = arcnet_inb(ioaddr, COM20020_REG_R_STATUS);
 
        if ((status & 0x99) != (NORXflag | TXFREEflag | RESETflag)) {
-               BUGMSG(D_NORMAL, "status invalid (%Xh).\n", status);
+               arc_printk(D_NORMAL, dev, "status invalid (%Xh).\n", status);
                return -ENODEV;
        }
-       BUGMSG(D_INIT_REASONS, "status after reset: %X\n", status);
+       arc_printk(D_INIT_REASONS, dev, "status after reset: %X\n", status);
 
        /* Enable TX */
-       outb(0x39, _CONFIG);
-       outb(inb(ioaddr + BUS_ALIGN*8), ioaddr + BUS_ALIGN*7);
+       lp->config |= TXENcfg;
+       arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
+       arcnet_outb(arcnet_inb(ioaddr, 8), ioaddr, COM20020_REG_W_XREG);
 
-       ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
-
-       status = ASTATUS();
-       BUGMSG(D_INIT_REASONS, "status after reset acknowledged: %X\n",
-              status);
+       arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
+                   ioaddr, COM20020_REG_W_COMMAND);
+       status = arcnet_inb(ioaddr, COM20020_REG_R_STATUS);
+       arc_printk(D_INIT_REASONS, dev, "status after reset acknowledged: %X\n",
+                  status);
 
        /* Read first location of memory */
-       outb(0 | RDDATAflag | AUTOINCflag, _ADDR_HI);
-       outb(0, _ADDR_LO);
-
-       if ((status = inb(_MEMDATA)) != TESTvalue) {
-               BUGMSG(D_NORMAL, "Signature byte not found (%02Xh != D1h).\n",
-                      status);
+       arcnet_outb(0 | RDDATAflag | AUTOINCflag,
+                   ioaddr, COM20020_REG_W_ADDR_HI);
+       arcnet_outb(0, ioaddr, COM20020_REG_W_ADDR_LO);
+
+       status = arcnet_inb(ioaddr, COM20020_REG_RW_MEMDATA);
+       if (status != TESTvalue) {
+               arc_printk(D_NORMAL, dev, "Signature byte not found (%02Xh != D1h).\n",
+                          status);
                return -ENODEV;
        }
        return 0;
@@ -156,8 +163,8 @@ static int com20020_set_hwaddr(struct net_device *dev, void *addr)
        struct sockaddr *hwaddr = addr;
 
        memcpy(dev->dev_addr, hwaddr->sa_data, 1);
-       SET_SUBADR(SUB_NODE);
-       outb(dev->dev_addr[0], _XREG);
+       com20020_set_subaddress(lp, ioaddr, SUB_NODE);
+       arcnet_outb(dev->dev_addr[0], ioaddr, COM20020_REG_W_XREG);
 
        return 0;
 }
@@ -192,48 +199,54 @@ int com20020_found(struct net_device *dev, int shared)
        lp->hw.copy_from_card = com20020_copy_from_card;
        lp->hw.close = com20020_close;
 
+       /* FIXME: do this some other way! */
        if (!dev->dev_addr[0])
-               dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8);   /* FIXME: do this some other way! */
+               dev->dev_addr[0] = arcnet_inb(ioaddr, 8);
 
-       SET_SUBADR(SUB_SETUP1);
-       outb(lp->setup, _XREG);
+       com20020_set_subaddress(lp, ioaddr, SUB_SETUP1);
+       arcnet_outb(lp->setup, ioaddr, COM20020_REG_W_XREG);
+
+       if (lp->card_flags & ARC_CAN_10MBIT) {
+               com20020_set_subaddress(lp, ioaddr, SUB_SETUP2);
+               arcnet_outb(lp->setup2, ioaddr, COM20020_REG_W_XREG);
 
-       if (lp->card_flags & ARC_CAN_10MBIT)
-       {
-               SET_SUBADR(SUB_SETUP2);
-               outb(lp->setup2, _XREG);
-       
                /* must now write the magic "restart operation" command */
                mdelay(1);
-               outb(0x18, _COMMAND);
+               arcnet_outb(STARTIOcmd, ioaddr, COM20020_REG_W_COMMAND);
        }
 
-       lp->config = 0x20 | (lp->timeout << 3) | (lp->backplane << 2) | 1;
+       lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE;
        /* Default 0x38 + register: Node ID */
-       SETCONF;
-       outb(dev->dev_addr[0], _XREG);
+       arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
+       arcnet_outb(dev->dev_addr[0], ioaddr, COM20020_REG_W_XREG);
 
        /* reserve the irq */
        if (request_irq(dev->irq, arcnet_interrupt, shared,
                        "arcnet (COM20020)", dev)) {
-               BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
+               arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", dev->irq);
                return -ENODEV;
        }
 
        dev->base_addr = ioaddr;
 
-       BUGMSG(D_NORMAL, "%s: station %02Xh found at %03lXh, IRQ %d.\n",
-              lp->card_name, dev->dev_addr[0], dev->base_addr, dev->irq);
+       arc_printk(D_NORMAL, dev, "%s: station %02Xh found at %03lXh, IRQ %d.\n",
+                  lp->card_name, dev->dev_addr[0], dev->base_addr, dev->irq);
 
        if (lp->backplane)
-               BUGMSG(D_NORMAL, "Using backplane mode.\n");
+               arc_printk(D_NORMAL, dev, "Using backplane mode.\n");
 
        if (lp->timeout != 3)
-               BUGMSG(D_NORMAL, "Using extended timeout value of %d.\n", lp->timeout);
-
-       BUGMSG(D_NORMAL, "Using CKP %d - data rate %s.\n",
-              lp->setup >> 1, 
-              clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]);
+               arc_printk(D_NORMAL, dev, "Using extended timeout value of %d\n",
+                          lp->timeout);
+
+       arc_printk(D_NORMAL, dev, "Using CKP %d - data rate %s\n",
+                  lp->setup >> 1,
+                  clockrates[3 -
+                             ((lp->setup2 & 0xF0) >> 4) +
+                             ((lp->setup & 0x0F) >> 1)]);
+                       /* The clockrates array index looks very fragile.
+                        * It seems like it could have negative indexing.
+                        */
 
        if (register_netdev(dev)) {
                free_irq(dev->irq, dev);
@@ -242,10 +255,8 @@ int com20020_found(struct net_device *dev, int shared)
        return 0;
 }
 
-
-/* 
- * Do a hardware reset on the card, and set up necessary registers.
- * 
+/* Do a hardware reset on the card, and set up necessary registers.
+ *
  * This should be called as little as possible, because it disrupts the
  * token on the network (causes a RECON) and requires a significant delay.
  *
@@ -257,65 +268,71 @@ static int com20020_reset(struct net_device *dev, int really_reset)
        u_int ioaddr = dev->base_addr;
        u_char inbyte;
 
-       BUGMSG(D_DEBUG, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n",
-               __FILE__,__LINE__,__func__,dev,lp,dev->name);
-       BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
-              dev->name, ASTATUS());
+       arc_printk(D_DEBUG, dev, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n",
+                  __FILE__, __LINE__, __func__, dev, lp, dev->name);
+       arc_printk(D_INIT, dev, "Resetting %s (status=%02Xh)\n",
+                  dev->name, arcnet_inb(ioaddr, COM20020_REG_R_STATUS));
 
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
        lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
        /* power-up defaults */
-       SETCONF;
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
+       arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
 
        if (really_reset) {
                /* reset the card */
-               ARCRESET;
-               mdelay(RESETtime * 2);  /* COM20020 seems to be slower sometimes */
+               arcnet_outb(lp->config | RESETcfg, ioaddr, COM20020_REG_W_CONFIG);
+               udelay(5);
+               arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
+               mdelay(RESETtime * 2);
+                               /* COM20020 seems to be slower sometimes */
        }
        /* clear flags & end reset */
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
-       ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
+       arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
+                   ioaddr, COM20020_REG_W_COMMAND);
 
        /* verify that the ARCnet signature byte is present */
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
 
        com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
        if (inbyte != TESTvalue) {
-               BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
-               BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
+               arc_printk(D_DEBUG, dev, "%s: %d: %s\n",
+                          __FILE__, __LINE__, __func__);
+               arc_printk(D_NORMAL, dev, "reset failed: TESTvalue not present.\n");
                return 1;
        }
        /* enable extended (512-byte) packets */
-       ACOMMAND(CONFIGcmd | EXTconf);
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
+       arcnet_outb(CONFIGcmd | EXTconf, ioaddr, COM20020_REG_W_COMMAND);
+
+       arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
 
        /* done!  return success. */
        return 0;
 }
 
-
 static void com20020_setmask(struct net_device *dev, int mask)
 {
        u_int ioaddr = dev->base_addr;
-       BUGMSG(D_DURING, "Setting mask to %x at %x\n",mask,ioaddr);
-       AINTMASK(mask);
-}
 
+       arc_printk(D_DURING, dev, "Setting mask to %x at %x\n", mask, ioaddr);
+       arcnet_outb(mask, ioaddr, COM20020_REG_W_INTMASK);
+}
 
 static void com20020_command(struct net_device *dev, int cmd)
 {
        u_int ioaddr = dev->base_addr;
-       ACOMMAND(cmd);
-}
 
+       arcnet_outb(cmd, ioaddr, COM20020_REG_W_COMMAND);
+}
 
 static int com20020_status(struct net_device *dev)
 {
        u_int ioaddr = dev->base_addr;
 
-       return ASTATUS() + (ADIAGSTATUS()<<8);
+       return arcnet_inb(ioaddr, COM20020_REG_R_STATUS) +
+               (arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT) << 8);
 }
 
 static void com20020_close(struct net_device *dev)
@@ -325,7 +342,7 @@ static void com20020_close(struct net_device *dev)
 
        /* disable transmitter */
        lp->config &= ~TXENcfg;
-       SETCONF;
+       arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
 }
 
 /* Set or clear the multicast filter for this adaptor.
@@ -340,20 +357,20 @@ static void com20020_set_mc_list(struct net_device *dev)
        struct arcnet_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
 
-       if ((dev->flags & IFF_PROMISC) && (dev->flags & IFF_UP)) {      /* Enable promiscuous mode */
+       if ((dev->flags & IFF_PROMISC) && (dev->flags & IFF_UP)) {
+               /* Enable promiscuous mode */
                if (!(lp->setup & PROMISCset))
-                       BUGMSG(D_NORMAL, "Setting promiscuous flag...\n");
-               SET_SUBADR(SUB_SETUP1);
+                       arc_printk(D_NORMAL, dev, "Setting promiscuous flag...\n");
+               com20020_set_subaddress(lp, ioaddr, SUB_SETUP1);
                lp->setup |= PROMISCset;
-               outb(lp->setup, _XREG);
-       } else
+               arcnet_outb(lp->setup, ioaddr, COM20020_REG_W_XREG);
+       } else {
                /* Disable promiscuous mode, use normal mode */
-       {
                if ((lp->setup & PROMISCset))
-                       BUGMSG(D_NORMAL, "Resetting promiscuous flag...\n");
-               SET_SUBADR(SUB_SETUP1);
+                       arc_printk(D_NORMAL, dev, "Resetting promiscuous flag...\n");
+               com20020_set_subaddress(lp, ioaddr, SUB_SETUP1);
                lp->setup &= ~PROMISCset;
-               outb(lp->setup, _XREG);
+               arcnet_outb(lp->setup, ioaddr, COM20020_REG_W_XREG);
        }
 }
 
@@ -371,7 +388,8 @@ MODULE_LICENSE("GPL");
 
 static int __init com20020_module_init(void)
 {
-       BUGLVL(D_NORMAL) printk(VERSION);
+       if (BUGLVL(D_NORMAL))
+               pr_info("%s\n", "COM20020 chipset support (by David Woodhouse et al.)");
        return 0;
 }
 
diff --git a/drivers/net/arcnet/com20020.h b/drivers/net/arcnet/com20020.h
new file mode 100644 (file)
index 0000000..22a460f
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Linux ARCnet driver - COM20020 chipset support - function declarations
+ *
+ * Written 1997 by David Woodhouse.
+ * Written 1994-1999 by Avery Pennarun.
+ * Derived from skeleton.c by Donald Becker.
+ *
+ * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
+ *  for sponsoring the further development of this driver.
+ *
+ * **********************
+ *
+ * The original copyright of skeleton.c was as follows:
+ *
+ * skeleton.c Written 1993 by Donald Becker.
+ * Copyright 1993 United States Government as represented by the
+ * Director, National Security Agency.  This software may only be used
+ * and distributed according to the terms of the GNU General Public License as
+ * modified by SRC, incorporated herein by reference.
+ *
+ * **********************
+ *
+ * For more details, see drivers/net/arcnet.c
+ *
+ * **********************
+ */
+#ifndef __COM20020_H
+#define __COM20020_H
+
+int com20020_check(struct net_device *dev);
+int com20020_found(struct net_device *dev, int shared);
+extern const struct net_device_ops com20020_netdev_ops;
+
+/* The number of low I/O ports used by the card. */
+#define ARCNET_TOTAL_SIZE 8
+
+#define PLX_PCI_MAX_CARDS 2
+
+struct com20020_pci_channel_map {
+       u32 bar;
+       u32 offset;
+       u32 size;               /* 0x00 - auto, e.g. length of entire bar */
+};
+
+struct com20020_pci_card_info {
+       const char *name;
+       int devcount;
+
+       struct com20020_pci_channel_map chan_map_tbl[PLX_PCI_MAX_CARDS];
+
+       unsigned int flags;
+};
+
+struct com20020_priv {
+       struct com20020_pci_card_info *ci;
+       struct list_head list_dev;
+};
+
+struct com20020_dev {
+       struct list_head list;
+       struct net_device *dev;
+
+       struct com20020_priv *pci_priv;
+       int index;
+};
+
+#define COM20020_REG_W_INTMASK 0       /* writable */
+#define COM20020_REG_R_STATUS  0       /* readable */
+#define COM20020_REG_W_COMMAND 1       /* standard arcnet commands */
+#define COM20020_REG_R_DIAGSTAT        1       /* diagnostic status */
+#define COM20020_REG_W_ADDR_HI 2       /* control for IO-mapped memory */
+#define COM20020_REG_W_ADDR_LO 3
+#define COM20020_REG_RW_MEMDATA        4       /* data port for IO-mapped memory */
+#define COM20020_REG_W_SUBADR  5       /* the extended port _XREG refers to */
+#define COM20020_REG_W_CONFIG  6       /* configuration */
+#define COM20020_REG_W_XREG    7       /* extra
+                                        * (indexed by _CONFIG or _SUBADDR)
+                                        */
+
+/* in the ADDR_HI register */
+#define RDDATAflag     0x80    /* next access is a read (not a write) */
+
+/* in the DIAGSTAT register */
+#define NEWNXTIDflag   0x02    /* ID to which token is passed has changed */
+
+/* in the CONFIG register */
+#define RESETcfg       0x80    /* put card in reset state */
+#define TXENcfg                0x20    /* enable TX */
+#define XTOcfg(x)      ((x) << 3)      /* extended timeout */
+
+/* in SETUP register */
+#define PROMISCset     0x10    /* enable RCV_ALL */
+#define P1MODE         0x80    /* enable P1-MODE for Backplane */
+#define SLOWARB                0x01    /* enable Slow Arbitration for >=5Mbps */
+
+/* COM2002x */
+#define SUB_TENTATIVE  0       /* tentative node ID */
+#define SUB_NODE       1       /* node ID */
+#define SUB_SETUP1     2       /* various options */
+#define SUB_TEST       3       /* test/diag register */
+
+/* COM20022 only */
+#define SUB_SETUP2     4       /* sundry options */
+#define SUB_BUSCTL     5       /* bus control options */
+#define SUB_DMACOUNT   6       /* DMA count options */
+
+static inline void com20020_set_subaddress(struct arcnet_local *lp,
+                                          int ioaddr, int val)
+{
+       if (val < 4) {
+               lp->config = (lp->config & ~0x03) | val;
+               arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
+       } else {
+               arcnet_outb(val, ioaddr, COM20020_REG_W_SUBADR);
+       }
+}
+
+#endif /* __COM20020_H */
index 057d9582132a6f659c7d5c08fbd99f883e50fb07..cf607ffcf358e95eab6a63c3c7bb63382cd57c49 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - COM20020 PCMCIA support
- * 
+ *
  * Written 1994-1999 by Avery Pennarun,
  *    based on an ISA version by David Woodhouse.
  * Derived from ibmtr_cs.c by Steve Kipisz (pcmcia-cs 3.1.4)
  * Director, National Security Agency.  This software may only be used
  * and distributed according to the terms of the GNU General Public License as
  * modified by SRC, incorporated herein by reference.
- * 
+ *
  * **********************
  * Changes:
  * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
  * - reorganize kmallocs in com20020_attach, checking all for failure
  *   and releasing the previous allocations if one fails
  * **********************
- * 
+ *
  * For more details, see drivers/net/arcnet.c
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
-#include <linux/arcdevice.h>
-#include <linux/com20020.h>
-
+#include <linux/io.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 
-#include <asm/io.h>
-
-#define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
-
+#include "arcdevice.h"
+#include "com20020.h"
 
 static void regdump(struct net_device *dev)
 {
 #ifdef DEBUG
-    int ioaddr = dev->base_addr;
-    int count;
-    
-    netdev_dbg(dev, "register dump:\n");
-    for (count = ioaddr; count < ioaddr + 16; count++)
-    {
-       if (!(count % 16))
-           pr_cont("%04X:", count);
-       pr_cont(" %02X", inb(count));
-    }
-    pr_cont("\n");
-    
-    netdev_dbg(dev, "buffer0 dump:\n");
+       int ioaddr = dev->base_addr;
+       int count;
+
+       netdev_dbg(dev, "register dump:\n");
+       for (count = 0; count < 16; count++) {
+               if (!(count % 16))
+                       pr_cont("%04X:", ioaddr + count);
+               pr_cont(" %02X", arcnet_inb(ioaddr, count));
+       }
+       pr_cont("\n");
+
+       netdev_dbg(dev, "buffer0 dump:\n");
        /* set up the address register */
-        count = 0;
-       outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
-       outb(count & 0xff, _ADDR_LO);
-    
-    for (count = 0; count < 256+32; count++)
-    {
-       if (!(count % 16))
-           pr_cont("%04X:", count);
-       
-       /* copy the data */
-       pr_cont(" %02X", inb(_MEMDATA));
-    }
-    pr_cont("\n");
-#endif
-}
+       count = 0;
+       arcnet_outb((count >> 8) | RDDATAflag | AUTOINCflag,
+                   ioaddr, com20020_REG_W_ADDR_HI);
+       arcnet_outb(count & 0xff, ioaddr, COM20020_REG_W_ADDR_LO);
 
+       for (count = 0; count < 256 + 32; count++) {
+               if (!(count % 16))
+                       pr_cont("%04X:", count);
 
+               /* copy the data */
+               pr_cont(" %02X", arcnet_inb(ioaddr, COM20020_REG_RW_MEMDATA));
+       }
+       pr_cont("\n");
+#endif
+}
 
 /*====================================================================*/
 
@@ -114,169 +110,161 @@ static void com20020_detach(struct pcmcia_device *p_dev);
 
 static int com20020_probe(struct pcmcia_device *p_dev)
 {
-    struct com20020_dev *info;
-    struct net_device *dev;
-    struct arcnet_local *lp;
+       struct com20020_dev *info;
+       struct net_device *dev;
+       struct arcnet_local *lp;
 
-    dev_dbg(&p_dev->dev, "com20020_attach()\n");
+       dev_dbg(&p_dev->dev, "com20020_attach()\n");
 
-    /* Create new network device */
-    info = kzalloc(sizeof(*info), GFP_KERNEL);
-    if (!info)
-       goto fail_alloc_info;
+       /* Create new network device */
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               goto fail_alloc_info;
 
-    dev = alloc_arcdev("");
-    if (!dev)
-       goto fail_alloc_dev;
+       dev = alloc_arcdev("");
+       if (!dev)
+               goto fail_alloc_dev;
 
-    lp = netdev_priv(dev);
-    lp->timeout = timeout;
-    lp->backplane = backplane;
-    lp->clockp = clockp;
-    lp->clockm = clockm & 3;
-    lp->hw.owner = THIS_MODULE;
+       lp = netdev_priv(dev);
+       lp->timeout = timeout;
+       lp->backplane = backplane;
+       lp->clockp = clockp;
+       lp->clockm = clockm & 3;
+       lp->hw.owner = THIS_MODULE;
 
-    /* fill in our module parameters as defaults */
-    dev->dev_addr[0] = node;
+       /* fill in our module parameters as defaults */
+       dev->dev_addr[0] = node;
 
-    p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
-    p_dev->resource[0]->end = 16;
-    p_dev->config_flags |= CONF_ENABLE_IRQ;
+       p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+       p_dev->resource[0]->end = 16;
+       p_dev->config_flags |= CONF_ENABLE_IRQ;
 
-    info->dev = dev;
-    p_dev->priv = info;
+       info->dev = dev;
+       p_dev->priv = info;
 
-    return com20020_config(p_dev);
+       return com20020_config(p_dev);
 
 fail_alloc_dev:
-    kfree(info);
+       kfree(info);
 fail_alloc_info:
-    return -ENOMEM;
+       return -ENOMEM;
 } /* com20020_attach */
 
 static void com20020_detach(struct pcmcia_device *link)
 {
-    struct com20020_dev *info = link->priv;
-    struct net_device *dev = info->dev;
+       struct com20020_dev *info = link->priv;
+       struct net_device *dev = info->dev;
 
-    dev_dbg(&link->dev, "detach...\n");
+       dev_dbg(&link->dev, "detach...\n");
 
-    dev_dbg(&link->dev, "com20020_detach\n");
+       dev_dbg(&link->dev, "com20020_detach\n");
 
-    dev_dbg(&link->dev, "unregister...\n");
+       dev_dbg(&link->dev, "unregister...\n");
 
-    unregister_netdev(dev);
+       unregister_netdev(dev);
 
-    /*
-     * this is necessary because we register our IRQ separately
-     * from card services.
-     */
-    if (dev->irq)
-           free_irq(dev->irq, dev);
+       /* this is necessary because we register our IRQ separately
+        * from card services.
+        */
+       if (dev->irq)
+               free_irq(dev->irq, dev);
 
-    com20020_release(link);
+       com20020_release(link);
 
-    /* Unlink device structure, free bits */
-    dev_dbg(&link->dev, "unlinking...\n");
-    if (link->priv)
-    {
-       dev = info->dev;
-       if (dev)
-       {
-           dev_dbg(&link->dev, "kfree...\n");
-           free_netdev(dev);
+       /* Unlink device structure, free bits */
+       dev_dbg(&link->dev, "unlinking...\n");
+       if (link->priv) {
+               dev = info->dev;
+               if (dev) {
+                       dev_dbg(&link->dev, "kfree...\n");
+                       free_netdev(dev);
+               }
+               dev_dbg(&link->dev, "kfree2...\n");
+               kfree(info);
        }
-       dev_dbg(&link->dev, "kfree2...\n");
-       kfree(info);
-    }
 
 } /* com20020_detach */
 
 static int com20020_config(struct pcmcia_device *link)
 {
-    struct arcnet_local *lp;
-    struct com20020_dev *info;
-    struct net_device *dev;
-    int i, ret;
-    int ioaddr;
+       struct arcnet_local *lp;
+       struct com20020_dev *info;
+       struct net_device *dev;
+       int i, ret;
+       int ioaddr;
+
+       info = link->priv;
+       dev = info->dev;
+
+       dev_dbg(&link->dev, "config...\n");
+
+       dev_dbg(&link->dev, "com20020_config\n");
 
-    info = link->priv;
-    dev = info->dev;
+       dev_dbg(&link->dev, "baseport1 is %Xh\n",
+               (unsigned int)link->resource[0]->start);
 
-    dev_dbg(&link->dev, "config...\n");
+       i = -ENODEV;
+       link->io_lines = 16;
 
-    dev_dbg(&link->dev, "com20020_config\n");
+       if (!link->resource[0]->start) {
+               for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10) {
+                       link->resource[0]->start = ioaddr;
+                       i = pcmcia_request_io(link);
+                       if (i == 0)
+                               break;
+               }
+       } else {
+               i = pcmcia_request_io(link);
+       }
 
-    dev_dbg(&link->dev, "baseport1 is %Xh\n",
-           (unsigned int) link->resource[0]->start);
+       if (i != 0) {
+               dev_dbg(&link->dev, "requestIO failed totally!\n");
+               goto failed;
+       }
 
-    i = -ENODEV;
-    link->io_lines = 16;
+       ioaddr = dev->base_addr = link->resource[0]->start;
+       dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
 
-    if (!link->resource[0]->start)
-    {
-       for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
-       {
-           link->resource[0]->start = ioaddr;
-           i = pcmcia_request_io(link);
-           if (i == 0)
-               break;
+       dev_dbg(&link->dev, "request IRQ %d\n",
+               link->irq);
+       if (!link->irq) {
+               dev_dbg(&link->dev, "requestIRQ failed totally!\n");
+               goto failed;
        }
-    }
-    else
-       i = pcmcia_request_io(link);
-    
-    if (i != 0)
-    {
-       dev_dbg(&link->dev, "requestIO failed totally!\n");
-       goto failed;
-    }
-       
-    ioaddr = dev->base_addr = link->resource[0]->start;
-    dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
-
-    dev_dbg(&link->dev, "request IRQ %d\n",
-           link->irq);
-    if (!link->irq)
-    {
-       dev_dbg(&link->dev, "requestIRQ failed totally!\n");
-       goto failed;
-    }
-
-    dev->irq = link->irq;
-
-    ret = pcmcia_enable_device(link);
-    if (ret)
-           goto failed;
-
-    if (com20020_check(dev))
-    {
-       regdump(dev);
-       goto failed;
-    }
-    
-    lp = netdev_priv(dev);
-    lp->card_name = "PCMCIA COM20020";
-    lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
-
-    SET_NETDEV_DEV(dev, &link->dev);
-
-    i = com20020_found(dev, 0);        /* calls register_netdev */
-    
-    if (i != 0) {
-       dev_notice(&link->dev,
-                  "com20020_found() failed\n");
-       goto failed;
-    }
-
-    netdev_dbg(dev, "port %#3lx, irq %d\n",
-              dev->base_addr, dev->irq);
-    return 0;
+
+       dev->irq = link->irq;
+
+       ret = pcmcia_enable_device(link);
+       if (ret)
+               goto failed;
+
+       if (com20020_check(dev)) {
+               regdump(dev);
+               goto failed;
+       }
+
+       lp = netdev_priv(dev);
+       lp->card_name = "PCMCIA COM20020";
+       lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
+
+       SET_NETDEV_DEV(dev, &link->dev);
+
+       i = com20020_found(dev, 0);     /* calls register_netdev */
+
+       if (i != 0) {
+               dev_notice(&link->dev,
+                          "com20020_found() failed\n");
+               goto failed;
+       }
+
+       netdev_dbg(dev, "port %#3lx, irq %d\n",
+                  dev->base_addr, dev->irq);
+       return 0;
 
 failed:
-    dev_dbg(&link->dev, "com20020_config failed...\n");
-    com20020_release(link);
-    return -ENODEV;
+       dev_dbg(&link->dev, "com20020_config failed...\n");
+       com20020_release(link);
+       return -ENODEV;
 } /* com20020_config */
 
 static void com20020_release(struct pcmcia_device *link)
@@ -304,7 +292,10 @@ static int com20020_resume(struct pcmcia_device *link)
        if (link->open) {
                int ioaddr = dev->base_addr;
                struct arcnet_local *lp = netdev_priv(dev);
-               ARCRESET;
+
+               arcnet_outb(lp->config | 0x80, ioaddr, COM20020_REG_W_CONFIG);
+               udelay(5);
+               arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
        }
 
        return 0;
@@ -312,9 +303,9 @@ static int com20020_resume(struct pcmcia_device *link)
 
 static const struct pcmcia_device_id com20020_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.",
-                       "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
+                               "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
        PCMCIA_DEVICE_PROD_ID12("SoHard AG",
-                       "SH ARC PCMCIA", 0xf8991729, 0x69dff0c7),
+                               "SH ARC PCMCIA", 0xf8991729, 0x69dff0c7),
        PCMCIA_DEVICE_NULL
 };
 MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
diff --git a/drivers/net/arcnet/com9026.h b/drivers/net/arcnet/com9026.h
new file mode 100644 (file)
index 0000000..efcaf67
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef __COM9026_H
+#define __COM9026_H
+
+/* COM 9026 controller chip --> ARCnet register addresses */
+
+#define COM9026_REG_W_INTMASK  0       /* writable */
+#define COM9026_REG_R_STATUS   0       /* readable */
+#define COM9026_REG_W_COMMAND  1       /* writable, returns random vals on read (?) */
+#define COM9026_REG_RW_CONFIG  2       /* Configuration register */
+#define COM9026_REG_R_RESET    8       /* software reset (on read) */
+#define COM9026_REG_RW_MEMDATA 12      /* Data port for IO-mapped memory */
+#define COM9026_REG_W_ADDR_LO  14      /* Control registers for said */
+#define COM9026_REG_W_ADDR_HI  15
+
+#define COM9026_REG_R_STATION  1       /* Station ID */
+
+#endif
index 487d780ebbdfd73768f575e43353da5f2e8a1fa3..b57863df5bf53e6ee0269b4d9f2055a06011b1d1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - COM90xx chipset (IO-mapped buffers)
- * 
+ *
  * Written 1997 by David Woodhouse.
  * Written 1994-1999 by Avery Pennarun.
  * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
@@ -25,6 +25,9 @@
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/bootmem.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <asm/io.h>
-#include <linux/arcdevice.h>
-
-
-#define VERSION "arcnet: COM90xx IO-mapped mode support (by David Woodhouse et el.)\n"
+#include <linux/io.h>
 
+#include "arcdevice.h"
+#include "com9026.h"
 
 /* Internal function declarations */
 
@@ -50,35 +51,14 @@ static void com90io_setmask(struct net_device *dev, int mask);
 static int com90io_reset(struct net_device *dev, int really_reset);
 static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset,
                                 void *buf, int count);
-static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offset,
-                                  void *buf, int count);
-
+static void com90io_copy_from_card(struct net_device *dev, int bufnum,
+                                  int offset, void *buf, int count);
 
 /* Handy defines for ARCnet specific stuff */
 
 /* The number of low I/O ports used by the card. */
 #define ARCNET_TOTAL_SIZE 16
 
-/* COM 9026 controller chip --> ARCnet register addresses */
-#define _INTMASK (ioaddr+0)    /* writable */
-#define _STATUS  (ioaddr+0)    /* readable */
-#define _COMMAND (ioaddr+1)    /* writable, returns random vals on read (?) */
-#define _RESET  (ioaddr+8)     /* software reset (on read) */
-#define _MEMDATA  (ioaddr+12)  /* Data port for IO-mapped memory */
-#define _ADDR_HI  (ioaddr+15)  /* Control registers for said */
-#define _ADDR_LO  (ioaddr+14)
-#define _CONFIG  (ioaddr+2)    /* Configuration register */
-
-#undef ASTATUS
-#undef ACOMMAND
-#undef AINTMASK
-
-#define ASTATUS()      inb(_STATUS)
-#define ACOMMAND(cmd) outb((cmd),_COMMAND)
-#define AINTMASK(msk)  outb((msk),_INTMASK)
-#define SETCONF()      outb((lp->config),_CONFIG)
-
-
 /****************************************************************************
  *                                                                          *
  * IO-mapped operation routines                                             *
@@ -92,58 +72,59 @@ static u_char get_buffer_byte(struct net_device *dev, unsigned offset)
 {
        int ioaddr = dev->base_addr;
 
-       outb(offset >> 8, _ADDR_HI);
-       outb(offset & 0xff, _ADDR_LO);
+       arcnet_outb(offset >> 8, ioaddr, COM9026_REG_W_ADDR_HI);
+       arcnet_outb(offset & 0xff, ioaddr, COM9026_REG_W_ADDR_LO);
 
-       return inb(_MEMDATA);
+       return arcnet_inb(ioaddr, COM9026_REG_RW_MEMDATA);
 }
 
 #ifdef ONE_AT_A_TIME_TX
-static void put_buffer_byte(struct net_device *dev, unsigned offset, u_char datum)
+static void put_buffer_byte(struct net_device *dev, unsigned offset,
+                           u_char datum)
 {
        int ioaddr = dev->base_addr;
 
-       outb(offset >> 8, _ADDR_HI);
-       outb(offset & 0xff, _ADDR_LO);
+       arcnet_outb(offset >> 8, ioaddr, COM9026_REG_W_ADDR_HI);
+       arcnet_outb(offset & 0xff, ioaddr, COM9026_REG_W_ADDR_LO);
 
-       outb(datum, _MEMDATA);
+       arcnet_outb(datum, ioaddr, COM9026_REG_RW_MEMDATA);
 }
 
 #endif
 
-
-static void get_whole_buffer(struct net_device *dev, unsigned offset, unsigned length, char *dest)
+static void get_whole_buffer(struct net_device *dev, unsigned offset,
+                            unsigned length, char *dest)
 {
        int ioaddr = dev->base_addr;
 
-       outb((offset >> 8) | AUTOINCflag, _ADDR_HI);
-       outb(offset & 0xff, _ADDR_LO);
+       arcnet_outb((offset >> 8) | AUTOINCflag, ioaddr, COM9026_REG_W_ADDR_HI);
+       arcnet_outb(offset & 0xff, ioaddr, COM9026_REG_W_ADDR_LO);
 
        while (length--)
 #ifdef ONE_AT_A_TIME_RX
                *(dest++) = get_buffer_byte(dev, offset++);
 #else
-               *(dest++) = inb(_MEMDATA);
+               *(dest++) = arcnet_inb(ioaddr, COM9026_REG_RW_MEMDATA);
 #endif
 }
 
-static void put_whole_buffer(struct net_device *dev, unsigned offset, unsigned length, char *dest)
+static void put_whole_buffer(struct net_device *dev, unsigned offset,
+                            unsigned length, char *dest)
 {
        int ioaddr = dev->base_addr;
 
-       outb((offset >> 8) | AUTOINCflag, _ADDR_HI);
-       outb(offset & 0xff, _ADDR_LO);
+       arcnet_outb((offset >> 8) | AUTOINCflag, ioaddr, COM9026_REG_W_ADDR_HI);
+       arcnet_outb(offset & 0xff, ioaddr,COM9026_REG_W_ADDR_LO);
 
        while (length--)
 #ifdef ONE_AT_A_TIME_TX
                put_buffer_byte(dev, offset++, *(dest++));
 #else
-               outb(*(dest++), _MEMDATA);
+               arcnet_outb(*(dest++), ioaddr, COM9026_REG_RW_MEMDATA);
 #endif
 }
 
-/*
- * We cannot probe for an IO mapped card either, although we can check that
+/* We cannot probe for an IO mapped card either, although we can check that
  * it's where we were told it was, and even autoirq
  */
 static int __init com90io_probe(struct net_device *dev)
@@ -151,71 +132,78 @@ static int __init com90io_probe(struct net_device *dev)
        int ioaddr = dev->base_addr, status;
        unsigned long airqmask;
 
-       BUGLVL(D_NORMAL) printk(VERSION);
-       BUGLVL(D_NORMAL) printk("E-mail me if you actually test this driver, please!\n");
+       if (BUGLVL(D_NORMAL)) {
+               pr_info("%s\n", "COM90xx IO-mapped mode support (by David Woodhouse et el.)");
+               pr_info("E-mail me if you actually test this driver, please!\n");
+       }
 
        if (!ioaddr) {
-               BUGMSG(D_NORMAL, "No autoprobe for IO mapped cards; you "
-                      "must specify the base address!\n");
+               arc_printk(D_NORMAL, dev, "No autoprobe for IO mapped cards; you must specify the base address!\n");
                return -ENODEV;
        }
        if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com90io probe")) {
-               BUGMSG(D_INIT_REASONS, "IO request_region %x-%x failed.\n",
-                      ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
+               arc_printk(D_INIT_REASONS, dev, "IO request_region %x-%x failed\n",
+                          ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
                return -ENXIO;
        }
-       if (ASTATUS() == 0xFF) {
-               BUGMSG(D_INIT_REASONS, "IO address %x empty\n", ioaddr);
+       if (arcnet_inb(ioaddr, COM9026_REG_R_STATUS) == 0xFF) {
+               arc_printk(D_INIT_REASONS, dev, "IO address %x empty\n",
+                          ioaddr);
                goto err_out;
        }
-       inb(_RESET);
+       arcnet_inb(ioaddr, COM9026_REG_R_RESET);
        mdelay(RESETtime);
 
-       status = ASTATUS();
+       status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
 
        if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
-               BUGMSG(D_INIT_REASONS, "Status invalid (%Xh).\n", status);
+               arc_printk(D_INIT_REASONS, dev, "Status invalid (%Xh)\n",
+                          status);
                goto err_out;
        }
-       BUGMSG(D_INIT_REASONS, "Status after reset: %X\n", status);
+       arc_printk(D_INIT_REASONS, dev, "Status after reset: %X\n", status);
 
-       ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
+       arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
+                   ioaddr, COM9026_REG_W_COMMAND);
 
-       BUGMSG(D_INIT_REASONS, "Status after reset acknowledged: %X\n", status);
+       arc_printk(D_INIT_REASONS, dev, "Status after reset acknowledged: %X\n",
+                  status);
 
-       status = ASTATUS();
+       status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
 
        if (status & RESETflag) {
-               BUGMSG(D_INIT_REASONS, "Eternal reset (status=%Xh)\n", status);
+               arc_printk(D_INIT_REASONS, dev, "Eternal reset (status=%Xh)\n",
+                          status);
                goto err_out;
        }
-       outb((0x16 | IOMAPflag) & ~ENABLE16flag, _CONFIG);
+       arcnet_outb((0x16 | IOMAPflag) & ~ENABLE16flag,
+                   ioaddr, COM9026_REG_RW_CONFIG);
 
        /* Read first loc'n of memory */
 
-       outb(AUTOINCflag, _ADDR_HI);
-       outb(0, _ADDR_LO);
+       arcnet_outb(AUTOINCflag, ioaddr, COM9026_REG_W_ADDR_HI);
+       arcnet_outb(0, ioaddr,  COM9026_REG_W_ADDR_LO);
 
-       if ((status = inb(_MEMDATA)) != 0xd1) {
-               BUGMSG(D_INIT_REASONS, "Signature byte not found"
-                      " (%Xh instead).\n", status);
+       status = arcnet_inb(ioaddr, COM9026_REG_RW_MEMDATA);
+       if (status != 0xd1) {
+               arc_printk(D_INIT_REASONS, dev, "Signature byte not found (%Xh instead).\n",
+                          status);
                goto err_out;
        }
        if (!dev->irq) {
-               /*
-                * if we do this, we're sure to get an IRQ since the
+               /* if we do this, we're sure to get an IRQ since the
                 * card has just reset and the NORXflag is on until
                 * we tell it to start receiving.
                 */
 
                airqmask = probe_irq_on();
-               outb(NORXflag, _INTMASK);
+               arcnet_outb(NORXflag, ioaddr, COM9026_REG_W_INTMASK);
                udelay(1);
-               outb(0, _INTMASK);
+               arcnet_outb(0, ioaddr, COM9026_REG_W_INTMASK);
                dev->irq = probe_irq_off(airqmask);
 
                if ((int)dev->irq <= 0) {
-                       BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed\n");
+                       arc_printk(D_INIT_REASONS, dev, "Autoprobe IRQ failed\n");
                        goto err_out;
                }
        }
@@ -227,7 +215,6 @@ err_out:
        return -ENODEV;
 }
 
-
 /* Set up the struct net_device associated with this card.  Called after
  * probing succeeds.
  */
@@ -238,12 +225,14 @@ static int __init com90io_found(struct net_device *dev)
        int err;
 
        /* Reserve the irq */
-       if (request_irq(dev->irq, arcnet_interrupt, 0, "arcnet (COM90xx-IO)", dev)) {
-               BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
+       if (request_irq(dev->irq, arcnet_interrupt, 0,
+                       "arcnet (COM90xx-IO)", dev)) {
+               arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", dev->irq);
                return -ENODEV;
        }
        /* Reserve the I/O region */
-       if (!request_region(dev->base_addr, ARCNET_TOTAL_SIZE, "arcnet (COM90xx-IO)")) {
+       if (!request_region(dev->base_addr, ARCNET_TOTAL_SIZE,
+                           "arcnet (COM90xx-IO)")) {
                free_irq(dev->irq, dev);
                return -EBUSY;
        }
@@ -259,7 +248,7 @@ static int __init com90io_found(struct net_device *dev)
        lp->hw.copy_from_card = com90io_copy_from_card;
 
        lp->config = (0x16 | IOMAPflag) & ~ENABLE16flag;
-       SETCONF();
+       arcnet_outb(lp->config, ioaddr, COM9026_REG_RW_CONFIG);
 
        /* get and check the station ID from offset 1 in shmem */
 
@@ -267,21 +256,20 @@ static int __init com90io_found(struct net_device *dev)
 
        err = register_netdev(dev);
        if (err) {
-               outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG);
+               arcnet_outb(arcnet_inb(ioaddr, COM9026_REG_RW_CONFIG) & ~IOMAPflag,
+                           ioaddr, COM9026_REG_RW_CONFIG);
                free_irq(dev->irq, dev);
                release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
                return err;
        }
 
-       BUGMSG(D_NORMAL, "COM90IO: station %02Xh found at %03lXh, IRQ %d.\n",
-              dev->dev_addr[0], dev->base_addr, dev->irq);
+       arc_printk(D_NORMAL, dev, "COM90IO: station %02Xh found at %03lXh, IRQ %d.\n",
+                  dev->dev_addr[0], dev->base_addr, dev->irq);
 
        return 0;
 }
 
-
-/*
- * Do a hardware reset on the card, and set up necessary registers.
+/* Do a hardware reset on the card, and set up necessary registers.
  *
  * This should be called as little as possible, because it disrupts the
  * token on the network (causes a RECON) and requires a significant delay.
@@ -293,67 +281,66 @@ static int com90io_reset(struct net_device *dev, int really_reset)
        struct arcnet_local *lp = netdev_priv(dev);
        short ioaddr = dev->base_addr;
 
-       BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
+       arc_printk(D_INIT, dev, "Resetting %s (status=%02Xh)\n",
+                  dev->name, arcnet_inb(ioaddr, COM9026_REG_R_STATUS));
 
        if (really_reset) {
                /* reset the card */
-               inb(_RESET);
+               arcnet_inb(ioaddr, COM9026_REG_R_RESET);
                mdelay(RESETtime);
        }
        /* Set the thing to IO-mapped, 8-bit  mode */
        lp->config = (0x1C | IOMAPflag) & ~ENABLE16flag;
-       SETCONF();
+       arcnet_outb(lp->config, ioaddr, COM9026_REG_RW_CONFIG);
 
-       ACOMMAND(CFLAGScmd | RESETclear);       /* clear flags & end reset */
-       ACOMMAND(CFLAGScmd | CONFIGclear);
+       arcnet_outb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND);
+                                       /* clear flags & end reset */
+       arcnet_outb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND);
 
        /* verify that the ARCnet signature byte is present */
        if (get_buffer_byte(dev, 0) != TESTvalue) {
-               BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
+               arc_printk(D_NORMAL, dev, "reset failed: TESTvalue not present.\n");
                return 1;
        }
        /* enable extended (512-byte) packets */
-       ACOMMAND(CONFIGcmd | EXTconf);
-
+       arcnet_outb(CONFIGcmd | EXTconf, ioaddr, COM9026_REG_W_COMMAND);
        /* done!  return success. */
        return 0;
 }
 
-
 static void com90io_command(struct net_device *dev, int cmd)
 {
        short ioaddr = dev->base_addr;
 
-       ACOMMAND(cmd);
+       arcnet_outb(cmd, ioaddr, COM9026_REG_W_COMMAND);
 }
 
-
 static int com90io_status(struct net_device *dev)
 {
        short ioaddr = dev->base_addr;
 
-       return ASTATUS();
+       return arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
 }
 
-
 static void com90io_setmask(struct net_device *dev, int mask)
 {
        short ioaddr = dev->base_addr;
 
-       AINTMASK(mask);
+       arcnet_outb(mask, ioaddr, COM9026_REG_W_INTMASK);
 }
 
-static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset,
-                                void *buf, int count)
+static void com90io_copy_to_card(struct net_device *dev, int bufnum,
+                                int offset, void *buf, int count)
 {
-       TIME("put_whole_buffer", count, put_whole_buffer(dev, bufnum * 512 + offset, count, buf));
+       TIME(dev, "put_whole_buffer", count,
+            put_whole_buffer(dev, bufnum * 512 + offset, count, buf));
 }
 
-
-static void com90io_copy_from_card(struct net_device *dev, int bufnum, int offset,
-                                  void *buf, int count)
+static void com90io_copy_from_card(struct net_device *dev, int bufnum,
+                                  int offset, void *buf, int count)
 {
-       TIME("get_whole_buffer", count, get_whole_buffer(dev, bufnum * 512 + offset, count, buf));
+       TIME(dev, "get_whole_buffer", count,
+            get_whole_buffer(dev, bufnum * 512 + offset, count, buf));
 }
 
 static int io;                 /* use the insmod io= irq= shmem= options */
@@ -369,12 +356,13 @@ MODULE_LICENSE("GPL");
 static int __init com90io_setup(char *s)
 {
        int ints[4];
+
        s = get_options(s, 4, ints);
        if (!ints[0])
                return 0;
        switch (ints[0]) {
        default:                /* ERROR */
-               printk("com90io: Too many arguments.\n");
+               pr_err("Too many arguments\n");
        case 2:         /* IRQ */
                irq = ints[2];
        case 1:         /* IO address */
@@ -421,8 +409,11 @@ static void __exit com90io_exit(void)
 
        unregister_netdev(dev);
 
-       /* Set the thing back to MMAP mode, in case the old driver is loaded later */
-       outb((inb(_CONFIG) & ~IOMAPflag), _CONFIG);
+       /* In case the old driver is loaded later,
+        * set the thing back to MMAP mode
+        */
+       arcnet_outb(arcnet_inb(ioaddr, COM9026_REG_RW_CONFIG) & ~IOMAPflag,
+                   ioaddr, COM9026_REG_RW_CONFIG);
 
        free_irq(dev->irq, dev);
        release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
index b80fbe40aa0e2b16b25fec455dd10e43c65ac355..0d9b45ff1bb21bc7878c251c63082a5400a7d93b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - COM90xx chipset (memory-mapped buffers)
- * 
+ *
  * Written 1994-1999 by Avery Pennarun.
  * Written 1999 by Martin Mares <mj@ucw.cz>.
  * Derived from skeleton.c by Donald Becker.
@@ -24,6 +24,9 @@
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
-#include <asm/io.h>
-#include <linux/arcdevice.h>
-
-
-#define VERSION "arcnet: COM90xx chipset support\n"
+#include <linux/io.h>
 
+#include "arcdevice.h"
+#include "com9026.h"
 
 /* Define this to speed up the autoprobe by assuming if only one io port and
  * shmem are left in the list at Stage 5, they must correspond to each
@@ -53,7 +54,6 @@
  */
 #undef FAST_PROBE
 
-
 /* Internal function declarations */
 static int com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *);
 static void com90xx_command(struct net_device *dev, int command);
@@ -62,8 +62,8 @@ static void com90xx_setmask(struct net_device *dev, int mask);
 static int com90xx_reset(struct net_device *dev, int really_reset);
 static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
                                 void *buf, int count);
-static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
-                                  void *buf, int count);
+static void com90xx_copy_from_card(struct net_device *dev, int bufnum,
+                                  int offset, void *buf, int count);
 
 /* Known ARCnet cards */
 
@@ -77,26 +77,7 @@ static int numcards;
 
 /* Amount of I/O memory used by the card */
 #define BUFFER_SIZE (512)
-#define MIRROR_SIZE (BUFFER_SIZE*4)
-
-/* COM 9026 controller chip --> ARCnet register addresses */
-#define _INTMASK (ioaddr+0)    /* writable */
-#define _STATUS  (ioaddr+0)    /* readable */
-#define _COMMAND (ioaddr+1)    /* writable, returns random vals on read (?) */
-#define _CONFIG  (ioaddr+2)    /* Configuration register */
-#define _RESET   (ioaddr+8)    /* software reset (on read) */
-#define _MEMDATA (ioaddr+12)   /* Data port for IO-mapped memory */
-#define _ADDR_HI (ioaddr+15)   /* Control registers for said */
-#define _ADDR_LO (ioaddr+14)
-
-#undef ASTATUS
-#undef ACOMMAND
-#undef AINTMASK
-
-#define ASTATUS()      inb(_STATUS)
-#define ACOMMAND(cmd)  outb((cmd),_COMMAND)
-#define AINTMASK(msk)  outb((msk),_INTMASK)
-
+#define MIRROR_SIZE (BUFFER_SIZE * 4)
 
 static int com90xx_skip_probe __initdata = 0;
 
@@ -116,8 +97,7 @@ static void __init com90xx_probe(void)
 {
        int count, status, ioaddr, numprint, airq, openparen = 0;
        unsigned long airqmask;
-       int ports[(0x3f0 - 0x200) / 16 + 1] =
-       {0};
+       int ports[(0x3f0 - 0x200) / 16 + 1] = { 0 };
        unsigned long *shmems;
        void __iomem **iomem;
        int numports, numshmems, *port;
@@ -127,18 +107,19 @@ static void __init com90xx_probe(void)
        if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
                return;
 
-       shmems = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(unsigned long),
+       shmems = kzalloc(((0x100000 - 0xa0000) / 0x800) * sizeof(unsigned long),
                         GFP_KERNEL);
        if (!shmems)
                return;
-       iomem = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(void __iomem *),
-                        GFP_KERNEL);
+       iomem = kzalloc(((0x100000 - 0xa0000) / 0x800) * sizeof(void __iomem *),
+                       GFP_KERNEL);
        if (!iomem) {
                kfree(shmems);
                return;
        }
 
-       BUGLVL(D_NORMAL) printk(VERSION);
+       if (BUGLVL(D_NORMAL))
+               pr_info("%s\n", "COM90xx chipset support");
 
        /* set up the arrays where we'll store the possible probe addresses */
        numports = numshmems = 0;
@@ -161,38 +142,43 @@ static void __init com90xx_probe(void)
                numprint++;
                numprint %= 8;
                if (!numprint) {
-                       BUGMSG2(D_INIT, "\n");
-                       BUGMSG2(D_INIT, "S1: ");
+                       arc_cont(D_INIT, "\n");
+                       arc_cont(D_INIT, "S1: ");
                }
-               BUGMSG2(D_INIT, "%Xh ", *port);
+               arc_cont(D_INIT, "%Xh ", *port);
 
                ioaddr = *port;
 
-               if (!request_region(*port, ARCNET_TOTAL_SIZE, "arcnet (90xx)")) {
-                       BUGMSG2(D_INIT_REASONS, "(request_region)\n");
-                       BUGMSG2(D_INIT_REASONS, "S1: ");
-                       BUGLVL(D_INIT_REASONS) numprint = 0;
+               if (!request_region(*port, ARCNET_TOTAL_SIZE,
+                                   "arcnet (90xx)")) {
+                       arc_cont(D_INIT_REASONS, "(request_region)\n");
+                       arc_cont(D_INIT_REASONS, "S1: ");
+                       if (BUGLVL(D_INIT_REASONS))
+                               numprint = 0;
                        *port-- = ports[--numports];
                        continue;
                }
-               if (ASTATUS() == 0xFF) {
-                       BUGMSG2(D_INIT_REASONS, "(empty)\n");
-                       BUGMSG2(D_INIT_REASONS, "S1: ");
-                       BUGLVL(D_INIT_REASONS) numprint = 0;
+               if (arcnet_inb(ioaddr, COM9026_REG_R_STATUS) == 0xFF) {
+                       arc_cont(D_INIT_REASONS, "(empty)\n");
+                       arc_cont(D_INIT_REASONS, "S1: ");
+                       if (BUGLVL(D_INIT_REASONS))
+                               numprint = 0;
                        release_region(*port, ARCNET_TOTAL_SIZE);
                        *port-- = ports[--numports];
                        continue;
                }
-               inb(_RESET);    /* begin resetting card */
+               /* begin resetting card */
+               arcnet_inb(ioaddr, COM9026_REG_R_RESET);
 
-               BUGMSG2(D_INIT_REASONS, "\n");
-               BUGMSG2(D_INIT_REASONS, "S1: ");
-               BUGLVL(D_INIT_REASONS) numprint = 0;
+               arc_cont(D_INIT_REASONS, "\n");
+               arc_cont(D_INIT_REASONS, "S1: ");
+               if (BUGLVL(D_INIT_REASONS))
+                       numprint = 0;
        }
-       BUGMSG2(D_INIT, "\n");
+       arc_cont(D_INIT, "\n");
 
        if (!numports) {
-               BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");
+               arc_cont(D_NORMAL, "S1: No ARCnet cards found.\n");
                kfree(shmems);
                kfree(iomem);
                return;
@@ -206,12 +192,12 @@ static void __init com90xx_probe(void)
                numprint++;
                numprint %= 8;
                if (!numprint) {
-                       BUGMSG2(D_INIT, "\n");
-                       BUGMSG2(D_INIT, "S2: ");
+                       arc_cont(D_INIT, "\n");
+                       arc_cont(D_INIT, "S2: ");
                }
-               BUGMSG2(D_INIT, "%Xh ", *port);
+               arc_cont(D_INIT, "%Xh ", *port);
        }
-       BUGMSG2(D_INIT, "\n");
+       arc_cont(D_INIT, "\n");
        mdelay(RESETtime);
 
        /* Stage 3: abandon any shmem addresses that don't have the signature
@@ -224,29 +210,33 @@ static void __init com90xx_probe(void)
                numprint++;
                numprint %= 8;
                if (!numprint) {
-                       BUGMSG2(D_INIT, "\n");
-                       BUGMSG2(D_INIT, "S3: ");
+                       arc_cont(D_INIT, "\n");
+                       arc_cont(D_INIT, "S3: ");
                }
-               BUGMSG2(D_INIT, "%lXh ", *p);
+               arc_cont(D_INIT, "%lXh ", *p);
 
                if (!request_mem_region(*p, MIRROR_SIZE, "arcnet (90xx)")) {
-                       BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n");
-                       BUGMSG2(D_INIT_REASONS, "Stage 3: ");
-                       BUGLVL(D_INIT_REASONS) numprint = 0;
+                       arc_cont(D_INIT_REASONS, "(request_mem_region)\n");
+                       arc_cont(D_INIT_REASONS, "Stage 3: ");
+                       if (BUGLVL(D_INIT_REASONS))
+                               numprint = 0;
                        goto out;
                }
                base = ioremap(*p, MIRROR_SIZE);
                if (!base) {
-                       BUGMSG2(D_INIT_REASONS, "(ioremap)\n");
-                       BUGMSG2(D_INIT_REASONS, "Stage 3: ");
-                       BUGLVL(D_INIT_REASONS) numprint = 0;
+                       arc_cont(D_INIT_REASONS, "(ioremap)\n");
+                       arc_cont(D_INIT_REASONS, "Stage 3: ");
+                       if (BUGLVL(D_INIT_REASONS))
+                               numprint = 0;
                        goto out1;
                }
-               if (readb(base) != TESTvalue) {
-                       BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
-                               readb(base), TESTvalue);
-                       BUGMSG2(D_INIT_REASONS, "S3: ");
-                       BUGLVL(D_INIT_REASONS) numprint = 0;
+               if (arcnet_readb(base, COM9026_REG_R_STATUS) != TESTvalue) {
+                       arc_cont(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
+                                arcnet_readb(base, COM9026_REG_R_STATUS),
+                                TESTvalue);
+                       arc_cont(D_INIT_REASONS, "S3: ");
+                       if (BUGLVL(D_INIT_REASONS))
+                               numprint = 0;
                        goto out2;
                }
                /* By writing 0x42 to the TESTvalue location, we also make
@@ -254,15 +244,16 @@ static void __init com90xx_probe(void)
                 * in another pass through this loop, they will be discarded
                 * because *cptr != TESTvalue.
                 */
-               writeb(0x42, base);
-               if (readb(base) != 0x42) {
-                       BUGMSG2(D_INIT_REASONS, "(read only)\n");
-                       BUGMSG2(D_INIT_REASONS, "S3: ");
+               arcnet_writeb(0x42, base, COM9026_REG_W_INTMASK);
+               if (arcnet_readb(base, COM9026_REG_R_STATUS) != 0x42) {
+                       arc_cont(D_INIT_REASONS, "(read only)\n");
+                       arc_cont(D_INIT_REASONS, "S3: ");
                        goto out2;
                }
-               BUGMSG2(D_INIT_REASONS, "\n");
-               BUGMSG2(D_INIT_REASONS, "S3: ");
-               BUGLVL(D_INIT_REASONS) numprint = 0;
+               arc_cont(D_INIT_REASONS, "\n");
+               arc_cont(D_INIT_REASONS, "S3: ");
+               if (BUGLVL(D_INIT_REASONS))
+                       numprint = 0;
                iomem[index] = base;
                continue;
        out2:
@@ -273,10 +264,10 @@ static void __init com90xx_probe(void)
                *p-- = shmems[--numshmems];
                index--;
        }
-       BUGMSG2(D_INIT, "\n");
+       arc_cont(D_INIT, "\n");
 
        if (!numshmems) {
-               BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");
+               arc_cont(D_NORMAL, "S3: No ARCnet cards found.\n");
                for (port = &ports[0]; port < ports + numports; port++)
                        release_region(*port, ARCNET_TOTAL_SIZE);
                kfree(shmems);
@@ -291,12 +282,12 @@ static void __init com90xx_probe(void)
                numprint++;
                numprint %= 8;
                if (!numprint) {
-                       BUGMSG2(D_INIT, "\n");
-                       BUGMSG2(D_INIT, "S4: ");
+                       arc_cont(D_INIT, "\n");
+                       arc_cont(D_INIT, "S4: ");
                }
-               BUGMSG2(D_INIT, "%lXh ", *p);
+               arc_cont(D_INIT, "%lXh ", *p);
        }
-       BUGMSG2(D_INIT, "\n");
+       arc_cont(D_INIT, "\n");
 
        /* Stage 5: for any ports that have the correct status, can disable
         * the RESET flag, and (if no irq is given) generate an autoirq,
@@ -308,33 +299,37 @@ static void __init com90xx_probe(void)
        numprint = -1;
        for (port = &ports[0]; port < ports + numports; port++) {
                int found = 0;
+
                numprint++;
                numprint %= 8;
                if (!numprint) {
-                       BUGMSG2(D_INIT, "\n");
-                       BUGMSG2(D_INIT, "S5: ");
+                       arc_cont(D_INIT, "\n");
+                       arc_cont(D_INIT, "S5: ");
                }
-               BUGMSG2(D_INIT, "%Xh ", *port);
+               arc_cont(D_INIT, "%Xh ", *port);
 
                ioaddr = *port;
-               status = ASTATUS();
+               status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
 
                if ((status & 0x9D)
                    != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
-                       BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
-                       BUGMSG2(D_INIT_REASONS, "S5: ");
-                       BUGLVL(D_INIT_REASONS) numprint = 0;
+                       arc_cont(D_INIT_REASONS, "(status=%Xh)\n", status);
+                       arc_cont(D_INIT_REASONS, "S5: ");
+                       if (BUGLVL(D_INIT_REASONS))
+                               numprint = 0;
                        release_region(*port, ARCNET_TOTAL_SIZE);
                        *port-- = ports[--numports];
                        continue;
                }
-               ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
-               status = ASTATUS();
+               arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
+                           ioaddr, COM9026_REG_W_COMMAND);
+               status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
                if (status & RESETflag) {
-                       BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
-                               status);
-                       BUGMSG2(D_INIT_REASONS, "S5: ");
-                       BUGLVL(D_INIT_REASONS) numprint = 0;
+                       arc_cont(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
+                                status);
+                       arc_cont(D_INIT_REASONS, "S5: ");
+                       if (BUGLVL(D_INIT_REASONS))
+                               numprint = 0;
                        release_region(*port, ARCNET_TOTAL_SIZE);
                        *port-- = ports[--numports];
                        continue;
@@ -348,15 +343,16 @@ static void __init com90xx_probe(void)
                         * we tell it to start receiving.
                         */
                        airqmask = probe_irq_on();
-                       AINTMASK(NORXflag);
+                       arcnet_outb(NORXflag, ioaddr, COM9026_REG_W_INTMASK);
                        udelay(1);
-                       AINTMASK(0);
+                       arcnet_outb(0, ioaddr, COM9026_REG_W_INTMASK);
                        airq = probe_irq_off(airqmask);
 
                        if (airq <= 0) {
-                               BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
-                               BUGMSG2(D_INIT_REASONS, "S5: ");
-                               BUGLVL(D_INIT_REASONS) numprint = 0;
+                               arc_cont(D_INIT_REASONS, "(airq=%d)\n", airq);
+                               arc_cont(D_INIT_REASONS, "S5: ");
+                               if (BUGLVL(D_INIT_REASONS))
+                                       numprint = 0;
                                release_region(*port, ARCNET_TOTAL_SIZE);
                                *port-- = ports[--numports];
                                continue;
@@ -365,7 +361,7 @@ static void __init com90xx_probe(void)
                        airq = irq;
                }
 
-               BUGMSG2(D_INIT, "(%d,", airq);
+               arc_cont(D_INIT, "(%d,", airq);
                openparen = 1;
 
                /* Everything seems okay.  But which shmem, if any, puts
@@ -376,14 +372,15 @@ static void __init com90xx_probe(void)
                 */
 #ifdef FAST_PROBE
                if (numports > 1 || numshmems > 1) {
-                       inb(_RESET);
+                       arcnet_inb(ioaddr, COM9026_REG_R_RESET);
                        mdelay(RESETtime);
                } else {
                        /* just one shmem and port, assume they match */
-                       writeb(TESTvalue, iomem[0]);
+                       arcnet_writeb(TESTvalue, iomem[0],
+                                     COM9026_REG_W_INTMASK);
                }
 #else
-               inb(_RESET);
+               arcnet_inb(ioaddr, COM9026_REG_R_RESET);
                mdelay(RESETtime);
 #endif
 
@@ -391,8 +388,8 @@ static void __init com90xx_probe(void)
                        u_long ptr = shmems[index];
                        void __iomem *base = iomem[index];
 
-                       if (readb(base) == TESTvalue) { /* found one */
-                               BUGMSG2(D_INIT, "%lXh)\n", *p);
+                       if (arcnet_readb(base, COM9026_REG_R_STATUS) == TESTvalue) {    /* found one */
+                               arc_cont(D_INIT, "%lXh)\n", *p);
                                openparen = 0;
 
                                /* register the card */
@@ -405,25 +402,30 @@ static void __init com90xx_probe(void)
                                iomem[index] = iomem[numshmems];
                                break;  /* go to the next I/O port */
                        } else {
-                               BUGMSG2(D_INIT_REASONS, "%Xh-", readb(base));
+                               arc_cont(D_INIT_REASONS, "%Xh-",
+                                        arcnet_readb(base, COM9026_REG_R_STATUS));
                        }
                }
 
                if (openparen) {
-                       BUGLVL(D_INIT) printk("no matching shmem)\n");
-                       BUGLVL(D_INIT_REASONS) printk("S5: ");
-                       BUGLVL(D_INIT_REASONS) numprint = 0;
+                       if (BUGLVL(D_INIT))
+                               pr_cont("no matching shmem)\n");
+                       if (BUGLVL(D_INIT_REASONS)) {
+                               pr_cont("S5: ");
+                               numprint = 0;
+                       }
                }
                if (!found)
                        release_region(*port, ARCNET_TOTAL_SIZE);
                *port-- = ports[--numports];
        }
 
-       BUGLVL(D_INIT_REASONS) printk("\n");
+       if (BUGLVL(D_INIT_REASONS))
+               pr_cont("\n");
 
        /* Now put back TESTvalue on all leftover shmems. */
        for (index = 0; index < numshmems; index++) {
-               writeb(TESTvalue, iomem[index]);
+               arcnet_writeb(TESTvalue, iomem[index], COM9026_REG_W_INTMASK);
                iounmap(iomem[index]);
                release_mem_region(shmems[index], MIRROR_SIZE);
        }
@@ -441,7 +443,7 @@ static int check_mirror(unsigned long addr, size_t size)
 
        p = ioremap(addr, size);
        if (p) {
-               if (readb(p) == TESTvalue)
+               if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue)
                        res = 1;
                else
                        res = 0;
@@ -455,7 +457,8 @@ static int check_mirror(unsigned long addr, size_t size)
 /* Set up the struct net_device associated with this card.  Called after
  * probing succeeds.
  */
-static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *p)
+static int __init com90xx_found(int ioaddr, int airq, u_long shmem,
+                               void __iomem *p)
 {
        struct net_device *dev = NULL;
        struct arcnet_local *lp;
@@ -465,7 +468,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem
        /* allocate struct net_device */
        dev = alloc_arcdev(device);
        if (!dev) {
-               BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");
+               arc_cont(D_NORMAL, "com90xx: Can't allocate device!\n");
                iounmap(p);
                release_mem_region(shmem, MIRROR_SIZE);
                return -ENOMEM;
@@ -478,7 +481,7 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem
         * 2k (or there are no mirrors at all) but on some, it's 4k.
         */
        mirror_size = MIRROR_SIZE;
-       if (readb(p) == TESTvalue &&
+       if (arcnet_readb(p, COM9026_REG_R_STATUS) == TESTvalue &&
            check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 &&
            check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
                mirror_size = 2 * MIRROR_SIZE;
@@ -499,12 +502,14 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem
        iounmap(p);
        release_mem_region(shmem, MIRROR_SIZE);
 
-       if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"))
+       if (!request_mem_region(dev->mem_start,
+                               dev->mem_end - dev->mem_start + 1,
+                               "arcnet (90xx)"))
                goto err_free_dev;
 
        /* reserve the irq */
        if (request_irq(airq, arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
-               BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
+               arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", airq);
                goto err_release_mem;
        }
        dev->irq = airq;
@@ -518,22 +523,23 @@ static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem
        lp->hw.owner = THIS_MODULE;
        lp->hw.copy_to_card = com90xx_copy_to_card;
        lp->hw.copy_from_card = com90xx_copy_from_card;
-       lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+       lp->mem_start = ioremap(dev->mem_start,
+                               dev->mem_end - dev->mem_start + 1);
        if (!lp->mem_start) {
-               BUGMSG(D_NORMAL, "Can't remap device memory!\n");
+               arc_printk(D_NORMAL, dev, "Can't remap device memory!\n");
                goto err_free_irq;
        }
 
        /* get and check the station ID from offset 1 in shmem */
-       dev->dev_addr[0] = readb(lp->mem_start + 1);
+       dev->dev_addr[0] = arcnet_readb(lp->mem_start, COM9026_REG_R_STATION);
 
        dev->base_addr = ioaddr;
 
-       BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
-              "ShMem %lXh (%ld*%xh).\n",
-              dev->dev_addr[0],
-              dev->base_addr, dev->irq, dev->mem_start,
-        (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
+       arc_printk(D_NORMAL, dev, "COM90xx station %02Xh found at %03lXh, IRQ %d, ShMem %lXh (%ld*%xh).\n",
+                  dev->dev_addr[0],
+                  dev->base_addr, dev->irq, dev->mem_start,
+                  (dev->mem_end - dev->mem_start + 1) / mirror_size,
+                  mirror_size);
 
        if (register_netdev(dev))
                goto err_unmap;
@@ -552,34 +558,29 @@ err_free_dev:
        return -EIO;
 }
 
-
 static void com90xx_command(struct net_device *dev, int cmd)
 {
        short ioaddr = dev->base_addr;
 
-       ACOMMAND(cmd);
+       arcnet_outb(cmd, ioaddr, COM9026_REG_W_COMMAND);
 }
 
-
 static int com90xx_status(struct net_device *dev)
 {
        short ioaddr = dev->base_addr;
 
-       return ASTATUS();
+       return arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
 }
 
-
 static void com90xx_setmask(struct net_device *dev, int mask)
 {
        short ioaddr = dev->base_addr;
 
-       AINTMASK(mask);
+       arcnet_outb(mask, ioaddr, COM9026_REG_W_INTMASK);
 }
 
-
-/*
- * Do a hardware reset on the card, and set up necessary registers.
- * 
+/* Do a hardware reset on the card, and set up necessary registers.
+ *
  * This should be called as little as possible, because it disrupts the
  * token on the network (causes a RECON) and requires a significant delay.
  *
@@ -590,53 +591,58 @@ static int com90xx_reset(struct net_device *dev, int really_reset)
        struct arcnet_local *lp = netdev_priv(dev);
        short ioaddr = dev->base_addr;
 
-       BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());
+       arc_printk(D_INIT, dev, "Resetting (status=%02Xh)\n",
+                  arcnet_inb(ioaddr, COM9026_REG_R_STATUS));
 
        if (really_reset) {
                /* reset the card */
-               inb(_RESET);
+               arcnet_inb(ioaddr, COM9026_REG_R_RESET);
                mdelay(RESETtime);
        }
-       ACOMMAND(CFLAGScmd | RESETclear);       /* clear flags & end reset */
-       ACOMMAND(CFLAGScmd | CONFIGclear);
+       /* clear flags & end reset */
+       arcnet_outb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND);
+       arcnet_outb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND);
 
+#if 0
        /* don't do this until we verify that it doesn't hurt older cards! */
-       /* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */
+       arcnet_outb(arcnet_inb(ioaddr, COM9026_REG_RW_CONFIG) | ENABLE16flag,
+                   ioaddr, COM9026_REG_RW_CONFIG);
+#endif
 
        /* verify that the ARCnet signature byte is present */
-       if (readb(lp->mem_start) != TESTvalue) {
+       if (arcnet_readb(lp->mem_start, COM9026_REG_R_STATUS) != TESTvalue) {
                if (really_reset)
-                       BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
+                       arc_printk(D_NORMAL, dev, "reset failed: TESTvalue not present.\n");
                return 1;
        }
        /* enable extended (512-byte) packets */
-       ACOMMAND(CONFIGcmd | EXTconf);
+       arcnet_outb(CONFIGcmd | EXTconf, ioaddr, COM9026_REG_W_COMMAND);
 
        /* clean out all the memory to make debugging make more sense :) */
-       BUGLVL(D_DURING)
-           memset_io(lp->mem_start, 0x42, 2048);
+       if (BUGLVL(D_DURING))
+               memset_io(lp->mem_start, 0x42, 2048);
 
        /* done!  return success. */
        return 0;
 }
 
-static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
-                                void *buf, int count)
+static void com90xx_copy_to_card(struct net_device *dev, int bufnum,
+                                int offset, void *buf, int count)
 {
        struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
-       TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
-}
 
+       TIME(dev, "memcpy_toio", count, memcpy_toio(memaddr, buf, count));
+}
 
-static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
-                                  void *buf, int count)
+static void com90xx_copy_from_card(struct net_device *dev, int bufnum,
+                                  int offset, void *buf, int count)
 {
        struct arcnet_local *lp = netdev_priv(dev);
        void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
-       TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
-}
 
+       TIME(dev, "memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
+}
 
 MODULE_LICENSE("GPL");
 
@@ -664,7 +670,8 @@ static void __exit com90xx_exit(void)
                free_irq(dev->irq, dev);
                iounmap(lp->mem_start);
                release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
-               release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
+               release_mem_region(dev->mem_start,
+                                  dev->mem_end - dev->mem_start + 1);
                free_netdev(dev);
        }
 }
@@ -679,13 +686,13 @@ static int __init com90xx_setup(char *s)
 
        s = get_options(s, 8, ints);
        if (!ints[0] && !*s) {
-               printk("com90xx: Disabled.\n");
+               pr_notice("Disabled\n");
                return 1;
        }
 
        switch (ints[0]) {
        default:                /* ERROR */
-               printk("com90xx: Too many arguments.\n");
+               pr_err("Too many arguments\n");
        case 3:         /* Mem address */
                shmem = ints[3];
        case 2:         /* IRQ */
index f81db4070a574500172fa4dd5521859cc6e063e3..4b1a75469cb10962f18f5958d94cb51fb51e18c9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - RFC1051 ("simple" standard) packet encapsulation
- * 
+ *
  * Written 1994-1999 by Avery Pennarun.
  * Derived from skeleton.c by Donald Becker.
  *
@@ -23,6 +23,9 @@
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/gfp.h>
 #include <linux/init.h>
 #include <net/arp.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/arcdevice.h>
-
-#define VERSION "arcnet: RFC1051 \"simple standard\" (`s') encapsulation support loaded.\n"
 
+#include "arcdevice.h"
 
 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev);
 static void rx(struct net_device *dev, int bufnum,
@@ -43,9 +44,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum);
 
-
-static struct ArcProto rfc1051_proto =
-{
+static struct ArcProto rfc1051_proto = {
        .suffix         = 's',
        .mtu            = XMTU - RFC1051_HDR_SIZE,
        .is_ip          = 1,
@@ -56,10 +55,9 @@ static struct ArcProto rfc1051_proto =
        .ack_tx         = NULL
 };
 
-
 static int __init arcnet_rfc1051_init(void)
 {
-       printk(VERSION);
+       pr_info("%s\n", "RFC1051 \"simple standard\" (`s') encapsulation support loaded");
 
        arc_proto_map[ARC_P_IP_RFC1051]
            = arc_proto_map[ARC_P_ARP_RFC1051]
@@ -82,14 +80,13 @@ module_exit(arcnet_rfc1051_exit);
 
 MODULE_LICENSE("GPL");
 
-/*
- * Determine a packet's protocol ID.
- * 
+/* Determine a packet's protocol ID.
+ *
  * With ARCnet we have to convert everything to Ethernet-style stuff.
  */
 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
 {
-       struct archdr *pkt = (struct archdr *) skb->data;
+       struct archdr *pkt = (struct archdr *)skb->data;
        struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
        int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
 
@@ -97,9 +94,9 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
        skb_reset_mac_header(skb);
        skb_pull(skb, hdr_size);
 
-       if (pkt->hard.dest == 0)
+       if (pkt->hard.dest == 0) {
                skb->pkt_type = PACKET_BROADCAST;
-       else if (dev->flags & IFF_PROMISC) {
+       else if (dev->flags & IFF_PROMISC) {
                /* if we're not sending to ourselves :) */
                if (pkt->hard.dest != dev->dev_addr[0])
                        skb->pkt_type = PACKET_OTHERHOST;
@@ -120,7 +117,6 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
        return htons(ETH_P_IP);
 }
 
-
 /* packet receiver */
 static void rx(struct net_device *dev, int bufnum,
               struct archdr *pkthdr, int length)
@@ -130,7 +126,7 @@ static void rx(struct net_device *dev, int bufnum,
        struct archdr *pkt = pkthdr;
        int ofs;
 
-       BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);
+       arc_printk(D_DURING, dev, "it's a raw packet (length=%d)\n", length);
 
        if (length >= MinTU)
                ofs = 512 - length;
@@ -138,15 +134,14 @@ static void rx(struct net_device *dev, int bufnum,
                ofs = 256 - length;
 
        skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
-       if (skb == NULL) {
-               BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
+       if (!skb) {
                dev->stats.rx_dropped++;
                return;
        }
        skb_put(skb, length + ARC_HDR_SIZE);
        skb->dev = dev;
 
-       pkt = (struct archdr *) skb->data;
+       pkt = (struct archdr *)skb->data;
 
        /* up to sizeof(pkt->soft) has already been copied from the card */
        memcpy(pkt, pkthdr, sizeof(struct archdr));
@@ -155,21 +150,19 @@ static void rx(struct net_device *dev, int bufnum,
                                      pkt->soft.raw + sizeof(pkt->soft),
                                      length - sizeof(pkt->soft));
 
-       BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
+       if (BUGLVL(D_SKB))
+               arcnet_dump_skb(dev, skb, "rx");
 
        skb->protocol = type_trans(skb, dev);
        netif_rx(skb);
 }
 
-
-/*
- * Create the ARCnet hard/soft headers for RFC1051.
- */
+/* Create the ARCnet hard/soft headers for RFC1051 */
 static int build_header(struct sk_buff *skb, struct net_device *dev,
                        unsigned short type, uint8_t daddr)
 {
        int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
-       struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
+       struct archdr *pkt = (struct archdr *)skb_push(skb, hdr_size);
        struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
 
        /* set the protocol ID according to RFC1051 */
@@ -181,29 +174,26 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
                soft->proto = ARC_P_ARP_RFC1051;
                break;
        default:
-               BUGMSG(D_NORMAL, "RFC1051: I don't understand protocol %d (%Xh)\n",
-                      type, type);
+               arc_printk(D_NORMAL, dev, "RFC1051: I don't understand protocol %d (%Xh)\n",
+                          type, type);
                dev->stats.tx_errors++;
                dev->stats.tx_aborted_errors++;
                return 0;
        }
 
-
-       /*
-        * Set the source hardware address.
+       /* Set the source hardware address.
         *
         * This is pretty pointless for most purposes, but it can help in
-        * debugging.  ARCnet does not allow us to change the source address in
-        * the actual packet sent)
+        * debugging.  ARCnet does not allow us to change the source address
+        * in the actual packet sent.
         */
        pkt->hard.source = *dev->dev_addr;
 
        /* see linux/net/ethernet/eth.c to see where I got the following */
 
        if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
-               /* 
-                * FIXME: fill in the last byte of the dest ipaddr here to better
-                * comply with RFC1051 in "noarp" mode.
+               /* FIXME: fill in the last byte of the dest ipaddr here to
+                * better comply with RFC1051 in "noarp" mode.
                 */
                pkt->hard.dest = 0;
                return hdr_size;
@@ -214,7 +204,6 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
        return hdr_size;        /* success */
 }
 
-
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum)
 {
@@ -222,15 +211,16 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
        struct arc_hardware *hard = &pkt->hard;
        int ofs;
 
-       BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
-              lp->next_tx, lp->cur_tx, bufnum);
+       arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
+                  lp->next_tx, lp->cur_tx, bufnum);
 
-       length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
+       /* hard header is not included in packet length */
+       length -= ARC_HDR_SIZE;
 
        if (length > XMTU) {
                /* should never happen! other people already check for this. */
-               BUGMSG(D_NORMAL, "Bug!  prepare_tx with size %d (> %d)\n",
-                      length, XMTU);
+               arc_printk(D_NORMAL, dev, "Bug!  prepare_tx with size %d (> %d)\n",
+                          length, XMTU);
                length = XMTU;
        }
        if (length > MinTU) {
@@ -239,8 +229,9 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
        } else if (length > MTU) {
                hard->offset[0] = 0;
                hard->offset[1] = ofs = 512 - length - 3;
-       } else
+       } else {
                hard->offset[0] = ofs = 256 - length;
+       }
 
        lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
        lp->hw.copy_to_card(dev, bufnum, ofs, &pkt->soft, length);
index b71431aae0846ee8cb69101974f341246265fe59..566da5ecdc9d6b6c26b0242543f52b1bc7be8766 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Linux ARCnet driver - RFC1201 (standard) packet encapsulation
- * 
+ *
  * Written 1994-1999 by Avery Pennarun.
  * Derived from skeleton.c by Donald Becker.
  *
  *
  * **********************
  */
+
+#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
+
 #include <linux/gfp.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-#include <linux/arcdevice.h>
 
-MODULE_LICENSE("GPL");
-#define VERSION "arcnet: RFC1201 \"standard\" (`a') encapsulation support loaded.\n"
+#include "arcdevice.h"
 
+MODULE_LICENSE("GPL");
 
 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev);
 static void rx(struct net_device *dev, int bufnum,
@@ -44,8 +46,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum);
 static int continue_tx(struct net_device *dev, int bufnum);
 
-static struct ArcProto rfc1201_proto =
-{
+static struct ArcProto rfc1201_proto = {
        .suffix         = 'a',
        .mtu            = 1500, /* could be more, but some receivers can't handle it... */
        .is_ip          = 1,    /* This is for sending IP and ARP packages */
@@ -56,10 +57,9 @@ static struct ArcProto rfc1201_proto =
        .ack_tx         = NULL
 };
 
-
 static int __init arcnet_rfc1201_init(void)
 {
-       printk(VERSION);
+       pr_info("%s\n", "RFC1201 \"standard\" (`a') encapsulation support loaded");
 
        arc_proto_map[ARC_P_IP]
            = arc_proto_map[ARC_P_IPV6]
@@ -84,14 +84,13 @@ static void __exit arcnet_rfc1201_exit(void)
 module_init(arcnet_rfc1201_init);
 module_exit(arcnet_rfc1201_exit);
 
-/*
- * Determine a packet's protocol ID.
- * 
+/* Determine a packet's protocol ID.
+ *
  * With ARCnet we have to convert everything to Ethernet-style stuff.
  */
 static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
 {
-       struct archdr *pkt = (struct archdr *) skb->data;
+       struct archdr *pkt = (struct archdr *)skb->data;
        struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
        int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
 
@@ -99,9 +98,9 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
        skb_reset_mac_header(skb);
        skb_pull(skb, hdr_size);
 
-       if (pkt->hard.dest == 0)
+       if (pkt->hard.dest == 0) {
                skb->pkt_type = PACKET_BROADCAST;
-       else if (dev->flags & IFF_PROMISC) {
+       else if (dev->flags & IFF_PROMISC) {
                /* if we're not sending to ourselves :) */
                if (pkt->hard.dest != dev->dev_addr[0])
                        skb->pkt_type = PACKET_OTHERHOST;
@@ -129,7 +128,6 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
        return htons(ETH_P_IP);
 }
 
-
 /* packet receiver */
 static void rx(struct net_device *dev, int bufnum,
               struct archdr *pkthdr, int length)
@@ -141,7 +139,8 @@ static void rx(struct net_device *dev, int bufnum,
        int saddr = pkt->hard.source, ofs;
        struct Incoming *in = &lp->rfc1201.incoming[saddr];
 
-       BUGMSG(D_DURING, "it's an RFC1201 packet (length=%d)\n", length);
+       arc_printk(D_DURING, dev, "it's an RFC1201 packet (length=%d)\n",
+                  length);
 
        if (length >= MinTU)
                ofs = 512 - length;
@@ -149,11 +148,11 @@ static void rx(struct net_device *dev, int bufnum,
                ofs = 256 - length;
 
        if (soft->split_flag == 0xFF) {         /* Exception Packet */
-               if (length >= 4 + RFC1201_HDR_SIZE)
-                       BUGMSG(D_DURING, "compensating for exception packet\n");
-               else {
-                       BUGMSG(D_EXTRA, "short RFC1201 exception packet from %02Xh",
-                              saddr);
+               if (length >= 4 + RFC1201_HDR_SIZE) {
+                       arc_printk(D_DURING, dev, "compensating for exception packet\n");
+               else {
+                       arc_printk(D_EXTRA, dev, "short RFC1201 exception packet from %02Xh",
+                                  saddr);
                        return;
                }
 
@@ -164,12 +163,13 @@ static void rx(struct net_device *dev, int bufnum,
                                      soft, sizeof(pkt->soft));
        }
        if (!soft->split_flag) {        /* not split */
-               BUGMSG(D_RX, "incoming is not split (splitflag=%d)\n",
-                      soft->split_flag);
+               arc_printk(D_RX, dev, "incoming is not split (splitflag=%d)\n",
+                          soft->split_flag);
 
                if (in->skb) {  /* already assembling one! */
-                       BUGMSG(D_EXTRA, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
-                        in->sequence, soft->split_flag, soft->sequence);
+                       arc_printk(D_EXTRA, dev, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n",
+                                  in->sequence, soft->split_flag,
+                                  soft->sequence);
                        lp->rfc1201.aborted_seq = soft->sequence;
                        dev_kfree_skb_irq(in->skb);
                        dev->stats.rx_errors++;
@@ -179,82 +179,86 @@ static void rx(struct net_device *dev, int bufnum,
                in->sequence = soft->sequence;
 
                skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
-               if (skb == NULL) {
-                       BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
+               if (!skb) {
                        dev->stats.rx_dropped++;
                        return;
                }
                skb_put(skb, length + ARC_HDR_SIZE);
                skb->dev = dev;
 
-               pkt = (struct archdr *) skb->data;
+               pkt = (struct archdr *)skb->data;
                soft = &pkt->soft.rfc1201;
 
-               /* up to sizeof(pkt->soft) has already been copied from the card */
+               /* up to sizeof(pkt->soft) has already
+                * been copied from the card
+                */
                memcpy(pkt, pkthdr, sizeof(struct archdr));
                if (length > sizeof(pkt->soft))
-                       lp->hw.copy_from_card(dev, bufnum, ofs + sizeof(pkt->soft),
-                                      pkt->soft.raw + sizeof(pkt->soft),
+                       lp->hw.copy_from_card(dev, bufnum,
+                                             ofs + sizeof(pkt->soft),
+                                             pkt->soft.raw + sizeof(pkt->soft),
                                              length - sizeof(pkt->soft));
 
-               /*
-                * ARP packets have problems when sent from some DOS systems: the
-                * source address is always 0!  So we take the hardware source addr
-                * (which is impossible to fumble) and insert it ourselves.
+               /* ARP packets have problems when sent from some DOS systems:
+                * the source address is always 0!
+                * So we take the hardware source addr (which is impossible
+                * to fumble) and insert it ourselves.
                 */
                if (soft->proto == ARC_P_ARP) {
-                       struct arphdr *arp = (struct arphdr *) soft->payload;
+                       struct arphdr *arp = (struct arphdr *)soft->payload;
 
                        /* make sure addresses are the right length */
                        if (arp->ar_hln == 1 && arp->ar_pln == 4) {
-                               uint8_t *cptr = (uint8_t *) arp + sizeof(struct arphdr);
+                               uint8_t *cptr = (uint8_t *)arp + sizeof(struct arphdr);
 
                                if (!*cptr) {   /* is saddr = 00? */
-                                       BUGMSG(D_EXTRA,
-                                              "ARP source address was 00h, set to %02Xh.\n",
-                                              saddr);
+                                       arc_printk(D_EXTRA, dev,
+                                                  "ARP source address was 00h, set to %02Xh\n",
+                                                  saddr);
                                        dev->stats.rx_crc_errors++;
                                        *cptr = saddr;
                                } else {
-                                       BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",
-                                              *cptr);
+                                       arc_printk(D_DURING, dev, "ARP source address (%Xh) is fine.\n",
+                                                  *cptr);
                                }
                        } else {
-                               BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",
-                                      arp->ar_hln, arp->ar_pln);
+                               arc_printk(D_NORMAL, dev, "funny-shaped ARP packet. (%Xh, %Xh)\n",
+                                          arp->ar_hln, arp->ar_pln);
                                dev->stats.rx_errors++;
                                dev->stats.rx_crc_errors++;
                        }
                }
-               BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
+               if (BUGLVL(D_SKB))
+                       arcnet_dump_skb(dev, skb, "rx");
 
                skb->protocol = type_trans(skb, dev);
                netif_rx(skb);
        } else {                /* split packet */
-               /*
-                * NOTE: MSDOS ARP packet correction should only need to apply to
-                * unsplit packets, since ARP packets are so short.
+               /* NOTE: MSDOS ARP packet correction should only need to
+                * apply to unsplit packets, since ARP packets are so short.
                 *
-                * My interpretation of the RFC1201 document is that if a packet is
-                * received out of order, the entire assembly process should be
-                * aborted.
+                * My interpretation of the RFC1201 document is that if a
+                * packet is received out of order, the entire assembly
+                * process should be aborted.
                 *
-                * The RFC also mentions "it is possible for successfully received
-                * packets to be retransmitted." As of 0.40 all previously received
-                * packets are allowed, not just the most recent one.
+                * The RFC also mentions "it is possible for successfully
+                * received packets to be retransmitted." As of 0.40 all
+                * previously received packets are allowed, not just the
+                * most recent one.
                 *
-                * We allow multiple assembly processes, one for each ARCnet card
-                * possible on the network.  Seems rather like a waste of memory,
-                * but there's no other way to be reliable.
+                * We allow multiple assembly processes, one for each
+                * ARCnet card possible on the network.
+                * Seems rather like a waste of memory, but there's no
+                * other way to be reliable.
                 */
 
-               BUGMSG(D_RX, "packet is split (splitflag=%d, seq=%d)\n",
-                      soft->split_flag, in->sequence);
+               arc_printk(D_RX, dev, "packet is split (splitflag=%d, seq=%d)\n",
+                          soft->split_flag, in->sequence);
 
                if (in->skb && in->sequence != soft->sequence) {
-                       BUGMSG(D_EXTRA, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
-                              saddr, in->sequence, soft->sequence,
-                              soft->split_flag);
+                       arc_printk(D_EXTRA, dev, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n",
+                                  saddr, in->sequence, soft->sequence,
+                                  soft->split_flag);
                        dev_kfree_skb_irq(in->skb);
                        in->skb = NULL;
                        dev->stats.rx_errors++;
@@ -262,24 +266,23 @@ static void rx(struct net_device *dev, int bufnum,
                        in->lastpacket = in->numpackets = 0;
                }
                if (soft->split_flag & 1) {     /* first packet in split */
-                       BUGMSG(D_RX, "brand new splitpacket (splitflag=%d)\n",
-                              soft->split_flag);
+                       arc_printk(D_RX, dev, "brand new splitpacket (splitflag=%d)\n",
+                                  soft->split_flag);
                        if (in->skb) {  /* already assembling one! */
-                               BUGMSG(D_EXTRA, "aborting previous (seq=%d) assembly "
-                                      "(splitflag=%d, seq=%d)\n",
-                                      in->sequence, soft->split_flag,
-                                      soft->sequence);
+                               arc_printk(D_EXTRA, dev, "aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n",
+                                          in->sequence, soft->split_flag,
+                                          soft->sequence);
                                dev->stats.rx_errors++;
                                dev->stats.rx_missed_errors++;
                                dev_kfree_skb_irq(in->skb);
                        }
                        in->sequence = soft->sequence;
-                       in->numpackets = ((unsigned) soft->split_flag >> 1) + 2;
+                       in->numpackets = ((unsigned)soft->split_flag >> 1) + 2;
                        in->lastpacket = 1;
 
                        if (in->numpackets > 16) {
-                               BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
-                                      soft->split_flag);
+                               arc_printk(D_EXTRA, dev, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
+                                          soft->split_flag);
                                lp->rfc1201.aborted_seq = soft->sequence;
                                dev->stats.rx_errors++;
                                dev->stats.rx_length_errors++;
@@ -287,14 +290,14 @@ static void rx(struct net_device *dev, int bufnum,
                        }
                        in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
                                                  GFP_ATOMIC);
-                       if (skb == NULL) {
-                               BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
+                       if (!skb) {
+                               arc_printk(D_NORMAL, dev, "(split) memory squeeze, dropping packet.\n");
                                lp->rfc1201.aborted_seq = soft->sequence;
                                dev->stats.rx_dropped++;
                                return;
                        }
                        skb->dev = dev;
-                       pkt = (struct archdr *) skb->data;
+                       pkt = (struct archdr *)skb->data;
                        soft = &pkt->soft.rfc1201;
 
                        memcpy(pkt, pkthdr, ARC_HDR_SIZE + RFC1201_HDR_SIZE);
@@ -302,37 +305,37 @@ static void rx(struct net_device *dev, int bufnum,
 
                        soft->split_flag = 0;   /* end result won't be split */
                } else {        /* not first packet */
-                       int packetnum = ((unsigned) soft->split_flag >> 1) + 1;
+                       int packetnum = ((unsigned)soft->split_flag >> 1) + 1;
 
-                       /*
-                        * if we're not assembling, there's no point trying to
+                       /* if we're not assembling, there's no point trying to
                         * continue.
                         */
                        if (!in->skb) {
                                if (lp->rfc1201.aborted_seq != soft->sequence) {
-                                       BUGMSG(D_EXTRA, "can't continue split without starting "
-                                              "first! (splitflag=%d, seq=%d, aborted=%d)\n",
-                                       soft->split_flag, soft->sequence,
-                                              lp->rfc1201.aborted_seq);
+                                       arc_printk(D_EXTRA, dev, "can't continue split without starting first! (splitflag=%d, seq=%d, aborted=%d)\n",
+                                                  soft->split_flag,
+                                                  soft->sequence,
+                                                  lp->rfc1201.aborted_seq);
                                        dev->stats.rx_errors++;
                                        dev->stats.rx_missed_errors++;
                                }
                                return;
                        }
                        in->lastpacket++;
-                       if (packetnum != in->lastpacket) {      /* not the right flag! */
+                       /* if not the right flag */
+                       if (packetnum != in->lastpacket) {
                                /* harmless duplicate? ignore. */
                                if (packetnum <= in->lastpacket - 1) {
-                                       BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n",
-                                              soft->split_flag);
+                                       arc_printk(D_EXTRA, dev, "duplicate splitpacket ignored! (splitflag=%d)\n",
+                                                  soft->split_flag);
                                        dev->stats.rx_errors++;
                                        dev->stats.rx_frame_errors++;
                                        return;
                                }
                                /* "bad" duplicate, kill reassembly */
-                               BUGMSG(D_EXTRA, "out-of-order splitpacket, reassembly "
-                                      "(seq=%d) aborted (splitflag=%d, seq=%d)\n",
-                                      in->sequence, soft->split_flag, soft->sequence);
+                               arc_printk(D_EXTRA, dev, "out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n",
+                                          in->sequence, soft->split_flag,
+                                          soft->sequence);
                                lp->rfc1201.aborted_seq = soft->sequence;
                                dev_kfree_skb_irq(in->skb);
                                in->skb = NULL;
@@ -341,7 +344,7 @@ static void rx(struct net_device *dev, int bufnum,
                                in->lastpacket = in->numpackets = 0;
                                return;
                        }
-                       pkt = (struct archdr *) in->skb->data;
+                       pkt = (struct archdr *)in->skb->data;
                        soft = &pkt->soft.rfc1201;
                }
 
@@ -357,11 +360,12 @@ static void rx(struct net_device *dev, int bufnum,
                        in->skb = NULL;
                        in->lastpacket = in->numpackets = 0;
 
-           BUGMSG(D_SKB_SIZE, "skb: received %d bytes from %02X (unsplit)\n",
-               skb->len, pkt->hard.source);
-           BUGMSG(D_SKB_SIZE, "skb: received %d bytes from %02X (split)\n",
-               skb->len, pkt->hard.source);
-                       BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
+                       arc_printk(D_SKB_SIZE, dev, "skb: received %d bytes from %02X (unsplit)\n",
+                                  skb->len, pkt->hard.source);
+                       arc_printk(D_SKB_SIZE, dev, "skb: received %d bytes from %02X (split)\n",
+                                  skb->len, pkt->hard.source);
+                       if (BUGLVL(D_SKB))
+                               arcnet_dump_skb(dev, skb, "rx");
 
                        skb->protocol = type_trans(skb, dev);
                        netif_rx(skb);
@@ -369,14 +373,13 @@ static void rx(struct net_device *dev, int bufnum,
        }
 }
 
-
 /* Create the ARCnet hard/soft headers for RFC1201. */
 static int build_header(struct sk_buff *skb, struct net_device *dev,
                        unsigned short type, uint8_t daddr)
 {
        struct arcnet_local *lp = netdev_priv(dev);
        int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
-       struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
+       struct archdr *pkt = (struct archdr *)skb_push(skb, hdr_size);
        struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
 
        /* set the protocol ID according to RFC1201 */
@@ -402,19 +405,18 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
                soft->proto = ARC_P_ATALK;
                break;
        default:
-               BUGMSG(D_NORMAL, "RFC1201: I don't understand protocol %d (%Xh)\n",
-                      type, type);
+               arc_printk(D_NORMAL, dev, "RFC1201: I don't understand protocol %d (%Xh)\n",
+                          type, type);
                dev->stats.tx_errors++;
                dev->stats.tx_aborted_errors++;
                return 0;
        }
 
-       /*
-        * Set the source hardware address.
+       /* Set the source hardware address.
         *
         * This is pretty pointless for most purposes, but it can help in
-        * debugging.  ARCnet does not allow us to change the source address in
-        * the actual packet sent)
+        * debugging.  ARCnet does not allow us to change the source address
+        * in the actual packet sent.
         */
        pkt->hard.source = *dev->dev_addr;
 
@@ -424,10 +426,10 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
        /* see linux/net/ethernet/eth.c to see where I got the following */
 
        if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
-               /* 
-                * FIXME: fill in the last byte of the dest ipaddr here to better
-                * comply with RFC1051 in "noarp" mode.  For now, always broadcasting
-                * will probably at least get packets sent out :)
+               /* FIXME: fill in the last byte of the dest ipaddr here
+                * to better comply with RFC1051 in "noarp" mode.
+                * For now, always broadcasting will probably at least get
+                * packets sent out :)
                 */
                pkt->hard.dest = 0;
                return hdr_size;
@@ -437,7 +439,6 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
        return hdr_size;
 }
 
-
 static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
                     struct arc_rfc1201 *soft, int softlen, int bufnum)
 {
@@ -461,8 +462,9 @@ static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
                hard->offset[1] = ofs - RFC1201_HDR_SIZE;
                lp->hw.copy_to_card(dev, bufnum, ofs - RFC1201_HDR_SIZE,
                                    &excsoft, RFC1201_HDR_SIZE);
-       } else
+       } else {
                hard->offset[0] = ofs = 256 - softlen;
+       }
 
        lp->hw.copy_to_card(dev, bufnum, 0, hard, ARC_HDR_SIZE);
        lp->hw.copy_to_card(dev, bufnum, ofs, soft, softlen);
@@ -470,7 +472,6 @@ static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
        lp->lastload_dest = hard->dest;
 }
 
-
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                      int bufnum)
 {
@@ -478,11 +479,11 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
        const int maxsegsize = XMTU - RFC1201_HDR_SIZE;
        struct Outgoing *out;
 
+       arc_printk(D_DURING, dev, "prepare_tx: txbufs=%d/%d/%d\n",
+                  lp->next_tx, lp->cur_tx, bufnum);
 
-       BUGMSG(D_DURING, "prepare_tx: txbufs=%d/%d/%d\n",
-              lp->next_tx, lp->cur_tx, bufnum);
-
-       length -= ARC_HDR_SIZE; /* hard header is not included in packet length */
+       /* hard header is not included in packet length */
+       length -= ARC_HDR_SIZE;
        pkt->soft.rfc1201.split_flag = 0;
 
        /* need to do a split packet? */
@@ -494,9 +495,9 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
                out->numsegs = (out->dataleft + maxsegsize - 1) / maxsegsize;
                out->segnum = 0;
 
-               BUGMSG(D_DURING, "rfc1201 prep_tx: ready for %d-segment split "
-                      "(%d bytes, seq=%d)\n", out->numsegs, out->length,
-                      pkt->soft.rfc1201.sequence);
+               arc_printk(D_DURING, dev, "rfc1201 prep_tx: ready for %d-segment split (%d bytes, seq=%d)\n",
+                          out->numsegs, out->length,
+                          pkt->soft.rfc1201.sequence);
 
                return 0;       /* not done */
        }
@@ -506,7 +507,6 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
        return 1;               /* done */
 }
 
-
 static int continue_tx(struct net_device *dev, int bufnum)
 {
        struct arcnet_local *lp = netdev_priv(dev);
@@ -516,9 +516,9 @@ static int continue_tx(struct net_device *dev, int bufnum)
        int maxsegsize = XMTU - RFC1201_HDR_SIZE;
        int seglen;
 
-       BUGMSG(D_DURING,
-         "rfc1201 continue_tx: loading segment %d(+1) of %d (seq=%d)\n",
-              out->segnum, out->numsegs, soft->sequence);
+       arc_printk(D_DURING, dev,
+                  "rfc1201 continue_tx: loading segment %d(+1) of %d (seq=%d)\n",
+                  out->segnum, out->numsegs, soft->sequence);
 
        /* the "new" soft header comes right before the data chunk */
        newsoft = (struct arc_rfc1201 *)
index a2c96fd883938b6d15aa1335e4169b290f6bf241..ff665493ca976bb7662b7f49601671b875e200ae 100644 (file)
@@ -201,6 +201,7 @@ struct ethoc {
        void __iomem *membase;
        int dma_alloc;
        resource_size_t io_region_size;
+       bool big_endian;
 
        unsigned int num_bd;
        unsigned int num_tx;
@@ -236,12 +237,18 @@ struct ethoc_bd {
 
 static inline u32 ethoc_read(struct ethoc *dev, loff_t offset)
 {
-       return ioread32(dev->iobase + offset);
+       if (dev->big_endian)
+               return ioread32be(dev->iobase + offset);
+       else
+               return ioread32(dev->iobase + offset);
 }
 
 static inline void ethoc_write(struct ethoc *dev, loff_t offset, u32 data)
 {
-       iowrite32(data, dev->iobase + offset);
+       if (dev->big_endian)
+               iowrite32be(data, dev->iobase + offset);
+       else
+               iowrite32(data, dev->iobase + offset);
 }
 
 static inline void ethoc_read_bd(struct ethoc *dev, int index,
@@ -1106,6 +1113,9 @@ static int ethoc_probe(struct platform_device *pdev)
                priv->dma_alloc = buffer_size;
        }
 
+       priv->big_endian = pdata ? pdata->big_endian :
+               of_device_is_big_endian(pdev->dev.of_node);
+
        /* calculate the number of TX/RX buffers, maximum 128 supported */
        num_bd = min_t(unsigned int,
                128, (netdev->mem_end - netdev->mem_start + 1) / ETHOC_BUFSIZ);
index 45c8c864104ee7cb8f6a856ae322772da174c088..b1af0d613caabc55f7598b63201f59ca4c27c0e6 100644 (file)
@@ -3900,10 +3900,6 @@ static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
                return E1000_SUCCESS;
        }
 
-       /* If eeprom is not yet detected, do so now */
-       if (eeprom->word_size == 0)
-               e1000_init_eeprom_params(hw);
-
        /* A check for invalid values:  offset too large, too many words, and
         * not enough words.
         */
@@ -4074,10 +4070,6 @@ static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words,
                return E1000_SUCCESS;
        }
 
-       /* If eeprom is not yet detected, do so now */
-       if (eeprom->word_size == 0)
-               e1000_init_eeprom_params(hw);
-
        /* A check for invalid values:  offset too large, too many words, and
         * not enough words.
         */
index faf4b3f3d0b53ed5ecbf17c87507bba0e45ff1df..2e2ddec04a50cca071353f2a75ca281e98e60eb5 100644 (file)
@@ -6952,6 +6952,7 @@ static const struct net_device_ops e1000e_netdev_ops = {
 #endif
        .ndo_set_features = e1000_set_features,
        .ndo_fix_features = e1000_fix_features,
+       .ndo_features_check     = passthru_features_check,
 };
 
 /**
index c8c8c5baefda0552c011d8149812298585ae5709..14440200499b0300978caabc6d877a91f4ca91a9 100644 (file)
@@ -101,12 +101,19 @@ struct fm10k_tx_queue_stats {
        u64 csum_err;
        u64 tx_busy;
        u64 tx_done_old;
+       u64 csum_good;
 };
 
 struct fm10k_rx_queue_stats {
        u64 alloc_failed;
        u64 csum_err;
        u64 errors;
+       u64 csum_good;
+       u64 switch_errors;
+       u64 drops;
+       u64 pp_errors;
+       u64 link_errors;
+       u64 length_errors;
 };
 
 struct fm10k_ring {
@@ -251,6 +258,7 @@ struct fm10k_intfc {
 #define FM10K_FLAG_RSS_FIELD_IPV6_UDP          (u32)(1 << 2)
 #define FM10K_FLAG_RX_TS_ENABLED               (u32)(1 << 3)
 #define FM10K_FLAG_SWPRI_CONFIG                        (u32)(1 << 4)
+#define FM10K_FLAG_DEBUG_STATS                 (u32)(1 << 5)
        int xcast_mode;
 
        /* Tx fast path data */
@@ -277,6 +285,17 @@ struct fm10k_intfc {
        u64 rx_drops_nic;
        u64 rx_overrun_pf;
        u64 rx_overrun_vf;
+
+       /* Debug Statistics */
+       u64 hw_sm_mbx_full;
+       u64 hw_csum_tx_good;
+       u64 hw_csum_rx_good;
+       u64 rx_switch_errors;
+       u64 rx_drops;
+       u64 rx_pp_errors;
+       u64 rx_link_errors;
+       u64 rx_length_errors;
+
        u32 tx_timeout_count;
 
        /* RX */
index c6dc9683429e4aa4810722b7e861d4ed0cb4ad83..4ef2fbd229119578ca8681294556c5d906335814 100644 (file)
@@ -76,19 +76,22 @@ static const struct fm10k_stats fm10k_gstrings_global_stats[] = {
        FM10K_STAT("mac_rules_used", hw.swapi.mac.used),
        FM10K_STAT("mac_rules_avail", hw.swapi.mac.avail),
 
-       FM10K_STAT("mbx_tx_busy", hw.mbx.tx_busy),
-       FM10K_STAT("mbx_tx_oversized", hw.mbx.tx_dropped),
-       FM10K_STAT("mbx_tx_messages", hw.mbx.tx_messages),
-       FM10K_STAT("mbx_tx_dwords", hw.mbx.tx_dwords),
-       FM10K_STAT("mbx_rx_messages", hw.mbx.rx_messages),
-       FM10K_STAT("mbx_rx_dwords", hw.mbx.rx_dwords),
-       FM10K_STAT("mbx_rx_parse_err", hw.mbx.rx_parse_err),
-
        FM10K_STAT("tx_hang_count", tx_timeout_count),
 
        FM10K_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
 };
 
+static const struct fm10k_stats fm10k_gstrings_debug_stats[] = {
+       FM10K_STAT("hw_sm_mbx_full", hw_sm_mbx_full),
+       FM10K_STAT("hw_csum_tx_good", hw_csum_tx_good),
+       FM10K_STAT("hw_csum_rx_good", hw_csum_rx_good),
+       FM10K_STAT("rx_switch_errors", rx_switch_errors),
+       FM10K_STAT("rx_drops", rx_drops),
+       FM10K_STAT("rx_pp_errors", rx_pp_errors),
+       FM10K_STAT("rx_link_errors", rx_link_errors),
+       FM10K_STAT("rx_length_errors", rx_length_errors),
+};
+
 static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {
        FM10K_STAT("timeout", stats.timeout.count),
        FM10K_STAT("ur", stats.ur.count),
@@ -100,14 +103,33 @@ static const struct fm10k_stats fm10k_gstrings_pf_stats[] = {
        FM10K_STAT("nodesc_drop", stats.nodesc_drop.count),
 };
 
+#define FM10K_MBX_STAT(_name, _stat) { \
+       .stat_string = _name, \
+       .sizeof_stat = FIELD_SIZEOF(struct fm10k_mbx_info, _stat), \
+       .stat_offset = offsetof(struct fm10k_mbx_info, _stat) \
+}
+
+static const struct fm10k_stats fm10k_gstrings_mbx_stats[] = {
+       FM10K_MBX_STAT("mbx_tx_busy", tx_busy),
+       FM10K_MBX_STAT("mbx_tx_oversized", tx_dropped),
+       FM10K_MBX_STAT("mbx_tx_messages", tx_messages),
+       FM10K_MBX_STAT("mbx_tx_dwords", tx_dwords),
+       FM10K_MBX_STAT("mbx_rx_messages", rx_messages),
+       FM10K_MBX_STAT("mbx_rx_dwords", rx_dwords),
+       FM10K_MBX_STAT("mbx_rx_parse_err", rx_parse_err),
+};
+
 #define FM10K_GLOBAL_STATS_LEN ARRAY_SIZE(fm10k_gstrings_global_stats)
+#define FM10K_DEBUG_STATS_LEN ARRAY_SIZE(fm10k_gstrings_debug_stats)
 #define FM10K_PF_STATS_LEN ARRAY_SIZE(fm10k_gstrings_pf_stats)
+#define FM10K_MBX_STATS_LEN ARRAY_SIZE(fm10k_gstrings_mbx_stats)
 
 #define FM10K_QUEUE_STATS_LEN(_n) \
        ( (_n) * 2 * (sizeof(struct fm10k_queue_stats) / sizeof(u64)))
 
 #define FM10K_STATIC_STATS_LEN (FM10K_GLOBAL_STATS_LEN + \
-                               FM10K_NETDEV_STATS_LEN)
+                               FM10K_NETDEV_STATS_LEN + \
+                               FM10K_MBX_STATS_LEN)
 
 static const char fm10k_gstrings_test[][ETH_GSTRING_LEN] = {
        "Mailbox test (on/offline)"
@@ -120,47 +142,97 @@ enum fm10k_self_test_types {
        FM10K_TEST_MAX = FM10K_TEST_LEN
 };
 
-static void fm10k_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+enum {
+       FM10K_PRV_FLAG_DEBUG_STATS,
+       FM10K_PRV_FLAG_LEN,
+};
+
+static const char fm10k_prv_flags[FM10K_PRV_FLAG_LEN][ETH_GSTRING_LEN] = {
+       "debug-statistics",
+};
+
+static void fm10k_get_stat_strings(struct net_device *dev, u8 *data)
 {
        struct fm10k_intfc *interface = netdev_priv(dev);
+       struct fm10k_iov_data *iov_data = interface->iov_data;
        char *p = (char *)data;
        unsigned int i;
+       unsigned int j;
 
-       switch (stringset) {
-       case ETH_SS_TEST:
-               memcpy(data, *fm10k_gstrings_test,
-                      FM10K_TEST_LEN * ETH_GSTRING_LEN);
-               break;
-       case ETH_SS_STATS:
-               for (i = 0; i < FM10K_NETDEV_STATS_LEN; i++) {
-                       memcpy(p, fm10k_gstrings_net_stats[i].stat_string,
+       for (i = 0; i < FM10K_NETDEV_STATS_LEN; i++) {
+               memcpy(p, fm10k_gstrings_net_stats[i].stat_string,
+                      ETH_GSTRING_LEN);
+               p += ETH_GSTRING_LEN;
+       }
+
+       for (i = 0; i < FM10K_GLOBAL_STATS_LEN; i++) {
+               memcpy(p, fm10k_gstrings_global_stats[i].stat_string,
+                      ETH_GSTRING_LEN);
+               p += ETH_GSTRING_LEN;
+       }
+
+       if (interface->flags & FM10K_FLAG_DEBUG_STATS) {
+               for (i = 0; i < FM10K_DEBUG_STATS_LEN; i++) {
+                       memcpy(p, fm10k_gstrings_debug_stats[i].stat_string,
                               ETH_GSTRING_LEN);
                        p += ETH_GSTRING_LEN;
                }
-               for (i = 0; i < FM10K_GLOBAL_STATS_LEN; i++) {
-                       memcpy(p, fm10k_gstrings_global_stats[i].stat_string,
+       }
+
+       for (i = 0; i < FM10K_MBX_STATS_LEN; i++) {
+               memcpy(p, fm10k_gstrings_mbx_stats[i].stat_string,
+                      ETH_GSTRING_LEN);
+               p += ETH_GSTRING_LEN;
+       }
+
+       if (interface->hw.mac.type != fm10k_mac_vf) {
+               for (i = 0; i < FM10K_PF_STATS_LEN; i++) {
+                       memcpy(p, fm10k_gstrings_pf_stats[i].stat_string,
                               ETH_GSTRING_LEN);
                        p += ETH_GSTRING_LEN;
                }
+       }
 
-               if (interface->hw.mac.type != fm10k_mac_vf) {
-                       for (i = 0; i < FM10K_PF_STATS_LEN; i++) {
-                               memcpy(p, fm10k_gstrings_pf_stats[i].stat_string,
-                                      ETH_GSTRING_LEN);
+       if ((interface->flags & FM10K_FLAG_DEBUG_STATS) && iov_data) {
+               for (i = 0; i < iov_data->num_vfs; i++) {
+                       for (j = 0; j < FM10K_MBX_STATS_LEN; j++) {
+                               snprintf(p,
+                                        ETH_GSTRING_LEN,
+                                        "vf_%u_%s", i,
+                                        fm10k_gstrings_mbx_stats[j].stat_string);
                                p += ETH_GSTRING_LEN;
                        }
                }
+       }
 
-               for (i = 0; i < interface->hw.mac.max_queues; i++) {
-                       sprintf(p, "tx_queue_%u_packets", i);
-                       p += ETH_GSTRING_LEN;
-                       sprintf(p, "tx_queue_%u_bytes", i);
-                       p += ETH_GSTRING_LEN;
-                       sprintf(p, "rx_queue_%u_packets", i);
-                       p += ETH_GSTRING_LEN;
-                       sprintf(p, "rx_queue_%u_bytes", i);
-                       p += ETH_GSTRING_LEN;
-               }
+       for (i = 0; i < interface->hw.mac.max_queues; i++) {
+               sprintf(p, "tx_queue_%u_packets", i);
+               p += ETH_GSTRING_LEN;
+               sprintf(p, "tx_queue_%u_bytes", i);
+               p += ETH_GSTRING_LEN;
+               sprintf(p, "rx_queue_%u_packets", i);
+               p += ETH_GSTRING_LEN;
+               sprintf(p, "rx_queue_%u_bytes", i);
+               p += ETH_GSTRING_LEN;
+       }
+}
+
+static void fm10k_get_strings(struct net_device *dev,
+                             u32 stringset, u8 *data)
+{
+       char *p = (char *)data;
+
+       switch (stringset) {
+       case ETH_SS_TEST:
+               memcpy(data, *fm10k_gstrings_test,
+                      FM10K_TEST_LEN * ETH_GSTRING_LEN);
+               break;
+       case ETH_SS_STATS:
+               fm10k_get_stat_strings(dev, data);
+               break;
+       case ETH_SS_PRIV_FLAGS:
+               memcpy(p, fm10k_prv_flags,
+                      FM10K_PRV_FLAG_LEN * ETH_GSTRING_LEN);
                break;
        }
 }
@@ -168,6 +240,7 @@ static void fm10k_get_strings(struct net_device *dev, u32 stringset, u8 *data)
 static int fm10k_get_sset_count(struct net_device *dev, int sset)
 {
        struct fm10k_intfc *interface = netdev_priv(dev);
+       struct fm10k_iov_data *iov_data = interface->iov_data;
        struct fm10k_hw *hw = &interface->hw;
        int stats_len = FM10K_STATIC_STATS_LEN;
 
@@ -180,7 +253,16 @@ static int fm10k_get_sset_count(struct net_device *dev, int sset)
                if (hw->mac.type != fm10k_mac_vf)
                        stats_len += FM10K_PF_STATS_LEN;
 
+               if (interface->flags & FM10K_FLAG_DEBUG_STATS) {
+                       stats_len += FM10K_DEBUG_STATS_LEN;
+
+                       if (iov_data)
+                               stats_len += FM10K_MBX_STATS_LEN * iov_data->num_vfs;
+               }
+
                return stats_len;
+       case ETH_SS_PRIV_FLAGS:
+               return FM10K_PRV_FLAG_LEN;
        default:
                return -EOPNOTSUPP;
        }
@@ -192,6 +274,7 @@ static void fm10k_get_ethtool_stats(struct net_device *netdev,
 {
        const int stat_count = sizeof(struct fm10k_queue_stats) / sizeof(u64);
        struct fm10k_intfc *interface = netdev_priv(netdev);
+       struct fm10k_iov_data *iov_data = interface->iov_data;
        struct net_device_stats *net_stats = &netdev->stats;
        char *p;
        int i, j;
@@ -211,13 +294,47 @@ static void fm10k_get_ethtool_stats(struct net_device *netdev,
                        sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
        }
 
-       if (interface->hw.mac.type != fm10k_mac_vf)
+       if (interface->flags & FM10K_FLAG_DEBUG_STATS) {
+               for (i = 0; i < FM10K_DEBUG_STATS_LEN; i++) {
+                       p = (char *)interface + fm10k_gstrings_debug_stats[i].stat_offset;
+                       *(data++) = (fm10k_gstrings_debug_stats[i].sizeof_stat ==
+                                    sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+               }
+       }
+
+       for (i = 0; i < FM10K_MBX_STATS_LEN; i++) {
+               p = (char *)&interface->hw.mbx + fm10k_gstrings_mbx_stats[i].stat_offset;
+               *(data++) = (fm10k_gstrings_mbx_stats[i].sizeof_stat ==
+                       sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+       }
+
+       if (interface->hw.mac.type != fm10k_mac_vf) {
                for (i = 0; i < FM10K_PF_STATS_LEN; i++) {
                        p = (char *)interface +
                            fm10k_gstrings_pf_stats[i].stat_offset;
                        *(data++) = (fm10k_gstrings_pf_stats[i].sizeof_stat ==
                                     sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
                }
+       }
+
+       if ((interface->flags & FM10K_FLAG_DEBUG_STATS) && iov_data) {
+               for (i = 0; i < iov_data->num_vfs; i++) {
+                       struct fm10k_vf_info *vf_info;
+                       vf_info = &iov_data->vf_info[i];
+
+                       /* skip stats if we don't have a vf info */
+                       if (!vf_info) {
+                               data += FM10K_MBX_STATS_LEN;
+                               continue;
+                       }
+
+                       for (j = 0; j < FM10K_MBX_STATS_LEN; j++) {
+                               p = (char *)&vf_info->mbx + fm10k_gstrings_mbx_stats[j].stat_offset;
+                               *(data++) = (fm10k_gstrings_mbx_stats[j].sizeof_stat ==
+                                            sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+                       }
+               }
+       }
 
        for (i = 0; i < interface->hw.mac.max_queues; i++) {
                struct fm10k_ring *ring;
@@ -881,6 +998,33 @@ static void fm10k_self_test(struct net_device *dev,
                eth_test->flags |= ETH_TEST_FL_FAILED;
 }
 
+static u32 fm10k_get_priv_flags(struct net_device *netdev)
+{
+       struct fm10k_intfc *interface = netdev_priv(netdev);
+       u32 priv_flags = 0;
+
+       if (interface->flags & FM10K_FLAG_DEBUG_STATS)
+               priv_flags |= 1 << FM10K_PRV_FLAG_DEBUG_STATS;
+
+       return priv_flags;
+}
+
+static int fm10k_set_priv_flags(struct net_device *netdev, u32 priv_flags)
+{
+       struct fm10k_intfc *interface = netdev_priv(netdev);
+
+       if (priv_flags >= (1 << FM10K_PRV_FLAG_LEN))
+               return -EINVAL;
+
+       if (priv_flags & (1 << FM10K_PRV_FLAG_DEBUG_STATS))
+               interface->flags |= FM10K_FLAG_DEBUG_STATS;
+       else
+               interface->flags &= ~FM10K_FLAG_DEBUG_STATS;
+
+       return 0;
+}
+
+
 static u32 fm10k_get_reta_size(struct net_device __always_unused *netdev)
 {
        return FM10K_RETA_SIZE * FM10K_RETA_ENTRIES_PER_REG;
@@ -1094,6 +1238,8 @@ static const struct ethtool_ops fm10k_ethtool_ops = {
        .get_regs               = fm10k_get_regs,
        .get_regs_len           = fm10k_get_regs_len,
        .self_test              = fm10k_self_test,
+       .get_priv_flags         = fm10k_get_priv_flags,
+       .set_priv_flags         = fm10k_set_priv_flags,
        .get_rxfh_indir_size    = fm10k_get_reta_size,
        .get_rxfh_key_size      = fm10k_get_rssrk_size,
        .get_rxfh               = fm10k_get_rssh,
index 0e25a80417b923c1dbee67e2ff91cce3d86bd103..acfb8b1f88a70b3b725a6d81c8a8a8cb8b19577f 100644 (file)
@@ -137,8 +137,11 @@ process_mbx:
                }
 
                /* guarantee we have free space in the SM mailbox */
-               if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU))
+               if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU)) {
+                       /* keep track of how many times this occurs */
+                       interface->hw_sm_mbx_full++;
                        break;
+               }
 
                /* cleanup mailbox and process received messages */
                mbx->ops.process(hw, mbx);
index 92d415584749e06cbe6068295f10401711786ce9..2f47bfe6cc9084807d82d6bac60a68990226b553 100644 (file)
@@ -398,6 +398,8 @@ static inline void fm10k_rx_checksum(struct fm10k_ring *ring,
                return;
 
        skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+       ring->rx_stats.csum_good++;
 }
 
 #define FM10K_RSS_L4_TYPES_MASK \
@@ -556,6 +558,18 @@ static bool fm10k_cleanup_headers(struct fm10k_ring *rx_ring,
 {
        if (unlikely((fm10k_test_staterr(rx_desc,
                                         FM10K_RXD_STATUS_RXE)))) {
+#define FM10K_TEST_RXD_BIT(rxd, bit) \
+       ((rxd)->w.csum_err & cpu_to_le16(bit))
+               if (FM10K_TEST_RXD_BIT(rx_desc, FM10K_RXD_ERR_SWITCH_ERROR))
+                       rx_ring->rx_stats.switch_errors++;
+               if (FM10K_TEST_RXD_BIT(rx_desc, FM10K_RXD_ERR_NO_DESCRIPTOR))
+                       rx_ring->rx_stats.drops++;
+               if (FM10K_TEST_RXD_BIT(rx_desc, FM10K_RXD_ERR_PP_ERROR))
+                       rx_ring->rx_stats.pp_errors++;
+               if (FM10K_TEST_RXD_BIT(rx_desc, FM10K_RXD_ERR_SWITCH_READY))
+                       rx_ring->rx_stats.link_errors++;
+               if (FM10K_TEST_RXD_BIT(rx_desc, FM10K_RXD_ERR_TOO_BIG))
+                       rx_ring->rx_stats.length_errors++;
                dev_kfree_skb_any(skb);
                rx_ring->rx_stats.errors++;
                return true;
@@ -881,6 +895,7 @@ static void fm10k_tx_csum(struct fm10k_ring *tx_ring,
 
        /* update TX checksum flag */
        first->tx_flags |= FM10K_TX_FLAGS_CSUM;
+       tx_ring->tx_stats.csum_good++;
 
 no_csum:
        /* populate Tx descriptor header size and mss */
index 1a4b52637de9123d900f7362b54b985e46e345de..af09a1b272e68112c052df952c35ad6e8123dd6b 100644 (file)
@@ -129,8 +129,8 @@ static u16 fm10k_fifo_head_drop(struct fm10k_mbx_fifo *fifo)
  *  fm10k_fifo_drop_all - Drop all messages in FIFO
  *  @fifo: pointer to FIFO
  *
- *  This function resets the head pointer to drop all messages in the FIFO,
- *  and ensure the FIFO is empty.
+ *  This function resets the head pointer to drop all messages in the FIFO and
+ *  ensure the FIFO is empty.
  **/
 static void fm10k_fifo_drop_all(struct fm10k_mbx_fifo *fifo)
 {
@@ -898,6 +898,27 @@ static void fm10k_mbx_create_disconnect_hdr(struct fm10k_mbx_info *mbx)
        mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC);
 }
 
+/**
+ *  fm10k_mbx_create_fake_disconnect_hdr - Generate a false disconnect mailbox header
+ *  @mbx: pointer to mailbox
+ *
+ *  This function creates a fake disconnect header for loading into remote
+ *  mailbox header. The primary purpose is to prevent errors on immediate
+ *  start up after mbx->connect.
+ **/
+static void fm10k_mbx_create_fake_disconnect_hdr(struct fm10k_mbx_info *mbx)
+{
+       u32 hdr = FM10K_MSG_HDR_FIELD_SET(FM10K_MSG_DISCONNECT, TYPE) |
+                 FM10K_MSG_HDR_FIELD_SET(mbx->head, TAIL) |
+                 FM10K_MSG_HDR_FIELD_SET(mbx->tail, HEAD);
+       u16 crc = fm10k_crc_16b(&hdr, mbx->local, 1);
+
+       mbx->mbx_lock |= FM10K_MBX_ACK;
+
+       /* load header to memory to be written */
+       mbx->mbx_hdr = hdr | FM10K_MSG_HDR_FIELD_SET(crc, CRC);
+}
+
 /**
  *  fm10k_mbx_create_error_msg - Generate a error message
  *  @mbx: pointer to mailbox
@@ -1046,9 +1067,26 @@ static s32 fm10k_mbx_create_reply(struct fm10k_hw *hw,
  **/
 static void fm10k_mbx_reset_work(struct fm10k_mbx_info *mbx)
 {
+       u16 len, head, ack;
+
        /* reset our outgoing max size back to Rx limits */
        mbx->max_size = mbx->rx.size - 1;
 
+       /* update mbx->pulled to account for tail_len and ack */
+       head = FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, HEAD);
+       ack = fm10k_mbx_index_len(mbx, head, mbx->tail);
+       mbx->pulled += mbx->tail_len - ack;
+
+       /* now drop any messages which have started or finished transmitting */
+       while (fm10k_fifo_head_len(&mbx->tx) && mbx->pulled) {
+               len = fm10k_fifo_head_drop(&mbx->tx);
+               mbx->tx_dropped++;
+               if (mbx->pulled >= len)
+                       mbx->pulled -= len;
+               else
+                       mbx->pulled = 0;
+       }
+
        /* just do a quick resysnc to start of message */
        mbx->pushed = 0;
        mbx->pulled = 0;
@@ -1418,8 +1456,10 @@ static s32 fm10k_mbx_connect(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx)
        /* Place mbx in ready to connect state */
        mbx->state = FM10K_STATE_CONNECT;
 
+       fm10k_mbx_reset_work(mbx);
+
        /* initialize header of remote mailbox */
-       fm10k_mbx_create_disconnect_hdr(mbx);
+       fm10k_mbx_create_fake_disconnect_hdr(mbx);
        fm10k_write_reg(hw, mbx->mbmem_reg ^ mbx->mbmem_len, mbx->mbx_hdr);
 
        /* enable interrupt and notify other party of new message */
@@ -1725,7 +1765,7 @@ static void fm10k_sm_mbx_disconnect(struct fm10k_hw *hw,
        mbx->state = FM10K_STATE_CLOSED;
        mbx->remote = 0;
        fm10k_mbx_reset_work(mbx);
-       fm10k_mbx_update_max_size(mbx, 0);
+       fm10k_fifo_drop_all(&mbx->tx);
 
        fm10k_write_reg(hw, mbx->mbmem_reg, 0);
 }
index 3d71c520611018373b0d139638535ad2aabb74e6..74be792f3f1b7e0d31e729980b27c6602aeac263 100644 (file)
@@ -274,8 +274,6 @@ static void fm10k_watchdog_update_host_state(struct fm10k_intfc *interface)
  * @interface: board private structure
  *
  * This function will process both the upstream and downstream mailboxes.
- * It is necessary for us to hold the rtnl_lock while doing this as the
- * mailbox accesses are protected by this lock.
  **/
 static void fm10k_mbx_subtask(struct fm10k_intfc *interface)
 {
@@ -330,6 +328,9 @@ void fm10k_update_stats(struct fm10k_intfc *interface)
 {
        struct net_device_stats *net_stats = &interface->netdev->stats;
        struct fm10k_hw *hw = &interface->hw;
+       u64 hw_csum_tx_good = 0, hw_csum_rx_good = 0, rx_length_errors = 0;
+       u64 rx_switch_errors = 0, rx_drops = 0, rx_pp_errors = 0;
+       u64 rx_link_errors = 0;
        u64 rx_errors = 0, rx_csum_errors = 0, tx_csum_errors = 0;
        u64 restart_queue = 0, tx_busy = 0, alloc_failed = 0;
        u64 rx_bytes_nic = 0, rx_pkts_nic = 0, rx_drops_nic = 0;
@@ -349,6 +350,7 @@ void fm10k_update_stats(struct fm10k_intfc *interface)
                tx_csum_errors += tx_ring->tx_stats.csum_err;
                bytes += tx_ring->stats.bytes;
                pkts += tx_ring->stats.packets;
+               hw_csum_tx_good += tx_ring->tx_stats.csum_good;
        }
 
        interface->restart_queue = restart_queue;
@@ -356,6 +358,8 @@ void fm10k_update_stats(struct fm10k_intfc *interface)
        net_stats->tx_bytes = bytes;
        net_stats->tx_packets = pkts;
        interface->tx_csum_errors = tx_csum_errors;
+       interface->hw_csum_tx_good = hw_csum_tx_good;
+
        /* gather some stats to the interface struct that are per queue */
        for (bytes = 0, pkts = 0, i = 0; i < interface->num_rx_queues; i++) {
                struct fm10k_ring *rx_ring = interface->rx_ring[i];
@@ -365,12 +369,24 @@ void fm10k_update_stats(struct fm10k_intfc *interface)
                alloc_failed += rx_ring->rx_stats.alloc_failed;
                rx_csum_errors += rx_ring->rx_stats.csum_err;
                rx_errors += rx_ring->rx_stats.errors;
+               hw_csum_rx_good += rx_ring->rx_stats.csum_good;
+               rx_switch_errors += rx_ring->rx_stats.switch_errors;
+               rx_drops += rx_ring->rx_stats.drops;
+               rx_pp_errors += rx_ring->rx_stats.pp_errors;
+               rx_link_errors += rx_ring->rx_stats.link_errors;
+               rx_length_errors += rx_ring->rx_stats.length_errors;
        }
 
        net_stats->rx_bytes = bytes;
        net_stats->rx_packets = pkts;
        interface->alloc_failed = alloc_failed;
        interface->rx_csum_errors = rx_csum_errors;
+       interface->hw_csum_rx_good = hw_csum_rx_good;
+       interface->rx_switch_errors = rx_switch_errors;
+       interface->rx_drops = rx_drops;
+       interface->rx_pp_errors = rx_pp_errors;
+       interface->rx_link_errors = rx_link_errors;
+       interface->rx_length_errors = rx_length_errors;
 
        hw->mac.ops.update_hw_stats(hw, &interface->stats);
 
@@ -498,7 +514,7 @@ static void fm10k_service_task(struct work_struct *work)
 
        interface = container_of(work, struct fm10k_intfc, service_task);
 
-       /* tasks always capable of running, but must be rtnl protected */
+       /* tasks run even when interface is down */
        fm10k_mbx_subtask(interface);
        fm10k_detach_subtask(interface);
        fm10k_reset_subtask(interface);
index bac8d486d75f335d60322adcd0f827a5de367392..318a212f0a78e54e9705780b23a6ba3dd6ddba4b 100644 (file)
@@ -762,6 +762,12 @@ enum fm10k_rxdesc_xc {
 #define FM10K_RXD_STATUS_L4E           0x4000 /* L4 csum error */
 #define FM10K_RXD_STATUS_IPE           0x8000 /* IPv4 csum error */
 
+#define FM10K_RXD_ERR_SWITCH_ERROR     0x0001 /* Switch found bad packet */
+#define FM10K_RXD_ERR_NO_DESCRIPTOR    0x0002 /* No descriptor available */
+#define FM10K_RXD_ERR_PP_ERROR         0x0004 /* RAM error during processing */
+#define FM10K_RXD_ERR_SWITCH_READY     0x0008 /* Link transition mid-packet */
+#define FM10K_RXD_ERR_TOO_BIG          0x0010 /* Pkt too big for single buf */
+
 struct fm10k_ftag {
        __be16 swpri_type_user;
        __be16 vlan;
index 686fa7184179a473599584f25e0a6d714baff54f..e86d41ed9260780dd644509fd307e64974e9dd0e 100644 (file)
@@ -2615,6 +2615,7 @@ static const struct net_device_ops igbvf_netdev_ops = {
        .ndo_poll_controller    = igbvf_netpoll,
 #endif
        .ndo_set_features       = igbvf_set_features,
+       .ndo_features_check     = passthru_features_check,
 };
 
 /**
index a699c991ad2cfe50af67c5249f799d4cfbf87ea6..dda0f678339ad88e02904787b446e7ad1db5c99b 100644 (file)
@@ -594,6 +594,7 @@ struct ixgbe_mac_addr {
 
 /* default to trying for four seconds */
 #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
+#define IXGBE_SFP_POLL_JIFFIES (2 * HZ)        /* SFP poll every 2 seconds */
 
 /* board specific private data structure */
 struct ixgbe_adapter {
@@ -707,6 +708,7 @@ struct ixgbe_adapter {
 
        u32 link_speed;
        bool link_up;
+       unsigned long sfp_poll_time;
        unsigned long link_check_timeout;
 
        struct timer_list service_timer;
index dd7062fed61adfff717d56db55d6b275059b7c07..a39afcf03e2c4a84fb6e6aea7960c47a3d589528 100644 (file)
@@ -44,9 +44,8 @@
 static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
 static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
 static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
-static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
-                                                ixgbe_link_speed speed,
-                                                bool autoneg_wait_to_complete);
+static void
+ixgbe_set_hard_rate_select_speed(struct ixgbe_hw *, ixgbe_link_speed);
 static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
                                           ixgbe_link_speed speed,
                                           bool autoneg_wait_to_complete);
@@ -109,6 +108,9 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
        if (hw->phy.multispeed_fiber) {
                /* Set up dual speed SFP+ support */
                mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
+               mac->ops.setup_mac_link = ixgbe_setup_mac_link_82599;
+               mac->ops.set_rate_select_speed =
+                                              ixgbe_set_hard_rate_select_speed;
        } else {
                if ((mac->ops.get_media_type(hw) ==
                     ixgbe_media_type_backplane) &&
@@ -646,176 +648,32 @@ static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
- *  @hw: pointer to hardware structure
- *  @speed: new link speed
- *  @autoneg_wait_to_complete: true when waiting for completion is needed
+ * ixgbe_set_hard_rate_select_speed - Set module link speed
+ * @hw: pointer to hardware structure
+ * @speed: link speed to set
  *
- *  Set the link speed in the AUTOC register and restarts link.
- **/
-static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
-                                         ixgbe_link_speed speed,
-                                         bool autoneg_wait_to_complete)
+ * Set module link speed via RS0/RS1 rate select pins.
+ */
+static void
+ixgbe_set_hard_rate_select_speed(struct ixgbe_hw *hw, ixgbe_link_speed speed)
 {
-       s32 status = 0;
-       ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
-       ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
-       u32 speedcnt = 0;
        u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
-       u32 i = 0;
-       bool link_up = false;
-       bool autoneg = false;
-
-       /* Mask off requested but non-supported speeds */
-       status = hw->mac.ops.get_link_capabilities(hw, &link_speed,
-                                                  &autoneg);
-       if (status != 0)
-               return status;
-
-       speed &= link_speed;
-
-       /*
-        * Try each speed one by one, highest priority first.  We do this in
-        * software because 10gb fiber doesn't support speed autonegotiation.
-        */
-       if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
-               speedcnt++;
-               highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
-
-               /* If we already have link at this speed, just jump out */
-               status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
-                                               false);
-               if (status != 0)
-                       return status;
-
-               if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
-                       goto out;
-
-               /* Set the module link speed */
-               switch (hw->phy.media_type) {
-               case ixgbe_media_type_fiber:
-                       esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
-                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-                       IXGBE_WRITE_FLUSH(hw);
-                       break;
-               case ixgbe_media_type_fiber_qsfp:
-                       /* QSFP module automatically detects MAC link speed */
-                       break;
-               default:
-                       hw_dbg(hw, "Unexpected media type.\n");
-                       break;
-               }
-
-               /* Allow module to change analog characteristics (1G->10G) */
-               msleep(40);
-
-               status = ixgbe_setup_mac_link_82599(hw,
-                                                   IXGBE_LINK_SPEED_10GB_FULL,
-                                                   autoneg_wait_to_complete);
-               if (status != 0)
-                       return status;
-
-               /* Flap the tx laser if it has not already been done */
-               if (hw->mac.ops.flap_tx_laser)
-                       hw->mac.ops.flap_tx_laser(hw);
-
-               /*
-                * Wait for the controller to acquire link.  Per IEEE 802.3ap,
-                * Section 73.10.2, we may have to wait up to 500ms if KR is
-                * attempted.  82599 uses the same timing for 10g SFI.
-                */
-               for (i = 0; i < 5; i++) {
-                       /* Wait for the link partner to also set speed */
-                       msleep(100);
-
-                       /* If we have link, just jump out */
-                       status = hw->mac.ops.check_link(hw, &link_speed,
-                                                       &link_up, false);
-                       if (status != 0)
-                               return status;
-
-                       if (link_up)
-                               goto out;
-               }
-       }
-
-       if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
-               speedcnt++;
-               if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
-                       highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
-
-               /* If we already have link at this speed, just jump out */
-               status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
-                                               false);
-               if (status != 0)
-                       return status;
-
-               if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
-                       goto out;
-
-               /* Set the module link speed */
-               switch (hw->phy.media_type) {
-               case ixgbe_media_type_fiber:
-                       esdp_reg &= ~IXGBE_ESDP_SDP5;
-                       esdp_reg |= IXGBE_ESDP_SDP5_DIR;
-                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
-                       IXGBE_WRITE_FLUSH(hw);
-                       break;
-               case ixgbe_media_type_fiber_qsfp:
-                       /* QSFP module automatically detects MAC link speed */
-                       break;
-               default:
-                       hw_dbg(hw, "Unexpected media type.\n");
-                       break;
-               }
-
-               /* Allow module to change analog characteristics (10G->1G) */
-               msleep(40);
-
-               status = ixgbe_setup_mac_link_82599(hw,
-                                                   IXGBE_LINK_SPEED_1GB_FULL,
-                                                   autoneg_wait_to_complete);
-               if (status != 0)
-                       return status;
-
-               /* Flap the tx laser if it has not already been done */
-               if (hw->mac.ops.flap_tx_laser)
-                       hw->mac.ops.flap_tx_laser(hw);
 
-               /* Wait for the link partner to also set speed */
-               msleep(100);
-
-               /* If we have link, just jump out */
-               status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
-                                               false);
-               if (status != 0)
-                       return status;
-
-               if (link_up)
-                       goto out;
+       switch (speed) {
+       case IXGBE_LINK_SPEED_10GB_FULL:
+               esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+               break;
+       case IXGBE_LINK_SPEED_1GB_FULL:
+               esdp_reg &= ~IXGBE_ESDP_SDP5;
+               esdp_reg |= IXGBE_ESDP_SDP5_DIR;
+               break;
+       default:
+               hw_dbg(hw, "Invalid fixed module speed\n");
+               return;
        }
 
-       /*
-        * We didn't get link.  Configure back to the highest speed we tried,
-        * (if there was more than one).  We call ourselves back with just the
-        * single highest speed that the user requested.
-        */
-       if (speedcnt > 1)
-               status = ixgbe_setup_mac_link_multispeed_fiber(hw,
-                                                              highest_link_speed,
-                                                              autoneg_wait_to_complete);
-
-out:
-       /* Set autoneg_advertised value based on input link speed */
-       hw->phy.autoneg_advertised = 0;
-
-       if (speed & IXGBE_LINK_SPEED_10GB_FULL)
-               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
-
-       if (speed & IXGBE_LINK_SPEED_1GB_FULL)
-               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
-
-       return status;
+       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+       IXGBE_WRITE_FLUSH(hw);
 }
 
 /**
@@ -1766,6 +1624,16 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
        IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, ~fdirtcpm);
        IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, ~fdirtcpm);
 
+       /* also use it for SCTP */
+       switch (hw->mac.type) {
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm);
+               break;
+       default:
+               break;
+       }
+
        /* store source and destination IP masks (big-enian) */
        IXGBE_WRITE_REG_BE32(hw, IXGBE_FDIRSIP4M,
                             ~input_mask->formatted.src_ip[0]);
index 3f56a8080118ef0737e00e57ebc0e43deb4dc77a..ce61b36b94f10102644d3304359a03d208d60e3f 100644 (file)
@@ -297,13 +297,13 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
 
        /* Setup flow control */
        ret_val = ixgbe_setup_fc(hw);
-       if (!ret_val)
-               return 0;
+       if (ret_val)
+               return ret_val;
 
        /* Clear adapter stopped flag */
        hw->adapter_stopped = false;
 
-       return ret_val;
+       return 0;
 }
 
 /**
@@ -2164,10 +2164,11 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
                        /*
                         * In order to prevent Tx hangs when the internal Tx
                         * switch is enabled we must set the high water mark
-                        * to the maximum FCRTH value.  This allows the Tx
-                        * switch to function even under heavy Rx workloads.
+                        * to the Rx packet buffer size - 24KB.  This allows
+                        * the Tx switch to function even under heavy Rx
+                        * workloads.
                         */
-                       fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
+                       fcrth = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576;
                }
 
                IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), fcrth);
@@ -2476,6 +2477,9 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
        hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n");
        hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
 
+       if (hw->mac.type >= ixgbe_mac_X550)
+               return 0;
+
        /*
         * Before proceeding, make sure that the PCIe block does not have
         * transactions pending.
@@ -3920,3 +3924,213 @@ bool ixgbe_mng_present(struct ixgbe_hw *hw)
        fwsm &= IXGBE_FWSM_MODE_MASK;
        return fwsm == IXGBE_FWSM_FW_MODE_PT;
 }
+
+/**
+ *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
+ *  @hw: pointer to hardware structure
+ *  @speed: new link speed
+ *  @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ *  Set the link speed in the MAC and/or PHY register and restarts link.
+ */
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
+                                         ixgbe_link_speed speed,
+                                         bool autoneg_wait_to_complete)
+{
+       ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
+       ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
+       s32 status = 0;
+       u32 speedcnt = 0;
+       u32 i = 0;
+       bool autoneg, link_up = false;
+
+       /* Mask off requested but non-supported speeds */
+       status = hw->mac.ops.get_link_capabilities(hw, &link_speed, &autoneg);
+       if (status)
+               return status;
+
+       speed &= link_speed;
+
+       /* Try each speed one by one, highest priority first.  We do this in
+        * software because 10Gb fiber doesn't support speed autonegotiation.
+        */
+       if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
+               speedcnt++;
+               highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+
+               /* If we already have link at this speed, just jump out */
+               status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
+                                               false);
+               if (status)
+                       return status;
+
+               if (link_speed == IXGBE_LINK_SPEED_10GB_FULL && link_up)
+                       goto out;
+
+               /* Set the module link speed */
+               switch (hw->phy.media_type) {
+               case ixgbe_media_type_fiber:
+                       hw->mac.ops.set_rate_select_speed(hw,
+                                                   IXGBE_LINK_SPEED_10GB_FULL);
+                       break;
+               case ixgbe_media_type_fiber_qsfp:
+                       /* QSFP module automatically detects MAC link speed */
+                       break;
+               default:
+                       hw_dbg(hw, "Unexpected media type\n");
+                       break;
+               }
+
+               /* Allow module to change analog characteristics (1G->10G) */
+               msleep(40);
+
+               status = hw->mac.ops.setup_mac_link(hw,
+                                                   IXGBE_LINK_SPEED_10GB_FULL,
+                                                   autoneg_wait_to_complete);
+               if (status)
+                       return status;
+
+               /* Flap the Tx laser if it has not already been done */
+               if (hw->mac.ops.flap_tx_laser)
+                       hw->mac.ops.flap_tx_laser(hw);
+
+               /* Wait for the controller to acquire link.  Per IEEE 802.3ap,
+                * Section 73.10.2, we may have to wait up to 500ms if KR is
+                * attempted.  82599 uses the same timing for 10g SFI.
+                */
+               for (i = 0; i < 5; i++) {
+                       /* Wait for the link partner to also set speed */
+                       msleep(100);
+
+                       /* If we have link, just jump out */
+                       status = hw->mac.ops.check_link(hw, &link_speed,
+                                                       &link_up, false);
+                       if (status)
+                               return status;
+
+                       if (link_up)
+                               goto out;
+               }
+       }
+
+       if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
+               speedcnt++;
+               if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
+                       highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
+
+               /* If we already have link at this speed, just jump out */
+               status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
+                                               false);
+               if (status)
+                       return status;
+
+               if (link_speed == IXGBE_LINK_SPEED_1GB_FULL && link_up)
+                       goto out;
+
+               /* Set the module link speed */
+               switch (hw->phy.media_type) {
+               case ixgbe_media_type_fiber:
+                       hw->mac.ops.set_rate_select_speed(hw,
+                                                    IXGBE_LINK_SPEED_1GB_FULL);
+                       break;
+               case ixgbe_media_type_fiber_qsfp:
+                       /* QSFP module automatically detects link speed */
+                       break;
+               default:
+                       hw_dbg(hw, "Unexpected media type\n");
+                       break;
+               }
+
+               /* Allow module to change analog characteristics (10G->1G) */
+               msleep(40);
+
+               status = hw->mac.ops.setup_mac_link(hw,
+                                                   IXGBE_LINK_SPEED_1GB_FULL,
+                                                   autoneg_wait_to_complete);
+               if (status)
+                       return status;
+
+               /* Flap the Tx laser if it has not already been done */
+               if (hw->mac.ops.flap_tx_laser)
+                       hw->mac.ops.flap_tx_laser(hw);
+
+               /* Wait for the link partner to also set speed */
+               msleep(100);
+
+               /* If we have link, just jump out */
+               status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
+                                               false);
+               if (status)
+                       return status;
+
+               if (link_up)
+                       goto out;
+       }
+
+       /* We didn't get link.  Configure back to the highest speed we tried,
+        * (if there was more than one).  We call ourselves back with just the
+        * single highest speed that the user requested.
+        */
+       if (speedcnt > 1)
+               status = ixgbe_setup_mac_link_multispeed_fiber(hw,
+                                                     highest_link_speed,
+                                                     autoneg_wait_to_complete);
+
+out:
+       /* Set autoneg_advertised value based on input link speed */
+       hw->phy.autoneg_advertised = 0;
+
+       if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
+       if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
+
+       return status;
+}
+
+/**
+ *  ixgbe_set_soft_rate_select_speed - Set module link speed
+ *  @hw: pointer to hardware structure
+ *  @speed: link speed to set
+ *
+ *  Set module link speed via the soft rate select.
+ */
+void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw,
+                                     ixgbe_link_speed speed)
+{
+       s32 status;
+       u8 rs, eeprom_data;
+
+       switch (speed) {
+       case IXGBE_LINK_SPEED_10GB_FULL:
+               /* one bit mask same as setting on */
+               rs = IXGBE_SFF_SOFT_RS_SELECT_10G;
+               break;
+       case IXGBE_LINK_SPEED_1GB_FULL:
+               rs = IXGBE_SFF_SOFT_RS_SELECT_1G;
+               break;
+       default:
+               hw_dbg(hw, "Invalid fixed module speed\n");
+               return;
+       }
+
+       /* Set RS0 */
+       status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+                                          IXGBE_I2C_EEPROM_DEV_ADDR2,
+                                          &eeprom_data);
+       if (status) {
+               hw_dbg(hw, "Failed to read Rx Rate Select RS0\n");
+               return;
+       }
+
+       eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs;
+
+       status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_OSCB,
+                                           IXGBE_I2C_EEPROM_DEV_ADDR2,
+                                           eeprom_data);
+       if (status) {
+               hw_dbg(hw, "Failed to write Rx Rate Select RS0\n");
+               return;
+       }
+}
index 2f779f35dc4f5c6b7034c4263a79a03252b51aeb..a0044e4a8b90c92c49c08598423743fec070850c 100644 (file)
@@ -135,6 +135,11 @@ s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw);
 s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw);
 void ixgbe_disable_rx_generic(struct ixgbe_hw *hw);
 void ixgbe_enable_rx_generic(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
+                                         ixgbe_link_speed speed,
+                                         bool autoneg_wait_to_complete);
+void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw,
+                                     ixgbe_link_speed speed);
 
 #define IXGBE_FAILED_READ_REG 0xffffffffU
 #define IXGBE_FAILED_READ_CFG_DWORD 0xffffffffU
index 3b932fe64ab66c916f86f4184f45d626cc687cb1..23277ab153b6b177f234e23a8895bcf90a9a6f5d 100644 (file)
@@ -259,7 +259,13 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
                        fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
                        IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
                } else {
-                       reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
+                       /* In order to prevent Tx hangs when the internal Tx
+                        * switch is enabled we must set the high water mark
+                        * to the Rx packet buffer size - 24KB.  This allows
+                        * the Tx switch to function even under heavy Rx
+                        * workloads.
+                        */
+                       reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 24576;
                        IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
                }
 
index acb1b91408ec4ff1fba129b37ea5e98ceed22b11..191003901adb84f9faf8fa6a03013599b65e652c 100644 (file)
@@ -79,7 +79,7 @@ char ixgbe_default_device_descr[] =
 static char ixgbe_default_device_descr[] =
                              "Intel(R) 10 Gigabit Network Connection";
 #endif
-#define DRV_VERSION "4.0.1-k"
+#define DRV_VERSION "4.2.1-k"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
                                "Copyright (c) 1999-2015 Intel Corporation.";
@@ -137,6 +137,7 @@ static const struct pci_device_id ixgbe_pci_tbl[] = {
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_KX4), board_X550EM_x},
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_KR), board_X550EM_x},
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_10G_T), board_X550EM_x},
+       {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_SFP), board_X550EM_x},
        /* required last entry */
        {0, }
 };
@@ -1244,9 +1245,12 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
                                int cpu)
 {
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 txctrl = dca3_get_tag(tx_ring->dev, cpu);
+       u32 txctrl = 0;
        u16 reg_offset;
 
+       if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+               txctrl = dca3_get_tag(tx_ring->dev, cpu);
+
        switch (hw->mac.type) {
        case ixgbe_mac_82598EB:
                reg_offset = IXGBE_DCA_TXCTRL(tx_ring->reg_idx);
@@ -1278,9 +1282,11 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
                                int cpu)
 {
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 rxctrl = dca3_get_tag(rx_ring->dev, cpu);
+       u32 rxctrl = 0;
        u8 reg_idx = rx_ring->reg_idx;
 
+       if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+               rxctrl = dca3_get_tag(rx_ring->dev, cpu);
 
        switch (hw->mac.type) {
        case ixgbe_mac_82599EB:
@@ -1297,6 +1303,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
         * which will cause the DCA tag to be cleared.
         */
        rxctrl |= IXGBE_DCA_RXCTRL_DESC_RRO_EN |
+                 IXGBE_DCA_RXCTRL_DATA_DCA_EN |
                  IXGBE_DCA_RXCTRL_DESC_DCA_EN;
 
        IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl);
@@ -1326,11 +1333,13 @@ static void ixgbe_setup_dca(struct ixgbe_adapter *adapter)
 {
        int i;
 
-       if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED))
-               return;
-
        /* always use CB2 mode, difference is masked in the CB driver */
-       IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
+       if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL,
+                               IXGBE_DCA_CTRL_DCA_MODE_CB2);
+       else
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL,
+                               IXGBE_DCA_CTRL_DCA_DISABLE);
 
        for (i = 0; i < adapter->num_q_vectors; i++) {
                adapter->q_vector[i]->cpu = -1;
@@ -1353,7 +1362,8 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
                        break;
                if (dca_add_requester(dev) == 0) {
                        adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
-                       ixgbe_setup_dca(adapter);
+                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL,
+                                       IXGBE_DCA_CTRL_DCA_MODE_CB2);
                        break;
                }
                /* Fall Through since DCA is disabled. */
@@ -1361,7 +1371,8 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
                if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
                        dca_remove_requester(dev);
                        adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
-                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 1);
+                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL,
+                                       IXGBE_DCA_CTRL_DCA_DISABLE);
                }
                break;
        }
@@ -2509,6 +2520,7 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
                IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask);
                if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
                        adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
+                       adapter->sfp_poll_time = 0;
                        ixgbe_service_event_schedule(adapter);
                }
        }
@@ -2631,6 +2643,8 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues,
        case ixgbe_mac_X540:
        case ixgbe_mac_X550:
        case ixgbe_mac_X550EM_x:
+               if (adapter->hw.device_id == IXGBE_DEV_ID_X550EM_X_SFP)
+                       mask |= IXGBE_EIMS_GPI_SDP0(&adapter->hw);
                if (adapter->hw.phy.type == ixgbe_phy_x550em_ext_t)
                        mask |= IXGBE_EICR_GPI_SDP0_X540;
                mask |= IXGBE_EIMS_ECC;
@@ -3786,8 +3800,6 @@ static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter)
        u32 rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
 
        switch (hw->mac.type) {
-       case ixgbe_mac_X550:
-       case ixgbe_mac_X550EM_x:
        case ixgbe_mac_82598EB:
                /*
                 * For VMDq support of different descriptor types or
@@ -3801,6 +3813,11 @@ static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter)
                 */
                rdrxctl |= IXGBE_RDRXCTL_MVMEN;
                break;
+       case ixgbe_mac_X550:
+       case ixgbe_mac_X550EM_x:
+               if (adapter->num_vfs)
+                       rdrxctl |= IXGBE_RDRXCTL_PSP;
+               /* fall through for older HW */
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
                /* Disable RSC for ACK packets */
@@ -4776,6 +4793,12 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
                break;
        }
 
+#ifdef CONFIG_IXGBE_DCA
+       /* configure DCA */
+       if (adapter->flags & IXGBE_FLAG_DCA_CAPABLE)
+               ixgbe_setup_dca(adapter);
+#endif /* CONFIG_IXGBE_DCA */
+
 #ifdef IXGBE_FCOE
        /* configure FCoE L2 filters, redirection table, and Rx control */
        ixgbe_configure_fcoe(adapter);
@@ -4802,6 +4825,7 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
                adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
 
        adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
+       adapter->sfp_poll_time = 0;
 }
 
 /**
@@ -4892,9 +4916,6 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)
                case ixgbe_mac_82599EB:
                        gpie |= IXGBE_SDP0_GPIEN_8259X;
                        break;
-               case ixgbe_mac_X540:
-                       gpie |= IXGBE_EIMS_TS;
-                       break;
                default:
                        break;
                }
@@ -4904,9 +4925,15 @@ static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter)
        if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
                gpie |= IXGBE_SDP1_GPIEN(hw);
 
-       if (hw->mac.type == ixgbe_mac_82599EB) {
-               gpie |= IXGBE_SDP1_GPIEN_8259X;
-               gpie |= IXGBE_SDP2_GPIEN_8259X;
+       switch (hw->mac.type) {
+       case ixgbe_mac_82599EB:
+               gpie |= IXGBE_SDP1_GPIEN_8259X | IXGBE_SDP2_GPIEN_8259X;
+               break;
+       case ixgbe_mac_X550EM_x:
+               gpie |= IXGBE_SDP0_GPIEN_X540;
+               break;
+       default:
+               break;
        }
 
        IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
@@ -5229,11 +5256,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
 
        ixgbe_clean_all_tx_rings(adapter);
        ixgbe_clean_all_rx_rings(adapter);
-
-#ifdef CONFIG_IXGBE_DCA
-       /* since we reset the hardware DCA settings were cleared */
-       ixgbe_setup_dca(adapter);
-#endif
 }
 
 /**
@@ -6701,10 +6723,16 @@ static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter)
            !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
                return;
 
+       if (adapter->sfp_poll_time &&
+           time_after(adapter->sfp_poll_time, jiffies))
+               return; /* If not yet time to poll for SFP */
+
        /* someone else is in init, wait until next service event */
        if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
                return;
 
+       adapter->sfp_poll_time = jiffies + IXGBE_SFP_POLL_JIFFIES - 1;
+
        err = hw->phy.ops.identify_sfp(hw);
        if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
                goto sfp_out;
@@ -8704,8 +8732,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        hw->phy.reset_if_overtemp = true;
        err = hw->mac.ops.reset_hw(hw);
        hw->phy.reset_if_overtemp = false;
-       if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
-           hw->mac.type == ixgbe_mac_82598EB) {
+       if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
                err = 0;
        } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
                e_dev_err("failed to load because an unsupported SFP+ or QSFP module type was detected.\n");
@@ -9017,7 +9044,8 @@ static void ixgbe_remove(struct pci_dev *pdev)
        if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
                adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
                dca_remove_requester(&pdev->dev);
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 1);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL,
+                               IXGBE_DCA_CTRL_DCA_DISABLE);
        }
 
 #endif
index 597d0b1c23701eadad2c3d9a68448acc7d4c941c..fb8673d6380689fa7a79ebba5d5d493777d1bdc2 100644 (file)
@@ -100,16 +100,17 @@ static u8 ixgbe_ones_comp_byte_add(u8 add1, u8 add2)
 }
 
 /**
- *  ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
+ *  ixgbe_read_i2c_combined_generic_int - Perform I2C read combined operation
  *  @hw: pointer to the hardware structure
  *  @addr: I2C bus address to read from
  *  @reg: I2C device register to read from
  *  @val: pointer to location to receive read value
+ *  @lock: true if to take and release semaphore
  *
  *  Returns an error code on error.
- **/
-s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
-                                   u16 reg, u16 *val)
+ */
+static s32 ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
+                                              u16 reg, u16 *val, bool lock)
 {
        u32 swfw_mask = hw->phy.phy_semaphore_mask;
        int max_retry = 10;
@@ -124,7 +125,7 @@ s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
        csum = ixgbe_ones_comp_byte_add(reg_high, reg & 0xFF);
        csum = ~csum;
        do {
-               if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+               if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
                        return IXGBE_ERR_SWFW_SYNC;
                ixgbe_i2c_start(hw);
                /* Device Address and write indication */
@@ -157,13 +158,15 @@ s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
                if (ixgbe_clock_out_i2c_bit(hw, false))
                        goto fail;
                ixgbe_i2c_stop(hw);
-               hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+               if (lock)
+                       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
                *val = (high_bits << 8) | low_bits;
                return 0;
 
 fail:
                ixgbe_i2c_bus_clear(hw);
-               hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+               if (lock)
+                       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
                retry++;
                if (retry < max_retry)
                        hw_dbg(hw, "I2C byte read combined error - Retry.\n");
@@ -175,17 +178,49 @@ fail:
 }
 
 /**
- *  ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
+ *  ixgbe_read_i2c_combined_generic - Perform I2C read combined operation
+ *  @hw: pointer to the hardware structure
+ *  @addr: I2C bus address to read from
+ *  @reg: I2C device register to read from
+ *  @val: pointer to location to receive read value
+ *
+ *  Returns an error code on error.
+ */
+s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
+                                   u16 reg, u16 *val)
+{
+       return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, true);
+}
+
+/**
+ *  ixgbe_read_i2c_combined_generic_unlocked - Unlocked I2C read combined
+ *  @hw: pointer to the hardware structure
+ *  @addr: I2C bus address to read from
+ *  @reg: I2C device register to read from
+ *  @val: pointer to location to receive read value
+ *
+ *  Returns an error code on error.
+ */
+s32 ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
+                                            u16 reg, u16 *val)
+{
+       return ixgbe_read_i2c_combined_generic_int(hw, addr, reg, val, false);
+}
+
+/**
+ *  ixgbe_write_i2c_combined_generic_int - Perform I2C write combined operation
  *  @hw: pointer to the hardware structure
  *  @addr: I2C bus address to write to
  *  @reg: I2C device register to write to
  *  @val: value to write
+ *  @lock: true if to take and release semaphore
  *
  *  Returns an error code on error.
- **/
-s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
-                                    u8 addr, u16 reg, u16 val)
+ */
+static s32 ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *hw, u8 addr,
+                                               u16 reg, u16 val, bool lock)
 {
+       u32 swfw_mask = hw->phy.phy_semaphore_mask;
        int max_retry = 1;
        int retry = 0;
        u8 reg_high;
@@ -197,6 +232,8 @@ s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
        csum = ixgbe_ones_comp_byte_add(csum, val & 0xFF);
        csum = ~csum;
        do {
+               if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+                       return IXGBE_ERR_SWFW_SYNC;
                ixgbe_i2c_start(hw);
                /* Device Address and write indication */
                if (ixgbe_out_i2c_byte_ack(hw, addr))
@@ -217,10 +254,14 @@ s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
                if (ixgbe_out_i2c_byte_ack(hw, csum))
                        goto fail;
                ixgbe_i2c_stop(hw);
+               if (lock)
+                       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
                return 0;
 
 fail:
                ixgbe_i2c_bus_clear(hw);
+               if (lock)
+                       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
                retry++;
                if (retry < max_retry)
                        hw_dbg(hw, "I2C byte write combined error - Retry.\n");
@@ -231,6 +272,36 @@ fail:
        return IXGBE_ERR_I2C;
 }
 
+/**
+ *  ixgbe_write_i2c_combined_generic - Perform I2C write combined operation
+ *  @hw: pointer to the hardware structure
+ *  @addr: I2C bus address to write to
+ *  @reg: I2C device register to write to
+ *  @val: value to write
+ *
+ *  Returns an error code on error.
+ */
+s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw,
+                                    u8 addr, u16 reg, u16 val)
+{
+       return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, true);
+}
+
+/**
+ *  ixgbe_write_i2c_combined_generic_unlocked - Unlocked I2C write combined
+ *  @hw: pointer to the hardware structure
+ *  @addr: I2C bus address to write to
+ *  @reg: I2C device register to write to
+ *  @val: value to write
+ *
+ *  Returns an error code on error.
+ */
+s32 ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw,
+                                             u8 addr, u16 reg, u16 val)
+{
+       return ixgbe_write_i2c_combined_generic_int(hw, addr, reg, val, false);
+}
+
 /**
  *  ixgbe_identify_phy_generic - Get physical layer module
  *  @hw: pointer to hardware structure
@@ -1100,6 +1171,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                return IXGBE_ERR_SFP_NOT_PRESENT;
        }
 
+       /* LAN ID is needed for sfp_type determination */
+       hw->mac.ops.set_lan_id(hw);
+
        status = hw->phy.ops.read_i2c_eeprom(hw,
                                             IXGBE_SFF_IDENTIFIER,
                                             &identifier);
@@ -1107,9 +1181,6 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
        if (status)
                goto err_read_i2c_eeprom;
 
-       /* LAN ID is needed for sfp_type determination */
-       hw->mac.ops.set_lan_id(hw);
-
        if (identifier != IXGBE_SFF_IDENTIFIER_SFP) {
                hw->phy.type = ixgbe_phy_sfp_unsupported;
                return IXGBE_ERR_SFP_NOT_SUPPORTED;
@@ -1159,7 +1230,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                        hw->phy.sfp_type = ixgbe_sfp_type_lr;
                else
                        hw->phy.sfp_type = ixgbe_sfp_type_unknown;
-       } else if (hw->mac.type == ixgbe_mac_82599EB) {
+       } else {
                if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
                        if (hw->bus.lan_id == 0)
                                hw->phy.sfp_type =
@@ -1660,26 +1731,46 @@ s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
 }
 
 /**
- *  ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
+ * ixgbe_is_sfp_probe - Returns true if SFP is being detected
+ * @hw: pointer to hardware structure
+ * @offset: eeprom offset to be read
+ * @addr: I2C address to be read
+ */
+static bool ixgbe_is_sfp_probe(struct ixgbe_hw *hw, u8 offset, u8 addr)
+{
+       if (addr == IXGBE_I2C_EEPROM_DEV_ADDR &&
+           offset == IXGBE_SFF_IDENTIFIER &&
+           hw->phy.sfp_type == ixgbe_sfp_type_not_present)
+               return true;
+       return false;
+}
+
+/**
+ *  ixgbe_read_i2c_byte_generic_int - Reads 8 bit word over I2C
  *  @hw: pointer to hardware structure
  *  @byte_offset: byte offset to read
  *  @data: value read
+ *  @lock: true if to take and release semaphore
  *
  *  Performs byte read operation to SFP module's EEPROM over I2C interface at
  *  a specified device address.
- **/
-s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
-                               u8 dev_addr, u8 *data)
+ */
+static s32 ixgbe_read_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
+                                          u8 dev_addr, u8 *data, bool lock)
 {
        s32 status;
        u32 max_retry = 10;
        u32 retry = 0;
        u32 swfw_mask = hw->phy.phy_semaphore_mask;
        bool nack = true;
+
+       if (ixgbe_is_sfp_probe(hw, byte_offset, dev_addr))
+               max_retry = IXGBE_SFP_DETECT_RETRIES;
+
        *data = 0;
 
        do {
-               if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+               if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
                        return IXGBE_ERR_SWFW_SYNC;
 
                ixgbe_i2c_start(hw);
@@ -1721,12 +1812,16 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
                        goto fail;
 
                ixgbe_i2c_stop(hw);
-               break;
+               if (lock)
+                       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+               return 0;
 
 fail:
                ixgbe_i2c_bus_clear(hw);
-               hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-               msleep(100);
+               if (lock) {
+                       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+                       msleep(100);
+               }
                retry++;
                if (retry < max_retry)
                        hw_dbg(hw, "I2C byte read error - Retrying.\n");
@@ -1735,29 +1830,60 @@ fail:
 
        } while (retry < max_retry);
 
-       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
-
        return status;
 }
 
 /**
- *  ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
+ *  ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: byte offset to read
+ *  @data: value read
+ *
+ *  Performs byte read operation to SFP module's EEPROM over I2C interface at
+ *  a specified device address.
+ */
+s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                               u8 dev_addr, u8 *data)
+{
+       return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
+                                              data, true);
+}
+
+/**
+ *  ixgbe_read_i2c_byte_generic_unlocked - Reads 8 bit word over I2C
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: byte offset to read
+ *  @data: value read
+ *
+ *  Performs byte read operation to SFP module's EEPROM over I2C interface at
+ *  a specified device address.
+ */
+s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+                                        u8 dev_addr, u8 *data)
+{
+       return ixgbe_read_i2c_byte_generic_int(hw, byte_offset, dev_addr,
+                                              data, false);
+}
+
+/**
+ *  ixgbe_write_i2c_byte_generic_int - Writes 8 bit word over I2C
  *  @hw: pointer to hardware structure
  *  @byte_offset: byte offset to write
  *  @data: value to write
+ *  @lock: true if to take and release semaphore
  *
  *  Performs byte write operation to SFP module's EEPROM over I2C interface at
  *  a specified device address.
- **/
-s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
-                                u8 dev_addr, u8 data)
+ */
+static s32 ixgbe_write_i2c_byte_generic_int(struct ixgbe_hw *hw, u8 byte_offset,
+                                           u8 dev_addr, u8 data, bool lock)
 {
        s32 status;
        u32 max_retry = 1;
        u32 retry = 0;
        u32 swfw_mask = hw->phy.phy_semaphore_mask;
 
-       if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+       if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
                return IXGBE_ERR_SWFW_SYNC;
 
        do {
@@ -1788,7 +1914,9 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
                        goto fail;
 
                ixgbe_i2c_stop(hw);
-               break;
+               if (lock)
+                       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+               return 0;
 
 fail:
                ixgbe_i2c_bus_clear(hw);
@@ -1799,21 +1927,57 @@ fail:
                        hw_dbg(hw, "I2C byte write error.\n");
        } while (retry < max_retry);
 
-       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+       if (lock)
+               hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 
        return status;
 }
 
+/**
+ *  ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: byte offset to write
+ *  @data: value to write
+ *
+ *  Performs byte write operation to SFP module's EEPROM over I2C interface at
+ *  a specified device address.
+ */
+s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                u8 dev_addr, u8 data)
+{
+       return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
+                                               data, true);
+}
+
+/**
+ *  ixgbe_write_i2c_byte_generic_unlocked - Writes 8 bit word over I2C
+ *  @hw: pointer to hardware structure
+ *  @byte_offset: byte offset to write
+ *  @data: value to write
+ *
+ *  Performs byte write operation to SFP module's EEPROM over I2C interface at
+ *  a specified device address.
+ */
+s32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+                                         u8 dev_addr, u8 data)
+{
+       return ixgbe_write_i2c_byte_generic_int(hw, byte_offset, dev_addr,
+                                               data, false);
+}
+
 /**
  *  ixgbe_i2c_start - Sets I2C start condition
  *  @hw: pointer to hardware structure
  *
  *  Sets I2C start condition (High -> Low on SDA while SCL is High)
+ *  Set bit-bang mode on X550 hardware.
  **/
 static void ixgbe_i2c_start(struct ixgbe_hw *hw)
 {
        u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
 
+       i2cctl |= IXGBE_I2C_BB_EN(hw);
+
        /* Start condition must begin with data and clock high */
        ixgbe_set_i2c_data(hw, &i2cctl, 1);
        ixgbe_raise_i2c_clk(hw, &i2cctl);
@@ -1838,10 +2002,15 @@ static void ixgbe_i2c_start(struct ixgbe_hw *hw)
  *  @hw: pointer to hardware structure
  *
  *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
+ *  Disables bit-bang mode and negates data output enable on X550
+ *  hardware.
  **/
 static void ixgbe_i2c_stop(struct ixgbe_hw *hw)
 {
        u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
+       u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
+       u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN(hw);
+       u32 bb_en_bit = IXGBE_I2C_BB_EN(hw);
 
        /* Stop condition must begin with data low and clock high */
        ixgbe_set_i2c_data(hw, &i2cctl, 0);
@@ -1854,6 +2023,13 @@ static void ixgbe_i2c_stop(struct ixgbe_hw *hw)
 
        /* bus free time between stop and start (4.7us)*/
        udelay(IXGBE_I2C_T_BUF);
+
+       if (bb_en_bit || data_oe_bit || clk_oe_bit) {
+               i2cctl &= ~bb_en_bit;
+               i2cctl |= data_oe_bit | clk_oe_bit;
+               IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), i2cctl);
+               IXGBE_WRITE_FLUSH(hw);
+       }
 }
 
 /**
@@ -1868,6 +2044,7 @@ static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
        s32 i;
        bool bit = false;
 
+       *data = 0;
        for (i = 7; i >= 0; i--) {
                ixgbe_clock_in_i2c_bit(hw, &bit);
                *data |= bit << i;
@@ -1901,6 +2078,7 @@ static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
        /* Release SDA line (set high) */
        i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
        i2cctl |= IXGBE_I2C_DATA_OUT(hw);
+       i2cctl |= IXGBE_I2C_DATA_OE_N_EN(hw);
        IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), i2cctl);
        IXGBE_WRITE_FLUSH(hw);
 
@@ -1915,15 +2093,21 @@ static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
  **/
 static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
 {
+       u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
        s32 status = 0;
        u32 i = 0;
        u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
        u32 timeout = 10;
        bool ack = true;
 
+       if (data_oe_bit) {
+               i2cctl |= IXGBE_I2C_DATA_OUT(hw);
+               i2cctl |= data_oe_bit;
+               IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), i2cctl);
+               IXGBE_WRITE_FLUSH(hw);
+       }
        ixgbe_raise_i2c_clk(hw, &i2cctl);
 
-
        /* Minimum high period of clock is 4us */
        udelay(IXGBE_I2C_T_HIGH);
 
@@ -1961,7 +2145,14 @@ static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
 static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
 {
        u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
+       u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
 
+       if (data_oe_bit) {
+               i2cctl |= IXGBE_I2C_DATA_OUT(hw);
+               i2cctl |= data_oe_bit;
+               IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), i2cctl);
+               IXGBE_WRITE_FLUSH(hw);
+       }
        ixgbe_raise_i2c_clk(hw, &i2cctl);
 
        /* Minimum high period of clock is 4us */
@@ -2016,13 +2207,20 @@ static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
  *  @i2cctl: Current value of I2CCTL register
  *
  *  Raises the I2C clock line '0'->'1'
+ *  Negates the I2C clock output enable on X550 hardware.
  **/
 static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
 {
+       u32 clk_oe_bit = IXGBE_I2C_CLK_OE_N_EN(hw);
        u32 i = 0;
        u32 timeout = IXGBE_I2C_CLOCK_STRETCHING_TIMEOUT;
        u32 i2cctl_r = 0;
 
+       if (clk_oe_bit) {
+               *i2cctl |= clk_oe_bit;
+               IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
+       }
+
        for (i = 0; i < timeout; i++) {
                *i2cctl |= IXGBE_I2C_CLK_OUT(hw);
                IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
@@ -2042,11 +2240,13 @@ static void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
  *  @i2cctl: Current value of I2CCTL register
  *
  *  Lowers the I2C clock line '1'->'0'
+ *  Asserts the I2C clock output enable on X550 hardware.
  **/
 static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
 {
 
        *i2cctl &= ~IXGBE_I2C_CLK_OUT(hw);
+       *i2cctl &= ~IXGBE_I2C_CLK_OE_N_EN(hw);
 
        IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
        IXGBE_WRITE_FLUSH(hw);
@@ -2062,13 +2262,17 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
  *  @data: I2C data value (0 or 1) to set
  *
  *  Sets the I2C data bit
+ *  Asserts the I2C data output enable on X550 hardware.
  **/
 static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
 {
+       u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
+
        if (data)
                *i2cctl |= IXGBE_I2C_DATA_OUT(hw);
        else
                *i2cctl &= ~IXGBE_I2C_DATA_OUT(hw);
+       *i2cctl &= ~data_oe_bit;
 
        IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
        IXGBE_WRITE_FLUSH(hw);
@@ -2076,6 +2280,14 @@ static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
        /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
        udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
 
+       if (!data)      /* Can't verify data in this case */
+               return 0;
+       if (data_oe_bit) {
+               *i2cctl |= data_oe_bit;
+               IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
+               IXGBE_WRITE_FLUSH(hw);
+       }
+
        /* Verify data was set correctly */
        *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
        if (data != ixgbe_get_i2c_data(hw, i2cctl)) {
@@ -2092,9 +2304,19 @@ static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
  *  @i2cctl: Current value of I2CCTL register
  *
  *  Returns the I2C data bit value
+ *  Negates the I2C data output enable on X550 hardware.
  **/
 static bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl)
 {
+       u32 data_oe_bit = IXGBE_I2C_DATA_OE_N_EN(hw);
+
+       if (data_oe_bit) {
+               *i2cctl |= data_oe_bit;
+               IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), *i2cctl);
+               IXGBE_WRITE_FLUSH(hw);
+               udelay(IXGBE_I2C_T_FALL);
+       }
+
        if (*i2cctl & IXGBE_I2C_DATA_IN(hw))
                return true;
        return false;
@@ -2109,10 +2331,11 @@ static bool ixgbe_get_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl)
  **/
 static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
 {
-       u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
+       u32 i2cctl;
        u32 i;
 
        ixgbe_i2c_start(hw);
+       i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
 
        ixgbe_set_i2c_data(hw, &i2cctl, 1);
 
index e45988c4dad556e9b31195f2112de3a44fcb35ab..5abd66c84d005f4d211d20bab2fd42b1a5b2a5c7 100644 (file)
@@ -66,6 +66,9 @@
 #define IXGBE_SFF_1GBASET_CAPABLE              0x8
 #define IXGBE_SFF_10GBASESR_CAPABLE            0x10
 #define IXGBE_SFF_10GBASELR_CAPABLE            0x20
+#define IXGBE_SFF_SOFT_RS_SELECT_MASK          0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_10G           0x8
+#define IXGBE_SFF_SOFT_RS_SELECT_1G            0x0
 #define IXGBE_SFF_ADDRESSING_MODE              0x4
 #define IXGBE_SFF_QSFP_DA_ACTIVE_CABLE         0x1
 #define IXGBE_SFF_QSFP_DA_PASSIVE_CABLE                0x8
 #define IXGBE_I2C_EEPROM_STATUS_FAIL           0x2
 #define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS    0x3
 #define IXGBE_CS4227                           0xBE    /* CS4227 address */
-#define IXGBE_CS4227_SPARE24_LSB               0x12B0  /* Reg to program EDC */
+#define IXGBE_CS4227_SCRATCH                   2
+#define IXGBE_CS4227_RESET_PENDING             0x1357
+#define IXGBE_CS4227_RESET_COMPLETE            0x5AA5
+#define IXGBE_CS4227_RETRIES                   15
+#define IXGBE_CS4227_EFUSE_STATUS              0x0181
+#define IXGBE_CS4227_LINE_SPARE22_MSB          0x12AD  /* Reg to set speed */
+#define IXGBE_CS4227_LINE_SPARE24_LSB          0x12B0  /* Reg to set EDC */
+#define IXGBE_CS4227_HOST_SPARE22_MSB          0x1AAD  /* Reg to set speed */
+#define IXGBE_CS4227_HOST_SPARE24_LSB          0x1AB0  /* Reg to program EDC */
+#define IXGBE_CS4227_EEPROM_STATUS             0x5001
+#define IXGBE_CS4227_EEPROM_LOAD_OK            0x0001
+#define IXGBE_CS4227_SPEED_1G                  0x8000
+#define IXGBE_CS4227_SPEED_10G                 0
 #define IXGBE_CS4227_EDC_MODE_CX1              0x0002
 #define IXGBE_CS4227_EDC_MODE_SR               0x0004
+#define IXGBE_CS4227_EDC_MODE_DIAG             0x0008
+#define IXGBE_CS4227_RESET_HOLD                        500     /* microseconds */
+#define IXGBE_CS4227_RESET_DELAY               500     /* milliseconds */
+#define IXGBE_CS4227_CHECK_DELAY               30      /* milliseconds */
+#define IXGBE_PE                               0xE0    /* Port expander addr */
+#define IXGBE_PE_OUTPUT                                1       /* Output reg offset */
+#define IXGBE_PE_CONFIG                                3       /* Config reg offset */
+#define IXGBE_PE_BIT1                          (1 << 1)
 
 /* Flow control defines */
 #define IXGBE_TAF_SYM_PAUSE                  0x400
 #define IXGBE_I2C_T_SU_STO  4
 #define IXGBE_I2C_T_BUF     5
 
+#define IXGBE_SFP_DETECT_RETRIES       2
+
 #define IXGBE_TN_LASI_STATUS_REG        0x9005
 #define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008
 
@@ -154,8 +179,12 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
 s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw);
 s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
                                u8 dev_addr, u8 *data);
+s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+                                        u8 dev_addr, u8 *data);
 s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
                                 u8 dev_addr, u8 data);
+s32 ixgbe_write_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset,
+                                         u8 dev_addr, u8 data);
 s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
                                  u8 *eeprom_data);
 s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
@@ -164,6 +193,10 @@ s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
                                   u8 eeprom_data);
 s32 ixgbe_read_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
                                    u16 reg, u16 *val);
+s32 ixgbe_read_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
+                                            u16 reg, u16 *val);
 s32 ixgbe_write_i2c_combined_generic(struct ixgbe_hw *hw, u8 addr,
                                     u16 reg, u16 val);
+s32 ixgbe_write_i2c_combined_generic_unlocked(struct ixgbe_hw *hw, u8 addr,
+                                             u16 reg, u16 val);
 #endif /* _IXGBE_PHY_H_ */
index 63689192b149a0d44d1dcf1edcfbe39f6f9d8158..939c90c4ff3917871b583c2584733554a92ebdfb 100644 (file)
@@ -402,6 +402,7 @@ struct ixgbe_thermal_sensor_data {
 #define IXGBE_FDIRSIP4M 0x0EE40
 #define IXGBE_FDIRTCPM  0x0EE44
 #define IXGBE_FDIRUDPM  0x0EE48
+#define IXGBE_FDIRSCTPM        0x0EE78
 #define IXGBE_FDIRIP6M  0x0EE74
 #define IXGBE_FDIRM     0x0EE70
 
@@ -1192,6 +1193,7 @@ struct ixgbe_thermal_sensor_data {
 /* RDRXCTL Bit Masks */
 #define IXGBE_RDRXCTL_RDMTS_1_2     0x00000000 /* Rx Desc Min Threshold Size */
 #define IXGBE_RDRXCTL_CRCSTRIP      0x00000002 /* CRC Strip */
+#define IXGBE_RDRXCTL_PSP           0x00000004 /* Pad small packet */
 #define IXGBE_RDRXCTL_MVMEN         0x00000020
 #define IXGBE_RDRXCTL_DMAIDONE      0x00000008 /* DMA init cycle done */
 #define IXGBE_RDRXCTL_AGGDIS        0x00010000 /* Aggregation disable */
@@ -1948,6 +1950,7 @@ enum {
 #define IXGBE_GSSR_SW_MNG_SM           0x0400
 #define IXGBE_GSSR_SHARED_I2C_SM       0x1806 /* Wait for both phys & I2Cs */
 #define IXGBE_GSSR_I2C_MASK            0x1800
+#define IXGBE_GSSR_NVM_PHY_MASK                0xF
 
 /* FW Status register bitmask */
 #define IXGBE_FWSTS_FWRI    0x00000200 /* Firmware Reset Indication */
@@ -3255,9 +3258,11 @@ struct ixgbe_mac_operations {
        void (*flap_tx_laser)(struct ixgbe_hw *);
        void (*stop_link_on_d3)(struct ixgbe_hw *);
        s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool);
+       s32 (*setup_mac_link)(struct ixgbe_hw *, ixgbe_link_speed, bool);
        s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
        s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
                                     bool *);
+       void (*set_rate_select_speed)(struct ixgbe_hw *, ixgbe_link_speed);
 
        /* Packet Buffer Manipulation */
        void (*set_rxpba)(struct ixgbe_hw *, int, u32, int);
@@ -3328,6 +3333,10 @@ struct ixgbe_phy_operations {
        s32 (*set_phy_power)(struct ixgbe_hw *, bool on);
        s32 (*enter_lplu)(struct ixgbe_hw *);
        s32 (*handle_lasi)(struct ixgbe_hw *hw);
+       s32 (*read_i2c_combined_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg,
+                                         u16 *value);
+       s32 (*write_i2c_combined_unlocked)(struct ixgbe_hw *, u8 addr, u16 reg,
+                                          u16 value);
 };
 
 struct ixgbe_eeprom_info {
index 4e758435ece872943231ee490ab222df6a86fa25..c1d4584f6469df00e9b12d9254f6c2e17bd1070f 100644 (file)
@@ -567,19 +567,25 @@ static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw)
  **/
 s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
 {
-       u32 swfw_sync;
-       u32 swmask = mask;
-       u32 fwmask = mask << 5;
-       u32 hwmask = 0;
+       u32 swmask = mask & IXGBE_GSSR_NVM_PHY_MASK;
+       u32 swi2c_mask = mask & IXGBE_GSSR_I2C_MASK;
+       u32 fwmask = swmask << 5;
        u32 timeout = 200;
+       u32 hwmask = 0;
+       u32 swfw_sync;
        u32 i;
 
-       if (swmask == IXGBE_GSSR_EEP_SM)
+       if (swmask & IXGBE_GSSR_EEP_SM)
                hwmask = IXGBE_GSSR_FLASH_SM;
 
+       /* SW only mask does not have FW bit pair */
+       if (mask & IXGBE_GSSR_SW_MNG_SM)
+               swmask |= IXGBE_GSSR_SW_MNG_SM;
+
+       swmask |= swi2c_mask;
+       fwmask |= swi2c_mask << 2;
        for (i = 0; i < timeout; i++) {
-               /*
-                * SW NVM semaphore bit is used for access to all
+               /* SW NVM semaphore bit is used for access to all
                 * SW_FW_SYNC bits (not just NVM)
                 */
                if (ixgbe_get_swfw_sync_semaphore(hw))
@@ -590,39 +596,56 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
                        swfw_sync |= swmask;
                        IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC(hw), swfw_sync);
                        ixgbe_release_swfw_sync_semaphore(hw);
-                       break;
-               } else {
-                       /*
-                        * Firmware currently using resource (fwmask),
-                        * hardware currently using resource (hwmask),
-                        * or other software thread currently using
-                        * resource (swmask)
-                        */
-                       ixgbe_release_swfw_sync_semaphore(hw);
-                       usleep_range(5000, 10000);
+                       usleep_range(5000, 6000);
+                       return 0;
                }
+               /* Firmware currently using resource (fwmask), hardware
+                * currently using resource (hwmask), or other software
+                * thread currently using resource (swmask)
+                */
+               ixgbe_release_swfw_sync_semaphore(hw);
+               usleep_range(5000, 10000);
        }
 
-       /*
-        * If the resource is not released by the FW/HW the SW can assume that
-        * the FW/HW malfunctions. In that case the SW should sets the
-        * SW bit(s) of the requested resource(s) while ignoring the
-        * corresponding FW/HW bits in the SW_FW_SYNC register.
-        */
-       if (i >= timeout) {
-               swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC(hw));
-               if (swfw_sync & (fwmask | hwmask)) {
-                       if (ixgbe_get_swfw_sync_semaphore(hw))
-                               return IXGBE_ERR_SWFW_SYNC;
+       /* Failed to get SW only semaphore */
+       if (swmask == IXGBE_GSSR_SW_MNG_SM) {
+               hw_dbg(hw, "Failed to get SW only semaphore\n");
+               return IXGBE_ERR_SWFW_SYNC;
+       }
 
-                       swfw_sync |= swmask;
-                       IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC(hw), swfw_sync);
-                       ixgbe_release_swfw_sync_semaphore(hw);
-               }
+       /* If the resource is not released by the FW/HW the SW can assume that
+        * the FW/HW malfunctions. In that case the SW should set the SW bit(s)
+        * of the requested resource(s) while ignoring the corresponding FW/HW
+        * bits in the SW_FW_SYNC register.
+        */
+       if (ixgbe_get_swfw_sync_semaphore(hw))
+               return IXGBE_ERR_SWFW_SYNC;
+       swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC(hw));
+       if (swfw_sync & (fwmask | hwmask)) {
+               swfw_sync |= swmask;
+               IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC(hw), swfw_sync);
+               ixgbe_release_swfw_sync_semaphore(hw);
+               usleep_range(5000, 6000);
+               return 0;
        }
+       /* If the resource is not released by other SW the SW can assume that
+        * the other SW malfunctions. In that case the SW should clear all SW
+        * flags that it does not own and then repeat the whole process once
+        * again.
+        */
+       if (swfw_sync & swmask) {
+               u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM |
+                           IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM;
+
+               if (swi2c_mask)
+                       rmask |= IXGBE_GSSR_I2C_MASK;
+               ixgbe_release_swfw_sync_X540(hw, rmask);
+               ixgbe_release_swfw_sync_semaphore(hw);
+               return IXGBE_ERR_SWFW_SYNC;
+       }
+       ixgbe_release_swfw_sync_semaphore(hw);
 
-       usleep_range(5000, 10000);
-       return 0;
+       return IXGBE_ERR_SWFW_SYNC;
 }
 
 /**
@@ -635,9 +658,11 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
  **/
 void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
 {
+       u32 swmask = mask & (IXGBE_GSSR_NVM_PHY_MASK | IXGBE_GSSR_SW_MNG_SM);
        u32 swfw_sync;
-       u32 swmask = mask;
 
+       if (mask & IXGBE_GSSR_I2C_MASK)
+               swmask |= mask & IXGBE_GSSR_I2C_MASK;
        ixgbe_get_swfw_sync_semaphore(hw);
 
        swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC(hw));
@@ -645,7 +670,7 @@ void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask)
        IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC(hw), swfw_sync);
 
        ixgbe_release_swfw_sync_semaphore(hw);
-       usleep_range(5000, 10000);
+       usleep_range(5000, 6000);
 }
 
 /**
@@ -686,6 +711,11 @@ static s32 ixgbe_get_swfw_sync_semaphore(struct ixgbe_hw *hw)
                usleep_range(50, 100);
        }
 
+       /* Release semaphores and return error if SW NVM semaphore
+        * was not granted because we do not have access to the EEPROM
+        */
+       hw_dbg(hw, "REGSMP Software NVM semaphore not granted\n");
+       ixgbe_release_swfw_sync_semaphore(hw);
        return IXGBE_ERR_EEPROM;
 }
 
index 9fe9445cd73b0061d5c2c0a7dd1f405b01f1d200..ed7b2899affe03bbaf922ad3d4a1e48e59a663ff 100644 (file)
@@ -56,6 +56,283 @@ static void ixgbe_setup_mux_ctl(struct ixgbe_hw *hw)
        IXGBE_WRITE_FLUSH(hw);
 }
 
+/**
+ * ixgbe_read_cs4227 - Read CS4227 register
+ * @hw: pointer to hardware structure
+ * @reg: register number to write
+ * @value: pointer to receive value read
+ *
+ * Returns status code
+ */
+static s32 ixgbe_read_cs4227(struct ixgbe_hw *hw, u16 reg, u16 *value)
+{
+       return hw->phy.ops.read_i2c_combined_unlocked(hw, IXGBE_CS4227, reg,
+                                                     value);
+}
+
+/**
+ * ixgbe_write_cs4227 - Write CS4227 register
+ * @hw: pointer to hardware structure
+ * @reg: register number to write
+ * @value: value to write to register
+ *
+ * Returns status code
+ */
+static s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value)
+{
+       return hw->phy.ops.write_i2c_combined_unlocked(hw, IXGBE_CS4227, reg,
+                                                      value);
+}
+
+/**
+ * ixgbe_check_cs4227_reg - Perform diag on a CS4227 register
+ * @hw: pointer to hardware structure
+ * @reg: the register to check
+ *
+ * Performs a diagnostic on a register in the CS4227 chip. Returns an error
+ * if it is not operating correctly.
+ * This function assumes that the caller has acquired the proper semaphore.
+ */
+static s32 ixgbe_check_cs4227_reg(struct ixgbe_hw *hw, u16 reg)
+{
+       s32 status;
+       u32 retry;
+       u16 reg_val;
+
+       reg_val = (IXGBE_CS4227_EDC_MODE_DIAG << 1) | 1;
+       status = ixgbe_write_cs4227(hw, reg, reg_val);
+       if (status)
+               return status;
+       for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
+               msleep(IXGBE_CS4227_CHECK_DELAY);
+               reg_val = 0xFFFF;
+               ixgbe_read_cs4227(hw, reg, &reg_val);
+               if (!reg_val)
+                       break;
+       }
+       if (reg_val) {
+               hw_err(hw, "CS4227 reg 0x%04X failed diagnostic\n", reg);
+               return status;
+       }
+
+       return 0;
+}
+
+/**
+ * ixgbe_get_cs4227_status - Return CS4227 status
+ * @hw: pointer to hardware structure
+ *
+ * Performs a diagnostic on the CS4227 chip. Returns an error if it is
+ * not operating correctly.
+ * This function assumes that the caller has acquired the proper semaphore.
+ */
+static s32 ixgbe_get_cs4227_status(struct ixgbe_hw *hw)
+{
+       s32 status;
+       u16 value = 0;
+
+       /* Exit if the diagnostic has already been performed. */
+       status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
+       if (status)
+               return status;
+       if (value == IXGBE_CS4227_RESET_COMPLETE)
+               return 0;
+
+       /* Check port 0. */
+       status = ixgbe_check_cs4227_reg(hw, IXGBE_CS4227_LINE_SPARE24_LSB);
+       if (status)
+               return status;
+
+       status = ixgbe_check_cs4227_reg(hw, IXGBE_CS4227_HOST_SPARE24_LSB);
+       if (status)
+               return status;
+
+       /* Check port 1. */
+       status = ixgbe_check_cs4227_reg(hw, IXGBE_CS4227_LINE_SPARE24_LSB +
+                                       (1 << 12));
+       if (status)
+               return status;
+
+       return ixgbe_check_cs4227_reg(hw, IXGBE_CS4227_HOST_SPARE24_LSB +
+                                     (1 << 12));
+}
+
+/**
+ * ixgbe_read_pe - Read register from port expander
+ * @hw: pointer to hardware structure
+ * @reg: register number to read
+ * @value: pointer to receive read value
+ *
+ * Returns status code
+ */
+static s32 ixgbe_read_pe(struct ixgbe_hw *hw, u8 reg, u8 *value)
+{
+       s32 status;
+
+       status = ixgbe_read_i2c_byte_generic_unlocked(hw, reg, IXGBE_PE, value);
+       if (status)
+               hw_err(hw, "port expander access failed with %d\n", status);
+       return status;
+}
+
+/**
+ * ixgbe_write_pe - Write register to port expander
+ * @hw: pointer to hardware structure
+ * @reg: register number to write
+ * @value: value to write
+ *
+ * Returns status code
+ */
+static s32 ixgbe_write_pe(struct ixgbe_hw *hw, u8 reg, u8 value)
+{
+       s32 status;
+
+       status = ixgbe_write_i2c_byte_generic_unlocked(hw, reg, IXGBE_PE,
+                                                      value);
+       if (status)
+               hw_err(hw, "port expander access failed with %d\n", status);
+       return status;
+}
+
+/**
+ * ixgbe_reset_cs4227 - Reset CS4227 using port expander
+ * @hw: pointer to hardware structure
+ *
+ * Returns error code
+ */
+static s32 ixgbe_reset_cs4227(struct ixgbe_hw *hw)
+{
+       s32 status;
+       u32 retry;
+       u16 value;
+       u8 reg;
+
+       /* Trigger hard reset. */
+       status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
+       if (status)
+               return status;
+       reg |= IXGBE_PE_BIT1;
+       status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
+       if (status)
+               return status;
+
+       status = ixgbe_read_pe(hw, IXGBE_PE_CONFIG, &reg);
+       if (status)
+               return status;
+       reg &= ~IXGBE_PE_BIT1;
+       status = ixgbe_write_pe(hw, IXGBE_PE_CONFIG, reg);
+       if (status)
+               return status;
+
+       status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
+       if (status)
+               return status;
+       reg &= ~IXGBE_PE_BIT1;
+       status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
+       if (status)
+               return status;
+
+       usleep_range(IXGBE_CS4227_RESET_HOLD, IXGBE_CS4227_RESET_HOLD + 100);
+
+       status = ixgbe_read_pe(hw, IXGBE_PE_OUTPUT, &reg);
+       if (status)
+               return status;
+       reg |= IXGBE_PE_BIT1;
+       status = ixgbe_write_pe(hw, IXGBE_PE_OUTPUT, reg);
+       if (status)
+               return status;
+
+       /* Wait for the reset to complete. */
+       msleep(IXGBE_CS4227_RESET_DELAY);
+       for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
+               status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EFUSE_STATUS,
+                                          &value);
+               if (!status && value == IXGBE_CS4227_EEPROM_LOAD_OK)
+                       break;
+               msleep(IXGBE_CS4227_CHECK_DELAY);
+       }
+       if (retry == IXGBE_CS4227_RETRIES) {
+               hw_err(hw, "CS4227 reset did not complete\n");
+               return IXGBE_ERR_PHY;
+       }
+
+       status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value);
+       if (status || !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) {
+               hw_err(hw, "CS4227 EEPROM did not load successfully\n");
+               return IXGBE_ERR_PHY;
+       }
+
+       return 0;
+}
+
+/**
+ * ixgbe_check_cs4227 - Check CS4227 and reset as needed
+ * @hw: pointer to hardware structure
+ */
+static void ixgbe_check_cs4227(struct ixgbe_hw *hw)
+{
+       u32 swfw_mask = hw->phy.phy_semaphore_mask;
+       s32 status;
+       u16 value;
+       u8 retry;
+
+       for (retry = 0; retry < IXGBE_CS4227_RETRIES; retry++) {
+               status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
+               if (status) {
+                       hw_err(hw, "semaphore failed with %d\n", status);
+                       msleep(IXGBE_CS4227_CHECK_DELAY);
+                       continue;
+               }
+
+               /* Get status of reset flow. */
+               status = ixgbe_read_cs4227(hw, IXGBE_CS4227_SCRATCH, &value);
+               if (!status && value == IXGBE_CS4227_RESET_COMPLETE)
+                       goto out;
+
+               if (status || value != IXGBE_CS4227_RESET_PENDING)
+                       break;
+
+               /* Reset is pending. Wait and check again. */
+               hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+               msleep(IXGBE_CS4227_CHECK_DELAY);
+       }
+
+       /* Reset the CS4227. */
+       status = ixgbe_reset_cs4227(hw);
+       if (status) {
+               hw_err(hw, "CS4227 reset failed: %d", status);
+               goto out;
+       }
+
+       /* Reset takes so long, temporarily release semaphore in case the
+        * other driver instance is waiting for the reset indication.
+        */
+       ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
+                          IXGBE_CS4227_RESET_PENDING);
+       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+       usleep_range(10000, 12000);
+       status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
+       if (status) {
+               hw_err(hw, "semaphore failed with %d", status);
+               return;
+       }
+
+       /* Is the CS4227 working correctly? */
+       status = ixgbe_get_cs4227_status(hw);
+       if (status) {
+               hw_err(hw, "CS4227 status failed: %d", status);
+               goto out;
+       }
+
+       /* Record completion for next time. */
+       status = ixgbe_write_cs4227(hw, IXGBE_CS4227_SCRATCH,
+                                   IXGBE_CS4227_RESET_COMPLETE);
+
+out:
+       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+       msleep(hw->eeprom.semaphore_delay);
+}
+
 /** ixgbe_identify_phy_x550em - Get PHY type based on device id
  *  @hw: pointer to hardware structure
  *
@@ -68,7 +345,7 @@ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
                /* set up for CS4227 usage */
                hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
                ixgbe_setup_mux_ctl(hw);
-
+               ixgbe_check_cs4227(hw);
                return ixgbe_identify_module_generic(hw);
        case IXGBE_DEV_ID_X550EM_X_KX4:
                hw->phy.type = ixgbe_phy_x550em_kx4;
@@ -909,6 +1186,96 @@ static s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
        return status;
 }
 
+/**
+ *  ixgbe_supported_sfp_modules_X550em - Check if SFP module type is supported
+ *  @hw: pointer to hardware structure
+ *  @linear: true if SFP module is linear
+ */
+static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear)
+{
+       switch (hw->phy.sfp_type) {
+       case ixgbe_sfp_type_not_present:
+               return IXGBE_ERR_SFP_NOT_PRESENT;
+       case ixgbe_sfp_type_da_cu_core0:
+       case ixgbe_sfp_type_da_cu_core1:
+               *linear = true;
+               break;
+       case ixgbe_sfp_type_srlr_core0:
+       case ixgbe_sfp_type_srlr_core1:
+       case ixgbe_sfp_type_da_act_lmt_core0:
+       case ixgbe_sfp_type_da_act_lmt_core1:
+       case ixgbe_sfp_type_1g_sx_core0:
+       case ixgbe_sfp_type_1g_sx_core1:
+       case ixgbe_sfp_type_1g_lx_core0:
+       case ixgbe_sfp_type_1g_lx_core1:
+               *linear = false;
+               break;
+       case ixgbe_sfp_type_unknown:
+       case ixgbe_sfp_type_1g_cu_core0:
+       case ixgbe_sfp_type_1g_cu_core1:
+       default:
+               return IXGBE_ERR_SFP_NOT_SUPPORTED;
+       }
+
+       return 0;
+}
+
+/**
+ *  ixgbe_setup_mac_link_sfp_x550em - Configure the KR PHY for SFP.
+ *  @hw: pointer to hardware structure
+ *
+ *  Configures the extern PHY and the integrated KR PHY for SFP support.
+ */
+static s32
+ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw,
+                               ixgbe_link_speed speed,
+                               __always_unused bool autoneg_wait_to_complete)
+{
+       s32 status;
+       u16 slice, value;
+       bool setup_linear = false;
+
+       /* Check if SFP module is supported and linear */
+       status = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear);
+
+       /* If no SFP module present, then return success. Return success since
+        * there is no reason to configure CS4227 and SFP not present error is
+        * not accepted in the setup MAC link flow.
+        */
+       if (status == IXGBE_ERR_SFP_NOT_PRESENT)
+               return 0;
+
+       if (status)
+               return status;
+
+       /* Configure CS4227 LINE side to 10G SR. */
+       slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12);
+       value = IXGBE_CS4227_SPEED_10G;
+       status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, slice,
+                                                 value);
+
+       /* Configure CS4227 for HOST connection rate then type. */
+       slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12);
+       value = speed & IXGBE_LINK_SPEED_10GB_FULL ?
+               IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G;
+       status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, slice,
+                                                 value);
+
+       slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12);
+       if (setup_linear)
+               value = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
+       else
+               value = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
+       status = ixgbe_write_i2c_combined_generic(hw, IXGBE_CS4227, slice,
+                                                 value);
+
+       /* If internal link mode is XFI, then setup XFI internal link. */
+       if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE))
+               status = ixgbe_setup_ixfi_x550em(hw, &speed);
+
+       return status;
+}
+
 /**
  * ixgbe_setup_mac_link_t_X550em - Sets the auto advertised link speed
  * @hw: pointer to hardware structure
@@ -1003,6 +1370,10 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
                mac->ops.disable_tx_laser = NULL;
                mac->ops.enable_tx_laser = NULL;
                mac->ops.flap_tx_laser = NULL;
+               mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
+               mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
+               mac->ops.set_rate_select_speed =
+                                       ixgbe_set_soft_rate_select_speed;
                break;
        case ixgbe_media_type_copper:
                mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
@@ -1018,53 +1389,18 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
  */
 static s32 ixgbe_setup_sfp_modules_X550em(struct ixgbe_hw *hw)
 {
-       bool setup_linear;
-       u16 reg_slice, edc_mode;
-       s32 ret_val;
+       s32 status;
+       bool linear;
 
-       switch (hw->phy.sfp_type) {
-       case ixgbe_sfp_type_unknown:
-               return 0;
-       case ixgbe_sfp_type_not_present:
-               return IXGBE_ERR_SFP_NOT_PRESENT;
-       case ixgbe_sfp_type_da_cu_core0:
-       case ixgbe_sfp_type_da_cu_core1:
-               setup_linear = true;
-               break;
-       case ixgbe_sfp_type_srlr_core0:
-       case ixgbe_sfp_type_srlr_core1:
-       case ixgbe_sfp_type_da_act_lmt_core0:
-       case ixgbe_sfp_type_da_act_lmt_core1:
-       case ixgbe_sfp_type_1g_sx_core0:
-       case ixgbe_sfp_type_1g_sx_core1:
-               setup_linear = false;
-               break;
-       default:
-               return IXGBE_ERR_SFP_NOT_SUPPORTED;
-       }
+       /* Check if SFP module is supported */
+       status = ixgbe_supported_sfp_modules_X550em(hw, &linear);
+       if (status)
+               return status;
 
        ixgbe_init_mac_link_ops_X550em(hw);
        hw->phy.ops.reset = NULL;
 
-       /* The CS4227 slice address is the base address + the port-pair reg
-        * offset. I.e. Slice 0 = 0x12B0 and slice 1 = 0x22B0.
-        */
-       reg_slice = IXGBE_CS4227_SPARE24_LSB + (hw->bus.lan_id << 12);
-
-       if (setup_linear)
-               edc_mode = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
-       else
-               edc_mode = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
-
-       /* Configure CS4227 for connection type. */
-       ret_val = hw->phy.ops.write_i2c_combined(hw, IXGBE_CS4227, reg_slice,
-                                                edc_mode);
-
-       if (ret_val)
-               ret_val = hw->phy.ops.write_i2c_combined(hw, 0x80, reg_slice,
-                                                        edc_mode);
-
-       return ret_val;
+       return 0;
 }
 
 /** ixgbe_get_link_capabilities_x550em - Determines link capabilities
@@ -1927,6 +2263,62 @@ static void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw,
        IXGBE_WRITE_REG(hw, IXGBE_PFFLPH, (u32)(pfflp >> 32));
 }
 
+/**
+ * ixgbe_set_mux - Set mux for port 1 access with CS4227
+ * @hw: pointer to hardware structure
+ * @state: set mux if 1, clear if 0
+ */
+static void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state)
+{
+       u32 esdp;
+
+       if (!hw->bus.lan_id)
+               return;
+       esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+       if (state)
+               esdp |= IXGBE_ESDP_SDP1;
+       else
+               esdp &= ~IXGBE_ESDP_SDP1;
+       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
+       IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ * ixgbe_acquire_swfw_sync_X550em - Acquire SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to acquire
+ *
+ * Acquires the SWFW semaphore and sets the I2C MUX
+ */
+static s32 ixgbe_acquire_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
+{
+       s32 status;
+
+       status = ixgbe_acquire_swfw_sync_X540(hw, mask);
+       if (status)
+               return status;
+
+       if (mask & IXGBE_GSSR_I2C_MASK)
+               ixgbe_set_mux(hw, 1);
+
+       return 0;
+}
+
+/**
+ * ixgbe_release_swfw_sync_X550em - Release SWFW semaphore
+ * @hw: pointer to hardware structure
+ * @mask: Mask to specify which semaphore to release
+ *
+ * Releases the SWFW semaphore and sets the I2C MUX
+ */
+static void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
+{
+       if (mask & IXGBE_GSSR_I2C_MASK)
+               ixgbe_set_mux(hw, 0);
+
+       ixgbe_release_swfw_sync_X540(hw, mask);
+}
+
 #define X550_COMMON_MAC \
        .init_hw                        = &ixgbe_init_hw_generic, \
        .start_hw                       = &ixgbe_start_hw_X540, \
@@ -1964,8 +2356,6 @@ static void ixgbe_set_source_address_pruning_X550(struct ixgbe_hw *hw,
                                &ixgbe_set_source_address_pruning_X550, \
        .set_ethertype_anti_spoofing    = \
                                &ixgbe_set_ethertype_anti_spoofing_X550, \
-       .acquire_swfw_sync              = &ixgbe_acquire_swfw_sync_X540, \
-       .release_swfw_sync              = &ixgbe_release_swfw_sync_X540, \
        .disable_rx_buff                = &ixgbe_disable_rx_buff_generic, \
        .enable_rx_buff                 = &ixgbe_enable_rx_buff_generic, \
        .get_thermal_sensor_data        = NULL, \
@@ -1985,6 +2375,8 @@ static struct ixgbe_mac_operations mac_ops_X550 = {
        .get_link_capabilities  = &ixgbe_get_copper_link_capabilities_generic,
        .get_bus_info           = &ixgbe_get_bus_info_generic,
        .setup_sfp              = NULL,
+       .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X540,
+       .release_swfw_sync      = &ixgbe_release_swfw_sync_X540,
 };
 
 static struct ixgbe_mac_operations mac_ops_X550EM_x = {
@@ -1997,7 +2389,8 @@ static struct ixgbe_mac_operations mac_ops_X550EM_x = {
        .get_link_capabilities  = &ixgbe_get_link_capabilities_X550em,
        .get_bus_info           = &ixgbe_get_bus_info_X550em,
        .setup_sfp              = ixgbe_setup_sfp_modules_X550em,
-
+       .acquire_swfw_sync      = &ixgbe_acquire_swfw_sync_X550em,
+       .release_swfw_sync      = &ixgbe_release_swfw_sync_X550em,
 };
 
 #define X550_COMMON_EEP \
@@ -2039,14 +2432,17 @@ static struct ixgbe_phy_operations phy_ops_X550 = {
        X550_COMMON_PHY
        .init                   = NULL,
        .identify               = &ixgbe_identify_phy_generic,
-       .read_i2c_combined      = &ixgbe_read_i2c_combined_generic,
-       .write_i2c_combined     = &ixgbe_write_i2c_combined_generic,
 };
 
 static struct ixgbe_phy_operations phy_ops_X550EM_x = {
        X550_COMMON_PHY
        .init                   = &ixgbe_init_phy_ops_X550em,
        .identify               = &ixgbe_identify_phy_x550em,
+       .read_i2c_combined      = &ixgbe_read_i2c_combined_generic,
+       .write_i2c_combined     = &ixgbe_write_i2c_combined_generic,
+       .read_i2c_combined_unlocked = &ixgbe_read_i2c_combined_generic_unlocked,
+       .write_i2c_combined_unlocked =
+                                    &ixgbe_write_i2c_combined_generic_unlocked,
 };
 
 static const u32 ixgbe_mvals_X550[IXGBE_MVALS_IDX_LIMIT] = {
index 149a0b4489be4088514f9e02c7c768629185449f..35da2d74e73ecc74f567a528cb2ebffd9a25edcd 100644 (file)
@@ -3896,6 +3896,7 @@ static const struct net_device_ops ixgbevf_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = ixgbevf_netpoll,
 #endif
+       .ndo_features_check     = passthru_features_check,
 };
 
 static void ixgbevf_assign_netdev_ops(struct net_device *dev)
index 34ac41ac9e610b63e5bf3db276f64b215cce733c..32c5429ea5fee4904802fd0461fd0afa08b1d003 100644 (file)
@@ -152,8 +152,9 @@ struct rocker_fdb_tbl_entry {
        struct hlist_node entry;
        u32 key_crc32; /* key */
        bool learned;
+       unsigned long touched;
        struct rocker_fdb_tbl_key {
-               u32 pport;
+               struct rocker_port *rocker_port;
                u8 addr[ETH_ALEN];
                __be16 vlan_id;
        } key;
@@ -220,6 +221,7 @@ struct rocker_port {
        __be16 internal_vlan_id;
        int stp_state;
        u32 brport_flags;
+       unsigned long ageing_time;
        bool ctrls[ROCKER_CTRL_MAX];
        unsigned long vlan_bitmap[ROCKER_VLAN_BITMAP_LEN];
        struct napi_struct napi_tx;
@@ -246,6 +248,7 @@ struct rocker {
        u64 flow_tbl_next_cookie;
        DECLARE_HASHTABLE(group_tbl, 16);
        spinlock_t group_tbl_lock;              /* for group tbl accesses */
+       struct timer_list fdb_cleanup_timer;
        DECLARE_HASHTABLE(fdb_tbl, 16);
        spinlock_t fdb_tbl_lock;                /* for fdb tbl accesses */
        unsigned long internal_vlan_bitmap[ROCKER_INTERNAL_VLAN_BITMAP_LEN];
@@ -3629,7 +3632,8 @@ static int rocker_port_fdb(struct rocker_port *rocker_port,
                return -ENOMEM;
 
        fdb->learned = (flags & ROCKER_OP_FLAG_LEARNED);
-       fdb->key.pport = rocker_port->pport;
+       fdb->touched = jiffies;
+       fdb->key.rocker_port = rocker_port;
        ether_addr_copy(fdb->key.addr, addr);
        fdb->key.vlan_id = vlan_id;
        fdb->key_crc32 = crc32(~0, &fdb->key, sizeof(fdb->key));
@@ -3638,13 +3642,17 @@ static int rocker_port_fdb(struct rocker_port *rocker_port,
 
        found = rocker_fdb_tbl_find(rocker, fdb);
 
-       if (removing && found) {
-               rocker_port_kfree(trans, fdb);
-               if (trans != SWITCHDEV_TRANS_PREPARE)
-                       hash_del(&found->entry);
-       } else if (!removing && !found) {
+       if (found) {
+               found->touched = jiffies;
+               if (removing) {
+                       rocker_port_kfree(trans, fdb);
+                       if (trans != SWITCHDEV_TRANS_PREPARE)
+                               hash_del(&found->entry);
+               }
+       } else if (!removing) {
                if (trans != SWITCHDEV_TRANS_PREPARE)
-                       hash_add(rocker->fdb_tbl, &fdb->entry, fdb->key_crc32);
+                       hash_add(rocker->fdb_tbl, &fdb->entry,
+                                fdb->key_crc32);
        }
 
        spin_unlock_irqrestore(&rocker->fdb_tbl_lock, lock_flags);
@@ -3680,7 +3688,7 @@ static int rocker_port_fdb_flush(struct rocker_port *rocker_port,
        spin_lock_irqsave(&rocker->fdb_tbl_lock, lock_flags);
 
        hash_for_each_safe(rocker->fdb_tbl, bkt, tmp, found, entry) {
-               if (found->key.pport != rocker_port->pport)
+               if (found->key.rocker_port != rocker_port)
                        continue;
                if (!found->learned)
                        continue;
@@ -3699,6 +3707,41 @@ err_out:
        return err;
 }
 
+static void rocker_fdb_cleanup(unsigned long data)
+{
+       struct rocker *rocker = (struct rocker *)data;
+       struct rocker_port *rocker_port;
+       struct rocker_fdb_tbl_entry *entry;
+       struct hlist_node *tmp;
+       unsigned long next_timer = jiffies + BR_MIN_AGEING_TIME;
+       unsigned long expires;
+       unsigned long lock_flags;
+       int flags = ROCKER_OP_FLAG_NOWAIT | ROCKER_OP_FLAG_REMOVE |
+                   ROCKER_OP_FLAG_LEARNED;
+       int bkt;
+
+       spin_lock_irqsave(&rocker->fdb_tbl_lock, lock_flags);
+
+       hash_for_each_safe(rocker->fdb_tbl, bkt, tmp, entry, entry) {
+               if (!entry->learned)
+                       continue;
+               rocker_port = entry->key.rocker_port;
+               expires = entry->touched + rocker_port->ageing_time;
+               if (time_before_eq(expires, jiffies)) {
+                       rocker_port_fdb_learn(rocker_port, SWITCHDEV_TRANS_NONE,
+                                             flags, entry->key.addr,
+                                             entry->key.vlan_id);
+                       hash_del(&entry->entry);
+               } else if (time_before(expires, next_timer)) {
+                       next_timer = expires;
+               }
+       }
+
+       spin_unlock_irqrestore(&rocker->fdb_tbl_lock, lock_flags);
+
+       mod_timer(&rocker->fdb_cleanup_timer, round_jiffies_up(next_timer));
+}
+
 static int rocker_port_router_mac(struct rocker_port *rocker_port,
                                  enum switchdev_trans trans, int flags,
                                  __be16 vlan_id)
@@ -4547,7 +4590,7 @@ static int rocker_port_fdb_dump(const struct rocker_port *rocker_port,
 
        spin_lock_irqsave(&rocker->fdb_tbl_lock, lock_flags);
        hash_for_each_safe(rocker->fdb_tbl, bkt, tmp, found, entry) {
-               if (found->key.pport != rocker_port->pport)
+               if (found->key.rocker_port != rocker_port)
                        continue;
                fdb->addr = found->key.addr;
                fdb->ndm_state = NUD_REACHABLE;
@@ -4969,6 +5012,7 @@ static int rocker_probe_port(struct rocker *rocker, unsigned int port_number)
        rocker_port->port_number = port_number;
        rocker_port->pport = port_number + 1;
        rocker_port->brport_flags = BR_LEARNING | BR_LEARNING_SYNC;
+       rocker_port->ageing_time = BR_DEFAULT_AGEING_TIME;
        INIT_LIST_HEAD(&rocker_port->trans_mem);
 
        rocker_port_dev_addr_init(rocker_port);
@@ -5183,6 +5227,10 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                goto err_init_tbls;
        }
 
+       setup_timer(&rocker->fdb_cleanup_timer, rocker_fdb_cleanup,
+                   (unsigned long) rocker);
+       mod_timer(&rocker->fdb_cleanup_timer, jiffies);
+
        err = rocker_probe_ports(rocker);
        if (err) {
                dev_err(&pdev->dev, "failed to probe ports\n");
@@ -5195,6 +5243,7 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        return 0;
 
 err_probe_ports:
+       del_timer_sync(&rocker->fdb_cleanup_timer);
        rocker_free_tbls(rocker);
 err_init_tbls:
        free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);
@@ -5222,6 +5271,7 @@ static void rocker_remove(struct pci_dev *pdev)
 {
        struct rocker *rocker = pci_get_drvdata(pdev);
 
+       del_timer_sync(&rocker->fdb_cleanup_timer);
        rocker_free_tbls(rocker);
        rocker_write32(rocker, CONTROL, ROCKER_CONTROL_RESET);
        rocker_remove_ports(rocker);
index 39a54b27db6649707e587c2b0f036210605babcb..33bd3b902304f3e737ad08c616d43d9b75c86dce 100644 (file)
@@ -1861,8 +1861,12 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv)
        pdata->no_bd_ram = of_property_read_bool(np, "ti,davinci-no-bd-ram");
 
        priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
-       if (!priv->phy_node)
-               pdata->phy_id = NULL;
+       if (!priv->phy_node) {
+               if (!of_phy_is_fixed_link(np))
+                       pdata->phy_id = NULL;
+               else if (of_phy_register_fixed_link(np) >= 0)
+                       priv->phy_node = of_node_get(np);
+       }
 
        auxdata = pdev->dev.platform_data;
        if (auxdata) {
index 8cf9d4f56bb2223893dd912e1d475a48fc30f683..415de1eaf6412665fbaba35b7e67742819ebacd5 100644 (file)
@@ -59,16 +59,15 @@ static int temac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
 int temac_mdio_setup(struct temac_local *lp, struct device_node *np)
 {
        struct mii_bus *bus;
-       const u32 *bus_hz;
+       u32 bus_hz;
        int clk_div;
-       int rc, size;
+       int rc;
        struct resource res;
 
        /* Calculate a reasonable divisor for the clock rate */
        clk_div = 0x3f; /* worst-case default setting */
-       bus_hz = of_get_property(np, "clock-frequency", &size);
-       if (bus_hz && size >= sizeof(*bus_hz)) {
-               clk_div = (*bus_hz) / (2500 * 1000 * 2) - 1;
+       if (of_property_read_u32(np, "clock-frequency", &bus_hz) == 0) {
+               clk_div = bus_hz / (2500 * 1000 * 2) - 1;
                if (clk_div < 1)
                        clk_div = 1;
                if (clk_div > 0x3f)
index 2a5a16834c017c1c32e66591c7618ab47b9f8927..507bbb0355c23129c66a17a24717d6313e83d6e1 100644 (file)
@@ -129,7 +129,6 @@ int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np)
 {
        int ret;
        u32 clk_div, host_clock;
-       u32 *property_p;
        struct mii_bus *bus;
        struct resource res;
        struct device_node *np1;
@@ -168,8 +167,7 @@ int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np)
                clk_div = DEFAULT_CLOCK_DIVISOR;
                goto issue;
        }
-       property_p = (u32 *) of_get_property(np1, "clock-frequency", NULL);
-       if (!property_p) {
+       if (of_property_read_u32(np1, "clock-frequency", &host_clock)) {
                netdev_warn(lp->ndev, "clock-frequency property not found.\n");
                netdev_warn(lp->ndev,
                            "Setting MDIO clock divisor to default %d\n",
@@ -179,7 +177,6 @@ int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np)
                goto issue;
        }
 
-       host_clock = be32_to_cpup(property_p);
        clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1;
        /* If there is any remainder from the division of
         * fHOST / (MAX_MDIO_FREQ * 2), then we need to add
index efc18e05af0aed216144e91b7a835342a1b30a59..bbde9884ab8ae7fb952cbf6583feff10c9ce1109 100644 (file)
@@ -342,7 +342,7 @@ static void do_neigh_solicit(struct usbnet *dev, u8 *buf, u16 tci)
        in6_dev_put(in6_dev);
 
        /* ipv6_stub != NULL if in6_dev_get returned an inet6_dev */
-       ipv6_stub->ndisc_send_na(netdev, NULL, &iph->saddr, &msg->target,
+       ipv6_stub->ndisc_send_na(netdev, &iph->saddr, &msg->target,
                                 is_router /* router */,
                                 true /* solicited */,
                                 false /* override */,
index c1d0e7a9da04c36c58c43b6c8c432a1d8a8720f1..a681569ae0b5be395d8589acf818cbf37bde5479 100644 (file)
@@ -183,16 +183,22 @@ vmxnet3_get_sset_count(struct net_device *netdev, int sset)
 }
 
 
-/* Should be multiple of 4 */
-#define NUM_TX_REGS    8
-#define NUM_RX_REGS    12
-
+/* This is a version 2 of the vmxnet3 ethtool_regs which goes hand in hand with
+ * the version 2 of the vmxnet3 support for ethtool(8) --register-dump.
+ * Therefore, if any registers are added, removed or modified, then a version
+ * bump and a corresponding change in the vmxnet3 support for ethtool(8)
+ * --register-dump would be required.
+ */
 static int
 vmxnet3_get_regs_len(struct net_device *netdev)
 {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
-       return (adapter->num_tx_queues * NUM_TX_REGS * sizeof(u32) +
-               adapter->num_rx_queues * NUM_RX_REGS * sizeof(u32));
+
+       return ((9 /* BAR1 registers */ +
+               (1 + adapter->intr.num_intrs) +
+               (1 + adapter->num_tx_queues * 17 /* Tx queue registers */) +
+               (1 + adapter->num_rx_queues * 23 /* Rx queue registers */)) *
+               sizeof(u32));
 }
 
 
@@ -342,6 +348,12 @@ vmxnet3_get_ethtool_stats(struct net_device *netdev,
 }
 
 
+/* This is a version 2 of the vmxnet3 ethtool_regs which goes hand in hand with
+ * the version 2 of the vmxnet3 support for ethtool(8) --register-dump.
+ * Therefore, if any registers are added, removed or modified, then a version
+ * bump and a corresponding change in the vmxnet3 support for ethtool(8)
+ * --register-dump would be required.
+ */
 static void
 vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
 {
@@ -351,40 +363,90 @@ vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
 
        memset(p, 0, vmxnet3_get_regs_len(netdev));
 
-       regs->version = 1;
+       regs->version = 2;
 
        /* Update vmxnet3_get_regs_len if we want to dump more registers */
 
-       /* make each ring use multiple of 16 bytes */
-       for (i = 0; i < adapter->num_tx_queues; i++) {
-               buf[j++] = adapter->tx_queue[i].tx_ring.next2fill;
-               buf[j++] = adapter->tx_queue[i].tx_ring.next2comp;
-               buf[j++] = adapter->tx_queue[i].tx_ring.gen;
-               buf[j++] = 0;
+       buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_VRRS);
+       buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_UVRS);
+       buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_DSAL);
+       buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_DSAH);
+       buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
+       buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACL);
+       buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACH);
+       buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ICR);
+       buf[j++] = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ECR);
+
+       buf[j++] = adapter->intr.num_intrs;
+       for (i = 0; i < adapter->intr.num_intrs; i++) {
+               buf[j++] = VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_IMR
+                                                + i * VMXNET3_REG_ALIGN);
+       }
 
-               buf[j++] = adapter->tx_queue[i].comp_ring.next2proc;
-               buf[j++] = adapter->tx_queue[i].comp_ring.gen;
-               buf[j++] = adapter->tx_queue[i].stopped;
-               buf[j++] = 0;
+       buf[j++] = adapter->num_tx_queues;
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               struct vmxnet3_tx_queue *tq = &adapter->tx_queue[i];
+
+               buf[j++] = VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_TXPROD +
+                                                i * VMXNET3_REG_ALIGN);
+
+               buf[j++] = VMXNET3_GET_ADDR_LO(tq->tx_ring.basePA);
+               buf[j++] = VMXNET3_GET_ADDR_HI(tq->tx_ring.basePA);
+               buf[j++] = tq->tx_ring.size;
+               buf[j++] = tq->tx_ring.next2fill;
+               buf[j++] = tq->tx_ring.next2comp;
+               buf[j++] = tq->tx_ring.gen;
+
+               buf[j++] = VMXNET3_GET_ADDR_LO(tq->data_ring.basePA);
+               buf[j++] = VMXNET3_GET_ADDR_HI(tq->data_ring.basePA);
+               buf[j++] = tq->data_ring.size;
+               /* transmit data ring buffer size */
+               buf[j++] = VMXNET3_HDR_COPY_SIZE;
+
+               buf[j++] = VMXNET3_GET_ADDR_LO(tq->comp_ring.basePA);
+               buf[j++] = VMXNET3_GET_ADDR_HI(tq->comp_ring.basePA);
+               buf[j++] = tq->comp_ring.size;
+               buf[j++] = tq->comp_ring.next2proc;
+               buf[j++] = tq->comp_ring.gen;
+
+               buf[j++] = tq->stopped;
        }
 
+       buf[j++] = adapter->num_rx_queues;
        for (i = 0; i < adapter->num_rx_queues; i++) {
-               buf[j++] = adapter->rx_queue[i].rx_ring[0].next2fill;
-               buf[j++] = adapter->rx_queue[i].rx_ring[0].next2comp;
-               buf[j++] = adapter->rx_queue[i].rx_ring[0].gen;
+               struct vmxnet3_rx_queue *rq = &adapter->rx_queue[i];
+
+               buf[j++] =  VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_RXPROD +
+                                                 i * VMXNET3_REG_ALIGN);
+               buf[j++] =  VMXNET3_READ_BAR0_REG(adapter, VMXNET3_REG_RXPROD2 +
+                                                 i * VMXNET3_REG_ALIGN);
+
+               buf[j++] = VMXNET3_GET_ADDR_LO(rq->rx_ring[0].basePA);
+               buf[j++] = VMXNET3_GET_ADDR_HI(rq->rx_ring[0].basePA);
+               buf[j++] = rq->rx_ring[0].size;
+               buf[j++] = rq->rx_ring[0].next2fill;
+               buf[j++] = rq->rx_ring[0].next2comp;
+               buf[j++] = rq->rx_ring[0].gen;
+
+               buf[j++] = VMXNET3_GET_ADDR_LO(rq->rx_ring[1].basePA);
+               buf[j++] = VMXNET3_GET_ADDR_HI(rq->rx_ring[1].basePA);
+               buf[j++] = rq->rx_ring[1].size;
+               buf[j++] = rq->rx_ring[1].next2fill;
+               buf[j++] = rq->rx_ring[1].next2comp;
+               buf[j++] = rq->rx_ring[1].gen;
+
+               /* receive data ring */
                buf[j++] = 0;
-
-               buf[j++] = adapter->rx_queue[i].rx_ring[1].next2fill;
-               buf[j++] = adapter->rx_queue[i].rx_ring[1].next2comp;
-               buf[j++] = adapter->rx_queue[i].rx_ring[1].gen;
                buf[j++] = 0;
-
-               buf[j++] = adapter->rx_queue[i].comp_ring.next2proc;
-               buf[j++] = adapter->rx_queue[i].comp_ring.gen;
                buf[j++] = 0;
                buf[j++] = 0;
-       }
 
+               buf[j++] = VMXNET3_GET_ADDR_LO(rq->comp_ring.basePA);
+               buf[j++] = VMXNET3_GET_ADDR_HI(rq->comp_ring.basePA);
+               buf[j++] = rq->comp_ring.size;
+               buf[j++] = rq->comp_ring.next2proc;
+               buf[j++] = rq->comp_ring.gen;
+       }
 }
 
 
index 2652245631d12f5016915721d5f93268cb4453c1..3f859a55c035d6ab3b53530c4345083424566404 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.4.2.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.4.3.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01040200
+#define VMXNET3_DRIVER_VERSION_NUM      0x01040300
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
index 520bef80747f295bea9f98e4ca2573bbc5dde48a..66c963dbc3fd26427043a6aefe817a1938d89a9e 100644 (file)
@@ -2190,9 +2190,8 @@ static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
                                   struct genl_info *info)
 {
        if (info)
-               genl_notify(&hwsim_genl_family, mcast_skb,
-                           genl_info_net(info), info->snd_portid,
-                           HWSIM_MCGRP_CONFIG, info->nlhdr, GFP_KERNEL);
+               genl_notify(&hwsim_genl_family, mcast_skb, info,
+                           HWSIM_MCGRP_CONFIG, GFP_KERNEL);
        else
                genlmsg_multicast(&hwsim_genl_family, mcast_skb, 0,
                                  HWSIM_MCGRP_CONFIG, GFP_KERNEL);
diff --git a/include/linux/arcdevice.h b/include/linux/arcdevice.h
deleted file mode 100644 (file)
index df03562..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * INET         An implementation of the TCP/IP protocol suite for the LINUX
- *              operating system.  NET  is implemented using the  BSD Socket
- *              interface as the means of communication with the user level.
- *
- *              Definitions used by the ARCnet driver.
- *
- * Authors:     Avery Pennarun and David Woodhouse
- *
- *              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.
- *
- */
-#ifndef _LINUX_ARCDEVICE_H
-#define _LINUX_ARCDEVICE_H
-
-#include <asm/timex.h>
-#include <linux/if_arcnet.h>
-
-#ifdef __KERNEL__
-#include  <linux/irqreturn.h>
-
-/*
- * RECON_THRESHOLD is the maximum number of RECON messages to receive
- * within one minute before printing a "cabling problem" warning. The
- * default value should be fine.
- *
- * After that, a "cabling restored" message will be printed on the next IRQ
- * if no RECON messages have been received for 10 seconds.
- *
- * Do not define RECON_THRESHOLD at all if you want to disable this feature.
- */
-#define RECON_THRESHOLD 30
-
-
-/*
- * Define this to the minimum "timeout" value.  If a transmit takes longer
- * than TX_TIMEOUT jiffies, Linux will abort the TX and retry.  On a large
- * network, or one with heavy network traffic, this timeout may need to be
- * increased.  The larger it is, though, the longer it will be between
- * necessary transmits - don't set this too high.
- */
-#define TX_TIMEOUT (HZ * 200 / 1000)
-
-
-/* Display warnings about the driver being an ALPHA version. */
-#undef ALPHA_WARNING
-
-
-/*
- * Debugging bitflags: each option can be enabled individually.
- * 
- * Note: only debug flags included in the ARCNET_DEBUG_MAX define will
- *   actually be available.  GCC will (at least, GCC 2.7.0 will) notice
- *   lines using a BUGLVL not in ARCNET_DEBUG_MAX and automatically optimize
- *   them out.
- */
-#define D_NORMAL       1       /* important operational info             */
-#define D_EXTRA                2       /* useful, but non-vital information      */
-#define        D_INIT          4       /* show init/probe messages               */
-#define D_INIT_REASONS 8       /* show reasons for discarding probes     */
-#define D_RECON                32      /* print a message whenever token is lost */
-#define D_PROTO                64      /* debug auto-protocol support            */
-/* debug levels below give LOTS of output during normal operation! */
-#define D_DURING       128     /* trace operations (including irq's)     */
-#define D_TX           256     /* show tx packets                        */
-#define D_RX           512     /* show rx packets                        */
-#define D_SKB          1024    /* show skb's                             */
-#define D_SKB_SIZE     2048    /* show skb sizes                         */
-#define D_TIMING       4096    /* show time needed to copy buffers to card */
-#define D_DEBUG         8192    /* Very detailed debug line for line */
-
-#ifndef ARCNET_DEBUG_MAX
-#define ARCNET_DEBUG_MAX (127) /* change to ~0 if you want detailed debugging */
-#endif
-
-#ifndef ARCNET_DEBUG
-#define ARCNET_DEBUG (D_NORMAL|D_EXTRA)
-#endif
-extern int arcnet_debug;
-
-/* macros to simplify debug checking */
-#define BUGLVL(x) if ((ARCNET_DEBUG_MAX)&arcnet_debug&(x))
-#define BUGMSG2(x,msg,args...) do { BUGLVL(x) printk(msg, ## args); } while (0)
-#define BUGMSG(x,msg,args...) \
-       BUGMSG2(x, "%s%6s: " msg, \
-            x==D_NORMAL        ? KERN_WARNING \
-                       : x < D_DURING ? KERN_INFO : KERN_DEBUG, \
-           dev->name , ## args)
-
-/* see how long a function call takes to run, expressed in CPU cycles */
-#define TIME(name, bytes, call) BUGLVL(D_TIMING) { \
-           unsigned long _x, _y; \
-           _x = get_cycles(); \
-           call; \
-           _y = get_cycles(); \
-           BUGMSG(D_TIMING, \
-              "%s: %d bytes in %lu cycles == " \
-              "%lu Kbytes/100Mcycle\n",\
-                  name, bytes, _y - _x, \
-                  100000000 / 1024 * bytes / (_y - _x + 1));\
-       } \
-       else { \
-                   call;\
-       }
-
-
-/*
- * Time needed to reset the card - in ms (milliseconds).  This works on my
- * SMC PC100.  I can't find a reference that tells me just how long I
- * should wait.
- */
-#define RESETtime (300)
-
-/*
- * These are the max/min lengths of packet payload, not including the
- * arc_hardware header, but definitely including the soft header.
- *
- * Note: packet sizes 254, 255, 256 are impossible because of the way
- * ARCnet registers work  That's why RFC1201 defines "exception" packets.
- * In non-RFC1201 protocols, we have to just tack some extra bytes on the
- * end.
- */
-#define MTU    253             /* normal packet max size */
-#define MinTU  257             /* extended packet min size */
-#define XMTU   508             /* extended packet max size */
-
-/* status/interrupt mask bit fields */
-#define TXFREEflag     0x01    /* transmitter available */
-#define TXACKflag       0x02   /* transmitted msg. ackd */
-#define RECONflag       0x04   /* network reconfigured */
-#define TESTflag        0x08   /* test flag */
-#define EXCNAKflag      0x08    /* excesive nak flag */
-#define RESETflag       0x10   /* power-on-reset */
-#define RES1flag        0x20   /* reserved - usually set by jumper */
-#define RES2flag        0x40   /* reserved - usually set by jumper */
-#define NORXflag        0x80   /* receiver inhibited */
-
-/* Flags used for IO-mapped memory operations */
-#define AUTOINCflag     0x40   /* Increase location with each access */
-#define IOMAPflag       0x02   /* (for 90xx) Use IO mapped memory, not mmap */
-#define ENABLE16flag    0x80   /* (for 90xx) Enable 16-bit mode */
-
-/* in the command register, the following bits have these meanings:
- *                0-2     command
- *                3-4     page number (for enable rcv/xmt command)
- *                 7      receive broadcasts
- */
-#define NOTXcmd         0x01   /* disable transmitter */
-#define NORXcmd         0x02   /* disable receiver */
-#define TXcmd           0x03   /* enable transmitter */
-#define RXcmd           0x04   /* enable receiver */
-#define CONFIGcmd       0x05   /* define configuration */
-#define CFLAGScmd       0x06   /* clear flags */
-#define TESTcmd         0x07   /* load test flags */
-
-/* flags for "clear flags" command */
-#define RESETclear      0x08   /* power-on-reset */
-#define CONFIGclear     0x10   /* system reconfigured */
-
-#define EXCNAKclear     0x0E    /* Clear and acknowledge the excive nak bit */
-
-/* flags for "load test flags" command */
-#define TESTload        0x08   /* test flag (diagnostic) */
-
-/* byte deposited into first address of buffers on reset */
-#define TESTvalue       0321   /* that's octal for 0xD1 :) */
-
-/* for "enable receiver" command */
-#define RXbcasts        0x80   /* receive broadcasts */
-
-/* flags for "define configuration" command */
-#define NORMALconf      0x00   /* 1-249 byte packets */
-#define EXTconf         0x08   /* 250-504 byte packets */
-
-/* card feature flags, set during auto-detection.
- * (currently only used by com20020pci)
- */
-#define ARC_IS_5MBIT    1   /* card default speed is 5MBit */
-#define ARC_CAN_10MBIT  2   /* card uses COM20022, supporting 10MBit,
-                                but default is 2.5MBit. */
-
-
-/* information needed to define an encapsulation driver */
-struct ArcProto {
-       char suffix;            /* a for RFC1201, e for ether-encap, etc. */
-       int mtu;                /* largest possible packet */
-       int is_ip;              /* This is a ip plugin - not a raw thing */
-
-       void (*rx) (struct net_device * dev, int bufnum,
-                   struct archdr * pkthdr, int length);
-       int (*build_header) (struct sk_buff * skb, struct net_device *dev,
-                            unsigned short ethproto, uint8_t daddr);
-
-       /* these functions return '1' if the skb can now be freed */
-       int (*prepare_tx) (struct net_device * dev, struct archdr * pkt, int length,
-                          int bufnum);
-       int (*continue_tx) (struct net_device * dev, int bufnum);
-       int (*ack_tx) (struct net_device * dev, int acked);
-};
-
-extern struct ArcProto *arc_proto_map[256], *arc_proto_default,
-       *arc_bcast_proto, *arc_raw_proto;
-
-
-/*
- * "Incoming" is information needed for each address that could be sending
- * to us.  Mostly for partially-received split packets.
- */
-struct Incoming {
-       struct sk_buff *skb;    /* packet data buffer             */
-       __be16 sequence;        /* sequence number of assembly    */
-       uint8_t lastpacket,     /* number of last packet (from 1) */
-               numpackets;     /* number of packets in split     */
-};
-
-
-/* only needed for RFC1201 */
-struct Outgoing {
-       struct ArcProto *proto; /* protocol driver that owns this:
-                                *   if NULL, no packet is pending.
-                                */
-       struct sk_buff *skb;    /* buffer from upper levels */
-       struct archdr *pkt;     /* a pointer into the skb */
-       uint16_t length,        /* bytes total */
-               dataleft,       /* bytes left */
-               segnum,         /* segment being sent */
-               numsegs;        /* number of segments */
-};
-
-
-struct arcnet_local {
-       uint8_t config,         /* current value of CONFIG register */
-               timeout,        /* Extended timeout for COM20020 */
-               backplane,      /* Backplane flag for COM20020 */
-               clockp,         /* COM20020 clock divider */
-               clockm,         /* COM20020 clock multiplier flag */
-               setup,          /* Contents of setup1 register */
-               setup2,         /* Contents of setup2 register */
-               intmask;        /* current value of INTMASK register */
-       uint8_t default_proto[256];     /* default encap to use for each host */
-       int     cur_tx,         /* buffer used by current transmit, or -1 */
-               next_tx,        /* buffer where a packet is ready to send */
-               cur_rx;         /* current receive buffer */
-       int     lastload_dest,  /* can last loaded packet be acked? */
-               lasttrans_dest; /* can last TX'd packet be acked? */
-       int     timed_out;      /* need to process TX timeout and drop packet */
-       unsigned long last_timeout;     /* time of last reported timeout */
-       char *card_name;        /* card ident string */
-       int card_flags;         /* special card features */
-
-
-       /* On preemtive and SMB a lock is needed */
-       spinlock_t lock;
-
-       /*
-        * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of
-        * which can be used for either sending or receiving.  The new dynamic
-        * buffer management routines use a simple circular queue of available
-        * buffers, and take them as they're needed.  This way, we simplify
-        * situations in which we (for example) want to pre-load a transmit
-        * buffer, or start receiving while we copy a received packet to
-        * memory.
-        * 
-        * The rules: only the interrupt handler is allowed to _add_ buffers to
-        * the queue; thus, this doesn't require a lock.  Both the interrupt
-        * handler and the transmit function will want to _remove_ buffers, so
-        * we need to handle the situation where they try to do it at the same
-        * time.
-        * 
-        * If next_buf == first_free_buf, the queue is empty.  Since there are
-        * only four possible buffers, the queue should never be full.
-        */
-       atomic_t buf_lock;
-       int buf_queue[5];
-       int next_buf, first_free_buf;
-
-       /* network "reconfiguration" handling */
-       unsigned long first_recon; /* time of "first" RECON message to count */
-       unsigned long last_recon;  /* time of most recent RECON */
-       int num_recons;         /* number of RECONs between first and last. */
-       int network_down;       /* do we think the network is down? */
-
-       int excnak_pending;    /* We just got an excesive nak interrupt */
-
-       struct {
-               uint16_t sequence;      /* sequence number (incs with each packet) */
-               __be16 aborted_seq;
-
-               struct Incoming incoming[256];  /* one from each address */
-       } rfc1201;
-
-       /* really only used by rfc1201, but we'll pretend it's not */
-       struct Outgoing outgoing;       /* packet currently being sent */
-
-       /* hardware-specific functions */
-       struct {
-               struct module *owner;
-               void (*command) (struct net_device * dev, int cmd);
-               int (*status) (struct net_device * dev);
-               void (*intmask) (struct net_device * dev, int mask);
-               int (*reset) (struct net_device * dev, int really_reset);
-               void (*open) (struct net_device * dev);
-               void (*close) (struct net_device * dev);
-
-               void (*copy_to_card) (struct net_device * dev, int bufnum, int offset,
-                                     void *buf, int count);
-               void (*copy_from_card) (struct net_device * dev, int bufnum, int offset,
-                                       void *buf, int count);
-       } hw;
-
-       void __iomem *mem_start;        /* pointer to ioremap'ed MMIO */
-};
-
-
-#define ARCRESET(x)  (lp->hw.reset(dev, (x)))
-#define ACOMMAND(x)  (lp->hw.command(dev, (x)))
-#define ASTATUS()    (lp->hw.status(dev))
-#define AINTMASK(x)  (lp->hw.intmask(dev, (x)))
-
-
-
-#if ARCNET_DEBUG_MAX & D_SKB
-void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc);
-#else
-#define arcnet_dump_skb(dev,skb,desc) ;
-#endif
-
-void arcnet_unregister_proto(struct ArcProto *proto);
-irqreturn_t arcnet_interrupt(int irq, void *dev_id);
-struct net_device *alloc_arcdev(const char *name);
-
-int arcnet_open(struct net_device *dev);
-int arcnet_close(struct net_device *dev);
-netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
-                                    struct net_device *dev);
-void arcnet_timeout(struct net_device *dev);
-
-#endif                         /* __KERNEL__ */
-#endif                         /* _LINUX_ARCDEVICE_H */
diff --git a/include/linux/com20020.h b/include/linux/com20020.h
deleted file mode 100644 (file)
index 8589899..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Linux ARCnet driver - COM20020 chipset support - function declarations
- * 
- * Written 1997 by David Woodhouse.
- * Written 1994-1999 by Avery Pennarun.
- * Derived from skeleton.c by Donald Becker.
- *
- * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
- *  for sponsoring the further development of this driver.
- *
- * **********************
- *
- * The original copyright of skeleton.c was as follows:
- *
- * skeleton.c Written 1993 by Donald Becker.
- * Copyright 1993 United States Government as represented by the
- * Director, National Security Agency.  This software may only be used
- * and distributed according to the terms of the GNU General Public License as
- * modified by SRC, incorporated herein by reference.
- *
- * **********************
- *
- * For more details, see drivers/net/arcnet.c
- *
- * **********************
- */
-#ifndef __COM20020_H
-#define __COM20020_H
-
-int com20020_check(struct net_device *dev);
-int com20020_found(struct net_device *dev, int shared);
-extern const struct net_device_ops com20020_netdev_ops;
-
-/* The number of low I/O ports used by the card. */
-#define ARCNET_TOTAL_SIZE 8
-
-/* various register addresses */
-#ifdef CONFIG_SA1100_CT6001
-#define BUS_ALIGN  2  /* 8 bit device on a 16 bit bus - needs padding */
-#else
-#define BUS_ALIGN  1
-#endif
-
-#define PLX_PCI_MAX_CARDS 2
-
-struct com20020_pci_channel_map {
-       u32 bar;
-       u32 offset;
-       u32 size;               /* 0x00 - auto, e.g. length of entire bar */
-};
-
-struct com20020_pci_card_info {
-       const char *name;
-       int devcount;
-
-       struct com20020_pci_channel_map chan_map_tbl[PLX_PCI_MAX_CARDS];
-
-       unsigned int flags;
-};
-
-struct com20020_priv {
-       struct com20020_pci_card_info *ci;
-       struct list_head list_dev;
-};
-
-struct com20020_dev {
-       struct list_head list;
-       struct net_device *dev;
-
-       struct com20020_priv *pci_priv;
-       int index;
-};
-
-#define _INTMASK  (ioaddr+BUS_ALIGN*0) /* writable */
-#define _STATUS   (ioaddr+BUS_ALIGN*0) /* readable */
-#define _COMMAND  (ioaddr+BUS_ALIGN*1) /* standard arcnet commands */
-#define _DIAGSTAT (ioaddr+BUS_ALIGN*1) /* diagnostic status register */
-#define _ADDR_HI  (ioaddr+BUS_ALIGN*2) /* control registers for IO-mapped memory */
-#define _ADDR_LO  (ioaddr+BUS_ALIGN*3)
-#define _MEMDATA  (ioaddr+BUS_ALIGN*4) /* data port for IO-mapped memory */
-#define _SUBADR   (ioaddr+BUS_ALIGN*5) /* the extended port _XREG refers to */
-#define _CONFIG   (ioaddr+BUS_ALIGN*6) /* configuration register */
-#define _XREG     (ioaddr+BUS_ALIGN*7) /* extra registers (indexed by _CONFIG
-                                       or _SUBADR) */
-
-/* in the ADDR_HI register */
-#define RDDATAflag     0x80    /* next access is a read (not a write) */
-
-/* in the DIAGSTAT register */
-#define NEWNXTIDflag   0x02    /* ID to which token is passed has changed */
-
-/* in the CONFIG register */
-#define RESETcfg       0x80    /* put card in reset state */
-#define TXENcfg                0x20    /* enable TX */
-
-/* in SETUP register */
-#define PROMISCset     0x10    /* enable RCV_ALL */
-#define P1MODE         0x80    /* enable P1-MODE for Backplane */
-#define SLOWARB                0x01    /* enable Slow Arbitration for >=5Mbps */
-
-/* COM2002x */
-#define SUB_TENTATIVE  0       /* tentative node ID */
-#define SUB_NODE       1       /* node ID */
-#define SUB_SETUP1     2       /* various options */
-#define SUB_TEST       3       /* test/diag register */
-
-/* COM20022 only */
-#define SUB_SETUP2     4       /* sundry options */
-#define SUB_BUSCTL     5       /* bus control options */
-#define SUB_DMACOUNT   6       /* DMA count options */
-
-#define SET_SUBADR(x) do { \
-       if ((x) < 4) \
-       { \
-               lp->config = (lp->config & ~0x03) | (x); \
-               SETCONF; \
-       } \
-       else \
-       { \
-               outb(x, _SUBADR); \
-       } \
-} while (0)
-
-#undef ARCRESET
-#undef ASTATUS
-#undef ACOMMAND
-#undef AINTMASK
-
-#define ARCRESET { outb(lp->config | 0x80, _CONFIG); \
-                   udelay(5);                        \
-                   outb(lp->config , _CONFIG);       \
-                  }
-#define ARCRESET0 { outb(0x18 | 0x80, _CONFIG);   \
-                   udelay(5);                       \
-                   outb(0x18 , _CONFIG);            \
-                  }
-
-#define ASTATUS()      inb(_STATUS)
-#define ADIAGSTATUS()  inb(_DIAGSTAT)
-#define ACOMMAND(cmd)  outb((cmd),_COMMAND)
-#define AINTMASK(msk)  outb((msk),_INTMASK)
-
-#define SETCONF                outb(lp->config, _CONFIG)
-
-#endif /* __COM20020_H */
index dad8b00beed27220856985c984e620d88cafd736..a338a688ee4a4237eb938ff71627bbd5aafa442a 100644 (file)
@@ -46,6 +46,12 @@ struct br_ip_list {
 #define BR_LEARNING_SYNC       BIT(9)
 #define BR_PROXYARP_WIFI       BIT(10)
 
+/* values as per ieee8021QBridgeFdbAgingTime */
+#define BR_MIN_AGEING_TIME     (10 * HZ)
+#define BR_MAX_AGEING_TIME     (1000000 * HZ)
+
+#define BR_DEFAULT_AGEING_TIME (300 * HZ)
+
 extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
 
 typedef int br_should_route_hook_t(struct sk_buff *skb);
index b5474b1fcd8399e667e5f807ee99c1e6150f517a..78003dfb8539bd42f75f8c2d04cbb7dce872e1bf 100644 (file)
@@ -192,8 +192,7 @@ struct ipv6_stub {
        int (*ipv6_dst_lookup)(struct net *net, struct sock *sk,
                               struct dst_entry **dst, struct flowi6 *fl6);
        void (*udpv6_encap_enable)(void);
-       void (*ndisc_send_na)(struct net_device *dev, struct neighbour *neigh,
-                             const struct in6_addr *daddr,
+       void (*ndisc_send_na)(struct net_device *dev, const struct in6_addr *daddr,
                              const struct in6_addr *solicited_addr,
                              bool router, bool solicited, bool override, bool inc_opt);
        struct neigh_table *nd_tbl;
index 2a2d6bb34eb8b5923ca8b951f2a5e10acd99be40..bb7f467da7fcd6957ada0111b9d412f298ebc729 100644 (file)
@@ -17,6 +17,7 @@ struct ethoc_platform_data {
        u8 hwaddr[IFHWADDRLEN];
        s8 phy_id;
        u32 eth_clkfreq;
+       bool big_endian;
 };
 
 #endif /* !LINUX_NET_ETHOC_H */
index a9af1cc8c1bc6089d0facdf56001274cf7993a5a..1b6b6dcb018def094a36786bc5cd3d03e26fa453 100644 (file)
@@ -183,9 +183,8 @@ _genl_register_family_with_ops_grps(struct genl_family *family,
                                            (grps), ARRAY_SIZE(grps))
 
 int genl_unregister_family(struct genl_family *family);
-void genl_notify(struct genl_family *family,
-                struct sk_buff *skb, struct net *net, u32 portid,
-                u32 group, struct nlmsghdr *nlh, gfp_t flags);
+void genl_notify(struct genl_family *family, struct sk_buff *skb,
+                struct genl_info *info, u32 group, gfp_t flags);
 
 struct sk_buff *genlmsg_new_unicast(size_t payload, struct genl_info *info,
                                    gfp_t flags);
index aba5695fadb00df5fb83ff2439474c1f7ecda65a..bf39374310305d61e2948cbd1801eee056efc323 100644 (file)
@@ -180,15 +180,13 @@ void ndisc_cleanup(void);
 
 int ndisc_rcv(struct sk_buff *skb);
 
-void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
-                  const struct in6_addr *solicit,
+void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
                   const struct in6_addr *daddr, const struct in6_addr *saddr,
                   struct sk_buff *oskb);
 
 void ndisc_send_rs(struct net_device *dev,
                   const struct in6_addr *saddr, const struct in6_addr *daddr);
-void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
-                  const struct in6_addr *daddr,
+void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
                   const struct in6_addr *solicited_addr,
                   bool router, bool solicited, bool override, bool inc_opt);
 
index 46e34bd0e7832075c9446680d6b4183c6eda8a52..cfb642f8e7bd3b0eb0446fce2d5898eeb04bec4d 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/types.h>
 #include <linux/if_ether.h>
 
-
 /*
  *    These are the defined ARCnet Protocol ID's.
  */
  * The RFC1201-specific components of an arcnet packet header.
  */
 struct arc_rfc1201 {
-    __u8  proto;               /* protocol ID field - varies           */
-    __u8  split_flag;  /* for use with split packets           */
-    __be16   sequence;         /* sequence number                      */
-    __u8  payload[0];  /* space remaining in packet (504 bytes)*/
+       __u8  proto;            /* protocol ID field - varies           */
+       __u8  split_flag;       /* for use with split packets           */
+       __be16   sequence;      /* sequence number                      */
+       __u8  payload[0];       /* space remaining in packet (504 bytes)*/
 };
 #define RFC1201_HDR_SIZE 4
 
-
 /*
  * The RFC1051-specific components.
  */
 struct arc_rfc1051 {
-    __u8 proto;                /* ARC_P_RFC1051_ARP/RFC1051_IP */
-    __u8 payload[0];           /* 507 bytes                    */
+       __u8 proto;             /* ARC_P_RFC1051_ARP/RFC1051_IP */
+       __u8 payload[0];        /* 507 bytes                    */
 };
 #define RFC1051_HDR_SIZE 1
 
-
 /*
  * The ethernet-encap-specific components.  We have a real ethernet header
  * and some data.
  */
 struct arc_eth_encap {
-    __u8 proto;                /* Always ARC_P_ETHER                   */
-    struct ethhdr eth;         /* standard ethernet header (yuck!)     */
-    __u8 payload[0];           /* 493 bytes                            */
+       __u8 proto;             /* Always ARC_P_ETHER                   */
+       struct ethhdr eth;      /* standard ethernet header (yuck!)     */
+       __u8 payload[0];        /* 493 bytes                            */
 };
 #define ETH_ENCAP_HDR_SIZE 14
 
-
 struct arc_cap {
        __u8 proto;
-       __u8 cookie[sizeof(int)];   /* Actually NOT sent over the network */
+       __u8 cookie[sizeof(int)];
+                               /* Actually NOT sent over the network */
        union {
                __u8 ack;
-               __u8 raw[0];            /* 507 bytes */
+               __u8 raw[0];    /* 507 bytes */
        } mes;
 };
 
@@ -105,9 +102,9 @@ struct arc_cap {
  * driver.
  */
 struct arc_hardware {
-    __u8  source,              /* source ARCnet - filled in automagically */
-             dest,             /* destination ARCnet - 0 for broadcast    */
-            offset[2];         /* offset bytes (some weird semantics)     */
+       __u8 source;            /* source ARCnet - filled in automagically */
+       __u8 dest;              /* destination ARCnet - 0 for broadcast    */
+       __u8 offset[2];         /* offset bytes (some weird semantics)     */
 };
 #define ARC_HDR_SIZE 4
 
@@ -116,17 +113,17 @@ struct arc_hardware {
  * when you do a raw packet capture).
  */
 struct archdr {
-    /* hardware requirements */
-    struct arc_hardware hard;
-     
-    /* arcnet encapsulation-specific bits */
-    union {
-       struct arc_rfc1201   rfc1201;
-       struct arc_rfc1051   rfc1051;
-       struct arc_eth_encap eth_encap;
-       struct arc_cap       cap;
-       __u8 raw[0];            /* 508 bytes                            */
-    } soft;
+       /* hardware requirements */
+       struct arc_hardware hard;
+
+       /* arcnet encapsulation-specific bits */
+       union {
+               struct arc_rfc1201   rfc1201;
+               struct arc_rfc1051   rfc1051;
+               struct arc_eth_encap eth_encap;
+               struct arc_cap       cap;
+               __u8 raw[0];    /* 508 bytes                            */
+       } soft;
 };
 
 #endif                         /* _LINUX_IF_ARCNET_H */
index 6ed2feb51e3c7ae3d0f0fd629d6e147549b5fa54..2f81624a82578360ec08a20c8817231b838f478c 100644 (file)
@@ -391,7 +391,7 @@ void br_dev_setup(struct net_device *dev)
        br->bridge_max_age = br->max_age = 20 * HZ;
        br->bridge_hello_time = br->hello_time = 2 * HZ;
        br->bridge_forward_delay = br->forward_delay = 15 * HZ;
-       br->ageing_time = 300 * HZ;
+       br->ageing_time = BR_DEFAULT_AGEING_TIME;
 
        br_netfilter_rtable_init(br);
        br_stp_timer_init(br);
index 9e9875da0a4f979c5389f616b432d218b19fd776..6663cc0789a6bd3f5ad0e57d8cb968ae5d08259a 100644 (file)
@@ -299,6 +299,8 @@ void br_fdb_cleanup(unsigned long _data)
                        unsigned long this_timer;
                        if (f->is_static)
                                continue;
+                       if (f->added_by_external_learn)
+                               continue;
                        this_timer = f->updated + delay;
                        if (time_before_eq(this_timer, jiffies))
                                fdb_delete(br, f);
index da3f3d94d6e93c7411a1f8369be9c180124fffc9..96bd962c292df9f63720a009a85561d6a9a848b3 100644 (file)
@@ -1404,9 +1404,6 @@ static u64 bpf_clone_redirect(u64 r1, u64 ifindex, u64 flags, u64 r4, u64 r5)
        if (unlikely(!dev))
                return -EINVAL;
 
-       if (unlikely(!(dev->flags & IFF_UP)))
-               return -EINVAL;
-
        skb2 = skb_clone(skb, GFP_ATOMIC);
        if (unlikely(!skb2))
                return -ENOMEM;
index d671d742a2398d04ce2d6f5126ab941a36bbc1cc..7e26465423129755732ba7a03f8fd5347a79fa6a 100644 (file)
@@ -1276,7 +1276,6 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        newinet->mc_index     = inet_iif(skb);
        newinet->mc_ttl       = ip_hdr(skb)->ttl;
        newinet->rcv_tos      = ip_hdr(skb)->tos;
-       newsk->sk_txhash      = tcp_rsk(req)->txhash;
        inet_csk(newsk)->icsk_ext_hdr_len = 0;
        if (inet_opt)
                inet_csk(newsk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
index 10933d01b982137b113f49497c6a971513e27aae..85830bb92d04df82d4417fa45deb6d1af46ec9f9 100644 (file)
@@ -471,6 +471,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                tcp_enable_early_retrans(newtp);
                newtp->tlp_high_seq = 0;
                newtp->lsndtime = treq->snt_synack.stamp_jiffies;
+               newsk->sk_txhash = treq->txhash;
                newtp->last_oow_ack_time = 0;
                newtp->total_retrans = req->num_retrans;
 
index 75d3dde32c695bbbfa7aecb0eaf9ca25720d42e6..759d28ad16b7266e806cc98141585918cc9f5f62 100644 (file)
@@ -3625,7 +3625,7 @@ static void addrconf_dad_work(struct work_struct *w)
 
        /* send a neighbour solicitation for our addr */
        addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
-       ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any, NULL);
+       ndisc_send_ns(ifp->idev->dev, &ifp->addr, &mcaddr, &in6addr_any, NULL);
 out:
        in6_ifa_put(ifp);
        rtnl_unlock();
index dde5a1e5875add991ea57965045d672c2b80a81c..7089c305245c81f7aa28af5141f2b64d9812e693 100644 (file)
@@ -474,8 +474,7 @@ static void ndisc_send_skb(struct sk_buff *skb,
        rcu_read_unlock();
 }
 
-void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
-                  const struct in6_addr *daddr,
+void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
                   const struct in6_addr *solicited_addr,
                   bool router, bool solicited, bool override, bool inc_opt)
 {
@@ -541,7 +540,7 @@ static void ndisc_send_unsol_na(struct net_device *dev)
 
        read_lock_bh(&idev->lock);
        list_for_each_entry(ifa, &idev->addr_list, if_list) {
-               ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &ifa->addr,
+               ndisc_send_na(dev, &in6addr_linklocal_allnodes, &ifa->addr,
                              /*router=*/ !!idev->cnf.forwarding,
                              /*solicited=*/ false, /*override=*/ true,
                              /*inc_opt=*/ true);
@@ -551,8 +550,7 @@ static void ndisc_send_unsol_na(struct net_device *dev)
        in6_dev_put(idev);
 }
 
-void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
-                  const struct in6_addr *solicit,
+void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
                   const struct in6_addr *daddr, const struct in6_addr *saddr,
                   struct sk_buff *oskb)
 {
@@ -679,12 +677,12 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
                                  "%s: trying to ucast probe in NUD_INVALID: %pI6\n",
                                  __func__, target);
                }
-               ndisc_send_ns(dev, neigh, target, target, saddr, skb);
+               ndisc_send_ns(dev, target, target, saddr, skb);
        } else if ((probes -= NEIGH_VAR(neigh->parms, APP_PROBES)) < 0) {
                neigh_app_ns(neigh);
        } else {
                addrconf_addr_solict_mult(target, &mcaddr);
-               ndisc_send_ns(dev, NULL, target, &mcaddr, saddr, skb);
+               ndisc_send_ns(dev, target, &mcaddr, saddr, skb);
        }
 }
 
@@ -828,7 +826,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
                is_router = idev->cnf.forwarding;
 
        if (dad) {
-               ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &msg->target,
+               ndisc_send_na(dev, &in6addr_linklocal_allnodes, &msg->target,
                              !!is_router, false, (ifp != NULL), true);
                goto out;
        }
@@ -849,8 +847,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
                             NEIGH_UPDATE_F_WEAK_OVERRIDE|
                             NEIGH_UPDATE_F_OVERRIDE);
        if (neigh || !dev->header_ops) {
-               ndisc_send_na(dev, neigh, saddr, &msg->target,
-                             !!is_router,
+               ndisc_send_na(dev, saddr, &msg->target, !!is_router,
                              true, (ifp != NULL && inc), inc);
                if (neigh)
                        neigh_release(neigh);
index 53617d71518850dfc26220dd15923b8027c5249a..118f8fa1a80922715df80f079b51c29c65975ba1 100644 (file)
@@ -421,31 +421,7 @@ static bool rt6_check_expired(const struct rt6_info *rt)
 static int rt6_info_hash_nhsfn(unsigned int candidate_count,
                               const struct flowi6 *fl6)
 {
-       unsigned int val = fl6->flowi6_proto;
-
-       val ^= ipv6_addr_hash(&fl6->daddr);
-       val ^= ipv6_addr_hash(&fl6->saddr);
-
-       /* Work only if this not encapsulated */
-       switch (fl6->flowi6_proto) {
-       case IPPROTO_UDP:
-       case IPPROTO_TCP:
-       case IPPROTO_SCTP:
-               val ^= (__force u16)fl6->fl6_sport;
-               val ^= (__force u16)fl6->fl6_dport;
-               break;
-
-       case IPPROTO_ICMPV6:
-               val ^= (__force u16)fl6->fl6_icmp_type;
-               val ^= (__force u16)fl6->fl6_icmp_code;
-               break;
-       }
-       /* RFC6438 recommands to use flowlabel */
-       val ^= (__force u32)fl6->flowlabel;
-
-       /* Perhaps, we need to tune, this function? */
-       val = val ^ (val >> 7) ^ (val >> 12);
-       return val % candidate_count;
+       return get_hash_from_flowi6(fl6) % candidate_count;
 }
 
 static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
@@ -538,7 +514,7 @@ static void rt6_probe_deferred(struct work_struct *w)
                container_of(w, struct __rt6_probe_work, work);
 
        addrconf_addr_solict_mult(&work->target, &mcaddr);
-       ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL, NULL);
+       ndisc_send_ns(work->dev, &work->target, &mcaddr, NULL, NULL);
        dev_put(work->dev);
        kfree(work);
 }
index f9c0e264067104260ed586836364da10019851aa..a004e0b0b3e961b3a5fdcc5babb8d2ea065bf5b9 100644 (file)
@@ -1090,8 +1090,6 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        newsk->sk_v6_rcv_saddr = ireq->ir_v6_loc_addr;
        newsk->sk_bound_dev_if = ireq->ir_iif;
 
-       newsk->sk_txhash = tcp_rsk(req)->txhash;
-
        /* Now IPv6 options...
 
           First: no IPv4 options.
index 2ed5f964772ee44fc693cf18bc6055308820bf78..75724a96aef26723236b957cff47bac26a45e52e 100644 (file)
@@ -1136,19 +1136,19 @@ int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb,
 }
 EXPORT_SYMBOL(genlmsg_multicast_allns);
 
-void genl_notify(struct genl_family *family,
-                struct sk_buff *skb, struct net *net, u32 portid, u32 group,
-                struct nlmsghdr *nlh, gfp_t flags)
+void genl_notify(struct genl_family *family, struct sk_buff *skb,
+                struct genl_info *info, u32 group, gfp_t flags)
 {
+       struct net *net = genl_info_net(info);
        struct sock *sk = net->genl_sock;
        int report = 0;
 
-       if (nlh)
-               report = nlmsg_report(nlh);
+       if (info->nlhdr)
+               report = nlmsg_report(info->nlhdr);
 
        if (WARN_ON_ONCE(group >= family->n_mcgrps))
                return;
        group = family->mcgrp_offset + group;
-       nlmsg_notify(sk, skb, portid, group, report, flags);
+       nlmsg_notify(sk, skb, info->snd_portid, group, report, flags);
 }
 EXPORT_SYMBOL(genl_notify);
index 6fbd2decb19e2682bacd1d1cfedf186b4724bd9c..2913594c51231192252e1abf0409bc8c8c2b4382 100644 (file)
@@ -91,8 +91,7 @@ static bool ovs_must_notify(struct genl_family *family, struct genl_info *info,
 static void ovs_notify(struct genl_family *family,
                       struct sk_buff *skb, struct genl_info *info)
 {
-       genl_notify(family, skb, genl_info_net(info), info->snd_portid,
-                   0, info->nlhdr, GFP_KERNEL);
+       genl_notify(family, skb, info, 0, GFP_KERNEL);
 }
 
 /**
index 0590816ab7b03bf0571e81933b613fb4b96288d0..7eeffaf69c7585eeead5d9dee60793d899678692 100644 (file)
@@ -65,11 +65,8 @@ static int cls_bpf_exec_opcode(int code)
 {
        switch (code) {
        case TC_ACT_OK:
-       case TC_ACT_RECLASSIFY:
        case TC_ACT_SHOT:
-       case TC_ACT_PIPE:
        case TC_ACT_STOLEN:
-       case TC_ACT_QUEUED:
        case TC_ACT_REDIRECT:
        case TC_ACT_UNSPEC:
                return code;
@@ -265,8 +262,7 @@ static int cls_bpf_prog_from_ops(struct nlattr **tb, struct cls_bpf_prog *prog)
        return 0;
 }
 
-static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog,
-                                const struct tcf_proto *tp)
+static int cls_bpf_prog_from_efd(struct nlattr **tb, struct cls_bpf_prog *prog)
 {
        struct bpf_prog *fp;
        char *name = NULL;
@@ -308,14 +304,11 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
 {
        bool is_bpf, is_ebpf, have_exts = false;
        struct tcf_exts exts;
-       u32 classid;
        int ret;
 
        is_bpf = tb[TCA_BPF_OPS_LEN] && tb[TCA_BPF_OPS];
        is_ebpf = tb[TCA_BPF_FD];
-
-       if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf) ||
-           !tb[TCA_BPF_CLASSID])
+       if ((!is_bpf && !is_ebpf) || (is_bpf && is_ebpf))
                return -EINVAL;
 
        tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
@@ -323,7 +316,6 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
        if (ret < 0)
                return ret;
 
-       classid = nla_get_u32(tb[TCA_BPF_CLASSID]);
        if (tb[TCA_BPF_FLAGS]) {
                u32 bpf_flags = nla_get_u32(tb[TCA_BPF_FLAGS]);
 
@@ -335,19 +327,21 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
                have_exts = bpf_flags & TCA_BPF_FLAG_ACT_DIRECT;
        }
 
-       prog->res.classid = classid;
        prog->exts_integrated = have_exts;
 
        ret = is_bpf ? cls_bpf_prog_from_ops(tb, prog) :
-                      cls_bpf_prog_from_efd(tb, prog, tp);
+                      cls_bpf_prog_from_efd(tb, prog);
        if (ret < 0) {
                tcf_exts_destroy(&exts);
                return ret;
        }
 
-       tcf_bind_filter(tp, &prog->res, base);
-       tcf_exts_change(tp, &prog->exts, &exts);
+       if (tb[TCA_BPF_CLASSID]) {
+               prog->res.classid = nla_get_u32(tb[TCA_BPF_CLASSID]);
+               tcf_bind_filter(tp, &prog->res, base);
+       }
 
+       tcf_exts_change(tp, &prog->exts, &exts);
        return 0;
 }
 
@@ -468,6 +462,7 @@ static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
 {
        struct cls_bpf_prog *prog = (struct cls_bpf_prog *) fh;
        struct nlattr *nest;
+       u32 bpf_flags = 0;
        int ret;
 
        if (prog == NULL)
@@ -479,7 +474,8 @@ static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
        if (nest == NULL)
                goto nla_put_failure;
 
-       if (nla_put_u32(skb, TCA_BPF_CLASSID, prog->res.classid))
+       if (prog->res.classid &&
+           nla_put_u32(skb, TCA_BPF_CLASSID, prog->res.classid))
                goto nla_put_failure;
 
        if (cls_bpf_is_ebpf(prog))
@@ -492,6 +488,11 @@ static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
        if (tcf_exts_dump(skb, &prog->exts) < 0)
                goto nla_put_failure;
 
+       if (prog->exts_integrated)
+               bpf_flags |= TCA_BPF_FLAG_ACT_DIRECT;
+       if (bpf_flags && nla_put_u32(skb, TCA_BPF_FLAGS, bpf_flags))
+               goto nla_put_failure;
+
        nla_nest_end(skb, nest);
 
        if (tcf_exts_dump_stats(skb, &prog->exts) < 0)