Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
David S. Miller [Fri, 17 Apr 2009 00:35:26 +0000 (17:35 -0700)]
94 files changed:
Documentation/isdn/00-INDEX
MAINTAINERS
drivers/net/8390.c
drivers/net/8390p.c
drivers/net/atl1e/atl1e_main.c
drivers/net/atlx/atl1.c
drivers/net/benet/be_main.c
drivers/net/bmac.c
drivers/net/chelsio/sge.c
drivers/net/cpmac.c
drivers/net/cxgb3/adapter.h
drivers/net/cxgb3/sge.c
drivers/net/dm9000.c
drivers/net/fec.c
drivers/net/fec.h
drivers/net/fs_enet/mii-fec.c
drivers/net/hplance.c
drivers/net/ibmveth.c
drivers/net/irda/au1k_ir.c
drivers/net/irda/pxaficp_ir.c
drivers/net/irda/sa1100_ir.c
drivers/net/iseries_veth.c
drivers/net/ixgb/ixgb_osdep.h
drivers/net/ixgbe/ixgbe_82598.c
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_common.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_phy.c
drivers/net/ixgbe/ixgbe_phy.h
drivers/net/ixgbe/ixgbe_type.h
drivers/net/ixp2000/ixpdev.c
drivers/net/jazzsonic.c
drivers/net/korina.c
drivers/net/lib82596.c
drivers/net/mace.c
drivers/net/macmace.c
drivers/net/meth.c
drivers/net/mipsnet.c
drivers/net/mvme147.c
drivers/net/netx-eth.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_ctx.c
drivers/net/netxen/netxen_nic_ethtool.c
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_hw.h
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/netxen/netxen_nic_niu.c
drivers/net/netxen/netxen_nic_phan_reg.h
drivers/net/pasemi_mac.c
drivers/net/pci-skeleton.c
drivers/net/pppol2tp.c
drivers/net/r8169.c
drivers/net/rionet.c
drivers/net/sb1250-mac.c
drivers/net/sfc/boards.c
drivers/net/sfc/rx.c
drivers/net/sfc/sfe4001.c
drivers/net/sgiseeq.c
drivers/net/smc911x.c
drivers/net/sun3lance.c
drivers/net/tulip/winbond-840.c
drivers/net/usb/kaweth.c
drivers/net/usb/usbnet.c
drivers/net/virtio_net.c
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/ath5k/reset.c
drivers/net/wireless/ath9k/ath9k.h
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/ipw2x00/libipw_module.c
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas_tf/if_usb.c
include/linux/if_vlan.h
include/linux/netdevice.h
net/8021q/vlan_core.c
net/core/dev.c
net/rds/af_rds.c
net/rds/connection.c
net/rds/ib.c
net/rds/ib.h
net/rds/ib_recv.c
net/rds/ib_ring.c
net/rds/ib_send.c
net/rds/info.c
net/rds/iw.c
net/rds/iw.h
net/rds/iw_recv.c
net/rds/iw_ring.c
net/rds/iw_send.c
net/rds/rdma.c
net/rds/rdma_transport.c
net/rds/rds.h
net/rds/send.c

index 9fee5f2..33543ac 100644 (file)
@@ -2,28 +2,20 @@
        - this file (info on ISDN implementation for Linux)
 CREDITS
        - list of the kind folks that brought you this stuff.
+HiSax.cert
+       - information about the ITU approval certification of the HiSax driver.
 INTERFACE
-       - description of Linklevel and Hardwarelevel ISDN interface.
+       - description of isdn4linux Link Level and Hardware Level interfaces.
+INTERFACE.fax
+       - description of the fax subinterface of isdn4linux.
 README
        - general info on what you need and what to do for Linux ISDN.
 README.FAQ
        - general info for FAQ.
-README.audio
-       - info for running audio over ISDN.
-README.fax
-       - info for using Fax over ISDN.
-README.icn
-       - info on the ICN-ISDN-card and its driver.
 README.HiSax
        - info on the HiSax driver which replaces the old teles.
-README.hfc-pci
-       - info on hfc-pci based cards.
-README.pcbit
-       - info on the PCBIT-D ISDN adapter and driver.
-README.syncppp
-       - info on running Sync PPP over ISDN.
-syncPPP.FAQ
-       - frequently asked questions about running PPP over ISDN.
+README.audio
+       - info for running audio over ISDN.
 README.avmb1
        - info on driver for AVM-B1 ISDN card.
 README.act2000
@@ -34,10 +26,25 @@ README.concap
        - info on "CONCAP" encapsulation protocol interface used for X.25.
 README.diversion
        - info on module for isdn diversion services.
+README.fax
+       - info for using Fax over ISDN.
+README.gigaset
+       - info on the drivers for Siemens Gigaset ISDN adapters
+README.hfc-pci
+       - info on hfc-pci based cards.
+README.hysdn
+        - info on driver for Hypercope active HYSDN cards
+README.icn
+       - info on the ICN-ISDN-card and its driver.
+README.mISDN
+       - info on the Modular ISDN subsystem (mISDN)
+README.pcbit
+       - info on the PCBIT-D ISDN adapter and driver.
 README.sc
        - info on driver for Spellcaster cards.
+README.syncppp
+       - info on running Sync PPP over ISDN.
 README.x25
-    _ info for running X.25 over ISDN.
-README.hysdn
-        - info on driver for Hypercope active HYSDN cards
+       - info on running X.25 over ISDN.
+syncPPP.FAQ
+       - frequently asked questions about running PPP over ISDN.
index abedca5..cb44e1c 100644 (file)
@@ -4600,7 +4600,7 @@ F:        drivers/net/r6040.c
 RDS - RELIABLE DATAGRAM SOCKETS
 P:     Andy Grover
 M:     andy.grover@oracle.com
-L:     rds-devel@oss.oracle.com
+L:     rds-devel@oss.oracle.com (moderated for non-subscribers)
 S:     Supported
 F:     net/rds/
 
index ec3e22e..21153de 100644 (file)
@@ -74,14 +74,8 @@ EXPORT_SYMBOL(ei_netdev_ops);
 struct net_device *__alloc_ei_netdev(int size)
 {
        struct net_device *dev = ____alloc_ei_netdev(size);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       if (dev) {
-               dev->hard_start_xmit = ei_start_xmit;
-               dev->get_stats  = ei_get_stats;
-               dev->set_multicast_list = ei_set_multicast_list;
-               dev->tx_timeout = ei_tx_timeout;
-       }
-#endif
+       if (dev)
+               dev->netdev_ops = &ei_netdev_ops;
        return dev;
 }
 EXPORT_SYMBOL(__alloc_ei_netdev);
index da863c9..6ec11da 100644 (file)
@@ -79,14 +79,8 @@ EXPORT_SYMBOL(eip_netdev_ops);
 struct net_device *__alloc_eip_netdev(int size)
 {
        struct net_device *dev = ____alloc_ei_netdev(size);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       if (dev) {
-               dev->hard_start_xmit = eip_start_xmit;
-               dev->get_stats  = eip_get_stats;
-               dev->set_multicast_list = eip_set_multicast_list;
-               dev->tx_timeout = eip_tx_timeout;
-       }
-#endif
+       if (dev)
+               dev->netdev_ops = &eip_netdev_ops;
        return dev;
 }
 EXPORT_SYMBOL(__alloc_eip_netdev);
index fb57b75..adac061 100644 (file)
@@ -1794,8 +1794,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
                        memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
 
                        tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
-                       if (tx_buffer->skb)
-                               BUG();
+                       BUG_ON(tx_buffer->skb);
 
                        tx_buffer->skb = NULL;
                        tx_buffer->length =
index 0ab2254..13f0bdc 100644 (file)
@@ -2207,8 +2207,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
        nr_frags = skb_shinfo(skb)->nr_frags;
        next_to_use = atomic_read(&tpd_ring->next_to_use);
        buffer_info = &tpd_ring->buffer_info[next_to_use];
-       if (unlikely(buffer_info->skb))
-               BUG();
+       BUG_ON(buffer_info->skb);
        /* put skb in last TPD */
        buffer_info->skb = NULL;
 
@@ -2274,8 +2273,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
                        ATL1_MAX_TX_BUF_LEN;
                for (i = 0; i < nseg; i++) {
                        buffer_info = &tpd_ring->buffer_info[next_to_use];
-                       if (unlikely(buffer_info->skb))
-                               BUG();
+                       BUG_ON(buffer_info->skb);
+
                        buffer_info->skb = NULL;
                        buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
                                ATL1_MAX_TX_BUF_LEN : buf_len;
index 9b75aa6..8994b03 100644 (file)
@@ -637,6 +637,22 @@ static void be_rx_stats_update(struct be_adapter *adapter,
        stats->be_rx_bytes += pktsize;
 }
 
+static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
+{
+       u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk;
+
+       l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
+       ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp);
+       ip_version = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp);
+       if (ip_version) {
+               tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
+               udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp);
+       }
+       ipv6_chk = (ip_version && (tcpf || udpf));
+
+       return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true;
+}
+
 static struct be_rx_page_info *
 get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
 {
@@ -752,9 +768,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 {
        struct sk_buff *skb;
        u32 vtp, vid;
-       int l4_cksm;
 
-       l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
        vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
 
        skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
@@ -769,10 +783,10 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 
        skb_fill_rx_data(adapter, skb, rxcp);
 
-       if (l4_cksm && adapter->rx_csum)
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
-       else
+       if (do_pkt_csum(rxcp, adapter->rx_csum))
                skb->ip_summed = CHECKSUM_NONE;
+       else
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
 
        skb->truesize = skb->len + sizeof(struct sk_buff);
        skb->protocol = eth_type_trans(skb, adapter->netdev);
@@ -1626,10 +1640,12 @@ static void be_netdev_init(struct net_device *netdev)
 
        netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
                NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM |
-               NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+               NETIF_F_IPV6_CSUM;
 
        netdev->flags |= IFF_MULTICAST;
 
+       adapter->rx_csum = true;
+
        BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
 
        SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
index 44d015f..9578a3d 100644 (file)
@@ -1247,6 +1247,16 @@ static const struct ethtool_ops bmac_ethtool_ops = {
        .get_link               = ethtool_op_get_link,
 };
 
+static const struct net_device_ops bmac_netdev_ops = {
+       .ndo_open               = bmac_open,
+       .ndo_stop               = bmac_close,
+       .ndo_start_xmit         = bmac_output,
+       .ndo_set_multicast_list = bmac_set_multicast,
+       .ndo_set_mac_address    = bmac_set_address,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
        int j, rev, ret;
@@ -1308,12 +1318,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
        bmac_enable_and_reset_chip(dev);
        bmwrite(dev, INTDISABLE, DisableAll);
 
-       dev->open = bmac_open;
-       dev->stop = bmac_close;
+       dev->netdev_ops = &bmac_netdev_ops;
        dev->ethtool_ops = &bmac_ethtool_ops;
-       dev->hard_start_xmit = bmac_output;
-       dev->set_multicast_list = bmac_set_multicast;
-       dev->set_mac_address = bmac_set_address;
 
        bmac_get_station_address(dev, addr);
        if (bmac_verify_checksum(dev) != 0)
index 58f6fc0..5e97a1a 100644 (file)
@@ -1149,8 +1149,8 @@ static inline void write_tx_desc(struct cmdQ_e *e, dma_addr_t mapping,
                                 unsigned int len, unsigned int gen,
                                 unsigned int eop)
 {
-       if (unlikely(len > SGE_TX_DESC_MAX_PLEN))
-               BUG();
+       BUG_ON(len > SGE_TX_DESC_MAX_PLEN);
+
        e->addr_lo = (u32)mapping;
        e->addr_hi = (u64)mapping >> 32;
        e->len_gen = V_CMD_LEN(len) | V_CMD_GEN1(gen);
index 3f476c7..af305c0 100644 (file)
@@ -1093,6 +1093,19 @@ static int cpmac_stop(struct net_device *dev)
        return 0;
 }
 
+static const struct net_device_ops cpmac_netdev_ops = {
+       .ndo_open               = cpmac_open,
+       .ndo_stop               = cpmac_stop,
+       .ndo_start_xmit         = cpmac_start_xmit,
+       .ndo_tx_timeout         = cpmac_tx_timeout,
+       .ndo_set_multicast_list = cpmac_set_multicast_list,
+       .ndo_so_ioctl           = cpmac_ioctl,
+       .ndo_set_config         = cpmac_config,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int external_switch;
 
 static int __devinit cpmac_probe(struct platform_device *pdev)
@@ -1143,14 +1156,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
 
        dev->irq = platform_get_irq_byname(pdev, "irq");
 
-       dev->open               = cpmac_open;
-       dev->stop               = cpmac_stop;
-       dev->set_config         = cpmac_config;
-       dev->hard_start_xmit    = cpmac_start_xmit;
-       dev->do_ioctl           = cpmac_ioctl;
-       dev->set_multicast_list = cpmac_set_multicast_list;
-       dev->tx_timeout         = cpmac_tx_timeout;
-       dev->ethtool_ops        = &cpmac_ethtool_ops;
+       dev->netdev_ops = &cpmac_netdev_ops;
+       dev->ethtool_ops = &cpmac_ethtool_ops;
 
        netif_napi_add(dev, &priv->napi, cpmac_poll, 64);
 
index 714df2b..322434a 100644 (file)
@@ -195,7 +195,7 @@ struct sge_qset {           /* an SGE queue set */
        struct sge_rspq rspq;
        struct sge_fl fl[SGE_RXQ_PER_SET];
        struct sge_txq txq[SGE_TXQ_PER_SET];
-       struct napi_gro_fraginfo lro_frag_tbl;
+       int nomem;
        int lro_enabled;
        void *lro_va;
        struct net_device *netdev;
index 26d3587..73d569e 100644 (file)
@@ -654,7 +654,8 @@ static void t3_reset_qset(struct sge_qset *q)
        q->txq_stopped = 0;
        q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
        q->rx_reclaim_timer.function = NULL;
-       q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
+       q->nomem = 0;
+       napi_free_frags(&q->napi);
 }
 
 
@@ -2074,20 +2075,19 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
                         struct sge_fl *fl, int len, int complete)
 {
        struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
+       struct sk_buff *skb = NULL;
        struct cpl_rx_pkt *cpl;
-       struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags;
-       int nr_frags = qs->lro_frag_tbl.nr_frags;
-       int frag_len = qs->lro_frag_tbl.len;
+       struct skb_frag_struct *rx_frag;
+       int nr_frags;
        int offset = 0;
 
-       if (!nr_frags) {
-               offset = 2 + sizeof(struct cpl_rx_pkt);
-               qs->lro_va = cpl = sd->pg_chunk.va + 2;
+       if (!qs->nomem) {
+               skb = napi_get_frags(&qs->napi);
+               qs->nomem = !skb;
        }
 
        fl->credits--;
 
-       len -= offset;
        pci_dma_sync_single_for_cpu(adap->pdev,
                                    pci_unmap_addr(sd, dma_addr),
                                    fl->buf_size - SGE_PG_RSVD,
@@ -2100,21 +2100,38 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
                               fl->alloc_size,
                               PCI_DMA_FROMDEVICE);
 
+       if (!skb) {
+               put_page(sd->pg_chunk.page);
+               if (complete)
+                       qs->nomem = 0;
+               return;
+       }
+
+       rx_frag = skb_shinfo(skb)->frags;
+       nr_frags = skb_shinfo(skb)->nr_frags;
+
+       if (!nr_frags) {
+               offset = 2 + sizeof(struct cpl_rx_pkt);
+               qs->lro_va = sd->pg_chunk.va + 2;
+       }
+       len -= offset;
+
        prefetch(qs->lro_va);
 
        rx_frag += nr_frags;
        rx_frag->page = sd->pg_chunk.page;
        rx_frag->page_offset = sd->pg_chunk.offset + offset;
        rx_frag->size = len;
-       frag_len += len;
-       qs->lro_frag_tbl.nr_frags++;
-       qs->lro_frag_tbl.len = frag_len;
 
+       skb->len += len;
+       skb->data_len += len;
+       skb->truesize += len;
+       skb_shinfo(skb)->nr_frags++;
 
        if (!complete)
                return;
 
-       qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
        cpl = qs->lro_va;
 
        if (unlikely(cpl->vlan_valid)) {
@@ -2123,15 +2140,11 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
                struct vlan_group *grp = pi->vlan_grp;
 
                if (likely(grp != NULL)) {
-                       vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
-                                      &qs->lro_frag_tbl);
-                       goto out;
+                       vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan));
+                       return;
                }
        }
-       napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
-
-out:
-       qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
+       napi_gro_frags(&qs->napi);
 }
 
 /**
@@ -2300,8 +2313,6 @@ no_mem:
                        if (fl->use_pages) {
                                void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
 
-                               prefetch(&qs->lro_frag_tbl);
-
                                prefetch(addr);
 #if L1_CACHE_BYTES < 128
                                prefetch(addr + L1_CACHE_BYTES);
index d835086..e402e91 100644 (file)
@@ -1170,6 +1170,21 @@ dm9000_stop(struct net_device *ndev)
        return 0;
 }
 
+static const struct net_device_ops dm9000_netdev_ops = {
+       .ndo_open               = dm9000_open,
+       .ndo_stop               = dm9000_stop,
+       .ndo_start_xmit         = dm9000_start_xmit,
+       .ndo_tx_timeout         = dm9000_timeout,
+       .ndo_set_multicast_list = dm9000_hash_table,
+       .ndo_do_ioctl           = dm9000_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = dm9000_poll_controller,
+#endif
+};
+
 #define res_size(_r) (((_r)->end - (_r)->start) + 1)
 
 /*
@@ -1339,18 +1354,9 @@ dm9000_probe(struct platform_device *pdev)
        /* driver system function */
        ether_setup(ndev);
 
-       ndev->open               = &dm9000_open;
-       ndev->hard_start_xmit    = &dm9000_start_xmit;
-       ndev->tx_timeout         = &dm9000_timeout;
-       ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
-       ndev->stop               = &dm9000_stop;
-       ndev->set_multicast_list = &dm9000_hash_table;
-       ndev->ethtool_ops        = &dm9000_ethtool_ops;
-       ndev->do_ioctl           = &dm9000_ioctl;
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       ndev->poll_controller    = &dm9000_poll_controller;
-#endif
+       ndev->netdev_ops        = &dm9000_netdev_ops;
+       ndev->watchdog_timeo    = msecs_to_jiffies(watchdog);
+       ndev->ethtool_ops       = &dm9000_ethtool_ops;
 
        db->msg_enable       = NETIF_MSG_LINK;
        db->mii.phy_id_mask  = 0x1f;
index 682e7f0..28db691 100644 (file)
@@ -86,8 +86,7 @@ static unsigned char  fec_mac_default[] = {
 #endif
 #endif /* CONFIG_M5272 */
 
-/* Forward declarations of some structures to support different PHYs
-*/
+/* Forward declarations of some structures to support different PHYs */
 
 typedef struct {
        uint mii_data;
@@ -123,8 +122,7 @@ typedef struct {
 #error "FEC: descriptor ring size constants too large"
 #endif
 
-/* Interrupt events/masks.
-*/
+/* Interrupt events/masks. */
 #define FEC_ENET_HBERR ((uint)0x80000000)      /* Heartbeat error */
 #define FEC_ENET_BABR  ((uint)0x40000000)      /* Babbling receiver */
 #define FEC_ENET_BABT  ((uint)0x20000000)      /* Babbling transmitter */
@@ -165,7 +163,7 @@ typedef struct {
  */
 struct fec_enet_private {
        /* Hardware registers of the FEC device */
-       volatile fec_t  *hwp;
+       void __iomem *hwp;
 
        struct net_device *netdev;
 
@@ -174,16 +172,20 @@ struct fec_enet_private {
        /* The saved address of a sent-in-place packet/buffer, for skfree(). */
        unsigned char *tx_bounce[TX_RING_SIZE];
        struct  sk_buff* tx_skbuff[TX_RING_SIZE];
+       struct  sk_buff* rx_skbuff[RX_RING_SIZE];
        ushort  skb_cur;
        ushort  skb_dirty;
 
-       /* CPM dual port RAM relative addresses.
-       */
+       /* CPM dual port RAM relative addresses */
        dma_addr_t      bd_dma;
-       cbd_t   *rx_bd_base;            /* Address of Rx and Tx buffers. */
-       cbd_t   *tx_bd_base;
-       cbd_t   *cur_rx, *cur_tx;               /* The next free ring entry */
-       cbd_t   *dirty_tx;      /* The ring entries to be free()ed. */
+       /* Address of Rx and Tx buffers */
+       struct bufdesc  *rx_bd_base;
+       struct bufdesc  *tx_bd_base;
+       /* The next free ring entry */
+       struct bufdesc  *cur_rx, *cur_tx; 
+       /* The ring entries to be free()ed */
+       struct bufdesc  *dirty_tx;
+
        uint    tx_full;
        /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
        spinlock_t hw_lock;
@@ -209,17 +211,13 @@ struct fec_enet_private {
        int     full_duplex;
 };
 
-static int fec_enet_open(struct net_device *dev);
-static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void fec_enet_mii(struct net_device *dev);
 static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
 static void fec_enet_tx(struct net_device *dev);
 static void fec_enet_rx(struct net_device *dev);
 static int fec_enet_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
 static void fec_restart(struct net_device *dev, int duplex);
 static void fec_stop(struct net_device *dev);
-static void fec_set_mac_address(struct net_device *dev);
 
 
 /* MII processing.  We keep this as simple as possible.  Requests are
@@ -241,19 +239,16 @@ static mii_list_t *mii_tail;
 static int     mii_queue(struct net_device *dev, int request,
                                void (*func)(uint, struct net_device *));
 
-/* Make MII read/write commands for the FEC.
-*/
+/* Make MII read/write commands for the FEC */
 #define mk_mii_read(REG)       (0x60020000 | ((REG & 0x1f) << 18))
 #define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \
                                                (VAL & 0xffff))
 #define mk_mii_end     0
 
-/* Transmitter timeout.
-*/
-#define TX_TIMEOUT (2*HZ)
+/* Transmitter timeout */
+#define TX_TIMEOUT (2 * HZ)
 
-/* Register definitions for the PHY.
-*/
+/* Register definitions for the PHY */
 
 #define MII_REG_CR          0  /* Control Register                         */
 #define MII_REG_SR          1  /* Status Register                          */
@@ -288,15 +283,11 @@ static int        mii_queue(struct net_device *dev, int request,
 static int
 fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct fec_enet_private *fep;
-       volatile fec_t  *fecp;
-       volatile cbd_t  *bdp;
+       struct fec_enet_private *fep = netdev_priv(dev);
+       struct bufdesc *bdp;
        unsigned short  status;
        unsigned long flags;
 
-       fep = netdev_priv(dev);
-       fecp = (volatile fec_t*)dev->base_addr;
-
        if (!fep->link) {
                /* Link is down or autonegotiation is in progress. */
                return 1;
@@ -307,7 +298,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        bdp = fep->cur_tx;
 
        status = bdp->cbd_sc;
-#ifndef final_version
+
        if (status & BD_ENET_TX_READY) {
                /* Ooops.  All transmit buffers are full.  Bail out.
                 * This should not happen, since dev->tbusy should be set.
@@ -316,21 +307,18 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
                spin_unlock_irqrestore(&fep->hw_lock, flags);
                return 1;
        }
-#endif
 
-       /* Clear all of the status flags.
-        */
+       /* Clear all of the status flags */
        status &= ~BD_ENET_TX_STATS;
 
-       /* Set buffer length and buffer pointer.
-       */
+       /* Set buffer length and buffer pointer */
        bdp->cbd_bufaddr = __pa(skb->data);
        bdp->cbd_datlen = skb->len;
 
        /*
-        *      On some FEC implementations data must be aligned on
-        *      4-byte boundaries. Use bounce buffers to copy data
-        *      and get it aligned. Ugh.
+        * On some FEC implementations data must be aligned on
+        * 4-byte boundaries. Use bounce buffers to copy data
+        * and get it aligned. Ugh.
         */
        if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
                unsigned int index;
@@ -339,8 +327,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
                bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
        }
 
-       /* Save skb pointer.
-       */
+       /* Save skb pointer */
        fep->tx_skbuff[fep->skb_cur] = skb;
 
        dev->stats.tx_bytes += skb->len;
@@ -349,13 +336,12 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Push the data cache so the CPM does not get stale memory
         * data.
         */
-       dma_sync_single(NULL, bdp->cbd_bufaddr,
-                       bdp->cbd_datlen, DMA_TO_DEVICE);
+       bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+                       FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
 
        /* Send it on its way.  Tell FEC it's ready, interrupt when done,
         * it's the last BD of the frame, and to put the CRC on the end.
         */
-
        status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
                        | BD_ENET_TX_LAST | BD_ENET_TX_TC);
        bdp->cbd_sc = status;
@@ -363,22 +349,20 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dev->trans_start = jiffies;
 
        /* Trigger transmission start */
-       fecp->fec_x_des_active = 0;
+       writel(0, fep->hwp + FEC_X_DES_ACTIVE);
 
-       /* If this was the last BD in the ring, start at the beginning again.
-       */
-       if (status & BD_ENET_TX_WRAP) {
+       /* If this was the last BD in the ring, start at the beginning again. */
+       if (status & BD_ENET_TX_WRAP)
                bdp = fep->tx_bd_base;
-       } else {
+       else
                bdp++;
-       }
 
        if (bdp == fep->dirty_tx) {
                fep->tx_full = 1;
                netif_stop_queue(dev);
        }
 
-       fep->cur_tx = (cbd_t *)bdp;
+       fep->cur_tx = bdp;
 
        spin_unlock_irqrestore(&fep->hw_lock, flags);
 
@@ -390,75 +374,33 @@ fec_timeout(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
 
-       printk("%s: transmit timed out.\n", dev->name);
        dev->stats.tx_errors++;
-#ifndef final_version
-       {
-       int     i;
-       cbd_t   *bdp;
-
-       printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
-              (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
-              (unsigned long)fep->dirty_tx,
-              (unsigned long)fep->cur_rx);
-
-       bdp = fep->tx_bd_base;
-       printk(" tx: %u buffers\n",  TX_RING_SIZE);
-       for (i = 0 ; i < TX_RING_SIZE; i++) {
-               printk("  %08x: %04x %04x %08x\n",
-                      (uint) bdp,
-                      bdp->cbd_sc,
-                      bdp->cbd_datlen,
-                      (int) bdp->cbd_bufaddr);
-               bdp++;
-       }
 
-       bdp = fep->rx_bd_base;
-       printk(" rx: %lu buffers\n",  (unsigned long) RX_RING_SIZE);
-       for (i = 0 ; i < RX_RING_SIZE; i++) {
-               printk("  %08x: %04x %04x %08x\n",
-                      (uint) bdp,
-                      bdp->cbd_sc,
-                      bdp->cbd_datlen,
-                      (int) bdp->cbd_bufaddr);
-               bdp++;
-       }
-       }
-#endif
        fec_restart(dev, fep->full_duplex);
        netif_wake_queue(dev);
 }
 
-/* The interrupt handler.
- * This is called from the MPC core interrupt.
- */
 static irqreturn_t
 fec_enet_interrupt(int irq, void * dev_id)
 {
        struct  net_device *dev = dev_id;
-       volatile fec_t  *fecp;
+       struct fec_enet_private *fep = netdev_priv(dev);
        uint    int_events;
        irqreturn_t ret = IRQ_NONE;
 
-       fecp = (volatile fec_t*)dev->base_addr;
-
-       /* Get the interrupt events that caused us to be here.
-       */
        do {
-               int_events = fecp->fec_ievent;
-               fecp->fec_ievent = int_events;
+               int_events = readl(fep->hwp + FEC_IEVENT);
+               writel(int_events, fep->hwp + FEC_IEVENT);
 
-               /* Handle receive event in its own function.
-                */
                if (int_events & FEC_ENET_RXF) {
                        ret = IRQ_HANDLED;
                        fec_enet_rx(dev);
                }
 
                /* Transmit OK, or non-fatal error. Update the buffer
-                  descriptors. FEC handles all errors, we just discover
-                  them as part of the transmit process.
-               */
+                * descriptors. FEC handles all errors, we just discover
+                * them as part of the transmit process.
+                */
                if (int_events & FEC_ENET_TXF) {
                        ret = IRQ_HANDLED;
                        fec_enet_tx(dev);
@@ -479,7 +421,7 @@ static void
 fec_enet_tx(struct net_device *dev)
 {
        struct  fec_enet_private *fep;
-       volatile cbd_t  *bdp;
+       struct bufdesc *bdp;
        unsigned short status;
        struct  sk_buff *skb;
 
@@ -488,7 +430,11 @@ fec_enet_tx(struct net_device *dev)
        bdp = fep->dirty_tx;
 
        while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
-               if (bdp == fep->cur_tx && fep->tx_full == 0) break;
+               if (bdp == fep->cur_tx && fep->tx_full == 0)
+                       break;
+
+               dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
+               bdp->cbd_bufaddr = 0;
 
                skb = fep->tx_skbuff[fep->skb_dirty];
                /* Check for errors. */
@@ -510,31 +456,27 @@ fec_enet_tx(struct net_device *dev)
                        dev->stats.tx_packets++;
                }
 
-#ifndef final_version
                if (status & BD_ENET_TX_READY)
                        printk("HEY! Enet xmit interrupt and TX_READY.\n");
-#endif
+
                /* Deferred means some collisions occurred during transmit,
                 * but we eventually sent the packet OK.
                 */
                if (status & BD_ENET_TX_DEF)
                        dev->stats.collisions++;
 
-               /* Free the sk buffer associated with this last transmit.
-                */
+               /* Free the sk buffer associated with this last transmit */
                dev_kfree_skb_any(skb);
                fep->tx_skbuff[fep->skb_dirty] = NULL;
                fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
 
-               /* Update pointer to next buffer descriptor to be transmitted.
-                */
+               /* Update pointer to next buffer descriptor to be transmitted */
                if (status & BD_ENET_TX_WRAP)
                        bdp = fep->tx_bd_base;
                else
                        bdp++;
 
-               /* Since we have freed up a buffer, the ring is no longer
-                * full.
+               /* Since we have freed up a buffer, the ring is no longer full
                 */
                if (fep->tx_full) {
                        fep->tx_full = 0;
@@ -542,7 +484,7 @@ fec_enet_tx(struct net_device *dev)
                                netif_wake_queue(dev);
                }
        }
-       fep->dirty_tx = (cbd_t *)bdp;
+       fep->dirty_tx = bdp;
        spin_unlock_irq(&fep->hw_lock);
 }
 
@@ -555,9 +497,8 @@ fec_enet_tx(struct net_device *dev)
 static void
 fec_enet_rx(struct net_device *dev)
 {
-       struct  fec_enet_private *fep;
-       volatile fec_t  *fecp;
-       volatile cbd_t *bdp;
+       struct  fec_enet_private *fep = netdev_priv(dev);
+       struct bufdesc *bdp;
        unsigned short status;
        struct  sk_buff *skb;
        ushort  pkt_len;
@@ -567,9 +508,6 @@ fec_enet_rx(struct net_device *dev)
        flush_cache_all();
 #endif
 
-       fep = netdev_priv(dev);
-       fecp = (volatile fec_t*)dev->base_addr;
-
        spin_lock_irq(&fep->hw_lock);
 
        /* First, grab all of the stats for the incoming packet.
@@ -577,143 +515,121 @@ fec_enet_rx(struct net_device *dev)
         */
        bdp = fep->cur_rx;
 
-while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
+       while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
 
-#ifndef final_version
-       /* Since we have allocated space to hold a complete frame,
-        * the last indicator should be set.
-        */
-       if ((status & BD_ENET_RX_LAST) == 0)
-               printk("FEC ENET: rcv is not +last\n");
-#endif
+               /* Since we have allocated space to hold a complete frame,
+                * the last indicator should be set.
+                */
+               if ((status & BD_ENET_RX_LAST) == 0)
+                       printk("FEC ENET: rcv is not +last\n");
 
-       if (!fep->opened)
-               goto rx_processing_done;
+               if (!fep->opened)
+                       goto rx_processing_done;
 
-       /* Check for errors. */
-       if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
+               /* Check for errors. */
+               if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
                           BD_ENET_RX_CR | BD_ENET_RX_OV)) {
-               dev->stats.rx_errors++;
-               if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
-               /* Frame too long or too short. */
-                       dev->stats.rx_length_errors++;
+                       dev->stats.rx_errors++;
+                       if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
+                               /* Frame too long or too short. */
+                               dev->stats.rx_length_errors++;
+                       }
+                       if (status & BD_ENET_RX_NO)     /* Frame alignment */
+                               dev->stats.rx_frame_errors++;
+                       if (status & BD_ENET_RX_CR)     /* CRC Error */
+                               dev->stats.rx_crc_errors++;
+                       if (status & BD_ENET_RX_OV)     /* FIFO overrun */
+                               dev->stats.rx_fifo_errors++;
                }
-               if (status & BD_ENET_RX_NO)     /* Frame alignment */
+
+               /* Report late collisions as a frame error.
+                * On this error, the BD is closed, but we don't know what we
+                * have in the buffer.  So, just drop this frame on the floor.
+                */
+               if (status & BD_ENET_RX_CL) {
+                       dev->stats.rx_errors++;
                        dev->stats.rx_frame_errors++;
-               if (status & BD_ENET_RX_CR)     /* CRC Error */
-                       dev->stats.rx_crc_errors++;
-               if (status & BD_ENET_RX_OV)     /* FIFO overrun */
-                       dev->stats.rx_fifo_errors++;
-       }
+                       goto rx_processing_done;
+               }
 
-       /* Report late collisions as a frame error.
-        * On this error, the BD is closed, but we don't know what we
-        * have in the buffer.  So, just drop this frame on the floor.
-        */
-       if (status & BD_ENET_RX_CL) {
-               dev->stats.rx_errors++;
-               dev->stats.rx_frame_errors++;
-               goto rx_processing_done;
-       }
+               /* Process the incoming frame. */
+               dev->stats.rx_packets++;
+               pkt_len = bdp->cbd_datlen;
+               dev->stats.rx_bytes += pkt_len;
+               data = (__u8*)__va(bdp->cbd_bufaddr);
 
-       /* Process the incoming frame.
-        */
-       dev->stats.rx_packets++;
-       pkt_len = bdp->cbd_datlen;
-       dev->stats.rx_bytes += pkt_len;
-       data = (__u8*)__va(bdp->cbd_bufaddr);
-
-       dma_sync_single(NULL, (unsigned long)__pa(data),
-                       pkt_len - 4, DMA_FROM_DEVICE);
-
-       /* This does 16 byte alignment, exactly what we need.
-        * The packet length includes FCS, but we don't want to
-        * include that when passing upstream as it messes up
-        * bridging applications.
-        */
-       skb = dev_alloc_skb(pkt_len-4);
+               dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
+                               DMA_FROM_DEVICE);
 
-       if (skb == NULL) {
-               printk("%s: Memory squeeze, dropping packet.\n", dev->name);
-               dev->stats.rx_dropped++;
-       } else {
-               skb_put(skb,pkt_len-4); /* Make room */
-               skb_copy_to_linear_data(skb, data, pkt_len-4);
-               skb->protocol=eth_type_trans(skb,dev);
-               netif_rx(skb);
-       }
-  rx_processing_done:
+               /* This does 16 byte alignment, exactly what we need.
+                * The packet length includes FCS, but we don't want to
+                * include that when passing upstream as it messes up
+                * bridging applications.
+                */
+               skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN);
 
-       /* Clear the status flags for this buffer.
-       */
-       status &= ~BD_ENET_RX_STATS;
+               if (unlikely(!skb)) {
+                       printk("%s: Memory squeeze, dropping packet.\n",
+                                       dev->name);
+                       dev->stats.rx_dropped++;
+               } else {
+                       skb_reserve(skb, NET_IP_ALIGN);
+                       skb_put(skb, pkt_len - 4);      /* Make room */
+                       skb_copy_to_linear_data(skb, data, pkt_len - 4);
+                       skb->protocol = eth_type_trans(skb, dev);
+                       netif_rx(skb);
+               }
 
-       /* Mark the buffer empty.
-       */
-       status |= BD_ENET_RX_EMPTY;
-       bdp->cbd_sc = status;
+               bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen,
+                       DMA_FROM_DEVICE);
+rx_processing_done:
+               /* Clear the status flags for this buffer */
+               status &= ~BD_ENET_RX_STATS;
 
-       /* Update BD pointer to next entry.
-       */
-       if (status & BD_ENET_RX_WRAP)
-               bdp = fep->rx_bd_base;
-       else
-               bdp++;
+               /* Mark the buffer empty */
+               status |= BD_ENET_RX_EMPTY;
+               bdp->cbd_sc = status;
 
-#if 1
-       /* Doing this here will keep the FEC running while we process
-        * incoming frames.  On a heavily loaded network, we should be
-        * able to keep up at the expense of system resources.
-        */
-       fecp->fec_r_des_active = 0;
-#endif
-   } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */
-       fep->cur_rx = (cbd_t *)bdp;
-
-#if 0
-       /* Doing this here will allow us to process all frames in the
-        * ring before the FEC is allowed to put more there.  On a heavily
-        * loaded network, some frames may be lost.  Unfortunately, this
-        * increases the interrupt overhead since we can potentially work
-        * our way back to the interrupt return only to come right back
-        * here.
-        */
-       fecp->fec_r_des_active = 0;
-#endif
+               /* Update BD pointer to next entry */
+               if (status & BD_ENET_RX_WRAP)
+                       bdp = fep->rx_bd_base;
+               else
+                       bdp++;
+               /* Doing this here will keep the FEC running while we process
+                * incoming frames.  On a heavily loaded network, we should be
+                * able to keep up at the expense of system resources.
+                */
+               writel(0, fep->hwp + FEC_R_DES_ACTIVE);
+       }
+       fep->cur_rx = bdp;
 
        spin_unlock_irq(&fep->hw_lock);
 }
 
-
 /* called from interrupt context */
 static void
 fec_enet_mii(struct net_device *dev)
 {
        struct  fec_enet_private *fep;
-       volatile fec_t  *ep;
        mii_list_t      *mip;
-       uint            mii_reg;
 
        fep = netdev_priv(dev);
        spin_lock_irq(&fep->mii_lock);
 
-       ep = fep->hwp;
-       mii_reg = ep->fec_mii_data;
-
        if ((mip = mii_head) == NULL) {
                printk("MII and no head!\n");
                goto unlock;
        }
 
        if (mip->mii_func != NULL)
-               (*(mip->mii_func))(mii_reg, dev);
+               (*(mip->mii_func))(readl(fep->hwp + FEC_MII_DATA), dev);
 
        mii_head = mip->mii_next;
        mip->mii_next = mii_free;
        mii_free = mip;
 
        if ((mip = mii_head) != NULL)
-               ep->fec_mii_data = mip->mii_regval;
+               writel(mip->mii_regval, fep->hwp + FEC_MII_DATA);
 
 unlock:
        spin_unlock_irq(&fep->mii_lock);
@@ -727,8 +643,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
        mii_list_t      *mip;
        int             retval;
 
-       /* Add PHY address to register command.
-       */
+       /* Add PHY address to register command */
        fep = netdev_priv(dev);
        spin_lock_irqsave(&fep->mii_lock, flags);
 
@@ -745,7 +660,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
                        mii_tail = mip;
                } else {
                        mii_head = mii_tail = mip;
-                       fep->hwp->fec_mii_data = regval;
+                       writel(regval, fep->hwp + FEC_MII_DATA);
                }
        } else {
                retval = 1;
@@ -1246,11 +1161,8 @@ static void __inline__ fec_phy_ack_intr(void)
 static void __inline__ fec_get_mac(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
-       volatile fec_t *fecp;
        unsigned char *iap, tmpaddr[ETH_ALEN];
 
-       fecp = fep->hwp;
-
        if (FEC_FLASHMAC) {
                /*
                 * Get MAC address from FLASH.
@@ -1264,8 +1176,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
                    (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
                        iap = fec_mac_default;
        } else {
-               *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
-               *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+               *((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
+               *((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
                iap = &tmpaddr[0];
        }
 
@@ -1375,11 +1287,6 @@ static void mii_relink(struct work_struct *work)
                fec_restart(dev, duplex);
        } else
                fec_stop(dev);
-
-#if 0
-       enable_irq(fep->mii_irq);
-#endif
-
 }
 
 /* mii_queue_relink is called in interrupt context from mii_link_interrupt */
@@ -1388,12 +1295,12 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
        struct fec_enet_private *fep = netdev_priv(dev);
 
        /*
-       ** We cannot queue phy_task twice in the workqueue.  It
-       ** would cause an endless loop in the workqueue.
-       ** Fortunately, if the last mii_relink entry has not yet been
-       ** executed now, it will do the job for the current interrupt,
-       ** which is just what we want.
-       */
+        * We cannot queue phy_task twice in the workqueue.  It
+        * would cause an endless loop in the workqueue.
+        * Fortunately, if the last mii_relink entry has not yet been
+        * executed now, it will do the job for the current interrupt,
+        * which is just what we want.
+        */
        if (fep->mii_phy_task_queued)
                return;
 
@@ -1424,8 +1331,7 @@ phy_cmd_t const phy_cmd_config[] = {
        { mk_mii_end, }
        };
 
-/* Read remainder of PHY ID.
-*/
+/* Read remainder of PHY ID. */
 static void
 mii_discover_phy3(uint mii_reg, struct net_device *dev)
 {
@@ -1457,17 +1363,14 @@ static void
 mii_discover_phy(uint mii_reg, struct net_device *dev)
 {
        struct fec_enet_private *fep;
-       volatile fec_t *fecp;
        uint phytype;
 
        fep = netdev_priv(dev);
-       fecp = fep->hwp;
 
        if (fep->phy_addr < 32) {
                if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
 
-                       /* Got first part of ID, now get remainder.
-                       */
+                       /* Got first part of ID, now get remainder */
                        fep->phy_id = phytype << 16;
                        mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
                                                        mii_discover_phy3);
@@ -1479,15 +1382,15 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
        } else {
                printk("FEC: No PHY device found.\n");
                /* Disable external MII interface */
-               fecp->fec_mii_speed = fep->phy_speed = 0;
+               writel(0, fep->hwp + FEC_MII_SPEED);
+               fep->phy_speed = 0;
 #ifdef HAVE_mii_link_interrupt
                fec_disable_phy_intr();
 #endif
        }
 }
 
-/* This interrupt occurs when the PHY detects a link change.
-*/
+/* This interrupt occurs when the PHY detects a link change */
 #ifdef HAVE_mii_link_interrupt
 static irqreturn_t
 mii_link_interrupt(int irq, void * dev_id)
@@ -1497,10 +1400,6 @@ mii_link_interrupt(int irq, void * dev_id)
 
        fec_phy_ack_intr();
 
-#if 0
-       disable_irq(fep->mii_irq);  /* disable now, enable later */
-#endif
-
        mii_do_cmd(dev, fep->phy->ack_int);
        mii_do_cmd(dev, phy_cmd_relink);  /* restart and display status */
 
@@ -1508,19 +1407,91 @@ mii_link_interrupt(int irq, void * dev_id)
 }
 #endif
 
+static void fec_enet_free_buffers(struct net_device *dev)
+{
+       struct fec_enet_private *fep = netdev_priv(dev);
+       int i;
+       struct sk_buff *skb;
+       struct bufdesc  *bdp;
+
+       bdp = fep->rx_bd_base;
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               skb = fep->rx_skbuff[i];
+
+               if (bdp->cbd_bufaddr)
+                       dma_unmap_single(&dev->dev, bdp->cbd_bufaddr,
+                                       FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+               if (skb)
+                       dev_kfree_skb(skb);
+               bdp++;
+       }
+
+       bdp = fep->tx_bd_base;
+       for (i = 0; i < TX_RING_SIZE; i++)
+               kfree(fep->tx_bounce[i]);
+}
+
+static int fec_enet_alloc_buffers(struct net_device *dev)
+{
+       struct fec_enet_private *fep = netdev_priv(dev);
+       int i;
+       struct sk_buff *skb;
+       struct bufdesc  *bdp;
+
+       bdp = fep->rx_bd_base;
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE);
+               if (!skb) {
+                       fec_enet_free_buffers(dev);
+                       return -ENOMEM;
+               }
+               fep->rx_skbuff[i] = skb;
+
+               bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+                               FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+               bdp->cbd_sc = BD_ENET_RX_EMPTY;
+               bdp++;
+       }
+
+       /* Set the last buffer to wrap. */
+       bdp--;
+       bdp->cbd_sc |= BD_SC_WRAP;
+
+       bdp = fep->tx_bd_base;
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+
+               bdp->cbd_sc = 0;
+               bdp->cbd_bufaddr = 0;
+               bdp++;
+       }
+
+       /* Set the last buffer to wrap. */
+       bdp--;
+       bdp->cbd_sc |= BD_SC_WRAP;
+
+       return 0;
+}
+
 static int
 fec_enet_open(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
+       int ret;
 
        /* I should reset the ring buffers here, but I don't yet know
         * a simple way to do that.
         */
-       fec_set_mac_address(dev);
+
+       ret = fec_enet_alloc_buffers(dev);
+       if (ret)
+               return ret;
 
        fep->sequence_done = 0;
        fep->link = 0;
 
+       fec_restart(dev, 1);
+
        if (fep->phy) {
                mii_do_cmd(dev, fep->phy->ack_int);
                mii_do_cmd(dev, fep->phy->config);
@@ -1537,21 +1508,17 @@ fec_enet_open(struct net_device *dev)
                        schedule();
 
                mii_do_cmd(dev, fep->phy->startup);
-
-               /* Set the initial link state to true. A lot of hardware
-                * based on this device does not implement a PHY interrupt,
-                * so we are never notified of link change.
-                */
-               fep->link = 1;
-       } else {
-               fep->link = 1; /* lets just try it and see */
-               /* no phy,  go full duplex,  it's most likely a hub chip */
-               fec_restart(dev, 1);
        }
 
+       /* Set the initial link state to true. A lot of hardware
+        * based on this device does not implement a PHY interrupt,
+        * so we are never notified of link change.
+        */
+       fep->link = 1;
+
        netif_start_queue(dev);
        fep->opened = 1;
-       return 0;               /* Success */
+       return 0;
 }
 
 static int
@@ -1559,12 +1526,13 @@ fec_enet_close(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
 
-       /* Don't know what to do yet.
-       */
+       /* Don't know what to do yet. */
        fep->opened = 0;
        netif_stop_queue(dev);
        fec_stop(dev);
 
+        fec_enet_free_buffers(dev);
+
        return 0;
 }
 
@@ -1583,87 +1551,102 @@ fec_enet_close(struct net_device *dev)
 
 static void set_multicast_list(struct net_device *dev)
 {
-       struct fec_enet_private *fep;
-       volatile fec_t *ep;
+       struct fec_enet_private *fep = netdev_priv(dev);
        struct dev_mc_list *dmi;
-       unsigned int i, j, bit, data, crc;
+       unsigned int i, j, bit, data, crc, tmp;
        unsigned char hash;
 
-       fep = netdev_priv(dev);
-       ep = fep->hwp;
+       if (dev->flags & IFF_PROMISC) {
+               tmp = readl(fep->hwp + FEC_R_CNTRL);
+               tmp |= 0x8;
+               writel(tmp, fep->hwp + FEC_R_CNTRL);
+               return;
+       }
 
-       if (dev->flags&IFF_PROMISC) {
-               ep->fec_r_cntrl |= 0x0008;
-       } else {
+       tmp = readl(fep->hwp + FEC_R_CNTRL);
+       tmp &= ~0x8;
+       writel(tmp, fep->hwp + FEC_R_CNTRL);
+
+       if (dev->flags & IFF_ALLMULTI) {
+               /* Catch all multicast addresses, so set the
+                * filter to all 1's
+                */
+               writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+               writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
 
-               ep->fec_r_cntrl &= ~0x0008;
+               return;
+       }
 
-               if (dev->flags & IFF_ALLMULTI) {
-                       /* Catch all multicast addresses, so set the
-                        * filter to all 1's.
-                        */
-                       ep->fec_grp_hash_table_high = 0xffffffff;
-                       ep->fec_grp_hash_table_low = 0xffffffff;
-               } else {
-                       /* Clear filter and add the addresses in hash register.
-                       */
-                       ep->fec_grp_hash_table_high = 0;
-                       ep->fec_grp_hash_table_low = 0;
-
-                       dmi = dev->mc_list;
-
-                       for (j = 0; j < dev->mc_count; j++, dmi = dmi->next)
-                       {
-                               /* Only support group multicast for now.
-                               */
-                               if (!(dmi->dmi_addr[0] & 1))
-                                       continue;
-
-                               /* calculate crc32 value of mac address
-                               */
-                               crc = 0xffffffff;
-
-                               for (i = 0; i < dmi->dmi_addrlen; i++)
-                               {
-                                       data = dmi->dmi_addr[i];
-                                       for (bit = 0; bit < 8; bit++, data >>= 1)
-                                       {
-                                               crc = (crc >> 1) ^
-                                               (((crc ^ data) & 1) ? CRC32_POLY : 0);
-                                       }
-                               }
-
-                               /* only upper 6 bits (HASH_BITS) are used
-                                  which point to specific bit in he hash registers
-                               */
-                               hash = (crc >> (32 - HASH_BITS)) & 0x3f;
-
-                               if (hash > 31)
-                                       ep->fec_grp_hash_table_high |= 1 << (hash - 32);
-                               else
-                                       ep->fec_grp_hash_table_low |= 1 << hash;
+       /* Clear filter and add the addresses in hash register
+        */
+       writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+       writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+
+       dmi = dev->mc_list;
+
+       for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
+               /* Only support group multicast for now */
+               if (!(dmi->dmi_addr[0] & 1))
+                       continue;
+
+               /* calculate crc32 value of mac address */
+               crc = 0xffffffff;
+
+               for (i = 0; i < dmi->dmi_addrlen; i++) {
+                       data = dmi->dmi_addr[i];
+                       for (bit = 0; bit < 8; bit++, data >>= 1) {
+                               crc = (crc >> 1) ^
+                               (((crc ^ data) & 1) ? CRC32_POLY : 0);
                        }
                }
+
+               /* only upper 6 bits (HASH_BITS) are used
+                * which point to specific bit in he hash registers
+                */
+               hash = (crc >> (32 - HASH_BITS)) & 0x3f;
+
+               if (hash > 31) {
+                       tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+                       tmp |= 1 << (hash - 32);
+                       writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+               } else {
+                       tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+                       tmp |= 1 << hash;
+                       writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+               }
        }
 }
 
-/* Set a MAC change in hardware.
- */
-static void
-fec_set_mac_address(struct net_device *dev)
+/* Set a MAC change in hardware. */
+static int
+fec_set_mac_address(struct net_device *dev, void *p)
 {
-       volatile fec_t *fecp;
+       struct fec_enet_private *fep = netdev_priv(dev);
+       struct sockaddr *addr = p;
 
-       fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp;
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
 
-       /* Set station address. */
-       fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
-               (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24);
-       fecp->fec_addr_high = (dev->dev_addr[5] << 16) |
-               (dev->dev_addr[4] << 24);
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
+       writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
+               (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
+               fep->hwp + FEC_ADDR_LOW);
+       writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24),
+               fep + FEC_ADDR_HIGH);
+       return 0;
 }
 
+static const struct net_device_ops fec_netdev_ops = {
+       .ndo_open               = fec_enet_open,
+       .ndo_stop               = fec_enet_close,
+       .ndo_start_xmit         = fec_enet_start_xmit,
+       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_tx_timeout         = fec_timeout,
+       .ndo_set_mac_address    = fec_set_mac_address,
+};
+
  /*
   * XXX:  We need to clean up on failure exits here.
   *
@@ -1672,17 +1655,13 @@ fec_set_mac_address(struct net_device *dev)
 int __init fec_enet_init(struct net_device *dev, int index)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
-       unsigned long   mem_addr;
-       volatile cbd_t  *bdp;
-       cbd_t           *cbd_base;
-       volatile fec_t  *fecp;
-       int             i, j;
+       struct bufdesc *cbd_base;
+       int i;
 
-       /* Allocate memory for buffer descriptors.
-       */
-       mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE,
-                       &fep->bd_dma, GFP_KERNEL);
-       if (mem_addr == 0) {
+       /* Allocate memory for buffer descriptors. */
+       cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
+                       GFP_KERNEL);
+       if (!cbd_base) {
                printk("FEC: allocate descriptor memory failed?\n");
                return -ENOMEM;
        }
@@ -1690,146 +1669,47 @@ int __init fec_enet_init(struct net_device *dev, int index)
        spin_lock_init(&fep->hw_lock);
        spin_lock_init(&fep->mii_lock);
 
-       /* Create an Ethernet device instance.
-       */
-       fecp = (volatile fec_t *)dev->base_addr;
-
        fep->index = index;
-       fep->hwp = fecp;
+       fep->hwp = (void __iomem *)dev->base_addr;
        fep->netdev = dev;
 
-       /* Whack a reset.  We should wait for this.
-       */
-       fecp->fec_ecntrl = 1;
-       udelay(10);
-
        /* Set the Ethernet address */
 #ifdef CONFIG_M5272
        fec_get_mac(dev);
 #else
        {
                unsigned long l;
-               l = fecp->fec_addr_low;
+               l = readl(fep->hwp + FEC_ADDR_LOW);
                dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
                dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
                dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
                dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
-               l = fecp->fec_addr_high;
+               l = readl(fep->hwp + FEC_ADDR_HIGH);
                dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
                dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
        }
 #endif
 
-       cbd_base = (cbd_t *)mem_addr;
-
-       /* Set receive and transmit descriptor base.
-       */
+       /* Set receive and transmit descriptor base. */
        fep->rx_bd_base = cbd_base;
        fep->tx_bd_base = cbd_base + RX_RING_SIZE;
 
-       fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
-       fep->cur_rx = fep->rx_bd_base;
-
-       fep->skb_cur = fep->skb_dirty = 0;
-
-       /* Initialize the receive buffer descriptors.
-       */
-       bdp = fep->rx_bd_base;
-       for (i=0; i<FEC_ENET_RX_PAGES; i++) {
-
-               /* Allocate a page.
-               */
-               mem_addr = __get_free_page(GFP_KERNEL);
-               /* XXX: missing check for allocation failure */
-
-               /* Initialize the BD for every fragment in the page.
-               */
-               for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
-                       bdp->cbd_sc = BD_ENET_RX_EMPTY;
-                       bdp->cbd_bufaddr = __pa(mem_addr);
-                       mem_addr += FEC_ENET_RX_FRSIZE;
-                       bdp++;
-               }
-       }
-
-       /* Set the last buffer to wrap.
-       */
-       bdp--;
-       bdp->cbd_sc |= BD_SC_WRAP;
-
-       /* ...and the same for transmmit.
-       */
-       bdp = fep->tx_bd_base;
-       for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
-               if (j >= FEC_ENET_TX_FRPPG) {
-                       mem_addr = __get_free_page(GFP_KERNEL);
-                       j = 1;
-               } else {
-                       mem_addr += FEC_ENET_TX_FRSIZE;
-                       j++;
-               }
-               fep->tx_bounce[i] = (unsigned char *) mem_addr;
-
-               /* Initialize the BD for every fragment in the page.
-               */
-               bdp->cbd_sc = 0;
-               bdp->cbd_bufaddr = 0;
-               bdp++;
-       }
-
-       /* Set the last buffer to wrap.
-       */
-       bdp--;
-       bdp->cbd_sc |= BD_SC_WRAP;
-
-       /* Set receive and transmit descriptor base.
-       */
-       fecp->fec_r_des_start = fep->bd_dma;
-       fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
-                               * RX_RING_SIZE;
-
 #ifdef HAVE_mii_link_interrupt
        fec_request_mii_intr(dev);
 #endif
-
-       fecp->fec_grp_hash_table_high = 0;
-       fecp->fec_grp_hash_table_low = 0;
-       fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-       fecp->fec_ecntrl = 2;
-       fecp->fec_r_des_active = 0;
-#ifndef CONFIG_M5272
-       fecp->fec_hash_table_high = 0;
-       fecp->fec_hash_table_low = 0;
-#endif
-
-       /* The FEC Ethernet specific entries in the device structure. */
-       dev->open = fec_enet_open;
-       dev->hard_start_xmit = fec_enet_start_xmit;
-       dev->tx_timeout = fec_timeout;
+       /* The FEC Ethernet specific entries in the device structure */
        dev->watchdog_timeo = TX_TIMEOUT;
-       dev->stop = fec_enet_close;
-       dev->set_multicast_list = set_multicast_list;
+       dev->netdev_ops = &fec_netdev_ops;
 
        for (i=0; i<NMII-1; i++)
                mii_cmds[i].mii_next = &mii_cmds[i+1];
        mii_free = mii_cmds;
 
-       /* setup MII interface */
-       fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
-       fecp->fec_x_cntrl = 0x00;
-
-       /*
-        * Set MII speed to 2.5 MHz
-        */
+       /* Set MII speed to 2.5 MHz */
        fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
                                        / 2500000) / 2) & 0x3F) << 1;
-       fecp->fec_mii_speed = fep->phy_speed;
        fec_restart(dev, 0);
 
-       /* Clear and enable interrupts */
-       fecp->fec_ievent = 0xffc00000;
-       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
-
        /* Queue up command to detect the PHY and initialize the
         * remainder of the interface.
         */
@@ -1847,145 +1727,118 @@ int __init fec_enet_init(struct net_device *dev, int index)
 static void
 fec_restart(struct net_device *dev, int duplex)
 {
-       struct fec_enet_private *fep;
-       volatile cbd_t *bdp;
-       volatile fec_t *fecp;
+       struct fec_enet_private *fep = netdev_priv(dev);
+       struct bufdesc *bdp;
        int i;
 
-       fep = netdev_priv(dev);
-       fecp = fep->hwp;
-
-       /* Whack a reset.  We should wait for this.
-       */
-       fecp->fec_ecntrl = 1;
+       /* Whack a reset.  We should wait for this. */
+       writel(1, fep->hwp + FEC_ECNTRL);
        udelay(10);
 
-       /* Clear any outstanding interrupt.
-       */
-       fecp->fec_ievent = 0xffc00000;
+       /* Clear any outstanding interrupt. */
+       writel(0xffc00000, fep->hwp + FEC_IEVENT);
 
-       /* Set station address.
-       */
-       fec_set_mac_address(dev);
+       /* Reset all multicast. */
+       writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+       writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+#ifndef CONFIG_M5272
+       writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
+       writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
+#endif
 
-       /* Reset all multicast.
-       */
-       fecp->fec_grp_hash_table_high = 0;
-       fecp->fec_grp_hash_table_low = 0;
+       /* Set maximum receive buffer size. */
+       writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
 
-       /* Set maximum receive buffer size.
-       */
-       fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-
-       /* Set receive and transmit descriptor base.
-       */
-       fecp->fec_r_des_start = fep->bd_dma;
-       fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
-                               * RX_RING_SIZE;
+       /* Set receive and transmit descriptor base. */
+       writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
+       writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
+                       fep->hwp + FEC_X_DES_START);
 
        fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
        fep->cur_rx = fep->rx_bd_base;
 
-       /* Reset SKB transmit buffers.
-       */
+       /* Reset SKB transmit buffers. */
        fep->skb_cur = fep->skb_dirty = 0;
-       for (i=0; i<=TX_RING_MOD_MASK; i++) {
-               if (fep->tx_skbuff[i] != NULL) {
+       for (i = 0; i <= TX_RING_MOD_MASK; i++) {
+               if (fep->tx_skbuff[i]) {
                        dev_kfree_skb_any(fep->tx_skbuff[i]);
                        fep->tx_skbuff[i] = NULL;
                }
        }
 
-       /* Initialize the receive buffer descriptors.
-       */
+       /* Initialize the receive buffer descriptors. */
        bdp = fep->rx_bd_base;
-       for (i=0; i<RX_RING_SIZE; i++) {
+       for (i = 0; i < RX_RING_SIZE; i++) {
 
-               /* Initialize the BD for every fragment in the page.
-               */
+               /* Initialize the BD for every fragment in the page. */
                bdp->cbd_sc = BD_ENET_RX_EMPTY;
                bdp++;
        }
 
-       /* Set the last buffer to wrap.
-       */
+       /* Set the last buffer to wrap */
        bdp--;
        bdp->cbd_sc |= BD_SC_WRAP;
 
-       /* ...and the same for transmmit.
-       */
+       /* ...and the same for transmit */
        bdp = fep->tx_bd_base;
-       for (i=0; i<TX_RING_SIZE; i++) {
+       for (i = 0; i < TX_RING_SIZE; i++) {
 
-               /* Initialize the BD for every fragment in the page.
-               */
+               /* Initialize the BD for every fragment in the page. */
                bdp->cbd_sc = 0;
                bdp->cbd_bufaddr = 0;
                bdp++;
        }
 
-       /* Set the last buffer to wrap.
-       */
+       /* Set the last buffer to wrap */
        bdp--;
        bdp->cbd_sc |= BD_SC_WRAP;
 
-       /* Enable MII mode.
-       */
+       /* Enable MII mode */
        if (duplex) {
-               fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
-               fecp->fec_x_cntrl = 0x04;                 /* FD enable */
+               /* MII enable / FD enable */
+               writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
+               writel(0x04, fep->hwp + FEC_X_CNTRL);
        } else {
-               /* MII enable|No Rcv on Xmit */
-               fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
-               fecp->fec_x_cntrl = 0x00;
+               /* MII enable / No Rcv on Xmit */
+               writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL);
+               writel(0x0, fep->hwp + FEC_X_CNTRL);
        }
        fep->full_duplex = duplex;
 
-       /* Set MII speed.
-       */
-       fecp->fec_mii_speed = fep->phy_speed;
+       /* Set MII speed */
+       writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 
-       /* And last, enable the transmit and receive processing.
-       */
-       fecp->fec_ecntrl = 2;
-       fecp->fec_r_des_active = 0;
+       /* And last, enable the transmit and receive processing */
+       writel(2, fep->hwp + FEC_ECNTRL);
+       writel(0, fep->hwp + FEC_R_DES_ACTIVE);
 
-       /* Enable interrupts we wish to service.
-       */
-       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
+       /* Enable interrupts we wish to service */
+       writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
+                       fep->hwp + FEC_IMASK);
 }
 
 static void
 fec_stop(struct net_device *dev)
 {
-       volatile fec_t *fecp;
-       struct fec_enet_private *fep;
-
-       fep = netdev_priv(dev);
-       fecp = fep->hwp;
+       struct fec_enet_private *fep = netdev_priv(dev);
 
-       /*
-       ** We cannot expect a graceful transmit stop without link !!!
-       */
-       if (fep->link)
-               {
-               fecp->fec_x_cntrl = 0x01;       /* Graceful transmit stop */
+       /* We cannot expect a graceful transmit stop without link !!! */
+       if (fep->link) {
+               writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
                udelay(10);
-               if (!(fecp->fec_ievent & FEC_ENET_GRA))
+               if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
                        printk("fec_stop : Graceful transmit stop did not complete !\n");
-               }
+       }
 
-       /* Whack a reset.  We should wait for this.
-       */
-       fecp->fec_ecntrl = 1;
+       /* Whack a reset.  We should wait for this. */
+       writel(1, fep->hwp + FEC_ECNTRL);
        udelay(10);
 
-       /* Clear outstanding MII command interrupts.
-       */
-       fecp->fec_ievent = FEC_ENET_MII;
+       /* Clear outstanding MII command interrupts. */
+       writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
 
-       fecp->fec_imask = FEC_ENET_MII;
-       fecp->fec_mii_speed = fep->phy_speed;
+       writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+       writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 }
 
 static int __devinit
index 76c64c9..30b7dd6 100644 (file)
  *     registers in the same peripheral device on different models
  *     of the ColdFire!
  */
-typedef struct fec {
-       unsigned long   fec_reserved0;
-       unsigned long   fec_ievent;             /* Interrupt event reg */
-       unsigned long   fec_imask;              /* Interrupt mask reg */
-       unsigned long   fec_reserved1;
-       unsigned long   fec_r_des_active;       /* Receive descriptor reg */
-       unsigned long   fec_x_des_active;       /* Transmit descriptor reg */
-       unsigned long   fec_reserved2[3];
-       unsigned long   fec_ecntrl;             /* Ethernet control reg */
-       unsigned long   fec_reserved3[6];
-       unsigned long   fec_mii_data;           /* MII manage frame reg */
-       unsigned long   fec_mii_speed;          /* MII speed control reg */
-       unsigned long   fec_reserved4[7];
-       unsigned long   fec_mib_ctrlstat;       /* MIB control/status reg */
-       unsigned long   fec_reserved5[7];
-       unsigned long   fec_r_cntrl;            /* Receive control reg */
-       unsigned long   fec_reserved6[15];
-       unsigned long   fec_x_cntrl;            /* Transmit Control reg */
-       unsigned long   fec_reserved7[7];
-       unsigned long   fec_addr_low;           /* Low 32bits MAC address */
-       unsigned long   fec_addr_high;          /* High 16bits MAC address */
-       unsigned long   fec_opd;                /* Opcode + Pause duration */
-       unsigned long   fec_reserved8[10];
-       unsigned long   fec_hash_table_high;    /* High 32bits hash table */
-       unsigned long   fec_hash_table_low;     /* Low 32bits hash table */
-       unsigned long   fec_grp_hash_table_high;/* High 32bits hash table */
-       unsigned long   fec_grp_hash_table_low; /* Low 32bits hash table */
-       unsigned long   fec_reserved9[7];
-       unsigned long   fec_x_wmrk;             /* FIFO transmit water mark */
-       unsigned long   fec_reserved10;
-       unsigned long   fec_r_bound;            /* FIFO receive bound reg */
-       unsigned long   fec_r_fstart;           /* FIFO receive start reg */
-       unsigned long   fec_reserved11[11];
-       unsigned long   fec_r_des_start;        /* Receive descriptor ring */
-       unsigned long   fec_x_des_start;        /* Transmit descriptor ring */
-       unsigned long   fec_r_buff_size;        /* Maximum receive buff size */
-} fec_t;
+#define FEC_IEVENT             0x004 /* Interrupt event reg */
+#define FEC_IMASK              0x008 /* Interrupt mask reg */
+#define FEC_R_DES_ACTIVE       0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE       0x014 /* Transmit descriptor reg */
+#define FEC_ECNTRL             0x024 /* Ethernet control reg */
+#define FEC_MII_DATA           0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED          0x044 /* MII speed control reg */
+#define FEC_MIB_CTRLSTAT       0x064 /* MIB control/status reg */
+#define FEC_R_CNTRL            0x084 /* Receive control reg */
+#define FEC_X_CNTRL            0x0c4 /* Transmit Control reg */
+#define FEC_ADDR_LOW           0x0e4 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH          0x0e8 /* High 16bits MAC address */
+#define FEC_OPD                        0x0ec /* Opcode + Pause duration */
+#define FEC_HASH_TABLE_HIGH    0x118 /* High 32bits hash table */
+#define FEC_HASH_TABLE_LOW     0x11c /* Low 32bits hash table */
+#define FEC_GRP_HASH_TABLE_HIGH        0x120 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x124 /* Low 32bits hash table */
+#define FEC_X_WMRK             0x144 /* FIFO transmit water mark */
+#define FEC_R_BOUND            0x14c /* FIFO receive bound reg */
+#define FEC_R_FSTART           0x150 /* FIFO receive start reg */
+#define FEC_R_DES_START                0x180 /* Receive descriptor ring */
+#define FEC_X_DES_START                0x184 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE                0x188 /* Maximum receive buff size */
 
 #else
 
-/*
- *     Define device register set address map.
- */
-typedef struct fec {
-       unsigned long   fec_ecntrl;             /* Ethernet control reg */
-       unsigned long   fec_ievent;             /* Interrupt even reg */
-       unsigned long   fec_imask;              /* Interrupt mask reg */
-       unsigned long   fec_ivec;               /* Interrupt vec status reg */
-       unsigned long   fec_r_des_active;       /* Receive descriptor reg */
-       unsigned long   fec_x_des_active;       /* Transmit descriptor reg */
-       unsigned long   fec_reserved1[10];
-       unsigned long   fec_mii_data;           /* MII manage frame reg */
-       unsigned long   fec_mii_speed;          /* MII speed control reg */
-       unsigned long   fec_reserved2[17];
-       unsigned long   fec_r_bound;            /* FIFO receive bound reg */
-       unsigned long   fec_r_fstart;           /* FIFO receive start reg */
-       unsigned long   fec_reserved3[4];
-       unsigned long   fec_x_wmrk;             /* FIFO transmit water mark */
-       unsigned long   fec_reserved4;
-       unsigned long   fec_x_fstart;           /* FIFO transmit start reg */
-       unsigned long   fec_reserved5[21];
-       unsigned long   fec_r_cntrl;            /* Receive control reg */
-       unsigned long   fec_max_frm_len;        /* Maximum frame length reg */
-       unsigned long   fec_reserved6[14];
-       unsigned long   fec_x_cntrl;            /* Transmit Control reg */
-       unsigned long   fec_reserved7[158];
-       unsigned long   fec_addr_low;           /* Low 32bits MAC address */
-       unsigned long   fec_addr_high;          /* High 16bits MAC address */
-       unsigned long   fec_grp_hash_table_high;/* High 32bits hash table */
-       unsigned long   fec_grp_hash_table_low; /* Low 32bits hash table */
-       unsigned long   fec_r_des_start;        /* Receive descriptor ring */
-       unsigned long   fec_x_des_start;        /* Transmit descriptor ring */
-       unsigned long   fec_r_buff_size;        /* Maximum receive buff size */
-       unsigned long   reserved8[9];
-       unsigned long   fec_fifo_ram[112];      /* FIFO RAM buffer */
-} fec_t;
+#define FEC_ECNTRL;            0x000 /* Ethernet control reg */
+#define FEC_IEVENT;            0x004 /* Interrupt even reg */
+#define FEC_IMASK;             0x008 /* Interrupt mask reg */
+#define FEC_IVEC;              0x00c /* Interrupt vec status reg */
+#define FEC_R_DES_ACTIVE;      0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE;      0x01c /* Transmit descriptor reg */
+#define FEC_MII_DATA           0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED          0x044 /* MII speed control reg */
+#define FEC_R_BOUND            0x08c /* FIFO receive bound reg */
+#define FEC_R_FSTART           0x090 /* FIFO receive start reg */
+#define FEC_X_WMRK             0x0a4 /* FIFO transmit water mark */
+#define FEC_X_FSTART           0x0ac /* FIFO transmit start reg */
+#define FEC_R_CNTRL            0x104 /* Receive control reg */
+#define FEC_MAX_FRM_LEN                0x108 /* Maximum frame length reg */
+#define FEC_X_CNTRL            0x144 /* Transmit Control reg */
+#define FEC_ADDR_LOW           0x3c0 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH          0x3c4 /* High 16bits MAC address */
+#define FEC_GRP_HASH_TABLE_HIGH        0x3c8 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x3cc /* Low 32bits hash table */
+#define FEC_R_DES_START                0x3d0 /* Receive descriptor ring */
+#define FEC_X_DES_START                0x3d4 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE                0x3d8 /* Maximum receive buff size */
+#define FEC_FIFO_RAM           0x400 /* FIFO RAM buffer */
 
 #endif /* CONFIG_M5272 */
 
@@ -104,17 +77,17 @@ typedef struct fec {
  *     Define the buffer descriptor structure.
  */
 #ifdef CONFIG_ARCH_MXC
-typedef struct bufdesc {
+struct bufdesc {
        unsigned short cbd_datlen;      /* Data length */
        unsigned short cbd_sc;  /* Control and status info */
        unsigned long cbd_bufaddr;      /* Buffer address */
-} cbd_t;
+};
 #else
-typedef struct bufdesc {
+struct bufdesc {
        unsigned short  cbd_sc;                 /* Control and status info */
        unsigned short  cbd_datlen;             /* Data length */
        unsigned long   cbd_bufaddr;            /* Buffer address */
-} cbd_t;
+};
 #endif
 
 /*
index 28077cc..61aaae4 100644 (file)
@@ -54,8 +54,7 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
        fec_t __iomem *fecp = fec->fecp;
        int i, ret = -1;
 
-       if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
-               BUG();
+       BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
 
        /* Add PHY address to register command.  */
        out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_read(location));
@@ -79,8 +78,7 @@ static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location,
        int i;
 
        /* this must never happen */
-       if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
-               BUG();
+       BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
 
        /* Add PHY address to register command.  */
        out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_write(location, val));
index 2e80263..3e3528a 100644 (file)
@@ -71,6 +71,19 @@ static struct dio_driver hplance_driver = {
        .remove    = __devexit_p(hplance_remove_one),
 };
 
+static const struct net_device_ops hplance_netdev_ops = {
+       .ndo_open               = hplance_open,
+       .ndo_stop               = hplance_close,
+       .ndo_start_xmit         = lance_start_xmit,
+       .ndo_set_multicast_list = lance_set_multicast,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = lance_poll,
+#endif
+};
+
 /* Find all the HP Lance boards and initialise them... */
 static int __devinit hplance_init_one(struct dio_dev *d,
                                const struct dio_device_id *ent)
@@ -135,13 +148,7 @@ static void __init hplance_init(struct net_device *dev, struct dio_dev *d)
 
         /* Fill the dev fields */
         dev->base_addr = va;
-        dev->open = &hplance_open;
-        dev->stop = &hplance_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-        dev->poll_controller = lance_poll;
-#endif
-        dev->hard_start_xmit = &lance_start_xmit;
-        dev->set_multicast_list = &lance_set_multicast;
+        dev->netdev_ops = &hplance_netdev_ops;
         dev->dma = 0;
 
         for (i=0; i<6; i++) {
index 5c6315d..0a51b0b 100644 (file)
@@ -1203,6 +1203,20 @@ static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev)
        return ret;
 }
 
+static const struct net_device_ops ibmveth_netdev_ops = {
+       .ndo_open               = ibmveth_open,
+       .ndo_stop               = ibmveth_close,
+       .ndo_start_xmit         = ibmveth_start_xmit,
+       .ndo_set_multicast_list = ibmveth_set_multicast_list,
+       .ndo_do_ioctl           = ibmveth_ioctl,
+       .ndo_change_mtu         = ibmveth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = ibmveth_poll_controller,
+#endif
+};
+
 static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
 {
        int rc, i;
@@ -1265,17 +1279,9 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
        memcpy(&adapter->mac_addr, mac_addr_p, 6);
 
        netdev->irq = dev->irq;
-       netdev->open               = ibmveth_open;
-       netdev->stop               = ibmveth_close;
-       netdev->hard_start_xmit    = ibmveth_start_xmit;
-       netdev->set_multicast_list = ibmveth_set_multicast_list;
-       netdev->do_ioctl           = ibmveth_ioctl;
-       netdev->ethtool_ops           = &netdev_ethtool_ops;
-       netdev->change_mtu         = ibmveth_change_mtu;
+       netdev->netdev_ops = &ibmveth_netdev_ops;
+       netdev->ethtool_ops = &netdev_ethtool_ops;
        SET_NETDEV_DEV(netdev, &dev->dev);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       netdev->poll_controller = ibmveth_poll_controller;
-#endif
        netdev->features |= NETIF_F_LLTX;
        spin_lock_init(&adapter->stats_lock);
 
index 9411640..204def0 100644 (file)
@@ -198,6 +198,17 @@ static int au1k_irda_init_iobuf(iobuff_t *io, int size)
        return io->head ? 0 : -ENOMEM;
 }
 
+static const struct net_device_ops au1k_irda_netdev_ops = {
+       .ndo_open               = au1k_irda_start,
+       .ndo_stop               = au1k_irda_stop,
+       .ndo_start_xmit         = au1k_irda_hard_xmit,
+       .ndo_tx_timeout         = au1k_tx_timeout,
+       .ndo_do_ioctl           = au1k_irda_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int au1k_irda_net_init(struct net_device *dev)
 {
        struct au1k_private *aup = netdev_priv(dev);
@@ -209,11 +220,7 @@ static int au1k_irda_net_init(struct net_device *dev)
        if (err)
                goto out1;
 
-       dev->open = au1k_irda_start;
-       dev->hard_start_xmit = au1k_irda_hard_xmit;
-       dev->stop = au1k_irda_stop;
-       dev->do_ioctl = au1k_irda_ioctl;
-       dev->tx_timeout = au1k_tx_timeout;
+       dev->netdev_ops = &au1k_irda_netdev_ops;
 
        irda_init_max_qos_capabilies(&aup->qos);
 
index e775338..e8ced56 100644 (file)
@@ -797,6 +797,16 @@ static int pxa_irda_init_iobuf(iobuff_t *io, int size)
        return io->head ? 0 : -ENOMEM;
 }
 
+static const struct net_device_ops pxa_irda_netdev_ops = {
+       .ndo_open               = pxa_irda_start,
+       .ndo_stop               = pxa_irda_stop,
+       .ndo_start_xmit         = pxa_irda_hard_xmit,
+       .ndo_do_ioctl           = pxa_irda_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int pxa_irda_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
@@ -845,10 +855,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
        if (err)
                goto err_startup;
 
-       dev->hard_start_xmit    = pxa_irda_hard_xmit;
-       dev->open               = pxa_irda_start;
-       dev->stop               = pxa_irda_stop;
-       dev->do_ioctl           = pxa_irda_ioctl;
+       dev->netdev_ops = &pxa_irda_netdev_ops;
 
        irda_init_max_qos_capabilies(&si->qos);
 
index 7a2b003..44a748e 100644 (file)
@@ -875,6 +875,16 @@ static int sa1100_irda_init_iobuf(iobuff_t *io, int size)
        return io->head ? 0 : -ENOMEM;
 }
 
+static const struct net_device_ops sa1100_irda_netdev_ops = {
+       .ndo_open               = sa1100_irda_start,
+       .ndo_stop               = sa1100_irda_stop,
+       .ndo_start_xmit         = sa1100_irda_hard_xmit,
+       .ndo_do_ioctl           = sa1100_irda_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int sa1100_irda_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
@@ -913,11 +923,8 @@ static int sa1100_irda_probe(struct platform_device *pdev)
        if (err)
                goto err_mem_5;
 
-       dev->hard_start_xmit    = sa1100_irda_hard_xmit;
-       dev->open               = sa1100_irda_start;
-       dev->stop               = sa1100_irda_stop;
-       dev->do_ioctl           = sa1100_irda_ioctl;
-       dev->irq                = IRQ_Ser2ICP;
+       dev->netdev_ops = &sa1100_irda_netdev_ops;
+       dev->ir         = IRQ_Ser2ICP;
 
        irda_init_max_qos_capabilies(&si->qos);
 
index cb793c2..264654d 100644 (file)
@@ -1021,6 +1021,16 @@ static const struct ethtool_ops ops = {
        .get_link = veth_get_link,
 };
 
+static const struct net_device_ops veth_netdev_ops = {
+       .ndo_open               = veth_open,
+       .ndo_stop               = veth_close,
+       .ndo_start_xmit         = veth_start_xmit,
+       .ndo_change_mtu         = veth_change_mtu,
+       .ndo_set_multicast_list = veth_set_multicast_list,
+       .ndo_set_mac_address    = NULL,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static struct net_device *veth_probe_one(int vlan,
                struct vio_dev *vio_dev)
 {
@@ -1067,12 +1077,7 @@ static struct net_device *veth_probe_one(int vlan,
 
        memcpy(&port->mac_addr, mac_addr, ETH_ALEN);
 
-       dev->open = veth_open;
-       dev->hard_start_xmit = veth_start_xmit;
-       dev->stop = veth_close;
-       dev->change_mtu = veth_change_mtu;
-       dev->set_mac_address = NULL;
-       dev->set_multicast_list = veth_set_multicast_list;
+       dev->netdev = &veth_netdev_ops;
        SET_ETHTOOL_OPS(dev, &ops);
 
        SET_NETDEV_DEV(dev, vdev);
index d92e72b..371a6be 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/sched.h>
 
 #undef ASSERT
-#define ASSERT(x)      if (!(x)) BUG()
+#define ASSERT(x)      BUG_ON(!(x))
 #define MSGOUT(S, A, B)        printk(KERN_DEBUG S "\n", A, B)
 
 #ifdef DBG
index 4791238..03eb54f 100644 (file)
@@ -75,18 +75,49 @@ static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
 static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
 {
        struct ixgbe_mac_info *mac = &hw->mac;
+
+       /* Call PHY identify routine to get the phy type */
+       ixgbe_identify_phy_generic(hw);
+
+       mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
+       mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
+       mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
+       mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
+       mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
+       mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_init_phy_ops_82598 - PHY/SFP specific init
+ *  @hw: pointer to hardware structure
+ *
+ *  Initialize any function pointers that were not able to be
+ *  set during get_invariants because the PHY/SFP type was
+ *  not known.  Perform the SFP init if necessary.
+ *
+ **/
+s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
+{
+       struct ixgbe_mac_info *mac = &hw->mac;
        struct ixgbe_phy_info *phy = &hw->phy;
        s32 ret_val = 0;
        u16 list_offset, data_offset;
 
-       /* Set the bus information prior to PHY identification */
-       mac->ops.get_bus_info(hw);
+       /* Identify the PHY */
+       phy->ops.identify(hw);
 
-       /* Call PHY identify routine to get the phy type */
-       ixgbe_identify_phy_generic(hw);
+       /* Overwrite the link function pointers if copper PHY */
+       if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+               mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
+               mac->ops.setup_link_speed =
+                                    &ixgbe_setup_copper_link_speed_82598;
+               mac->ops.get_link_capabilities =
+                                 &ixgbe_get_copper_link_capabilities_82598;
+       }
 
-       /* PHY Init */
-       switch (phy->type) {
+       switch (hw->phy.type) {
        case ixgbe_phy_tn:
                phy->ops.check_link = &ixgbe_check_phy_link_tnx;
                phy->ops.get_firmware_version =
@@ -106,8 +137,8 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
 
                /* Check to see if SFP+ module is supported */
                ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
-                                                             &list_offset,
-                                                             &data_offset);
+                                                           &list_offset,
+                                                           &data_offset);
                if (ret_val != 0) {
                        ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
                        goto out;
@@ -117,21 +148,6 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
                break;
        }
 
-       if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
-               mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
-               mac->ops.setup_link_speed =
-                                    &ixgbe_setup_copper_link_speed_82598;
-               mac->ops.get_link_capabilities =
-                                    &ixgbe_get_copper_link_capabilities_82598;
-       }
-
-       mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
-       mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
-       mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
-       mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
-       mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
-       mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
-
 out:
        return ret_val;
 }
@@ -149,12 +165,19 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
                                              bool *autoneg)
 {
        s32 status = 0;
+       u32 autoc = 0;
 
        /*
         * Determine link capabilities based on the stored value of AUTOC,
-        * which represents EEPROM defaults.
+        * which represents EEPROM defaults.  If AUTOC value has not been
+        * stored, use the current register value.
         */
-       switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+       if (hw->mac.orig_link_settings_stored)
+               autoc = hw->mac.orig_autoc;
+       else
+               autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+       switch (autoc & IXGBE_AUTOC_LMS_MASK) {
        case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
                *autoneg = false;
@@ -173,9 +196,9 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
        case IXGBE_AUTOC_LMS_KX4_AN:
        case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
                *speed = IXGBE_LINK_SPEED_UNKNOWN;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
                        *speed |= IXGBE_LINK_SPEED_1GB_FULL;
                *autoneg = true;
                break;
@@ -322,6 +345,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
        }
 
        /* Enable 802.3x based flow control settings. */
+       fctrl_reg |= IXGBE_FCTRL_DPF;
        IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
        IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
 
@@ -380,9 +404,11 @@ static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
         * because it causes the controller to just blast out fc packets.
         */
        if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
-               hw_dbg(hw, "Invalid water mark configuration\n");
-               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
-               goto out;
+               if (hw->fc.requested_mode != ixgbe_fc_none) {
+                       hw_dbg(hw, "Invalid water mark configuration\n");
+                       ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+                       goto out;
+               }
        }
 
        /*
@@ -716,14 +742,23 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
        }
 
        /* Reset PHY */
-       if (hw->phy.reset_disable == false)
+       if (hw->phy.reset_disable == false) {
+               /* PHY ops must be identified and initialized prior to reset */
+
+               /* Init PHY and function pointers, perform SFP setup */
+               status = hw->phy.ops.init(hw);
+               if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+                       goto reset_hw_out;
+
                hw->phy.ops.reset(hw);
+       }
 
        /*
         * Prevent the PCI-E bus from from hanging by disabling PCI-E master
         * access and verify no pending requests before reset
         */
-       if (ixgbe_disable_pcie_master(hw) != 0) {
+       status = ixgbe_disable_pcie_master(hw);
+       if (status != 0) {
                status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
                hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
        }
@@ -770,6 +805,7 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
        /* Store the permanent mac address */
        hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
 
+reset_hw_out:
        return status;
 }
 
@@ -998,35 +1034,56 @@ out:
 static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
 {
        u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+       u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+       u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+       u16 ext_ability = 0;
+
+       hw->phy.ops.identify(hw);
+
+       /* Copper PHY must be checked before AUTOC LMS to determine correct
+        * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
+       if (hw->phy.type == ixgbe_phy_tn ||
+           hw->phy.type == ixgbe_phy_cu_unknown) {
+               hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
+               IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
+               if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+               if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+               if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+               goto out;
+       }
 
-       switch (hw->device_id) {
-       case IXGBE_DEV_ID_82598:
-               /* Default device ID is mezzanine card KX/KX4 */
-               physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
-                                 IXGBE_PHYSICAL_LAYER_1000BASE_KX);
-               break;
-       case IXGBE_DEV_ID_82598_BX:
-               physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
-       case IXGBE_DEV_ID_82598EB_CX4:
-       case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
-               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
-               break;
-       case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
-               physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+       switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+       case IXGBE_AUTOC_LMS_1G_AN:
+       case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+               if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+               else
+                       physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
                break;
-       case IXGBE_DEV_ID_82598AF_DUAL_PORT:
-       case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
-       case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
-               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+       case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+               if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+               else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+               else /* XAUI */
+                       physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
                break;
-       case IXGBE_DEV_ID_82598EB_XF_LR:
-               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+       case IXGBE_AUTOC_LMS_KX4_AN:
+       case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
                break;
-       case IXGBE_DEV_ID_82598AT:
-               physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T |
-                                 IXGBE_PHYSICAL_LAYER_1000BASE_T);
+       default:
                break;
-       case IXGBE_DEV_ID_82598EB_SFP_LOM:
+       }
+
+       if (hw->phy.type == ixgbe_phy_nl) {
                hw->phy.ops.identify_sfp(hw);
 
                switch (hw->phy.sfp_type) {
@@ -1043,13 +1100,25 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
                        physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
                        break;
                }
-               break;
+       }
 
+       switch (hw->device_id) {
+       case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
+               physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+               break;
+       case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+       case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+       case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
+               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+               break;
+       case IXGBE_DEV_ID_82598EB_XF_LR:
+               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+               break;
        default:
-               physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
                break;
        }
 
+out:
        return physical_layer;
 }
 
@@ -1099,6 +1168,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
 static struct ixgbe_phy_operations phy_ops_82598 = {
        .identify               = &ixgbe_identify_phy_generic,
        .identify_sfp           = &ixgbe_identify_sfp_module_generic,
+       .init                   = &ixgbe_init_phy_ops_82598,
        .reset                  = &ixgbe_reset_phy_generic,
        .read_reg               = &ixgbe_read_phy_reg_generic,
        .write_reg              = &ixgbe_write_phy_reg_generic,
index 29771fb..9e824b4 100644 (file)
@@ -100,6 +100,9 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 
        if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
                ixgbe_init_mac_link_ops_82599(hw);
+
+               hw->phy.ops.reset = NULL;
+
                ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
                                                              &data_offset);
 
@@ -146,51 +149,60 @@ u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
 static s32 ixgbe_get_invariants_82599(struct ixgbe_hw *hw)
 {
        struct ixgbe_mac_info *mac = &hw->mac;
-       struct ixgbe_phy_info *phy = &hw->phy;
-       s32 ret_val;
 
-       /* Set the bus information prior to PHY identification */
-       mac->ops.get_bus_info(hw);
+       ixgbe_init_mac_link_ops_82599(hw);
 
-       /* Call PHY identify routine to get the Cu or SFI phy type */
-       ret_val = phy->ops.identify(hw);
+       mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
+       mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
+       mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
+       mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
+       mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
+       mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
 
-       if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
-               goto get_invariants_out;
+       return 0;
+}
 
-       ixgbe_init_mac_link_ops_82599(hw);
+/**
+ *  ixgbe_init_phy_ops_82599 - PHY/SFP specific init
+ *  @hw: pointer to hardware structure
+ *
+ *  Initialize any function pointers that were not able to be
+ *  set during get_invariants because the PHY/SFP type was
+ *  not known.  Perform the SFP init if necessary.
+ *
+ **/
+s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
+{
+       struct ixgbe_mac_info *mac = &hw->mac;
+       struct ixgbe_phy_info *phy = &hw->phy;
+       s32 ret_val = 0;
 
-       /* Setup SFP module if there is one present. */
-       ret_val = mac->ops.setup_sfp(hw);
+       /* Identify the PHY or SFP module */
+       ret_val = phy->ops.identify(hw);
+
+       /* Setup function pointers based on detected SFP module and speeds */
+       ixgbe_init_mac_link_ops_82599(hw);
 
        /* If copper media, overwrite with copper function pointers */
        if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
                mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
                mac->ops.setup_link_speed =
-                                 &ixgbe_setup_copper_link_speed_82599;
+                                    &ixgbe_setup_copper_link_speed_82599;
                mac->ops.get_link_capabilities =
                                  &ixgbe_get_copper_link_capabilities_82599;
        }
 
-       /* PHY Init */
+       /* Set necessary function pointers based on phy type */
        switch (hw->phy.type) {
        case ixgbe_phy_tn:
                phy->ops.check_link = &ixgbe_check_phy_link_tnx;
                phy->ops.get_firmware_version =
-                                 &ixgbe_get_phy_firmware_version_tnx;
+                            &ixgbe_get_phy_firmware_version_tnx;
                break;
        default:
                break;
        }
 
-       mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
-       mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
-       mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
-       mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
-       mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
-       mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
-
-get_invariants_out:
        return ret_val;
 }
 
@@ -207,8 +219,19 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
                                       bool *negotiation)
 {
        s32 status = 0;
+       u32 autoc = 0;
+
+       /*
+        * Determine link capabilities based on the stored value of AUTOC,
+        * which represents EEPROM defaults.  If AUTOC value has not been
+        * stored, use the current register value.
+        */
+       if (hw->mac.orig_link_settings_stored)
+               autoc = hw->mac.orig_autoc;
+       else
+               autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
 
-       switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+       switch (autoc & IXGBE_AUTOC_LMS_MASK) {
        case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
                *negotiation = false;
@@ -232,22 +255,22 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
        case IXGBE_AUTOC_LMS_KX4_KX_KR:
        case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
                *speed = IXGBE_LINK_SPEED_UNKNOWN;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+               if (autoc & IXGBE_AUTOC_KR_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
                        *speed |= IXGBE_LINK_SPEED_1GB_FULL;
                *negotiation = true;
                break;
 
        case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
                *speed = IXGBE_LINK_SPEED_100_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+               if (autoc & IXGBE_AUTOC_KR_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
                        *speed |= IXGBE_LINK_SPEED_1GB_FULL;
                *negotiation = true;
                break;
@@ -558,6 +581,7 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
        s32 status = 0;
        u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
        u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+       u32 orig_autoc = 0;
        u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
        u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
        u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
@@ -569,6 +593,13 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
        hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
        speed &= link_capabilities;
 
+       /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
+       if (hw->mac.orig_link_settings_stored)
+               orig_autoc = hw->mac.orig_autoc;
+       else
+               orig_autoc = autoc;
+
+
        if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
                status = IXGBE_ERR_LINK_SETUP;
        } else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
@@ -577,9 +608,9 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
                /* Set KX4/KX/KR support according to speed requested */
                autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
                if (speed & IXGBE_LINK_SPEED_10GB_FULL)
-                       if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+                       if (orig_autoc & IXGBE_AUTOC_KX4_SUPP)
                                autoc |= IXGBE_AUTOC_KX4_SUPP;
-                       if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+                       if (orig_autoc & IXGBE_AUTOC_KR_SUPP)
                                autoc |= IXGBE_AUTOC_KR_SUPP;
                if (speed & IXGBE_LINK_SPEED_1GB_FULL)
                        autoc |= IXGBE_AUTOC_KX_SUPP;
@@ -705,14 +736,30 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
        /* Call adapter stop to disable tx/rx and clear interrupts */
        hw->mac.ops.stop_adapter(hw);
 
+       /* PHY ops must be identified and initialized prior to reset */
+
+       /* Init PHY and function pointers, perform SFP setup */
+       status = hw->phy.ops.init(hw);
+
+       if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+               goto reset_hw_out;
+
+       /* Setup SFP module if there is one present. */
+       if (hw->phy.sfp_setup_needed) {
+               status = hw->mac.ops.setup_sfp(hw);
+               hw->phy.sfp_setup_needed = false;
+       }
+
        /* Reset PHY */
-       hw->phy.ops.reset(hw);
+       if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
+               hw->phy.ops.reset(hw);
 
        /*
         * Prevent the PCI-E bus from from hanging by disabling PCI-E master
         * access and verify no pending requests before reset
         */
-       if (ixgbe_disable_pcie_master(hw) != 0) {
+       status = ixgbe_disable_pcie_master(hw);
+       if (status != 0) {
                status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
                hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
        }
@@ -773,6 +820,7 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
        /* Store the permanent mac address */
        hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
 
+reset_hw_out:
        return status;
 }
 
@@ -1093,53 +1141,98 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
 u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
 {
        u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+       u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+       u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
+       u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+       u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+       u16 ext_ability = 0;
        u8 comp_codes_10g = 0;
 
-       switch (hw->device_id) {
-       case IXGBE_DEV_ID_82599:
-       case IXGBE_DEV_ID_82599_KX4:
-               /* Default device ID is mezzanine card KX/KX4 */
-               physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
-                                 IXGBE_PHYSICAL_LAYER_1000BASE_KX);
+       hw->phy.ops.identify(hw);
+
+       if (hw->phy.type == ixgbe_phy_tn ||
+           hw->phy.type == ixgbe_phy_cu_unknown) {
+               hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY,
+               IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability);
+               if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+               if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+               if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+               goto out;
+       }
+
+       switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+       case IXGBE_AUTOC_LMS_1G_AN:
+       case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+               if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) {
+                       physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX |
+                           IXGBE_PHYSICAL_LAYER_1000BASE_BX;
+                       goto out;
+               } else
+                       /* SFI mode so read SFP module */
+                       goto sfp_check;
                break;
-       case IXGBE_DEV_ID_82599_SFP:
-               hw->phy.ops.identify_sfp(hw);
+       case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+               if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+               else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+               goto out;
+               break;
+       case IXGBE_AUTOC_LMS_10G_SERIAL:
+               if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) {
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+                       goto out;
+               } else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)
+                       goto sfp_check;
+               break;
+       case IXGBE_AUTOC_LMS_KX4_KX_KR:
+       case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+               if (autoc & IXGBE_AUTOC_KR_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+               goto out;
+               break;
+       default:
+               goto out;
+               break;
+       }
 
-               switch (hw->phy.sfp_type) {
-               case ixgbe_sfp_type_da_cu:
-               case ixgbe_sfp_type_da_cu_core0:
-               case ixgbe_sfp_type_da_cu_core1:
-                       physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
-                       break;
-               case ixgbe_sfp_type_sr:
+sfp_check:
+       /* SFP check must be done last since DA modules are sometimes used to
+        * test KR mode -  we need to id KR mode correctly before SFP module.
+        * Call identify_sfp because the pluggable module may have changed */
+       hw->phy.ops.identify_sfp(hw);
+       if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
+               goto out;
+
+       switch (hw->phy.type) {
+       case ixgbe_phy_tw_tyco:
+       case ixgbe_phy_tw_unknown:
+               physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+               break;
+       case ixgbe_phy_sfp_avago:
+       case ixgbe_phy_sfp_ftl:
+       case ixgbe_phy_sfp_intel:
+       case ixgbe_phy_sfp_unknown:
+               hw->phy.ops.read_i2c_eeprom(hw,
+                     IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
+               if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
                        physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
-                       break;
-               case ixgbe_sfp_type_lr:
+               else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
                        physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
-                       break;
-               case ixgbe_sfp_type_srlr_core0:
-               case ixgbe_sfp_type_srlr_core1:
-                       hw->phy.ops.read_i2c_eeprom(hw,
-                                                   IXGBE_SFF_10GBE_COMP_CODES,
-                                                   &comp_codes_10g);
-                       if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
-                               physical_layer =
-                                               IXGBE_PHYSICAL_LAYER_10GBASE_SR;
-                       else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
-                               physical_layer =
-                                               IXGBE_PHYSICAL_LAYER_10GBASE_LR;
-                       else
-                               physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
-               default:
-                       physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
-                       break;
-               }
                break;
        default:
-               physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
                break;
        }
 
+out:
        return physical_layer;
 }
 
@@ -1187,6 +1280,22 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
        return 0;
 }
 
+/**
+ *  ixgbe_get_device_caps_82599 - Get additional device capabilities
+ *  @hw: pointer to hardware structure
+ *  @device_caps: the EEPROM word with the extra device capabilities
+ *
+ *  This function will read the EEPROM location for the device capabilities,
+ *  and return the word through device_caps.
+ **/
+s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
+{
+       hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
+
+       return 0;
+}
+
+
 static struct ixgbe_mac_operations mac_ops_82599 = {
        .init_hw                = &ixgbe_init_hw_generic,
        .reset_hw               = &ixgbe_reset_hw_82599,
@@ -1196,6 +1305,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
        .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599,
        .enable_rx_dma          = &ixgbe_enable_rx_dma_82599,
        .get_mac_addr           = &ixgbe_get_mac_addr_generic,
+       .get_device_caps        = &ixgbe_get_device_caps_82599,
        .stop_adapter           = &ixgbe_stop_adapter_generic,
        .get_bus_info           = &ixgbe_get_bus_info_generic,
        .set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie,
@@ -1236,6 +1346,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
 static struct ixgbe_phy_operations phy_ops_82599 = {
        .identify               = &ixgbe_identify_phy_82599,
        .identify_sfp           = &ixgbe_identify_sfp_module_generic,
+       .init                   = &ixgbe_init_phy_ops_82599,
        .reset                  = &ixgbe_reset_phy_generic,
        .read_reg               = &ixgbe_read_phy_reg_generic,
        .write_reg              = &ixgbe_write_phy_reg_generic,
index 5567519..5f2ee34 100644 (file)
@@ -1700,6 +1700,7 @@ s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
        }
 
        /* Enable 802.3x based flow control settings. */
+       mflcn_reg |= IXGBE_MFLCN_DPF;
        IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
        IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
 
@@ -1906,9 +1907,11 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
         * because it causes the controller to just blast out fc packets.
         */
        if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
-               hw_dbg(hw, "Invalid water mark configuration\n");
-               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
-               goto out;
+               if (hw->fc.requested_mode != ixgbe_fc_none) {
+                       hw_dbg(hw, "Invalid water mark configuration\n");
+                       ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+                       goto out;
+               }
        }
 
        /*
index 49a9037..0d9a3ac 100644 (file)
@@ -47,7 +47,7 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
                               "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "2.0.8-k2"
+#define DRV_VERSION "2.0.16-k2"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
 
@@ -4659,7 +4659,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 
        /* reset_hw fills in the perm_addr as well */
        err = hw->mac.ops.reset_hw(hw);
-       if (err) {
+       if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+               dev_err(&adapter->pdev->dev, "failed to load because an "
+                       "unsupported SFP+ module type was detected.\n");
+               goto err_sw_init;
+       } else if (err) {
                dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err);
                goto err_sw_init;
        }
@@ -4732,6 +4736,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        device_init_wakeup(&adapter->pdev->dev, true);
        device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
 
+       /* pick up the PCI bus settings for reporting later */
+       hw->mac.ops.get_bus_info(hw);
+
        /* print bus type/speed/width info */
        dev_info(&pdev->dev, "(PCI Express:%s:%s) %pM\n",
                ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
index 14e9606..f3258ec 100644 (file)
@@ -552,6 +552,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
        u32 vendor_oui = 0;
+       enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
        u8 identifier = 0;
        u8 comp_codes_1g = 0;
        u8 comp_codes_10g = 0;
@@ -620,8 +621,18 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                                hw->phy.sfp_type = ixgbe_sfp_type_unknown;
                }
 
+               if (hw->phy.sfp_type != stored_sfp_type)
+                       hw->phy.sfp_setup_needed = true;
+
+               /* Determine if the SFP+ PHY is dual speed or not. */
+               if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
+                  (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
+                  ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
+                  (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
+                       hw->phy.multispeed_fiber = true;
+
                /* Determine PHY vendor */
-               if (hw->phy.type == ixgbe_phy_unknown) {
+               if (hw->phy.type != ixgbe_phy_nl) {
                        hw->phy.id = identifier;
                        hw->phy.ops.read_i2c_eeprom(hw,
                                                    IXGBE_SFF_VENDOR_OUI_BYTE0,
@@ -671,9 +682,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                        goto out;
                }
 
-               hw->eeprom.ops.read(hw, IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET,
-                                   &enforce_sfp);
-               if (!(enforce_sfp & IXGBE_PHY_ALLOW_ANY_SFP)) {
+               /* This is guaranteed to be 82599, no need to check for NULL */
+               hw->mac.ops.get_device_caps(hw, &enforce_sfp);
+               if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
                        /* Make sure we're a supported PHY type */
                        if (hw->phy.type == ixgbe_phy_sfp_intel) {
                                status = 0;
index cc5f1b3..c9964b7 100644 (file)
@@ -44,6 +44,7 @@
 /* Bitmasks */
 #define IXGBE_SFF_TWIN_AX_CAPABLE            0x80
 #define IXGBE_SFF_1GBASESX_CAPABLE           0x1
+#define IXGBE_SFF_1GBASELX_CAPABLE           0x2
 #define IXGBE_SFF_10GBASESR_CAPABLE          0x10
 #define IXGBE_SFF_10GBASELR_CAPABLE          0x20
 #define IXGBE_I2C_EEPROM_READ_MASK           0x100
index 030ff0a..a3317d8 100644 (file)
 #define IXGBE_MDIO_PHY_EXT_ABILITY        0xB /* Ext Ability Reg */
 #define IXGBE_MDIO_PHY_10GBASET_ABILITY   0x0004 /* 10GBaseT capable */
 #define IXGBE_MDIO_PHY_1000BASET_ABILITY  0x0020 /* 1000BaseT capable */
+#define IXGBE_MDIO_PHY_100BASETX_ABILITY  0x0080 /* 100BaseTX capable */
 
 #define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR     0xC30A /* PHY_XS SDA/SCL Addr Reg */
 #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA     0xC30B /* PHY_XS SDA/SCL Data Reg */
 #define IXGBE_CONTROL_NL         0x000F
 #define IXGBE_CONTROL_EOL_NL     0x0FFF
 #define IXGBE_CONTROL_SOL_NL     0x0000
-#define IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET 0x002C
-#define IXGBE_PHY_ALLOW_ANY_SFP            0x1
 
 /* General purpose Interrupt Enable */
 #define IXGBE_SDP0_GPIEN         0x00000001 /* SDP0 */
 #define IXGBE_VT_CTL_DIS_DEFPL  0x20000000 /* disable default pool */
 #define IXGBE_VT_CTL_REPLEN     0x40000000 /* replication enabled */
 #define IXGBE_VT_CTL_VT_ENABLE  0x00000001  /* Enable VT Mode */
+#define IXGBE_VT_CTL_POOL_SHIFT 7
+#define IXGBE_VT_CTL_POOL_MASK  (0x3F << IXGBE_VT_CTL_POOL_SHIFT)
 
 /* VMOLR bitmasks */
 #define IXGBE_VMOLR_AUPE        0x01000000 /* accept untagged packets */
 
 /* Interrupt Vector Allocation Registers */
 #define IXGBE_IVAR_REG_NUM      25
+#define IXGBE_IVAR_REG_NUM_82599       64
 #define IXGBE_IVAR_TXRX_ENTRY   96
 #define IXGBE_IVAR_RX_ENTRY     64
 #define IXGBE_IVAR_RX_QUEUE(_i)    (0 + (_i))
 #define IXGBE_FW_PTR            0x0F
 #define IXGBE_PBANUM0_PTR       0x15
 #define IXGBE_PBANUM1_PTR       0x16
+#define IXGBE_DEVICE_CAPS       0x2C
 #define IXGBE_PCIE_MSIX_82599_CAPS  0x72
 #define IXGBE_PCIE_MSIX_82598_CAPS  0x62
 
 #define IXGBE_EERD_ATTEMPTS 100000
 #endif
 
+#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP  0x1
+
 /* PCI Bus Info */
 #define IXGBE_PCI_LINK_STATUS     0xB2
 #define IXGBE_PCI_LINK_WIDTH      0x3F0
 #define IXGBE_MTQC_RT_ENA       0x1 /* DCB Enable */
 #define IXGBE_MTQC_VT_ENA       0x2 /* VMDQ2 Enable */
 #define IXGBE_MTQC_64Q_1PB      0x0 /* 64 queues 1 pack buffer */
-#define IXGBE_MTQC_64VF         0x8 /* 2 TX Queues per pool w/64VF's */
+#define IXGBE_MTQC_32VF         0x8 /* 4 TX Queues per pool w/32VF's */
+#define IXGBE_MTQC_64VF         0x4 /* 2 TX Queues per pool w/64VF's */
 #define IXGBE_MTQC_8TC_8TQ      0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
 
 /* Receive Descriptor bit definitions */
@@ -1861,7 +1867,7 @@ typedef u32 ixgbe_physical_layer;
 #define IXGBE_PHYSICAL_LAYER_UNKNOWN      0
 #define IXGBE_PHYSICAL_LAYER_10GBASE_T    0x0001
 #define IXGBE_PHYSICAL_LAYER_1000BASE_T   0x0002
-#define IXGBE_PHYSICAL_LAYER_100BASE_T    0x0004
+#define IXGBE_PHYSICAL_LAYER_100BASE_TX   0x0004
 #define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU  0x0008
 #define IXGBE_PHYSICAL_LAYER_10GBASE_LR   0x0010
 #define IXGBE_PHYSICAL_LAYER_10GBASE_LRM  0x0020
@@ -1870,6 +1876,7 @@ typedef u32 ixgbe_physical_layer;
 #define IXGBE_PHYSICAL_LAYER_10GBASE_CX4  0x0100
 #define IXGBE_PHYSICAL_LAYER_1000BASE_KX  0x0200
 #define IXGBE_PHYSICAL_LAYER_1000BASE_BX  0x0400
+#define IXGBE_PHYSICAL_LAYER_10GBASE_KR   0x0800
 
 enum ixgbe_eeprom_type {
        ixgbe_eeprom_uninitialized = 0,
@@ -2101,6 +2108,7 @@ struct ixgbe_mac_operations {
        enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
        u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
        s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
+       s32 (*get_device_caps)(struct ixgbe_hw *, u16 *);
        s32 (*stop_adapter)(struct ixgbe_hw *);
        s32 (*get_bus_info)(struct ixgbe_hw *);
        void (*set_lan_id)(struct ixgbe_hw *);
@@ -2146,6 +2154,7 @@ struct ixgbe_mac_operations {
 struct ixgbe_phy_operations {
        s32 (*identify)(struct ixgbe_hw *);
        s32 (*identify_sfp)(struct ixgbe_hw *);
+       s32 (*init)(struct ixgbe_hw *);
        s32 (*reset)(struct ixgbe_hw *);
        s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
        s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
@@ -2193,6 +2202,7 @@ struct ixgbe_phy_info {
        u32                             addr;
        u32                             id;
        enum ixgbe_sfp_type             sfp_type;
+       bool                            sfp_setup_needed;
        u32                             revision;
        enum ixgbe_media_type           media_type;
        bool                            reset_disable;
index d3bf2f0..2a0174b 100644 (file)
@@ -270,6 +270,18 @@ static int ixpdev_close(struct net_device *dev)
        return 0;
 }
 
+static const struct net_device_ops ixpdev_netdev_ops = {
+       .ndo_open               = ixpdev_open,
+       .ndo_stop               = ixpdev_close,
+       .ndo_start_xmit         = ixpdev_xmit,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = ixpdev_poll_controller,
+#endif
+};
+
 struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
 {
        struct net_device *dev;
@@ -279,12 +291,7 @@ struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
        if (dev == NULL)
                return NULL;
 
-       dev->hard_start_xmit = ixpdev_xmit;
-       dev->open = ixpdev_open;
-       dev->stop = ixpdev_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = ixpdev_poll_controller;
-#endif
+       dev->netdev_ops = &ixpdev_netdev_ops;
 
        dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
index 14248cf..d12106b 100644 (file)
@@ -96,6 +96,18 @@ static int jazzsonic_close(struct net_device* dev)
        return err;
 }
 
+static const struct net_device_ops sonic_netdev_ops = {
+       .ndo_open               = jazzsonic_open,
+       .ndo_stop               = jazzsonic_close,
+       .ndo_start_xmit         = sonic_send_packet,
+       .ndo_get_stats          = sonic_get_stats,
+       .ndo_set_multicast_list = sonic_multicast_list,
+       .ndo_tx_timeout         = sonic_tx_timeout,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int __init sonic_probe1(struct net_device *dev)
 {
        static unsigned version_printed;
@@ -179,12 +191,7 @@ static int __init sonic_probe1(struct net_device *dev)
        lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
                             * SONIC_BUS_SCALE(lp->dma_bitmode));
 
-       dev->open = jazzsonic_open;
-       dev->stop = jazzsonic_close;
-       dev->hard_start_xmit = sonic_send_packet;
-       dev->get_stats = sonic_get_stats;
-       dev->set_multicast_list = &sonic_multicast_list;
-       dev->tx_timeout = sonic_tx_timeout;
+       dev->netdev_ops = &sonic_netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
 
        /*
index 38d6649..dc23856 100644 (file)
@@ -1081,6 +1081,21 @@ static int korina_close(struct net_device *dev)
        return 0;
 }
 
+static const struct net_device_ops korina_netdev_ops = {
+       .ndo_open               = korina_open,
+       .ndo_stop               = korina_close,
+       .ndo_start_xmit         = korina_send_packet,
+       .ndo_set_multicast_list = korina_multicast_list,
+       .ndo_tx_timeout         = korina_tx_timeout,
+       .ndo_do_ioctl           = korina_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = korina_poll_controller,
+#endif
+};
+
 static int korina_probe(struct platform_device *pdev)
 {
        struct korina_device *bif = platform_get_drvdata(pdev);
@@ -1149,17 +1164,9 @@ static int korina_probe(struct platform_device *pdev)
        dev->irq = lp->rx_irq;
        lp->dev = dev;
 
-       dev->open = korina_open;
-       dev->stop = korina_close;
-       dev->hard_start_xmit = korina_send_packet;
-       dev->set_multicast_list = &korina_multicast_list;
+       dev->netdev_ops = &korina_netdev_ops;
        dev->ethtool_ops = &netdev_ethtool_ops;
-       dev->tx_timeout = korina_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
-       dev->do_ioctl = &korina_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = korina_poll_controller;
-#endif
        netif_napi_add(dev, &lp->napi, korina_poll, 64);
 
        lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
index 7415f51..070fa45 100644 (file)
@@ -1036,6 +1036,19 @@ static void print_eth(unsigned char *add, char *str)
        printk(KERN_DEBUG "i596 0x%p, %pM --> %pM %02X%02X, %s\n",
               add, add + 6, add, add[12], add[13], str);
 }
+static const struct net_device_ops i596_netdev_ops = {
+       .ndo_open               = i596_open,
+       .ndo_stop               = i596_close,
+       .ndo_start_xmit         = i596_start_xmit,
+       .ndo_set_multicast_list = set_multicast_list,
+       .ndo_tx_timeout         = i596_tx_timeout,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = i596_poll_controller,
+#endif
+};
 
 static int __devinit i82596_probe(struct net_device *dev)
 {
@@ -1062,16 +1075,8 @@ static int __devinit i82596_probe(struct net_device *dev)
                return -ENOMEM;
        }
 
-       /* The 82596-specific entries in the device structure. */
-       dev->open = i596_open;
-       dev->stop = i596_close;
-       dev->hard_start_xmit = i596_start_xmit;
-       dev->set_multicast_list = set_multicast_list;
-       dev->tx_timeout = i596_tx_timeout;
+       dev->netdev_ops = &i596_netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = i596_poll_controller;
-#endif
 
        memset(dma, 0, sizeof(struct i596_dma));
        lp->dma = dma;
index feebbd9..1ad740b 100644 (file)
@@ -94,6 +94,16 @@ static void __mace_set_address(struct net_device *dev, void *addr);
  */
 static unsigned char *dummy_buf;
 
+static const struct net_device_ops mace_netdev_ops = {
+       .ndo_open               = mace_open,
+       .ndo_stop               = mace_close,
+       .ndo_start_xmit         = mace_xmit_start,
+       .ndo_set_multicast_list = mace_set_multicast,
+       .ndo_set_mac_address    = mace_set_address,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
        struct device_node *mace = macio_get_of_node(mdev);
@@ -207,11 +217,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
                }
        }
 
-       dev->open = mace_open;
-       dev->stop = mace_close;
-       dev->hard_start_xmit = mace_xmit_start;
-       dev->set_multicast_list = mace_set_multicast;
-       dev->set_mac_address = mace_set_address;
+       dev->netdev_ops = &mace_netdev_ops;
 
        /*
         * Most of what is below could be moved to mace_open()
index 274e99b..44f3c28 100644 (file)
@@ -180,6 +180,17 @@ static void mace_dma_off(struct net_device *dev)
        psc_write_word(PSC_ENETWR_CMD + PSC_SET1, 0x1100);
 }
 
+static const struct net_device_ops mace_netdev_ops = {
+       .ndo_open               = mace_open,
+       .ndo_stop               = mace_close,
+       .ndo_start_xmit         = mace_xmit_start,
+       .ndo_tx_timeout         = mace_tx_timeout,
+       .ndo_set_multicast_list = mace_set_multicast,
+       .ndo_set_mac_address    = mace_set_address,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 /*
  * Not really much of a probe. The hardware table tells us if this
  * model of Macintrash has a MACE (AV macintoshes)
@@ -240,13 +251,8 @@ static int __devinit mace_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       dev->open               = mace_open;
-       dev->stop               = mace_close;
-       dev->hard_start_xmit    = mace_xmit_start;
-       dev->tx_timeout         = mace_tx_timeout;
+       dev->netdev_ops         = &mace_netdev_ops;
        dev->watchdog_timeo     = TX_TIMEOUT;
-       dev->set_multicast_list = mace_set_multicast;
-       dev->set_mac_address    = mace_set_address;
 
        printk(KERN_INFO "%s: 68K MACE, hardware address %pM\n",
               dev->name, dev->dev_addr);
index aa08987..46ffdb4 100644 (file)
@@ -769,9 +769,17 @@ static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        }
 }
 
-/*
- * Return statistics to the caller
- */
+static const struct net_device_ops meth_netdev_ops = {
+       .ndo_open               = meth_open,
+       .ndo_stop               = meth_release,
+       .ndo_start_xmit         = meth_tx,
+       .ndo_do_ioctl           = meth_ioctl,
+       .ndo_tx_timeout         = meth_tx_timeout,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 /*
  * The init function.
  */
@@ -785,16 +793,10 @@ static int __init meth_probe(struct platform_device *pdev)
        if (!dev)
                return -ENOMEM;
 
-       dev->open            = meth_open;
-       dev->stop            = meth_release;
-       dev->hard_start_xmit = meth_tx;
-       dev->do_ioctl        = meth_ioctl;
-#ifdef HAVE_TX_TIMEOUT
-       dev->tx_timeout      = meth_tx_timeout;
-       dev->watchdog_timeo  = timeout;
-#endif
-       dev->irq             = MACE_ETHERNET_IRQ;
-       dev->base_addr       = (unsigned long)&mace->eth;
+       dev->netdev_ops         = &meth_netdev_ops;
+       dev->watchdog_timeo     = timeout;
+       dev->irq                = MACE_ETHERNET_IRQ;
+       dev->base_addr          = (unsigned long)&mace->eth;
        memcpy(dev->dev_addr, o2meth_eaddr, 6);
 
        priv = netdev_priv(dev);
index 664835b..b3b9a14 100644 (file)
@@ -237,6 +237,16 @@ static void mipsnet_set_mclist(struct net_device *dev)
 {
 }
 
+static const struct net_device_ops mipsnet_netdev_ops = {
+       .ndo_open               = mipsnet_open,
+       .ndo_stop               = mipsnet_close,
+       .ndo_start_xmit         = mipsnet_xmit,
+       .ndo_set_multicast_list = mipsnet_set_mclist,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int __init mipsnet_probe(struct platform_device *dev)
 {
        struct net_device *netdev;
@@ -250,10 +260,7 @@ static int __init mipsnet_probe(struct platform_device *dev)
 
        platform_set_drvdata(dev, netdev);
 
-       netdev->open                    = mipsnet_open;
-       netdev->stop                    = mipsnet_close;
-       netdev->hard_start_xmit         = mipsnet_xmit;
-       netdev->set_multicast_list      = mipsnet_set_mclist;
+       netdev->netdev_ops = &mipsnet_netdev_ops;
 
        /*
         * TODO: probe for these or load them from PARAM
index 435e5a8..93c709d 100644 (file)
@@ -57,6 +57,17 @@ typedef void (*writerap_t)(void *, unsigned short);
 typedef void (*writerdp_t)(void *, unsigned short);
 typedef unsigned short (*readrdp_t)(void *);
 
+static const struct net_device_ops lance_netdev_ops = {
+       .ndo_open               = m147lance_open,
+       .ndo_stop               = m147lance_close,
+       .ndo_start_xmit         = lance_start_xmit,
+       .ndo_set_multicast_list = lance_set_multicast,
+       .ndo_tx_timeout         = lance_tx_timeout,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 /* Initialise the one and only on-board 7990 */
 struct net_device * __init mvme147lance_probe(int unit)
 {
@@ -81,11 +92,7 @@ struct net_device * __init mvme147lance_probe(int unit)
 
        /* Fill the dev fields */
        dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
-       dev->open = &m147lance_open;
-       dev->stop = &m147lance_close;
-       dev->hard_start_xmit = &lance_start_xmit;
-       dev->set_multicast_list = &lance_set_multicast;
-       dev->tx_timeout = &lance_tx_timeout;
+       dev->netdev_ops = &lance_netdev_ops;
        dev->dma = 0;
 
        addr=(u_long *)ETHERNET_ADDRESS;
index 1861d5b..946366d 100644 (file)
@@ -301,6 +301,17 @@ netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value)
        while (readl(NETX_MIIMU) & MIIMU_SNRDY);
 }
 
+static const struct net_device_ops netx_eth_netdev_ops = {
+       .ndo_open               = netx_eth_open,
+       .ndo_stop               = netx_eth_close,
+       .ndo_start_xmit         = netx_eth_hard_start_xmit,
+       .ndo_tx_timeout         = netx_eth_timeout,
+       .ndo_set_multicast_list = netx_eth_set_multicast_list,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int netx_eth_enable(struct net_device *ndev)
 {
        struct netx_eth_priv *priv = netdev_priv(ndev);
@@ -309,12 +320,8 @@ static int netx_eth_enable(struct net_device *ndev)
 
        ether_setup(ndev);
 
-       ndev->open = netx_eth_open;
-       ndev->stop = netx_eth_close;
-       ndev->hard_start_xmit = netx_eth_hard_start_xmit;
-       ndev->tx_timeout = netx_eth_timeout;
+       ndev->netdev_ops = &netx_eth_netdev_ops;
        ndev->watchdog_timeo = msecs_to_jiffies(5000);
-       ndev->set_multicast_list = netx_eth_set_multicast_list;
 
        priv->msg_enable       = NETIF_MSG_LINK;
        priv->mii.phy_id_mask  = 0x1f;
index c408151..ebd6c2e 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 
 #include <linux/ethtool.h>
 #include <linux/mii.h>
-#include <linux/interrupt.h>
 #include <linux/timer.h>
 
-#include <linux/mm.h>
-#include <linux/mman.h>
 #include <linux/vmalloc.h>
 
-#include <asm/system.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
 
 #include "netxen_nic_hw.h"
 
        (sizeof(struct netxen_rx_buffer) * rds_ring->num_desc)
 #define STATUS_DESC_RINGSIZE(sds_ring) \
        (sizeof(struct status_desc) * (sds_ring)->num_desc)
-#define TX_BUFF_RINGSIZE(adapter)      \
-       (sizeof(struct netxen_cmd_buffer) * adapter->num_txd)
-#define TX_DESC_RINGSIZE(adapter)      \
-       (sizeof(struct cmd_desc_type0) * adapter->num_txd)
+#define TX_BUFF_RINGSIZE(tx_ring)      \
+       (sizeof(struct netxen_cmd_buffer) * tx_ring->num_desc)
+#define TX_DESC_RINGSIZE(tx_ring)      \
+       (sizeof(struct cmd_desc_type0) * tx_ring->num_desc)
 
 #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
 
 #define NX_P3_A2               0x30
 #define NX_P3_B0               0x40
 #define NX_P3_B1               0x41
+#define NX_P3_B2               0x42
 
 #define NX_IS_REVISION_P2(REVISION)     (REVISION <= NX_P2_C1)
 #define NX_IS_REVISION_P3(REVISION)     (REVISION >= NX_P3_A0)
 #define MAX_RCV_DESCRIPTORS_10G                4096
 #define MAX_JUMBO_RCV_DESCRIPTORS      1024
 #define MAX_LRO_RCV_DESCRIPTORS                8
-#define MAX_RCVSTATUS_DESCRIPTORS      MAX_RCV_DESCRIPTORS
-#define MAX_JUMBO_RCV_DESC     MAX_JUMBO_RCV_DESCRIPTORS
-#define MAX_RCV_DESC           MAX_RCV_DESCRIPTORS
-#define MAX_RCVSTATUS_DESC     MAX_RCV_DESCRIPTORS
-#define MAX_EPG_DESCRIPTORS    (MAX_CMD_DESCRIPTORS * 8)
-#define NUM_RCV_DESC           (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS + \
-                                MAX_LRO_RCV_DESCRIPTORS)
-#define MIN_TX_COUNT   4096
-#define MIN_RX_COUNT   4096
 #define NETXEN_CTX_SIGNATURE   0xdee0
+#define NETXEN_CTX_SIGNATURE_V2        0x0002dee0
+#define NETXEN_CTX_RESET       0xbad0
 #define NETXEN_RCV_PRODUCER(ringid)    (ringid)
-#define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */
 
 #define PHAN_PEG_RCV_INITIALIZED       0xff01
 #define PHAN_PEG_RCV_START_INITIALIZE  0xff00
@@ -253,12 +236,19 @@ typedef u32 netxen_ctx_msg;
 #define netxen_set_msg_opcode(config_word, val)        \
        ((config_word) &= ~(0xf<<28), (config_word) |= (val & 0xf) << 28)
 
-struct netxen_rcv_context {
-       __le64 rcv_ring_addr;
-       __le32 rcv_ring_size;
+struct netxen_rcv_ring {
+       __le64 addr;
+       __le32 size;
        __le32 rsrvd;
 };
 
+struct netxen_sts_ring {
+       __le64 addr;
+       __le32 size;
+       __le16 msi_index;
+       __le16 rsvd;
+} ;
+
 struct netxen_ring_ctx {
 
        /* one command ring */
@@ -268,13 +258,18 @@ struct netxen_ring_ctx {
        __le32 rsrvd;
 
        /* three receive rings */
-       struct netxen_rcv_context rcv_ctx[3];
+       struct netxen_rcv_ring rcv_rings[NUM_RCV_DESC_RINGS];
 
-       /* one status ring */
        __le64 sts_ring_addr;
        __le32 sts_ring_size;
 
        __le32 ctx_id;
+
+       __le64 rsrvd_2[3];
+       __le32 sts_ring_count;
+       __le32 rsrvd_3;
+       struct netxen_sts_ring sts_rings[NUM_STS_DESC_RINGS];
+
 } __attribute__ ((aligned(64)));
 
 /*
@@ -373,6 +368,7 @@ struct rcv_desc {
 /* opcode field in status_desc */
 #define NETXEN_NIC_RXPKT_DESC  0x04
 #define NETXEN_OLD_RXPKT_DESC  0x3f
+#define NETXEN_NIC_RESPONSE_DESC 0x05
 
 /* for status field in status_desc */
 #define STATUS_NEED_CKSUM      (1)
@@ -382,13 +378,11 @@ struct rcv_desc {
 #define STATUS_OWNER_HOST      (0x1ULL << 56)
 #define STATUS_OWNER_PHANTOM   (0x2ULL << 56)
 
-/* Note: sizeof(status_desc) should always be a mutliple of 2 */
-
-#define netxen_get_sts_desc_lro_cnt(status_desc)       \
-       ((status_desc)->lro & 0x7F)
-#define netxen_get_sts_desc_lro_last_frag(status_desc) \
-       (((status_desc)->lro & 0x80) >> 7)
-
+/* Status descriptor:
+   0-3 port, 4-7 status, 8-11 type, 12-27 total_length
+   28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
+   53-55 desc_cnt, 56-57 owner, 58-63 opcode
+ */
 #define netxen_get_sts_port(sts_data)  \
        ((sts_data) & 0x0F)
 #define netxen_get_sts_status(sts_data)        \
@@ -403,41 +397,15 @@ struct rcv_desc {
        (((sts_data) >> 44) & 0x0F)
 #define netxen_get_sts_pkt_offset(sts_data)    \
        (((sts_data) >> 48) & 0x1F)
+#define netxen_get_sts_desc_cnt(sts_data)      \
+       (((sts_data) >> 53) & 0x7)
 #define netxen_get_sts_opcode(sts_data)        \
        (((sts_data) >> 58) & 0x03F)
 
 struct status_desc {
-       /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
-          28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
-          53-55 desc_cnt, 56-57 owner, 58-63 opcode
-        */
-       __le64 status_desc_data;
-       union {
-               struct {
-                       __le32 hash_value;
-                       u8 hash_type;
-                       u8 msg_type;
-                       u8 unused;
-                       union {
-                               /* Bit pattern: 0-6 lro_count indicates frag
-                                * sequence, 7 last_frag indicates last frag
-                                */
-                               u8 lro;
-
-                               /* chained buffers */
-                               u8 nr_frags;
-                       };
-               };
-               struct {
-                       __le16 frag_handles[4];
-               };
-       };
+       __le64 status_desc_data[2];
 } __attribute__ ((aligned(16)));
 
-enum {
-       NETXEN_RCV_PEG_0 = 0,
-       NETXEN_RCV_PEG_1
-};
 /* The version of the main data structure */
 #define        NETXEN_BDINFO_VERSION 1
 
@@ -447,85 +415,35 @@ enum {
 /* Max number of Gig ports on a Phantom board */
 #define NETXEN_MAX_PORTS 4
 
-typedef enum {
-       NETXEN_BRDTYPE_P1_BD = 0x0000,
-       NETXEN_BRDTYPE_P1_SB = 0x0001,
-       NETXEN_BRDTYPE_P1_SMAX = 0x0002,
-       NETXEN_BRDTYPE_P1_SOCK = 0x0003,
-
-       NETXEN_BRDTYPE_P2_SOCK_31 = 0x0008,
-       NETXEN_BRDTYPE_P2_SOCK_35 = 0x0009,
-       NETXEN_BRDTYPE_P2_SB35_4G = 0x000a,
-       NETXEN_BRDTYPE_P2_SB31_10G = 0x000b,
-       NETXEN_BRDTYPE_P2_SB31_2G = 0x000c,
-
-       NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d,
-       NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e,
-       NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f,
-
-       NETXEN_BRDTYPE_P3_REF_QG = 0x0021,
-       NETXEN_BRDTYPE_P3_HMEZ = 0x0022,
-       NETXEN_BRDTYPE_P3_10G_CX4_LP = 0x0023,
-       NETXEN_BRDTYPE_P3_4_GB = 0x0024,
-       NETXEN_BRDTYPE_P3_IMEZ = 0x0025,
-       NETXEN_BRDTYPE_P3_10G_SFP_PLUS = 0x0026,
-       NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027,
-       NETXEN_BRDTYPE_P3_XG_LOM = 0x0028,
-       NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029,
-       NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a,
-       NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b,
-       NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031,
-       NETXEN_BRDTYPE_P3_10G_XFP = 0x0032,
-       NETXEN_BRDTYPE_P3_10G_TP = 0x0080
-
-} netxen_brdtype_t;
-
-typedef enum {
-       NETXEN_BRDMFG_INVENTEC = 1
-} netxen_brdmfg;
-
-typedef enum {
-       MEM_ORG_128Mbx4 = 0x0,  /* DDR1 only */
-       MEM_ORG_128Mbx8 = 0x1,  /* DDR1 only */
-       MEM_ORG_128Mbx16 = 0x2, /* DDR1 only */
-       MEM_ORG_256Mbx4 = 0x3,
-       MEM_ORG_256Mbx8 = 0x4,
-       MEM_ORG_256Mbx16 = 0x5,
-       MEM_ORG_512Mbx4 = 0x6,
-       MEM_ORG_512Mbx8 = 0x7,
-       MEM_ORG_512Mbx16 = 0x8,
-       MEM_ORG_1Gbx4 = 0x9,
-       MEM_ORG_1Gbx8 = 0xa,
-       MEM_ORG_1Gbx16 = 0xb,
-       MEM_ORG_2Gbx4 = 0xc,
-       MEM_ORG_2Gbx8 = 0xd,
-       MEM_ORG_2Gbx16 = 0xe,
-       MEM_ORG_128Mbx32 = 0x10002,     /* GDDR only */
-       MEM_ORG_256Mbx32 = 0x10005      /* GDDR only */
-} netxen_mn_mem_org_t;
-
-typedef enum {
-       MEM_ORG_512Kx36 = 0x0,
-       MEM_ORG_1Mx36 = 0x1,
-       MEM_ORG_2Mx36 = 0x2
-} netxen_sn_mem_org_t;
-
-typedef enum {
-       MEM_DEPTH_4MB = 0x1,
-       MEM_DEPTH_8MB = 0x2,
-       MEM_DEPTH_16MB = 0x3,
-       MEM_DEPTH_32MB = 0x4,
-       MEM_DEPTH_64MB = 0x5,
-       MEM_DEPTH_128MB = 0x6,
-       MEM_DEPTH_256MB = 0x7,
-       MEM_DEPTH_512MB = 0x8,
-       MEM_DEPTH_1GB = 0x9,
-       MEM_DEPTH_2GB = 0xa,
-       MEM_DEPTH_4GB = 0xb,
-       MEM_DEPTH_8GB = 0xc,
-       MEM_DEPTH_16GB = 0xd,
-       MEM_DEPTH_32GB = 0xe
-} netxen_mem_depth_t;
+#define NETXEN_BRDTYPE_P1_BD           0x0000
+#define NETXEN_BRDTYPE_P1_SB           0x0001
+#define NETXEN_BRDTYPE_P1_SMAX         0x0002
+#define NETXEN_BRDTYPE_P1_SOCK         0x0003
+
+#define NETXEN_BRDTYPE_P2_SOCK_31      0x0008
+#define NETXEN_BRDTYPE_P2_SOCK_35      0x0009
+#define NETXEN_BRDTYPE_P2_SB35_4G      0x000a
+#define NETXEN_BRDTYPE_P2_SB31_10G     0x000b
+#define NETXEN_BRDTYPE_P2_SB31_2G      0x000c
+
+#define NETXEN_BRDTYPE_P2_SB31_10G_IMEZ                0x000d
+#define NETXEN_BRDTYPE_P2_SB31_10G_HMEZ                0x000e
+#define NETXEN_BRDTYPE_P2_SB31_10G_CX4         0x000f
+
+#define NETXEN_BRDTYPE_P3_REF_QG       0x0021
+#define NETXEN_BRDTYPE_P3_HMEZ         0x0022
+#define NETXEN_BRDTYPE_P3_10G_CX4_LP   0x0023
+#define NETXEN_BRDTYPE_P3_4_GB         0x0024
+#define NETXEN_BRDTYPE_P3_IMEZ         0x0025
+#define NETXEN_BRDTYPE_P3_10G_SFP_PLUS 0x0026
+#define NETXEN_BRDTYPE_P3_10000_BASE_T 0x0027
+#define NETXEN_BRDTYPE_P3_XG_LOM       0x0028
+#define NETXEN_BRDTYPE_P3_4_GB_MM      0x0029
+#define NETXEN_BRDTYPE_P3_10G_SFP_CT   0x002a
+#define NETXEN_BRDTYPE_P3_10G_SFP_QT   0x002b
+#define NETXEN_BRDTYPE_P3_10G_CX4      0x0031
+#define NETXEN_BRDTYPE_P3_10G_XFP      0x0032
+#define NETXEN_BRDTYPE_P3_10G_TP       0x0080
 
 struct netxen_board_info {
        u32 header_version;
@@ -676,17 +594,15 @@ struct netxen_new_user_info {
 #define PRIMARY_IMAGE_BAD      0xffffffff
 
 /* Flash memory map */
-typedef enum {
-       NETXEN_CRBINIT_START = 0,       /* Crbinit section */
-       NETXEN_BRDCFG_START = 0x4000,   /* board config */
-       NETXEN_INITCODE_START = 0x6000, /* pegtune code */
-       NETXEN_BOOTLD_START = 0x10000,  /* bootld */
-       NETXEN_IMAGE_START = 0x43000,   /* compressed image */
-       NETXEN_SECONDARY_START = 0x200000,      /* backup images */
-       NETXEN_PXE_START = 0x3E0000,    /* user defined region */
-       NETXEN_USER_START = 0x3E8000,   /* User defined region for new boards */
-       NETXEN_FIXED_START = 0x3F0000   /* backup of crbinit */
-} netxen_flash_map_t;
+#define NETXEN_CRBINIT_START   0       /* crbinit section */
+#define NETXEN_BRDCFG_START    0x4000  /* board config */
+#define NETXEN_INITCODE_START  0x6000  /* pegtune code */
+#define NETXEN_BOOTLD_START    0x10000 /* bootld */
+#define NETXEN_IMAGE_START     0x43000 /* compressed image */
+#define NETXEN_SECONDARY_START 0x200000        /* backup images */
+#define NETXEN_PXE_START       0x3E0000        /* PXE boot rom */
+#define NETXEN_USER_START      0x3E8000        /* Firmare info */
+#define NETXEN_FIXED_START     0x3F0000        /* backup of crbinit */
 
 #define NX_FW_VERSION_OFFSET   (NETXEN_USER_START+0x408)
 #define NX_FW_SIZE_OFFSET      (NETXEN_USER_START+0x40c)
@@ -708,21 +624,8 @@ typedef enum {
 #define NETXEN_FLASH_SECONDARY_SIZE    (NETXEN_USER_START-NETXEN_SECONDARY_START)
 #define NETXEN_NUM_PRIMARY_SECTORS     (0x20)
 #define NETXEN_NUM_CONFIG_SECTORS      (1)
-#define PFX "NetXen: "
 extern char netxen_nic_driver_name[];
 
-/* Note: Make sure to not call this before adapter->port is valid */
-#if !defined(NETXEN_DEBUG)
-#define DPRINTK(klevel, fmt, args...)  do { \
-       } while (0)
-#else
-#define DPRINTK(klevel, fmt, args...)  do { \
-       printk(KERN_##klevel PFX "%s: %s: " fmt, __func__,\
-               (adapter != NULL && adapter->netdev != NULL) ? \
-               adapter->netdev->name : NULL, \
-               ## args); } while(0)
-#endif
-
 /* Number of status descriptors to handle per interrupt */
 #define MAX_STATUS_HANDLE      (64)
 
@@ -732,7 +635,7 @@ extern char netxen_nic_driver_name[];
  */
 struct netxen_skb_frag {
        u64 dma;
-       ulong length;
+       u64 length;
 };
 
 #define _netxen_set_bits(config_word, start, bits, val)        {\
@@ -793,34 +696,24 @@ struct netxen_hardware_context {
 
        u8 cut_through;
        u8 revision_id;
+       u8 pci_func;
+       u8 linkup;
        u16 port_type;
-       int board_type;
-       u32 linkup;
-       /* Address of cmd ring in Phantom */
-       struct cmd_desc_type0 *cmd_desc_head;
-       dma_addr_t cmd_desc_phys_addr;
-       struct netxen_adapter *adapter;
-       int pci_func;
+       u16 board_type;
 };
 
 #define MINIMUM_ETHERNET_FRAME_SIZE    64      /* With FCS */
 #define ETHERNET_FCS_SIZE              4
 
 struct netxen_adapter_stats {
-       u64  rcvdbadskb;
        u64  xmitcalled;
-       u64  xmitedframes;
        u64  xmitfinished;
-       u64  badskblen;
-       u64  nocmddescriptor;
-       u64  polled;
        u64  rxdropped;
        u64  txdropped;
        u64  csummed;
        u64  no_rcv;
        u64  rxbytes;
        u64  txbytes;
-       u64  ints;
 };
 
 /*
@@ -852,14 +745,25 @@ struct nx_host_sds_ring {
        struct napi_struct napi;
        struct list_head free_list[NUM_RCV_DESC_RINGS];
 
-       u16 clean_tx;
-       u16 post_rxd;
        int irq;
 
        dma_addr_t phys_addr;
        char name[IFNAMSIZ+4];
 };
 
+struct nx_host_tx_ring {
+       u32 producer;
+       __le32 *hw_consumer;
+       u32 sw_consumer;
+       u32 crb_cmd_producer;
+       u32 crb_cmd_consumer;
+       u32 num_desc;
+
+       struct netxen_cmd_buffer *cmd_buf_arr;
+       struct cmd_desc_type0 *desc_head;
+       dma_addr_t phys_addr;
+};
+
 /*
  * Receive context. There is one such structure per instance of the
  * receive processing. Any state information that is relevant to
@@ -872,7 +776,7 @@ struct netxen_recv_context {
        u16 virt_port;
 
        struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS];
-       struct nx_host_sds_ring sds_rings[NUM_STS_DESC_RINGS];
+       struct nx_host_sds_ring *sds_rings;
 };
 
 /* New HW context creation */
@@ -1154,31 +1058,118 @@ typedef struct {
 
 #define NX_MAC_EVENT           0x1
 
-enum {
-       NX_NIC_H2C_OPCODE_START = 0,
-       NX_NIC_H2C_OPCODE_CONFIG_RSS,
-       NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL,
-       NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE,
-       NX_NIC_H2C_OPCODE_CONFIG_LED,
-       NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS,
-       NX_NIC_H2C_OPCODE_CONFIG_L2_MAC,
-       NX_NIC_H2C_OPCODE_LRO_REQUEST,
-       NX_NIC_H2C_OPCODE_GET_SNMP_STATS,
-       NX_NIC_H2C_OPCODE_PROXY_START_REQUEST,
-       NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST,
-       NX_NIC_H2C_OPCODE_PROXY_SET_MTU,
-       NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE,
-       NX_H2P_OPCODE_GET_FINGER_PRINT_REQUEST,
-       NX_H2P_OPCODE_INSTALL_LICENSE_REQUEST,
-       NX_H2P_OPCODE_GET_LICENSE_CAPABILITY_REQUEST,
-       NX_NIC_H2C_OPCODE_GET_NET_STATS,
-       NX_NIC_H2C_OPCODE_LAST
-};
+/*
+ * Driver --> Firmware
+ */
+#define NX_NIC_H2C_OPCODE_START                                0
+#define NX_NIC_H2C_OPCODE_CONFIG_RSS                   1
+#define NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL               2
+#define NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE         3
+#define NX_NIC_H2C_OPCODE_CONFIG_LED                   4
+#define NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS           5
+#define NX_NIC_H2C_OPCODE_CONFIG_L2_MAC                        6
+#define NX_NIC_H2C_OPCODE_LRO_REQUEST                  7
+#define NX_NIC_H2C_OPCODE_GET_SNMP_STATS               8
+#define NX_NIC_H2C_OPCODE_PROXY_START_REQUEST          9
+#define NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST           10
+#define NX_NIC_H2C_OPCODE_PROXY_SET_MTU                        11
+#define NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE    12
+#define NX_NIC_H2C_OPCODE_GET_FINGER_PRINT_REQUEST     13
+#define NX_NIC_H2C_OPCODE_INSTALL_LICENSE_REQUEST      14
+#define NX_NIC_H2C_OPCODE_GET_LICENSE_CAPABILITY_REQUEST       15
+#define NX_NIC_H2C_OPCODE_GET_NET_STATS                        16
+#define NX_NIC_H2C_OPCODE_PROXY_UPDATE_P2V             17
+#define NX_NIC_H2C_OPCODE_CONFIG_IPADDR                        18
+#define NX_NIC_H2C_OPCODE_CONFIG_LOOPBACK              19
+#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE              20
+#define NX_NIC_H2C_OPCODE_GET_LINKEVENT                        21
+#define NX_NIC_C2C_OPCODE                              22
+#define NX_NIC_H2C_OPCODE_LAST                         23
+
+/*
+ * Firmware --> Driver
+ */
+
+#define NX_NIC_C2H_OPCODE_START                                128
+#define NX_NIC_C2H_OPCODE_CONFIG_RSS_RESPONSE          129
+#define NX_NIC_C2H_OPCODE_CONFIG_RSS_TBL_RESPONSE      130
+#define NX_NIC_C2H_OPCODE_CONFIG_MAC_RESPONSE          131
+#define NX_NIC_C2H_OPCODE_CONFIG_PROMISCUOUS_RESPONSE  132
+#define NX_NIC_C2H_OPCODE_CONFIG_L2_MAC_RESPONSE       133
+#define NX_NIC_C2H_OPCODE_LRO_DELETE_RESPONSE          134
+#define NX_NIC_C2H_OPCODE_LRO_ADD_FAILURE_RESPONSE     135
+#define NX_NIC_C2H_OPCODE_GET_SNMP_STATS               136
+#define NX_NIC_C2H_OPCODE_GET_FINGER_PRINT_REPLY       137
+#define NX_NIC_C2H_OPCODE_INSTALL_LICENSE_REPLY                138
+#define NX_NIC_C2H_OPCODE_GET_LICENSE_CAPABILITIES_REPLY 139
+#define NX_NIC_C2H_OPCODE_GET_NET_STATS_RESPONSE       140
+#define NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE       141
+#define NX_NIC_C2H_OPCODE_LAST                         142
 
 #define VPORT_MISS_MODE_DROP           0 /* drop all unmatched */
 #define VPORT_MISS_MODE_ACCEPT_ALL     1 /* accept all packets */
 #define VPORT_MISS_MODE_ACCEPT_MULTI   2 /* accept unmatched multicast */
 
+#define NX_FW_CAPABILITY_LINK_NOTIFICATION     (1 << 5)
+#define NX_FW_CAPABILITY_SWITCHING             (1 << 6)
+
+/* module types */
+#define LINKEVENT_MODULE_NOT_PRESENT                   1
+#define LINKEVENT_MODULE_OPTICAL_UNKNOWN               2
+#define LINKEVENT_MODULE_OPTICAL_SRLR                  3
+#define LINKEVENT_MODULE_OPTICAL_LRM                   4
+#define LINKEVENT_MODULE_OPTICAL_SFP_1G                        5
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE      6
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN   7
+#define LINKEVENT_MODULE_TWINAX                                8
+
+#define LINKSPEED_10GBPS       10000
+#define LINKSPEED_1GBPS                1000
+#define LINKSPEED_100MBPS      100
+#define LINKSPEED_10MBPS       10
+
+#define LINKSPEED_ENCODED_10MBPS       0
+#define LINKSPEED_ENCODED_100MBPS      1
+#define LINKSPEED_ENCODED_1GBPS                2
+
+#define LINKEVENT_AUTONEG_DISABLED     0
+#define LINKEVENT_AUTONEG_ENABLED      1
+
+#define LINKEVENT_HALF_DUPLEX          0
+#define LINKEVENT_FULL_DUPLEX          1
+
+#define LINKEVENT_LINKSPEED_MBPS       0
+#define LINKEVENT_LINKSPEED_ENCODED    1
+
+/* firmware response header:
+ *     63:58 - message type
+ *     57:56 - owner
+ *     55:53 - desc count
+ *     52:48 - reserved
+ *     47:40 - completion id
+ *     39:32 - opcode
+ *     31:16 - error code
+ *     15:00 - reserved
+ */
+#define netxen_get_nic_msgtype(msg_hdr)        \
+       ((msg_hdr >> 58) & 0x3F)
+#define netxen_get_nic_msg_compid(msg_hdr)     \
+       ((msg_hdr >> 40) & 0xFF)
+#define netxen_get_nic_msg_opcode(msg_hdr)     \
+       ((msg_hdr >> 32) & 0xFF)
+#define netxen_get_nic_msg_errcode(msg_hdr)    \
+       ((msg_hdr >> 16) & 0xFFFF)
+
+typedef struct {
+       union {
+               struct {
+                       u64 hdr;
+                       u64 body[7];
+               };
+               u64 words[8];
+       };
+} nx_fw_msg_t;
+
 typedef struct {
        __le64 qhdr;
        __le64 req_hdr;
@@ -1218,78 +1209,60 @@ struct netxen_adapter {
 
        struct net_device *netdev;
        struct pci_dev *pdev;
-       int pci_using_dac;
-       struct net_device_stats net_stats;
-       int mtu;
-       int portnum;
-       u8 physical_port;
-       u16 tx_context_id;
-
-       uint8_t         mc_enabled;
-       uint8_t         max_mc_count;
        nx_mac_list_t   *mac_list;
 
-       struct netxen_legacy_intr_set legacy_intr;
-
-       struct work_struct watchdog_task;
-       struct timer_list watchdog_timer;
-       struct work_struct  tx_timeout_task;
-
        u32 curr_window;
        u32 crb_win;
        rwlock_t adapter_lock;
 
-       u32 cmd_producer;
-       __le32 *cmd_consumer;
-       u32 last_cmd_consumer;
-       u32 crb_addr_cmd_producer;
-       u32 crb_addr_cmd_consumer;
        spinlock_t tx_clean_lock;
 
-       u32 num_txd;
-       u32 num_rxd;
-       u32 num_jumbo_rxd;
-       u32 num_lro_rxd;
+       u16 num_txd;
+       u16 num_rxd;
+       u16 num_jumbo_rxd;
+       u16 num_lro_rxd;
+
+       u8 max_rds_rings;
+       u8 max_sds_rings;
+       u8 driver_mismatch;
+       u8 msix_supported;
+       u8 rx_csum;
+       u8 pci_using_dac;
+       u8 portnum;
+       u8 physical_port;
+
+       u8 mc_enabled;
+       u8 max_mc_count;
+       u8 rss_supported;
+       u8 resv2;
+       u32 resv3;
 
-       int max_rds_rings;
-       int max_sds_rings;
+       u8 has_link_events;
+       u8 resv1;
+       u16 tx_context_id;
+       u16 mtu;
+       u16 is_up;
+
+       u16 link_speed;
+       u16 link_duplex;
+       u16 link_autoneg;
+       u16 module_type;
 
+       u32 capabilities;
        u32 flags;
        u32 irq;
-       int driver_mismatch;
        u32 temp;
-
        u32 fw_major;
        u32 fw_version;
 
-       int msix_supported;
-       struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
-
        struct netxen_adapter_stats stats;
 
-       u16 link_speed;
-       u16 link_duplex;
-       u16 state;
-       u16 link_autoneg;
-       int rx_csum;
-
-       struct netxen_cmd_buffer *cmd_buf_arr;  /* Command buffers for xmit */
-
-       /*
-        * Receive instances. These can be either one per port,
-        * or one per peg, etc.
-        */
        struct netxen_recv_context recv_ctx;
-
-       int is_up;
-       struct netxen_dummy_dma dummy_dma;
-       nx_nic_intr_coalesce_t coal;
+       struct nx_host_tx_ring tx_ring;
 
        /* Context interface shared between card and host */
        struct netxen_ring_ctx *ctx_desc;
        dma_addr_t ctx_desc_phys_addr;
-       int intr_scheme;
-       int msi_mode;
        int (*enable_phy_interrupts) (struct netxen_adapter *);
        int (*disable_phy_interrupts) (struct netxen_adapter *);
        int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t);
@@ -1300,17 +1273,29 @@ struct netxen_adapter {
        int (*init_port) (struct netxen_adapter *, int);
        int (*stop_port) (struct netxen_adapter *);
 
-       int (*hw_read_wx)(struct netxen_adapter *, ulong, void *, int);
-       int (*hw_write_wx)(struct netxen_adapter *, ulong, void *, int);
+       u32 (*hw_read_wx)(struct netxen_adapter *, ulong);
+       int (*hw_write_wx)(struct netxen_adapter *, ulong, u32);
        int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int);
        int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int);
        int (*pci_write_immediate)(struct netxen_adapter *, u64, u32);
        u32 (*pci_read_immediate)(struct netxen_adapter *, u64);
-       void (*pci_write_normalize)(struct netxen_adapter *, u64, u32);
-       u32 (*pci_read_normalize)(struct netxen_adapter *, u64);
        unsigned long (*pci_set_window)(struct netxen_adapter *,
                        unsigned long long);
-};                             /* netxen_adapter structure */
+
+       struct netxen_legacy_intr_set legacy_intr;
+
+       struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+
+       struct netxen_dummy_dma dummy_dma;
+
+       struct work_struct watchdog_task;
+       struct timer_list watchdog_timer;
+       struct work_struct  tx_timeout_task;
+
+       struct net_device_stats net_stats;
+
+       nx_nic_intr_coalesce_t coal;
+};
 
 /*
  * NetXen dma watchdog control structure
@@ -1330,46 +1315,6 @@ struct netxen_adapter {
 #define netxen_get_dma_watchdog_disabled(config_word) \
        (((config_word) >> 1) & 0x1)
 
-/* Max number of xmit producer threads that can run simultaneously */
-#define        MAX_XMIT_PRODUCERS              16
-
-#define PCI_OFFSET_FIRST_RANGE(adapter, off)    \
-       ((adapter)->ahw.pci_base0 + (off))
-#define PCI_OFFSET_SECOND_RANGE(adapter, off)   \
-       ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
-#define PCI_OFFSET_THIRD_RANGE(adapter, off)    \
-       ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
-
-static inline void __iomem *pci_base_offset(struct netxen_adapter *adapter,
-                                           unsigned long off)
-{
-       if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) {
-               return (adapter->ahw.pci_base0 + off);
-       } else if ((off < SECOND_PAGE_GROUP_END) &&
-                  (off >= SECOND_PAGE_GROUP_START)) {
-               return (adapter->ahw.pci_base1 + off - SECOND_PAGE_GROUP_START);
-       } else if ((off < THIRD_PAGE_GROUP_END) &&
-                  (off >= THIRD_PAGE_GROUP_START)) {
-               return (adapter->ahw.pci_base2 + off - THIRD_PAGE_GROUP_START);
-       }
-       return NULL;
-}
-
-static inline void __iomem *pci_base(struct netxen_adapter *adapter,
-                                    unsigned long off)
-{
-       if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) {
-               return adapter->ahw.pci_base0;
-       } else if ((off < SECOND_PAGE_GROUP_END) &&
-                  (off >= SECOND_PAGE_GROUP_START)) {
-               return adapter->ahw.pci_base1;
-       } else if ((off < THIRD_PAGE_GROUP_END) &&
-                  (off >= THIRD_PAGE_GROUP_START)) {
-               return adapter->ahw.pci_base2;
-       }
-       return NULL;
-}
-
 int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter);
 int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter);
 int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter);
@@ -1382,21 +1327,19 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
 /* Functions available from netxen_nic_hw.c */
 int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
 int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu);
-void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val);
-int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value);
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value);
-void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value);
-void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value);
+
+#define NXRD32(adapter, off) \
+       (adapter->hw_read_wx(adapter, off))
+#define NXWR32(adapter, off, val) \
+       (adapter->hw_write_wx(adapter, off, val))
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter);
 void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
 int netxen_nic_wol_supported(struct netxen_adapter *adapter);
 
-int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len);
+u32 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off);
 int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len);
+               ulong off, u32 data);
 int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
                u64 off, void *data, int size);
 int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
@@ -1412,16 +1355,13 @@ unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
 void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter,
                u32 wndw);
 
-int netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len);
+u32 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off);
 int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len);
+               ulong off, u32 data);
 int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
                u64 off, void *data, int size);
 int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
                u64 off, void *data, int size);
-void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
-                                unsigned long off, int data);
 int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
                u64 off, u32 data);
 u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off);
@@ -1435,7 +1375,6 @@ unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 void netxen_free_adapter_offload(struct netxen_adapter *adapter);
 int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
 int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
-int netxen_receive_peg_ready(struct netxen_adapter *adapter);
 int netxen_load_firmware(struct netxen_adapter *adapter);
 int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
 
@@ -1475,6 +1414,8 @@ void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
 int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
 int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
 int netxen_config_rss(struct netxen_adapter *adapter, int enable);
+int netxen_linkevent_request(struct netxen_adapter *adapter, int enable);
+void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
 
 int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
 int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
@@ -1483,7 +1424,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p);
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
 
 void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
-               uint32_t crb_producer);
+               struct nx_host_tx_ring *tx_ring, uint32_t crb_producer);
 
 /*
  * NetXen Board information
@@ -1491,7 +1432,7 @@ void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
 
 #define NETXEN_MAX_SHORT_NAME 32
 struct netxen_brdinfo {
-       netxen_brdtype_t brdtype;       /* type of board */
+       int brdtype;    /* type of board */
        long ports;             /* max no of physical ports */
        char short_name[NETXEN_MAX_SHORT_NAME];
 };
@@ -1541,17 +1482,15 @@ dma_watchdog_shutdown_request(struct netxen_adapter *adapter)
        u32 ctrl;
 
        /* check if already inactive */
-       if (adapter->hw_read_wx(adapter,
-           NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
-               printk(KERN_ERR "failed to read dma watchdog status\n");
+       ctrl = adapter->hw_read_wx(adapter,
+                       NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
 
        if (netxen_get_dma_watchdog_enabled(ctrl) == 0)
                return 1;
 
        /* Send the disable request */
        netxen_set_dma_watchdog_disable_req(ctrl);
-       netxen_crb_writelit_adapter(adapter,
-               NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
+       NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
 
        return 0;
 }
@@ -1561,9 +1500,8 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
 {
        u32 ctrl;
 
-       if (adapter->hw_read_wx(adapter,
-           NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
-               printk(KERN_ERR "failed to read dma watchdog status\n");
+       ctrl = adapter->hw_read_wx(adapter,
+                       NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
 
        return (netxen_get_dma_watchdog_enabled(ctrl) == 0);
 }
@@ -1573,9 +1511,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
 {
        u32 ctrl;
 
-       if (adapter->hw_read_wx(adapter,
-               NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
-               printk(KERN_ERR "failed to read dma watchdog status\n");
+       ctrl = adapter->hw_read_wx(adapter,
+                       NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
 
        if (netxen_get_dma_watchdog_enabled(ctrl))
                return 1;
@@ -1583,8 +1520,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
        /* send the wakeup request */
        netxen_set_dma_watchdog_enable_req(ctrl);
 
-       netxen_crb_writelit_adapter(adapter,
-               NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
+       NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
 
        return 0;
 }
index 9234473..fd82adf 100644 (file)
@@ -41,8 +41,7 @@ netxen_api_lock(struct netxen_adapter *adapter)
 
        for (;;) {
                /* Acquire PCIE HW semaphore5 */
-               netxen_nic_read_w0(adapter,
-                       NETXEN_PCIE_REG(PCIE_SEM5_LOCK), &done);
+               done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK));
 
                if (done == 1)
                        break;
@@ -56,7 +55,7 @@ netxen_api_lock(struct netxen_adapter *adapter)
        }
 
 #if 0
-       netxen_nic_write_w1(adapter,
+       NXWR32(adapter,
                NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
 #endif
        return 0;
@@ -65,11 +64,8 @@ netxen_api_lock(struct netxen_adapter *adapter)
 static int
 netxen_api_unlock(struct netxen_adapter *adapter)
 {
-       u32 val;
-
        /* Release PCIE HW semaphore5 */
-       netxen_nic_read_w0(adapter,
-               NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK), &val);
+       NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK));
        return 0;
 }
 
@@ -86,7 +82,7 @@ netxen_poll_rsp(struct netxen_adapter *adapter)
                if (++timeout > NX_OS_CRB_RETRY_COUNT)
                        return NX_CDRP_RSP_TIMEOUT;
 
-               netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, &rsp);
+               rsp = NXRD32(adapter, NX_CDRP_CRB_OFFSET);
        } while (!NX_CDRP_IS_RSP(rsp));
 
        return rsp;
@@ -106,16 +102,15 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
        if (netxen_api_lock(adapter))
                return NX_RCODE_TIMEOUT;
 
-       netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, signature);
+       NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature);
 
-       netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1);
+       NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1);
 
-       netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2);
+       NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2);
 
-       netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3);
+       NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3);
 
-       netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET,
-                       NX_CDRP_FORM_CMD(cmd));
+       NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd));
 
        rsp = netxen_poll_rsp(adapter);
 
@@ -125,7 +120,7 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
 
                rcode = NX_RCODE_TIMEOUT;
        } else if (rsp == NX_CDRP_RSP_FAIL) {
-               netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode);
+               rcode = NXRD32(adapter, NX_ARG1_CRB_OFFSET);
 
                printk(KERN_ERR "%s: failed card response code:0x%x\n",
                                netxen_nic_driver_name, rcode);
@@ -328,6 +323,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
        int     err = 0;
        u64     offset, phys_addr;
        dma_addr_t      rq_phys_addr, rsp_phys_addr;
+       struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
 
        rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
        rq_addr = pci_alloc_consistent(adapter->pdev,
@@ -367,10 +363,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
 
        prq_cds = &prq->cds_ring;
 
-       prq_cds->host_phys_addr =
-               cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
-
-       prq_cds->ring_size = cpu_to_le32(adapter->num_txd);
+       prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
+       prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
 
        phys_addr = rq_phys_addr;
        err = netxen_issue_cmd(adapter,
@@ -383,8 +377,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
 
        if (err == NX_RCODE_SUCCESS) {
                temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
-               adapter->crb_addr_cmd_producer =
-                       NETXEN_NIC_REG(temp - 0x200);
+               tx_ring->crb_cmd_producer = NETXEN_NIC_REG(temp - 0x200);
 #if 0
                adapter->tx_state =
                        le32_to_cpu(prsp->host_ctx_state);
@@ -448,7 +441,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
                        NETXEN_NIC_REG(0x120)
                },
                /* crb_sts_consumer: */
-               NETXEN_NIC_REG(0x138),
+               {
+                       NETXEN_NIC_REG(0x138),
+                       NETXEN_NIC_REG_2(0x000),
+                       NETXEN_NIC_REG_2(0x004),
+                       NETXEN_NIC_REG_2(0x008),
+               },
+               /* sw_int_mask */
+               {
+                       CRB_SW_INT_MASK_0,
+                       NETXEN_NIC_REG_2(0x044),
+                       NETXEN_NIC_REG_2(0x048),
+                       NETXEN_NIC_REG_2(0x04c),
+               },
        },
        /* Instance 1 */
        {
@@ -461,7 +466,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
                        NETXEN_NIC_REG(0x164)
                },
                /* crb_sts_consumer: */
-               NETXEN_NIC_REG(0x17c),
+               {
+                       NETXEN_NIC_REG(0x17c),
+                       NETXEN_NIC_REG_2(0x020),
+                       NETXEN_NIC_REG_2(0x024),
+                       NETXEN_NIC_REG_2(0x028),
+               },
+               /* sw_int_mask */
+               {
+                       CRB_SW_INT_MASK_1,
+                       NETXEN_NIC_REG_2(0x064),
+                       NETXEN_NIC_REG_2(0x068),
+                       NETXEN_NIC_REG_2(0x06c),
+               },
        },
        /* Instance 2 */
        {
@@ -474,7 +491,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
                        NETXEN_NIC_REG(0x208)
                },
                /* crb_sts_consumer: */
-               NETXEN_NIC_REG(0x220),
+               {
+                       NETXEN_NIC_REG(0x220),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+               },
+               /* sw_int_mask */
+               {
+                       CRB_SW_INT_MASK_2,
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+               },
        },
        /* Instance 3 */
        {
@@ -487,7 +516,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
                        NETXEN_NIC_REG(0x24c)
                },
                /* crb_sts_consumer: */
-               NETXEN_NIC_REG(0x264),
+               {
+                       NETXEN_NIC_REG(0x264),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+               },
+               /* sw_int_mask */
+               {
+                       CRB_SW_INT_MASK_3,
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+               },
        },
 };
 
@@ -497,62 +538,65 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
        struct nx_host_sds_ring *sds_ring;
+       struct nx_host_tx_ring *tx_ring;
        int ring;
-       int func_id = adapter->portnum;
+       int port = adapter->portnum;
+       struct netxen_ring_ctx *hwctx = adapter->ctx_desc;
+       u32 signature;
 
-       adapter->ctx_desc->cmd_ring_addr =
-               cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
-       adapter->ctx_desc->cmd_ring_size =
-               cpu_to_le32(adapter->num_txd);
+       tx_ring = &adapter->tx_ring;
+       hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr);
+       hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc);
 
        recv_ctx = &adapter->recv_ctx;
 
        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
                rds_ring = &recv_ctx->rds_rings[ring];
 
-               adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
+               hwctx->rcv_rings[ring].addr =
                        cpu_to_le64(rds_ring->phys_addr);
-               adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+               hwctx->rcv_rings[ring].size =
                        cpu_to_le32(rds_ring->num_desc);
        }
-       sds_ring = &recv_ctx->sds_rings[0];
-       adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
-       adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
 
-       adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
+       for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+               sds_ring = &recv_ctx->sds_rings[ring];
+
+               if (ring == 0) {
+                       hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
+                       hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
+               }
+               hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr);
+               hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc);
+               hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring);
+       }
+       hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings);
+
+       signature = (adapter->max_sds_rings > 1) ?
+               NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE;
+
+       NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port),
                        lower32(adapter->ctx_desc_phys_addr));
-       adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_HI(func_id),
+       NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port),
                        upper32(adapter->ctx_desc_phys_addr));
-       adapter->pci_write_normalize(adapter, CRB_CTX_SIGNATURE_REG(func_id),
-                       NETXEN_CTX_SIGNATURE | func_id);
+       NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
+                       signature | port);
        return 0;
 }
 
-static uint32_t sw_int_mask[4] = {
-       CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
-       CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
-};
-
 int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 {
-       struct netxen_hardware_context *hw = &adapter->ahw;
-       u32 state = 0;
        void *addr;
        int err = 0;
        int ring;
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
        struct nx_host_sds_ring *sds_ring;
+       struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
 
        struct pci_dev *pdev = adapter->pdev;
        struct net_device *netdev = adapter->netdev;
-
-       err = netxen_receive_peg_ready(adapter);
-       if (err) {
-               printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n",
-                               state);
-               return err;
-       }
+       int port = adapter->portnum;
 
        addr = pci_alloc_consistent(pdev,
                        sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
@@ -564,17 +608,16 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
        }
        memset(addr, 0, sizeof(struct netxen_ring_ctx));
        adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
-       adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum);
+       adapter->ctx_desc->ctx_id = cpu_to_le32(port);
        adapter->ctx_desc->cmd_consumer_offset =
                cpu_to_le64(adapter->ctx_desc_phys_addr +
                        sizeof(struct netxen_ring_ctx));
-       adapter->cmd_consumer =
+       tx_ring->hw_consumer =
                (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
 
        /* cmd desc ring */
-       addr = pci_alloc_consistent(pdev,
-                       TX_DESC_RINGSIZE(adapter),
-                       &hw->cmd_desc_phys_addr);
+       addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
+                       &tx_ring->phys_addr);
 
        if (addr == NULL) {
                dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
@@ -582,7 +625,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
                return -ENOMEM;
        }
 
-       hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
+       tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
 
        recv_ctx = &adapter->recv_ctx;
 
@@ -602,8 +645,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 
                if (adapter->fw_major < 4)
                        rds_ring->crb_rcv_producer =
-                               recv_crb_registers[adapter->portnum].
-                               crb_rcv_producer[ring];
+                               recv_crb_registers[port].crb_rcv_producer[ring];
        }
 
        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -620,13 +662,16 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
                        goto err_out_free;
                }
                sds_ring->desc_head = (struct status_desc *)addr;
+
+               sds_ring->crb_sts_consumer =
+                       recv_crb_registers[port].crb_sts_consumer[ring];
+
+               sds_ring->crb_intr_mask =
+                       recv_crb_registers[port].sw_int_mask[ring];
        }
 
 
        if (adapter->fw_major >= 4) {
-               adapter->intr_scheme = INTR_SCHEME_PERPORT;
-               adapter->msi_mode = MSI_MODE_MULTIFUNC;
-
                err = nx_fw_cmd_create_rx_ctx(adapter);
                if (err)
                        goto err_out_free;
@@ -634,23 +679,11 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
                if (err)
                        goto err_out_free;
        } else {
-               sds_ring = &recv_ctx->sds_rings[0];
-               sds_ring->crb_sts_consumer =
-                       recv_crb_registers[adapter->portnum].crb_sts_consumer;
-
-               adapter->intr_scheme = adapter->pci_read_normalize(adapter,
-                               CRB_NIC_CAPABILITIES_FW);
-               adapter->msi_mode = adapter->pci_read_normalize(adapter,
-                               CRB_NIC_MSI_MODE_FW);
-               recv_ctx->sds_rings[0].crb_intr_mask =
-                               sw_int_mask[adapter->portnum];
-
                err = netxen_init_old_ctx(adapter);
                if (err) {
                        netxen_free_hw_resources(adapter);
                        return err;
                }
-
        }
 
        return 0;
@@ -665,11 +698,19 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
        struct nx_host_sds_ring *sds_ring;
+       struct nx_host_tx_ring *tx_ring;
        int ring;
 
+       int port = adapter->portnum;
+
        if (adapter->fw_major >= 4) {
                nx_fw_cmd_destroy_tx_ctx(adapter);
                nx_fw_cmd_destroy_rx_ctx(adapter);
+       } else {
+               netxen_api_lock(adapter);
+               NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
+                               NETXEN_CTX_RESET | port);
+               netxen_api_unlock(adapter);
        }
 
        if (adapter->ctx_desc != NULL) {
@@ -681,13 +722,12 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
                adapter->ctx_desc = NULL;
        }
 
-       if (adapter->ahw.cmd_desc_head != NULL) {
+       tx_ring = &adapter->tx_ring;
+       if (tx_ring->desc_head != NULL) {
                pci_free_consistent(adapter->pdev,
-                               sizeof(struct cmd_desc_type0) *
-                               adapter->num_txd,
-                               adapter->ahw.cmd_desc_head,
-                               adapter->ahw.cmd_desc_phys_addr);
-               adapter->ahw.cmd_desc_head = NULL;
+                               TX_DESC_RINGSIZE(tx_ring),
+                               tx_ring->desc_head, tx_ring->phys_addr);
+               tx_ring->desc_head = NULL;
        }
 
        recv_ctx = &adapter->recv_ctx;
index a677ff8..a452b2f 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <linux/types.h>
 #include <linux/delay.h>
-#include <asm/uaccess.h>
 #include <linux/pci.h>
 #include <asm/io.h>
 #include <linux/netdevice.h>
@@ -53,13 +52,9 @@ struct netxen_nic_stats {
 #define NETXEN_NIC_INVALID_DATA 0xDEADBEEF
 
 static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
-       {"rcvd_bad_skb", NETXEN_NIC_STAT(stats.rcvdbadskb)},
        {"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)},
-       {"xmited_frames", NETXEN_NIC_STAT(stats.xmitedframes)},
        {"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)},
-       {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)},
-       {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)},
-       {"polled", NETXEN_NIC_STAT(stats.polled)},
+       {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
        {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
        {"csummed", NETXEN_NIC_STAT(stats.csummed)},
        {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)},
@@ -97,12 +92,9 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
        strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
        strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
        write_lock_irqsave(&adapter->adapter_lock, flags);
-       fw_major = adapter->pci_read_normalize(adapter,
-                                       NETXEN_FW_VERSION_MAJOR);
-       fw_minor = adapter->pci_read_normalize(adapter,
-                                       NETXEN_FW_VERSION_MINOR);
-       fw_build = adapter->pci_read_normalize(adapter,
-                                       NETXEN_FW_VERSION_SUB);
+       fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+       fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+       fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
        write_unlock_irqrestore(&adapter->adapter_lock, flags);
        sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
 
@@ -115,6 +107,7 @@ static int
 netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
        struct netxen_adapter *adapter = netdev_priv(dev);
+       int check_sfp_module = 0;
 
        /* read which mode */
        if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
@@ -139,7 +132,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
                u32 val;
 
-               adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4);
+               val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
                if (val == NETXEN_PORT_MODE_802_3_AP) {
                        ecmd->supported = SUPPORTED_1000baseT_Full;
                        ecmd->advertising = ADVERTISED_1000baseT_Full;
@@ -148,13 +141,19 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                        ecmd->advertising = ADVERTISED_10000baseT_Full;
                }
 
+               if (netif_running(dev) && adapter->has_link_events) {
+                       ecmd->speed = adapter->link_speed;
+                       ecmd->autoneg = adapter->link_autoneg;
+                       ecmd->duplex = adapter->link_duplex;
+                       goto skip;
+               }
+
                ecmd->port = PORT_TP;
 
                if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
                        u16 pcifn = adapter->ahw.pci_func;
 
-                       adapter->hw_read_wx(adapter,
-                               P3_LINK_SPEED_REG(pcifn), &val, 4);
+                       val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
                        ecmd->speed = P3_LINK_SPEED_MHZ *
                                        P3_LINK_SPEED_VAL(pcifn, val);
                } else
@@ -165,10 +164,11 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        } else
                return -EIO;
 
+skip:
        ecmd->phy_address = adapter->physical_port;
        ecmd->transceiver = XCVR_EXTERNAL;
 
-       switch ((netxen_brdtype_t)adapter->ahw.board_type) {
+       switch (adapter->ahw.board_type) {
        case NETXEN_BRDTYPE_P2_SB35_4G:
        case NETXEN_BRDTYPE_P2_SB31_2G:
        case NETXEN_BRDTYPE_P3_REF_QG:
@@ -195,7 +195,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        case NETXEN_BRDTYPE_P3_HMEZ:
                ecmd->supported |= SUPPORTED_MII;
                ecmd->advertising |= ADVERTISED_MII;
-               ecmd->port = PORT_FIBRE;
+               ecmd->port = PORT_MII;
                ecmd->autoneg = AUTONEG_DISABLE;
                break;
        case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
@@ -203,6 +203,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        case NETXEN_BRDTYPE_P3_10G_SFP_QT:
                ecmd->advertising |= ADVERTISED_TP;
                ecmd->supported |= SUPPORTED_TP;
+               check_sfp_module = netif_running(dev) &&
+                       adapter->has_link_events;
        case NETXEN_BRDTYPE_P2_SB31_10G:
        case NETXEN_BRDTYPE_P3_10G_XFP:
                ecmd->supported |= SUPPORTED_FIBRE;
@@ -217,6 +219,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                        ecmd->advertising |=
                                (ADVERTISED_FIBRE | ADVERTISED_TP);
                        ecmd->port = PORT_FIBRE;
+                       check_sfp_module = netif_running(dev) &&
+                               adapter->has_link_events;
                } else {
                        ecmd->autoneg = AUTONEG_ENABLE;
                        ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg);
@@ -227,10 +231,27 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                break;
        default:
                printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
-                      (netxen_brdtype_t)adapter->ahw.board_type);
+                               adapter->ahw.board_type);
                return -EIO;
        }
 
+       if (check_sfp_module) {
+               switch (adapter->module_type) {
+               case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
+               case LINKEVENT_MODULE_OPTICAL_SRLR:
+               case LINKEVENT_MODULE_OPTICAL_LRM:
+               case LINKEVENT_MODULE_OPTICAL_SFP_1G:
+                       ecmd->port = PORT_FIBRE;
+                       break;
+               case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
+               case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
+               case LINKEVENT_MODULE_TWINAX:
+                       ecmd->port = PORT_TP;
+               default:
+                       ecmd->port = -1;
+               }
+       }
+
        return 0;
 }
 
@@ -398,12 +419,11 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
        regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
            (adapter->pdev)->device;
        /* which mode */
-       adapter->hw_read_wx(adapter, NETXEN_NIU_MODE, &regs_buff[0], 4);
+       regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE);
        mode = regs_buff[0];
 
        /* Common registers to all the modes */
-       adapter->hw_read_wx(adapter,
-                       NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, &regs_buff[2], 4);
+       regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER);
        /* GB/XGB Mode */
        mode = (mode / 2) - 1;
        window = 0;
@@ -414,9 +434,8 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
                                window = adapter->physical_port *
                                        NETXEN_NIC_PORT_WINDOW;
 
-                       adapter->hw_read_wx(adapter,
-                               niu_registers[mode].reg[i - 3] + window,
-                               &regs_buff[i], 4);
+                       regs_buff[i] = NXRD32(adapter,
+                               niu_registers[mode].reg[i - 3] + window);
                }
 
        }
@@ -440,7 +459,7 @@ static u32 netxen_nic_test_link(struct net_device *dev)
                        return !val;
                }
        } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
-               val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
+               val = NXRD32(adapter, CRB_XG_STATE);
                return (val == XG_LINK_UP) ? 0 : 1;
        }
        return -EIO;
@@ -504,10 +523,9 @@ netxen_nic_get_pauseparam(struct net_device *dev,
                if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
                        return;
                /* get flow control settings */
-               netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port),
-                               &val);
+               val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
                pause->rx_pause = netxen_gb_get_rx_flowctl(val);
-               netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+               val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
                switch (port) {
                        case 0:
                                pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
@@ -527,7 +545,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
                if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
                        return;
                pause->rx_pause = 1;
-               netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+               val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
                if (port == 0)
                        pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
                else
@@ -550,18 +568,17 @@ netxen_nic_set_pauseparam(struct net_device *dev,
                if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
                        return -EIO;
                /* set flow control */
-               netxen_nic_read_w0(adapter,
-                                       NETXEN_NIU_GB_MAC_CONFIG_0(port), &val);
+               val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
 
                if (pause->rx_pause)
                        netxen_gb_rx_flowctl(val);
                else
                        netxen_gb_unset_rx_flowctl(val);
 
-               netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+               NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
                                val);
                /* set autoneg */
-               netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+               val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
                switch (port) {
                        case 0:
                                if (pause->tx_pause)
@@ -589,11 +606,11 @@ netxen_nic_set_pauseparam(struct net_device *dev,
                                        netxen_gb_set_gb3_mask(val);
                                break;
                }
-               netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
+               NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
        } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
                if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
                        return -EIO;
-               netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+               val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
                if (port == 0) {
                        if (pause->tx_pause)
                                netxen_xg_unset_xg0_mask(val);
@@ -605,7 +622,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
                        else
                                netxen_xg_set_xg1_mask(val);
                }
-               netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
+               NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
        } else {
                printk(KERN_ERR "%s: Unknown board type: %x\n",
                                netxen_nic_driver_name,
@@ -619,14 +636,14 @@ static int netxen_nic_reg_test(struct net_device *dev)
        struct netxen_adapter *adapter = netdev_priv(dev);
        u32 data_read, data_written;
 
-       netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0), &data_read);
+       data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
        if ((data_read & 0xffff) != PHAN_VENDOR_ID)
        return 1;
 
        data_written = (u32)0xa5a5a5a5;
 
-       netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written);
-       data_read = adapter->pci_read_normalize(adapter, CRB_SCRATCHPAD_TEST);
+       NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
+       data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST);
        if (data_written != data_read)
                return 1;
 
@@ -743,11 +760,11 @@ netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
                return;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
        if (wol_cfg & (1UL << adapter->portnum))
                wol->supported |= WAKE_MAGIC;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
        if (wol_cfg & (1UL << adapter->portnum))
                wol->wolopts |= WAKE_MAGIC;
 }
@@ -764,16 +781,16 @@ netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        if (wol->wolopts & ~WAKE_MAGIC)
                return -EOPNOTSUPP;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
        if (!(wol_cfg & (1 << adapter->portnum)))
                return -EOPNOTSUPP;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
        if (wol->wolopts & WAKE_MAGIC)
                wol_cfg |= 1UL << adapter->portnum;
        else
                wol_cfg &= ~(1UL << adapter->portnum);
-       netxen_nic_reg_write(adapter, NETXEN_WOL_CONFIG, wol_cfg);
+       NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg);
 
        return 0;
 }
index 016c621..7f0ddbf 100644 (file)
 #ifndef __NETXEN_NIC_HDR_H_
 #define __NETXEN_NIC_HDR_H_
 
-#include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <asm/irq.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
 #include <linux/types.h>
-#include <asm/uaccess.h>
-#include <asm/string.h>                /* for memset */
 
 /*
  * The basic unit of access when reading/writing control registers.
index 5026811..3bb2b8c 100644 (file)
 #define CRB_HI(off)    ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
 #define CRB_INDIRECT_2M        (0x1e0000UL)
 
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+       return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 val, void __iomem *addr)
+{
+       writel(((u32) (val)), (addr));
+       writel(((u32) (val >> 32)), (addr + 4));
+}
+#endif
+
+#define ADDR_IN_RANGE(addr, low, high) \
+       (((addr) < (high)) && ((addr) >= (low)))
+
+#define PCI_OFFSET_FIRST_RANGE(adapter, off)    \
+       ((adapter)->ahw.pci_base0 + (off))
+#define PCI_OFFSET_SECOND_RANGE(adapter, off)   \
+       ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
+#define PCI_OFFSET_THIRD_RANGE(adapter, off)    \
+       ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
+
+static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
+                                           unsigned long off)
+{
+       if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END))
+               return PCI_OFFSET_FIRST_RANGE(adapter, off);
+
+       if (ADDR_IN_RANGE(off, SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_END))
+               return PCI_OFFSET_SECOND_RANGE(adapter, off);
+
+       if (ADDR_IN_RANGE(off, THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_END))
+               return PCI_OFFSET_THIRD_RANGE(adapter, off);
+
+       return NULL;
+}
+
 #define CRB_WIN_LOCK_TIMEOUT 100000000
-static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
+static crb_128M_2M_block_map_t
+crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
     {{{0, 0,         0,         0} } },                /* 0: PCI */
     {{{1, 0x0100000, 0x0102000, 0x120000},     /* 1: PCIE */
          {1, 0x0110000, 0x0120000, 0x130000},
@@ -279,18 +320,8 @@ static unsigned crb_hub_agt[64] =
 
 /*  PCI Windowing for DDR regions.  */
 
-#define ADDR_IN_RANGE(addr, low, high) \
-       (((addr) <= (high)) && ((addr) >= (low)))
-
 #define NETXEN_WINDOW_ONE      0x2000000 /*CRB Window: bit 25 of CRB address */
 
-#define NETXEN_NIC_ZERO_PAUSE_ADDR     0ULL
-#define NETXEN_NIC_UNIT_PAUSE_ADDR     0x200ULL
-#define NETXEN_NIC_EPG_PAUSE_ADDR1     0x2200010000c28001ULL
-#define NETXEN_NIC_EPG_PAUSE_ADDR2     0x0100088866554433ULL
-
-#define NETXEN_NIC_WINDOW_MARGIN 0x100000
-
 int netxen_nic_set_mac(struct net_device *netdev, void *p)
 {
        struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -331,22 +362,20 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
        if (adapter->mc_enabled)
                return 0;
 
-       adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
        val |= (1UL << (28+port));
-       adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
 
        /* add broadcast addr to filter */
        val = 0xffffff;
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_UNICAST_ADDR(port, 0)+4, val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
 
        /* add station addr to filter */
        val = MAC_HI(addr);
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
        val = MAC_LO(addr);
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_UNICAST_ADDR(port, 1)+4, val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, val);
 
        adapter->mc_enabled = 1;
        return 0;
@@ -362,18 +391,17 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
        if (!adapter->mc_enabled)
                return 0;
 
-       adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
        val &= ~(1UL << (28+port));
-       adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
 
        val = MAC_HI(addr);
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
        val = MAC_LO(addr);
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_UNICAST_ADDR(port, 0)+4, val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
 
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
 
        adapter->mc_enabled = 0;
        return 0;
@@ -389,10 +417,8 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
        lo = MAC_LO(addr);
        hi = MAC_HI(addr);
 
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_MCAST_ADDR(port, index), hi);
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_MCAST_ADDR(port, index)+4, lo);
+       NXWR32(adapter, NETXEN_MCAST_ADDR(port, index), hi);
+       NXWR32(adapter, NETXEN_MCAST_ADDR(port, index)+4, lo);
 
        return 0;
 }
@@ -486,45 +512,44 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
 
 static int
 netxen_send_cmd_descs(struct netxen_adapter *adapter,
-               struct cmd_desc_type0 *cmd_desc_arr, int nr_elements)
+               struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
 {
-       uint32_t i, producer;
+       u32 i, producer, consumer;
        struct netxen_cmd_buffer *pbuf;
        struct cmd_desc_type0 *cmd_desc;
-
-       if (nr_elements > MAX_PENDING_DESC_BLOCK_SIZE || nr_elements == 0) {
-               printk(KERN_WARNING "%s: Too many command descriptors in a "
-                             "request\n", __func__);
-               return -EINVAL;
-       }
+       struct nx_host_tx_ring *tx_ring;
 
        i = 0;
 
+       tx_ring = &adapter->tx_ring;
        netif_tx_lock_bh(adapter->netdev);
 
-       producer = adapter->cmd_producer;
+       producer = tx_ring->producer;
+       consumer = tx_ring->sw_consumer;
+
+       if (nr_desc > find_diff_among(producer, consumer, tx_ring->num_desc)) {
+               netif_tx_unlock_bh(adapter->netdev);
+               return -EBUSY;
+       }
+
        do {
                cmd_desc = &cmd_desc_arr[i];
 
-               pbuf = &adapter->cmd_buf_arr[producer];
+               pbuf = &tx_ring->cmd_buf_arr[producer];
                pbuf->skb = NULL;
                pbuf->frag_count = 0;
 
-               /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */
-               memcpy(&adapter->ahw.cmd_desc_head[producer],
+               memcpy(&tx_ring->desc_head[producer],
                        &cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
 
-               producer = get_next_index(producer,
-                               adapter->num_txd);
+               producer = get_next_index(producer, tx_ring->num_desc);
                i++;
 
-       } while (i != nr_elements);
+       } while (i != nr_desc);
 
-       adapter->cmd_producer = producer;
+       tx_ring->producer = producer;
 
-       /* write producer index to start the xmit */
-
-       netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
+       netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
 
        netif_tx_unlock_bh(adapter->netdev);
 
@@ -717,6 +742,28 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable)
        return rv;
 }
 
+int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
+{
+       nx_nic_req_t req;
+       u64 word;
+       int rv;
+
+       memset(&req, 0, sizeof(nx_nic_req_t));
+       req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+       word = NX_NIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
+       req.req_hdr = cpu_to_le64(word);
+       req.words[0] = cpu_to_le64(enable);
+
+       rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+       if (rv != 0) {
+               printk(KERN_ERR "%s: could not configure link notification\n",
+                               adapter->netdev->name);
+       }
+
+       return rv;
+}
+
 /*
  * netxen_nic_change_mtu - Change the Maximum Transfer Unit
  * @returns 0 on success, negative on failure
@@ -812,8 +859,8 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
        crbaddr = CRB_MAC_BLOCK_START +
                (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
 
-       adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
-       adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
+       mac_lo = NXRD32(adapter, crbaddr);
+       mac_hi = NXRD32(adapter, crbaddr+4);
 
        if (pci_func & 1)
                *mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16));
@@ -831,8 +878,7 @@ static int crb_win_lock(struct netxen_adapter *adapter)
 
        while (!done) {
                /* acquire semaphore3 from PCI HW block */
-               adapter->hw_read_wx(adapter,
-                               NETXEN_PCIE_REG(PCIE_SEM7_LOCK), &done, 4);
+               done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK));
                if (done == 1)
                        break;
                if (timeout >= CRB_WIN_LOCK_TIMEOUT)
@@ -840,8 +886,7 @@ static int crb_win_lock(struct netxen_adapter *adapter)
                timeout++;
                udelay(1);
        }
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
+       NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
        return 0;
 }
 
@@ -849,8 +894,7 @@ static void crb_win_unlock(struct netxen_adapter *adapter)
 {
        int val;
 
-       adapter->hw_read_wx(adapter,
-                       NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK), &val, 4);
+       val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK));
 }
 
 /*
@@ -986,8 +1030,7 @@ netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname,
                dev_info(&pdev->dev, "loading firmware from flash\n");
 
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
-               adapter->pci_write_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_CAS_RST, 1);
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1);
 
        if (fw) {
                __le64 data;
@@ -1039,13 +1082,10 @@ netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname,
        msleep(1);
 
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-               adapter->pci_write_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
        else {
-               adapter->pci_write_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
-               adapter->pci_write_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_CAS_RST, 0);
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0);
        }
 
        return 0;
@@ -1103,8 +1143,7 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname,
        if (NETXEN_VERSION_CODE(major, minor, build) > ver)
                return -EINVAL;
 
-       netxen_nic_reg_write(adapter, NETXEN_CAM_RAM(0x1fc),
-                       NETXEN_BDINFO_MAGIC);
+       NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
        return 0;
 }
 
@@ -1132,8 +1171,7 @@ request_mn:
        netxen_rom_fast_read(adapter,
                        NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
        if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
-               adapter->hw_read_wx(adapter,
-                               NX_PEG_TUNE_CAPABILITY, &capability, 4);
+               capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY);
                if (capability & NX_PEG_TUNE_MN_PRESENT) {
                        fw_type = NX_P3_MN_ROMIMAGE;
                        goto request_fw;
@@ -1173,13 +1211,10 @@ load_fw:
 }
 
 int
-netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len)
+netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
 {
        void __iomem *addr;
 
-       BUG_ON(len != 4);
-
        if (ADDR_IN_WINDOW1(off)) {
                addr = NETXEN_CRB_NORMALIZE(adapter, off);
        } else {                /* Window 0 */
@@ -1192,7 +1227,7 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
                return 1;
        }
 
-       writel(*(u32 *) data, addr);
+       writel(data, addr);
 
        if (!ADDR_IN_WINDOW1(off))
                netxen_nic_pci_change_crbwindow_128M(adapter, 1);
@@ -1200,13 +1235,11 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
        return 0;
 }
 
-int
-netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len)
+u32
+netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
 {
        void __iomem *addr;
-
-       BUG_ON(len != 4);
+       u32 data;
 
        if (ADDR_IN_WINDOW1(off)) {     /* Window 1 */
                addr = NETXEN_CRB_NORMALIZE(adapter, off);
@@ -1220,24 +1253,21 @@ netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
                return 1;
        }
 
-       *(u32 *)data = readl(addr);
+       data = readl(addr);
 
        if (!ADDR_IN_WINDOW1(off))
                netxen_nic_pci_change_crbwindow_128M(adapter, 1);
 
-       return 0;
+       return data;
 }
 
 int
-netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len)
+netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
 {
        unsigned long flags = 0;
        int rv;
 
-       BUG_ON(len != 4);
-
-       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
+       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, 4);
 
        if (rv == -1) {
                printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
@@ -1250,26 +1280,24 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
                write_lock_irqsave(&adapter->adapter_lock, flags);
                crb_win_lock(adapter);
                netxen_nic_pci_set_crbwindow_2M(adapter, &off);
-               writel(*(uint32_t *)data, (void __iomem *)off);
+               writel(data, (void __iomem *)off);
                crb_win_unlock(adapter);
                write_unlock_irqrestore(&adapter->adapter_lock, flags);
        } else
-               writel(*(uint32_t *)data, (void __iomem *)off);
+               writel(data, (void __iomem *)off);
 
 
        return 0;
 }
 
-int
-netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len)
+u32
+netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
 {
        unsigned long flags = 0;
        int rv;
+       u32 data;
 
-       BUG_ON(len != 4);
-
-       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
+       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, 4);
 
        if (rv == -1) {
                printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
@@ -1282,47 +1310,13 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
                write_lock_irqsave(&adapter->adapter_lock, flags);
                crb_win_lock(adapter);
                netxen_nic_pci_set_crbwindow_2M(adapter, &off);
-               *(uint32_t *)data = readl((void __iomem *)off);
+               data = readl((void __iomem *)off);
                crb_win_unlock(adapter);
                write_unlock_irqrestore(&adapter->adapter_lock, flags);
        } else
-               *(uint32_t *)data = readl((void __iomem *)off);
-
-       return 0;
-}
+               data = readl((void __iomem *)off);
 
-void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
-{
-       adapter->hw_write_wx(adapter, off, &val, 4);
-}
-
-int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
-{
-       int val;
-       adapter->hw_read_wx(adapter, off, &val, 4);
-       return val;
-}
-
-/* Change the window to 0, write and change back to window 1. */
-void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value)
-{
-       adapter->hw_write_wx(adapter, index, &value, 4);
-}
-
-/* Change the window to 0, read and change back to window 1. */
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value)
-{
-       adapter->hw_read_wx(adapter, index, value, 4);
-}
-
-void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value)
-{
-       adapter->hw_write_wx(adapter, index, &value, 4);
-}
-
-void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value)
-{
-       adapter->hw_read_wx(adapter, index, value, 4);
+       return data;
 }
 
 /*
@@ -1425,17 +1419,6 @@ u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
        return readl((void __iomem *)(pci_base_offset(adapter, off)));
 }
 
-void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter,
-               u64 off, u32 data)
-{
-       writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
-}
-
-u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off)
-{
-       return readl(NETXEN_CRB_NORMALIZE(adapter, off));
-}
-
 unsigned long
 netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
                unsigned long long addr)
@@ -1447,12 +1430,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
                /* DDR network side */
                window = MN_WIN(addr);
                adapter->ahw.ddr_mn_window = window;
-               adapter->hw_write_wx(adapter,
-                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-                               &window, 4);
-               adapter->hw_read_wx(adapter,
-                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-                               &win_read, 4);
+               NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+                               window);
+               win_read = NXRD32(adapter,
+                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
                if ((win_read << 17) != window) {
                        printk(KERN_INFO "Written MNwin (0x%x) != "
                                "Read MNwin (0x%x)\n", window, win_read);
@@ -1467,12 +1448,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 
                window = OCM_WIN(addr);
                adapter->ahw.ddr_mn_window = window;
-               adapter->hw_write_wx(adapter,
-                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-                               &window, 4);
-               adapter->hw_read_wx(adapter,
-                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-                               &win_read, 4);
+               NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+                               window);
+               win_read = NXRD32(adapter,
+                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
                if ((win_read >> 7) != window) {
                        printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
                                        "Read OCMwin (0x%x)\n",
@@ -1485,12 +1464,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
                /* QDR network side */
                window = MS_WIN(addr);
                adapter->ahw.qdr_sn_window = window;
-               adapter->hw_write_wx(adapter,
-                               adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
-                               &window, 4);
-               adapter->hw_read_wx(adapter,
-                               adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
-                               &win_read, 4);
+               NXWR32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
+                               window);
+               win_read = NXRD32(adapter,
+                               adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE);
                if (win_read != window) {
                        printk(KERN_INFO "%s: Written MSwin (0x%x) != "
                                        "Read MSwin (0x%x)\n",
@@ -1936,27 +1913,20 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 
        for (i = 0; i < loop; i++) {
                temp = off8 + (i << 3);
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
                temp = 0;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
                temp = word[i] & 0xffffffff;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
                temp = (word[i] >> 32) & 0xffffffff;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
                temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
                temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
 
                for (j = 0; j < MAX_CTL_CHECK; j++) {
-                       adapter->hw_read_wx(adapter,
-                                       mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+                       temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
                        if ((temp & MIU_TA_CTL_BUSY) == 0)
                                break;
                }
@@ -2013,21 +1983,16 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 
        for (i = 0; i < loop; i++) {
                temp = off8 + (i << 3);
-               adapter->hw_write_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
+               NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
                temp = 0;
-               adapter->hw_write_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
+               NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
                temp = MIU_TA_CTL_ENABLE;
-               adapter->hw_write_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+               NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
                temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
-               adapter->hw_write_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+               NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
 
                for (j = 0; j < MAX_CTL_CHECK; j++) {
-                       adapter->hw_read_wx(adapter,
-                                       mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+                       temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
                        if ((temp & MIU_TA_CTL_BUSY) == 0)
                                break;
                }
@@ -2042,8 +2007,8 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
                start = off0[i] >> 2;
                end   = (off0[i] + sz[i] - 1) >> 2;
                for (k = start; k <= end; k++) {
-                       adapter->hw_read_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
+                       temp = NXRD32(adapter,
+                               mem_crb + MIU_TEST_AGT_RDDATA(k));
                        word[i] |= ((uint64_t)temp << (32 * k));
                }
        }
@@ -2086,29 +2051,14 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
                u64 off, u32 data)
 {
-       adapter->hw_write_wx(adapter, off, &data, 4);
+       NXWR32(adapter, off, data);
 
        return 0;
 }
 
 u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
 {
-       u32 temp;
-       adapter->hw_read_wx(adapter, off, &temp, 4);
-       return temp;
-}
-
-void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter,
-               u64 off, u32 data)
-{
-       adapter->hw_write_wx(adapter, off, &data, 4);
-}
-
-u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off)
-{
-       u32 temp;
-       adapter->hw_read_wx(adapter, off, &temp, 4);
-       return temp;
+       return NXRD32(adapter, off);
 }
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
@@ -2142,13 +2092,12 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
        adapter->ahw.board_type = board_type;
 
        if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
-               u32 gpio = netxen_nic_reg_read(adapter,
-                               NETXEN_ROMUSB_GLB_PAD_GPIO_I);
+               u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I);
                if ((gpio & 0x8000) == 0)
                        board_type = NETXEN_BRDTYPE_P3_10G_TP;
        }
 
-       switch ((netxen_brdtype_t)board_type) {
+       switch (board_type) {
        case NETXEN_BRDTYPE_P2_SB35_4G:
                adapter->ahw.port_type = NETXEN_NIC_GBE;
                break;
@@ -2195,8 +2144,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
 {
        new_mtu += MTU_FUDGE_FACTOR;
-       netxen_nic_write_w0(adapter,
-               NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
+       NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
                new_mtu);
        return 0;
 }
@@ -2205,21 +2153,12 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
 {
        new_mtu += MTU_FUDGE_FACTOR;
        if (adapter->physical_port == 0)
-               netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
-                               new_mtu);
+               NXWR32(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
        else
-               netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE,
-                               new_mtu);
+               NXWR32(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
        return 0;
 }
 
-void
-netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
-               unsigned long off, int data)
-{
-       adapter->hw_write_wx(adapter, off, &data, 4);
-}
-
 void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 {
        __u32 status;
@@ -2234,8 +2173,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
        }
 
        if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
-               adapter->hw_read_wx(adapter,
-                               NETXEN_PORT_MODE_ADDR, &port_mode, 4);
+               port_mode = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
                if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
                        adapter->link_speed   = SPEED_1000;
                        adapter->link_duplex  = DUPLEX_FULL;
@@ -2312,9 +2250,9 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
                addr += sizeof(u32);
        }
 
-       adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR, &fw_major, 4);
-       adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR, &fw_minor, 4);
-       adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4);
+       fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+       fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+       fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
 
        adapter->fw_major = fw_major;
        adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
@@ -2337,8 +2275,7 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
                        fw_major, fw_minor, fw_build);
 
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-               adapter->hw_read_wx(adapter,
-                               NETXEN_MIU_MN_CONTROL, &i, 4);
+               i = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
                adapter->ahw.cut_through = (i & 0x4) ? 1 : 0;
                dev_info(&pdev->dev, "firmware running in %s mode\n",
                adapter->ahw.cut_through ? "cut-through" : "legacy");
@@ -2353,9 +2290,9 @@ netxen_nic_wol_supported(struct netxen_adapter *adapter)
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
                return 0;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
        if (wol_cfg & (1UL << adapter->portnum)) {
-               wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+               wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
                if (wol_cfg & (1 << adapter->portnum))
                        return 1;
        }
index 04b47a7..f20c965 100644 (file)
 /* Hardware memory size of 128 meg */
 #define NETXEN_MEMADDR_MAX (128 * 1024 * 1024)
 
-#ifndef readq
-static inline u64 readq(void __iomem * addr)
-{
-       return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(u64 val, void __iomem * addr)
-{
-       writel(((u32) (val)), (addr));
-       writel(((u32) (val >> 32)), (addr + 4));
-}
-#endif
-
 struct netxen_adapter;
 
 #define NETXEN_PCI_MAPSIZE_BYTES  (NETXEN_PCI_MAPSIZE << 20)
 
-struct netxen_port;
 void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
 
 typedef u8 netxen_ethernet_macaddr_t[6];
 
 /* Nibble or Byte mode for phy interface (GbE mode only) */
-typedef enum {
-       NETXEN_NIU_10_100_MB = 0,
-       NETXEN_NIU_1000_MB
-} netxen_niu_gbe_ifmode_t;
 
 #define _netxen_crb_get_bit(var, bit)  ((var >> bit) & 0x1)
 
@@ -222,30 +202,28 @@ typedef enum {
 /*
  * PHY-Specific MII control/status registers.
  */
-typedef enum {
-       NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL = 0,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS = 1,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 = 2,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 = 3,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG = 4,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART = 5,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE = 6,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT = 7,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE = 8,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL = 9,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS = 10,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS = 15,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL = 16,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS = 17,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE = 18,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS = 19,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE = 20,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT = 21,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL = 24,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE = 25,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET = 26,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE = 27
-} netxen_niu_phy_register_t;
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL            0
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS             1
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0           2
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1           3
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG            4
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART            5
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE       6
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT      7
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE   8
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL     9
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS      10
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS    15
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL                16
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS         17
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE         18
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS         19
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE   20
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT   21
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL                24
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE       25
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET       26
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE    27
 
 /*
  * PHY-Specific Status Register (reg 17).
index 0759c35..8893a97 100644 (file)
@@ -108,42 +108,6 @@ static void crb_addr_transform_setup(void)
        crb_addr_transform(I2C0);
 }
 
-int netxen_init_firmware(struct netxen_adapter *adapter)
-{
-       u32 state = 0, loops = 0, err = 0;
-
-       /* Window 1 call */
-       state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
-
-       if (state == PHAN_INITIALIZE_ACK)
-               return 0;
-
-       while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
-               msleep(1);
-               /* Window 1 call */
-               state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
-
-               loops++;
-       }
-       if (loops >= 2000) {
-               printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n",
-                      state);
-               err = -EIO;
-               return err;
-       }
-       /* Window 1 call */
-       adapter->pci_write_normalize(adapter,
-                       CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
-       adapter->pci_write_normalize(adapter,
-                       CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
-       adapter->pci_write_normalize(adapter,
-                       CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
-       adapter->pci_write_normalize(adapter,
-                       CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
-
-       return err;
-}
-
 void netxen_release_rx_buffers(struct netxen_adapter *adapter)
 {
        struct netxen_recv_context *recv_ctx;
@@ -173,9 +137,10 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
        struct netxen_cmd_buffer *cmd_buf;
        struct netxen_skb_frag *buffrag;
        int i, j;
+       struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
 
-       cmd_buf = adapter->cmd_buf_arr;
-       for (i = 0; i < adapter->num_txd; i++) {
+       cmd_buf = tx_ring->cmd_buf_arr;
+       for (i = 0; i < tx_ring->num_desc; i++) {
                buffrag = cmd_buf->frag_array;
                if (buffrag->dma) {
                        pci_unmap_single(adapter->pdev, buffrag->dma,
@@ -203,6 +168,7 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
 {
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
+       struct nx_host_tx_ring *tx_ring;
        int ring;
 
        recv_ctx = &adapter->recv_ctx;
@@ -214,8 +180,9 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
                }
        }
 
-       if (adapter->cmd_buf_arr)
-               vfree(adapter->cmd_buf_arr);
+       tx_ring = &adapter->tx_ring;
+       if (tx_ring->cmd_buf_arr)
+               vfree(tx_ring->cmd_buf_arr);
        return;
 }
 
@@ -224,21 +191,24 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
        struct nx_host_sds_ring *sds_ring;
+       struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
        struct netxen_rx_buffer *rx_buf;
        int ring, i, num_rx_bufs;
 
        struct netxen_cmd_buffer *cmd_buf_arr;
        struct net_device *netdev = adapter->netdev;
+       struct pci_dev *pdev = adapter->pdev;
 
+       tx_ring->num_desc = adapter->num_txd;
        cmd_buf_arr =
-               (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter));
+               (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(tx_ring));
        if (cmd_buf_arr == NULL) {
-               printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
+               dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n",
                       netdev->name);
                return -ENOMEM;
        }
-       memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter));
-       adapter->cmd_buf_arr = cmd_buf_arr;
+       memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
+       tx_ring->cmd_buf_arr = cmd_buf_arr;
 
        recv_ctx = &adapter->recv_ctx;
        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
@@ -307,8 +277,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
                sds_ring = &recv_ctx->sds_rings[ring];
                sds_ring->irq = adapter->msix_entries[ring].vector;
-               sds_ring->clean_tx = (ring == 0);
-               sds_ring->post_rxd = (ring == 0);
                sds_ring->adapter = adapter;
                sds_ring->num_desc = adapter->num_rxd;
 
@@ -400,8 +368,7 @@ static int rom_lock(struct netxen_adapter *adapter)
 
        while (!done) {
                /* acquire semaphore2 from PCI HW block */
-               netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK),
-                                  &done);
+               done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK));
                if (done == 1)
                        break;
                if (timeout >= rom_lock_timeout)
@@ -418,7 +385,7 @@ static int rom_lock(struct netxen_adapter *adapter)
                                cpu_relax();    /*This a nop instr on i386 */
                }
        }
-       netxen_nic_reg_write(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
+       NXWR32(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
        return 0;
 }
 
@@ -430,7 +397,7 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
        cond_resched();
 
        while (done == 0) {
-               done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS);
+               done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS);
                done &= 2;
                timeout++;
                if (timeout >= rom_max_timeout) {
@@ -443,30 +410,28 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
 
 static void netxen_rom_unlock(struct netxen_adapter *adapter)
 {
-       u32 val;
-
        /* release semaphore2 */
-       netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val);
+       NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK));
 
 }
 
 static int do_rom_fast_read(struct netxen_adapter *adapter,
                            int addr, int *valp)
 {
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
        if (netxen_wait_rom_done(adapter)) {
                printk("Error waiting for rom done\n");
                return -EIO;
        }
        /* reset abyte_cnt and dummy_byte_cnt */
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
        udelay(10);
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
 
-       *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
+       *valp = NXRD32(adapter, NETXEN_ROMUSB_ROM_RDATA);
        return 0;
 }
 
@@ -530,8 +495,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 
        /* resetall */
        rom_lock(adapter);
-       netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
-                                   0xffffffff);
+       NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
        netxen_rom_unlock(adapter);
 
        if (verbose) {
@@ -655,7 +619,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
                        }
                }
 
-               adapter->hw_write_wx(adapter, off, &buf[i].data, 4);
+               NXWR32(adapter, off, buf[i].data);
 
                msleep(init_delay);
        }
@@ -665,33 +629,31 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 
        /* unreset_net_cache */
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-               adapter->hw_read_wx(adapter,
-                               NETXEN_ROMUSB_GLB_SW_RESET, &val, 4);
-               netxen_crb_writelit_adapter(adapter,
-                               NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
+               val = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET);
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
        }
 
        /* p2dn replyCount */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
        /* disable_peg_cache 0 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
        /* disable_peg_cache 1 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
 
        /* peg_clr_all */
 
        /* peg_clr 0 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
        /* peg_clr 1 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
        /* peg_clr 2 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
        /* peg_clr 3 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
        return 0;
 }
 
@@ -715,12 +677,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
        hi = (addr >> 32) & 0xffffffff;
        lo = addr & 0xffffffff;
 
-       adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
-       adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
+       NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
+       NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
 
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
                uint32_t temp = 0;
-               adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4);
+               NXWR32(adapter, CRB_HOST_DUMMY_BUF, temp);
        }
 
        return 0;
@@ -762,8 +724,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
 
        if (!pegtune_val) {
                do {
-                       val = adapter->pci_read_normalize(adapter,
-                                       CRB_CMDPEG_STATE);
+                       val = NXRD32(adapter, CRB_CMDPEG_STATE);
 
                        if (val == PHAN_INITIALIZE_COMPLETE ||
                                val == PHAN_INITIALIZE_ACK)
@@ -774,7 +735,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
                } while (--retries);
 
                if (!retries) {
-                       pegtune_val = adapter->pci_read_normalize(adapter,
+                       pegtune_val = NXRD32(adapter,
                                        NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
                        printk(KERN_WARNING "netxen_phantom_init: init failed, "
                                        "pegtune_val=%x\n", pegtune_val);
@@ -785,13 +746,14 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
        return 0;
 }
 
-int netxen_receive_peg_ready(struct netxen_adapter *adapter)
+static int
+netxen_receive_peg_ready(struct netxen_adapter *adapter)
 {
        u32 val = 0;
        int retries = 2000;
 
        do {
-               val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE);
+               val = NXRD32(adapter, CRB_RCVPEG_STATE);
 
                if (val == PHAN_PEG_RCV_INITIALIZED)
                        return 0;
@@ -809,6 +771,93 @@ int netxen_receive_peg_ready(struct netxen_adapter *adapter)
        return 0;
 }
 
+int netxen_init_firmware(struct netxen_adapter *adapter)
+{
+       int err;
+
+       err = netxen_receive_peg_ready(adapter);
+       if (err)
+               return err;
+
+       NXWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
+       NXWR32(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
+       NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
+       NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
+
+       if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) {
+               adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
+       }
+
+       return err;
+}
+
+static void
+netxen_handle_linkevent(struct netxen_adapter *adapter, nx_fw_msg_t *msg)
+{
+       u32 cable_OUI;
+       u16 cable_len;
+       u16 link_speed;
+       u8  link_status, module, duplex, autoneg;
+       struct net_device *netdev = adapter->netdev;
+
+       adapter->has_link_events = 1;
+
+       cable_OUI = msg->body[1] & 0xffffffff;
+       cable_len = (msg->body[1] >> 32) & 0xffff;
+       link_speed = (msg->body[1] >> 48) & 0xffff;
+
+       link_status = msg->body[2] & 0xff;
+       duplex = (msg->body[2] >> 16) & 0xff;
+       autoneg = (msg->body[2] >> 24) & 0xff;
+
+       module = (msg->body[2] >> 8) & 0xff;
+       if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE) {
+               printk(KERN_INFO "%s: unsupported cable: OUI 0x%x, length %d\n",
+                               netdev->name, cable_OUI, cable_len);
+       } else if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN) {
+               printk(KERN_INFO "%s: unsupported cable length %d\n",
+                               netdev->name, cable_len);
+       }
+
+       netxen_advert_link_change(adapter, link_status);
+
+       /* update link parameters */
+       if (duplex == LINKEVENT_FULL_DUPLEX)
+               adapter->link_duplex = DUPLEX_FULL;
+       else
+               adapter->link_duplex = DUPLEX_HALF;
+       adapter->module_type = module;
+       adapter->link_autoneg = autoneg;
+       adapter->link_speed = link_speed;
+}
+
+static void
+netxen_handle_fw_message(int desc_cnt, int index,
+               struct nx_host_sds_ring *sds_ring)
+{
+       nx_fw_msg_t msg;
+       struct status_desc *desc;
+       int i = 0, opcode;
+
+       while (desc_cnt > 0 && i < 8) {
+               desc = &sds_ring->desc_head[index];
+               msg.words[i++] = le64_to_cpu(desc->status_desc_data[0]);
+               msg.words[i++] = le64_to_cpu(desc->status_desc_data[1]);
+
+               index = get_next_index(index, sds_ring->num_desc);
+               desc_cnt--;
+       }
+
+       opcode = netxen_get_nic_msg_opcode(msg.body[0]);
+       switch (opcode) {
+       case NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE:
+               netxen_handle_linkevent(sds_ring->adapter, &msg);
+               break;
+       default:
+               break;
+       }
+}
+
 static int
 netxen_alloc_rx_skb(struct netxen_adapter *adapter,
                struct nx_host_rds_ring *rds_ring,
@@ -874,7 +923,8 @@ no_skb:
 
 static struct netxen_rx_buffer *
 netxen_process_rcv(struct netxen_adapter *adapter,
-               int ring, int index, int length, int cksum, int pkt_offset)
+               int ring, int index, int length, int cksum, int pkt_offset,
+               struct nx_host_sds_ring *sds_ring)
 {
        struct net_device *netdev = adapter->netdev;
        struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
@@ -902,7 +952,7 @@ netxen_process_rcv(struct netxen_adapter *adapter,
 
        skb->protocol = eth_type_trans(skb, netdev);
 
-       netif_receive_skb(skb);
+       napi_gro_receive(&sds_ring->napi, skb);
 
        adapter->stats.no_rcv++;
        adapter->stats.rxbytes += length;
@@ -927,35 +977,53 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
 
        int count = 0;
        u64 sts_data;
-       int opcode, ring, index, length, cksum, pkt_offset;
+       int opcode, ring, index, length, cksum, pkt_offset, desc_cnt;
 
        while (count < max) {
                desc = &sds_ring->desc_head[consumer];
-               sts_data = le64_to_cpu(desc->status_desc_data);
+               sts_data = le64_to_cpu(desc->status_desc_data[0]);
 
                if (!(sts_data & STATUS_OWNER_HOST))
                        break;
 
+               desc_cnt = netxen_get_sts_desc_cnt(sts_data);
                ring   = netxen_get_sts_type(sts_data);
+
                if (ring > RCV_RING_JUMBO)
-                       continue;
+                       goto skip;
 
                opcode = netxen_get_sts_opcode(sts_data);
 
+               switch (opcode) {
+               case NETXEN_NIC_RXPKT_DESC:
+               case NETXEN_OLD_RXPKT_DESC:
+                       break;
+               case NETXEN_NIC_RESPONSE_DESC:
+                       netxen_handle_fw_message(desc_cnt, consumer, sds_ring);
+               default:
+                       goto skip;
+               }
+
+               WARN_ON(desc_cnt > 1);
+
                index  = netxen_get_sts_refhandle(sts_data);
                length = netxen_get_sts_totallength(sts_data);
                cksum  = netxen_get_sts_status(sts_data);
                pkt_offset = netxen_get_sts_pkt_offset(sts_data);
 
                rxbuf = netxen_process_rcv(adapter, ring, index,
-                               length, cksum, pkt_offset);
+                               length, cksum, pkt_offset, sds_ring);
 
                if (rxbuf)
                        list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
 
-               desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
-
-               consumer = get_next_index(consumer, sds_ring->num_desc);
+skip:
+               for (; desc_cnt > 0; desc_cnt--) {
+                       desc = &sds_ring->desc_head[consumer];
+                       desc->status_desc_data[0] =
+                               cpu_to_le64(STATUS_OWNER_PHANTOM);
+                       consumer = get_next_index(consumer, sds_ring->num_desc);
+               }
                count++;
        }
 
@@ -980,8 +1048,7 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
 
        if (count) {
                sds_ring->consumer = consumer;
-               adapter->pci_write_normalize(adapter,
-                               sds_ring->crb_sts_consumer, consumer);
+               NXWR32(adapter, sds_ring->crb_sts_consumer, consumer);
        }
 
        return count;
@@ -990,23 +1057,24 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
 /* Process Command status ring */
 int netxen_process_cmd_ring(struct netxen_adapter *adapter)
 {
-       u32 last_consumer, consumer;
+       u32 sw_consumer, hw_consumer;
        int count = 0, i;
        struct netxen_cmd_buffer *buffer;
        struct pci_dev *pdev = adapter->pdev;
        struct net_device *netdev = adapter->netdev;
        struct netxen_skb_frag *frag;
        int done = 0;
+       struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
 
        if (!spin_trylock(&adapter->tx_clean_lock))
                return 1;
 
-       last_consumer = adapter->last_cmd_consumer;
-       barrier(); /* cmd_consumer can change underneath */
-       consumer = le32_to_cpu(*(adapter->cmd_consumer));
+       sw_consumer = tx_ring->sw_consumer;
+       barrier(); /* hw_consumer can change underneath */
+       hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
 
-       while (last_consumer != consumer) {
-               buffer = &adapter->cmd_buf_arr[last_consumer];
+       while (sw_consumer != hw_consumer) {
+               buffer = &tx_ring->cmd_buf_arr[sw_consumer];
                if (buffer->skb) {
                        frag = &buffer->frag_array[0];
                        pci_unmap_single(pdev, frag->dma, frag->length,
@@ -1024,14 +1092,13 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
                        buffer->skb = NULL;
                }
 
-               last_consumer = get_next_index(last_consumer,
-                                              adapter->num_txd);
+               sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc);
                if (++count >= MAX_STATUS_HANDLE)
                        break;
        }
 
        if (count) {
-               adapter->last_cmd_consumer = last_consumer;
+               tx_ring->sw_consumer = sw_consumer;
                smp_mb();
                if (netif_queue_stopped(netdev) && netif_running(netdev)) {
                        netif_tx_lock(netdev);
@@ -1053,9 +1120,9 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
         * There is still a possible race condition and the host could miss an
         * interrupt. The card has to take care of this.
         */
-       barrier(); /* cmd_consumer can change underneath */
-       consumer = le32_to_cpu(*(adapter->cmd_consumer));
-       done = (last_consumer == consumer);
+       barrier(); /* hw_consumer can change underneath */
+       hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
+       done = (sw_consumer == hw_consumer);
        spin_unlock(&adapter->tx_clean_lock);
 
        return (done);
@@ -1099,8 +1166,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
 
        if (count) {
                rds_ring->producer = producer;
-               adapter->pci_write_normalize(adapter,
-                               rds_ring->crb_rcv_producer,
+               NXWR32(adapter, rds_ring->crb_rcv_producer,
                                (producer-1) & (rds_ring->num_desc-1));
 
                if (adapter->fw_major < 4) {
@@ -1160,8 +1226,7 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
 
        if (count) {
                rds_ring->producer = producer;
-               adapter->pci_write_normalize(adapter,
-                       rds_ring->crb_rcv_producer,
+               NXWR32(adapter, rds_ring->crb_rcv_producer,
                                (producer - 1) & (rds_ring->num_desc - 1));
                        wmb();
        }