drivers: net: use skb_headlen()
[safe/jmp/linux-2.6] / drivers / net / tehuti.c
index 2483431..e29f495 100644 (file)
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include "tehuti.h"
-#include "tehuti_fw.h"
 
-static struct pci_device_id __devinitdata bdx_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(bdx_pci_tbl) = {
        {0x1FC9, 0x3009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {0x1FC9, 0x3010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        {0x1FC9, 0x3014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -106,26 +107,24 @@ static void print_hw_id(struct pci_dev *pdev)
        pci_read_config_word(pdev, PCI_LINK_STATUS_REG, &pci_link_status);
        pci_read_config_word(pdev, PCI_DEV_CTRL_REG, &pci_ctrl);
 
-       printk(KERN_INFO "tehuti: %s%s\n", BDX_NIC_NAME,
-              nic->port_num == 1 ? "" : ", 2-Port");
-       printk(KERN_INFO
-              "tehuti: srom 0x%x fpga %d build %u lane# %d"
-              " max_pl 0x%x mrrs 0x%x\n",
-              readl(nic->regs + SROM_VER), readl(nic->regs + FPGA_VER) & 0xFFF,
-              readl(nic->regs + FPGA_SEED),
-              GET_LINK_STATUS_LANES(pci_link_status),
-              GET_DEV_CTRL_MAXPL(pci_ctrl), GET_DEV_CTRL_MRRS(pci_ctrl));
+       pr_info("%s%s\n", BDX_NIC_NAME,
+               nic->port_num == 1 ? "" : ", 2-Port");
+       pr_info("srom 0x%x fpga %d build %u lane# %d max_pl 0x%x mrrs 0x%x\n",
+               readl(nic->regs + SROM_VER), readl(nic->regs + FPGA_VER) & 0xFFF,
+               readl(nic->regs + FPGA_SEED),
+               GET_LINK_STATUS_LANES(pci_link_status),
+               GET_DEV_CTRL_MAXPL(pci_ctrl), GET_DEV_CTRL_MRRS(pci_ctrl));
 }
 
 static void print_fw_id(struct pci_nic *nic)
 {
-       printk(KERN_INFO "tehuti: fw 0x%x\n", readl(nic->regs + FW_VER));
+       pr_info("fw 0x%x\n", readl(nic->regs + FW_VER));
 }
 
 static void print_eth_id(struct net_device *ndev)
 {
-       printk(KERN_INFO "%s: %s, Port %c\n", ndev->name, BDX_NIC_NAME,
-              (ndev->if_port == 0) ? 'A' : 'B');
+       netdev_info(ndev, "%s, Port %c\n",
+                   BDX_NIC_NAME, (ndev->if_port == 0) ? 'A' : 'B');
 
 }
 
@@ -161,7 +160,7 @@ bdx_fifo_init(struct bdx_priv *priv, struct fifo *f, int fsz_type,
        f->va = pci_alloc_consistent(priv->pdev,
                                     memsz + FIFO_EXTRA_SPACE, &f->da);
        if (!f->va) {
-               ERR("pci_alloc_consistent failed\n");
+               pr_err("pci_alloc_consistent failed\n");
                RET(-ENOMEM);
        }
        f->reg_CFG0 = reg_CFG0;
@@ -205,13 +204,13 @@ static void bdx_link_changed(struct bdx_priv *priv)
                if (netif_carrier_ok(priv->ndev)) {
                        netif_stop_queue(priv->ndev);
                        netif_carrier_off(priv->ndev);
-                       ERR("%s: Link Down\n", priv->ndev->name);
+                       netdev_err(priv->ndev, "Link Down\n");
                }
        } else {
                if (!netif_carrier_ok(priv->ndev)) {
                        netif_wake_queue(priv->ndev);
                        netif_carrier_on(priv->ndev);
-                       ERR("%s: Link Up\n", priv->ndev->name);
+                       netdev_err(priv->ndev, "Link Up\n");
                }
        }
 }
@@ -227,10 +226,10 @@ static void bdx_isr_extra(struct bdx_priv *priv, u32 isr)
                bdx_link_changed(priv);
 
        if (isr & IR_PCIE_LINK)
-               ERR("%s: PCI-E Link Fault\n", priv->ndev->name);
+               netdev_err(priv->ndev, "PCI-E Link Fault\n");
 
        if (isr & IR_PCIE_TOUT)
-               ERR("%s: PCI-E Time Out\n", priv->ndev->name);
+               netdev_err(priv->ndev, "PCI-E Time Out\n");
 
 }
 
@@ -251,7 +250,7 @@ static void bdx_isr_extra(struct bdx_priv *priv, u32 isr)
 static irqreturn_t bdx_isr_napi(int irq, void *dev)
 {
        struct net_device *ndev = dev;
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        u32 isr;
 
        ENTER;
@@ -265,8 +264,8 @@ static irqreturn_t bdx_isr_napi(int irq, void *dev)
                bdx_isr_extra(priv, isr);
 
        if (isr & (IR_RX_DESC_0 | IR_TX_FREE_0)) {
-               if (likely(netif_rx_schedule_prep(ndev, &priv->napi))) {
-                       __netif_rx_schedule(ndev, &priv->napi);
+               if (likely(napi_schedule_prep(&priv->napi))) {
+                       __napi_schedule(&priv->napi);
                        RET(IRQ_HANDLED);
                } else {
                        /* NOTE: we get here if intr has slipped into window
@@ -289,7 +288,6 @@ static irqreturn_t bdx_isr_napi(int irq, void *dev)
 static int bdx_poll(struct napi_struct *napi, int budget)
 {
        struct bdx_priv *priv = container_of(napi, struct bdx_priv, napi);
-       struct net_device *dev = priv->ndev;
        int work_done;
 
        ENTER;
@@ -303,7 +301,7 @@ static int bdx_poll(struct napi_struct *napi, int budget)
                 * device lock and allow waiting tasks (eg rmmod) to advance) */
                priv->napi_stop = 0;
 
-               netif_rx_complete(dev, napi);
+               napi_complete(napi);
                bdx_enable_interrupts(priv);
        }
        return work_done;
@@ -319,28 +317,41 @@ static int bdx_poll(struct napi_struct *napi, int budget)
 
 static int bdx_fw_load(struct bdx_priv *priv)
 {
+       const struct firmware *fw = NULL;
        int master, i;
+       int rc;
 
        ENTER;
        master = READ_REG(priv, regINIT_SEMAPHORE);
        if (!READ_REG(priv, regINIT_STATUS) && master) {
-               bdx_tx_push_desc_safe(priv, s_firmLoad, sizeof(s_firmLoad));
+               rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev);
+               if (rc)
+                       goto out;
+               bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size);
                mdelay(100);
        }
        for (i = 0; i < 200; i++) {
-               if (READ_REG(priv, regINIT_STATUS))
-                       break;
+               if (READ_REG(priv, regINIT_STATUS)) {
+                       rc = 0;
+                       goto out;
+               }
                mdelay(2);
        }
+       rc = -EIO;
+out:
        if (master)
                WRITE_REG(priv, regINIT_SEMAPHORE, 1);
-
-       if (i == 200) {
-               ERR("%s: firmware loading failed\n", priv->ndev->name);
-               DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n",
-                   READ_REG(priv, regVPC),
-                   READ_REG(priv, regVIC), READ_REG(priv, regINIT_STATUS), i);
-               RET(-EIO);
+       if (fw)
+               release_firmware(fw);
+
+       if (rc) {
+               netdev_err(priv->ndev, "firmware loading failed\n");
+               if (rc == -EIO)
+                       DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n",
+                           READ_REG(priv, regVPC),
+                           READ_REG(priv, regVIC),
+                           READ_REG(priv, regINIT_STATUS), i);
+               RET(rc);
        } else {
                DBG("%s: firmware loading success\n", priv->ndev->name);
                RET(0);
@@ -408,9 +419,11 @@ static int bdx_hw_start(struct bdx_priv *priv)
        WRITE_REG(priv, regGMAC_RXF_A, GMAC_RX_FILTER_OSEN |
                  GMAC_RX_FILTER_AM | GMAC_RX_FILTER_AB);
 
-#define BDX_IRQ_TYPE   ((priv->nic->irq_type == IRQ_MSI)?0:IRQF_SHARED)
-       if ((rc = request_irq(priv->pdev->irq, &bdx_isr_napi, BDX_IRQ_TYPE,
-                        ndev->name, ndev)))
+#define BDX_IRQ_TYPE   ((priv->nic->irq_type == IRQ_MSI) ? 0 : IRQF_SHARED)
+
+       rc = request_irq(priv->pdev->irq, bdx_isr_napi, BDX_IRQ_TYPE,
+                        ndev->name, ndev);
+       if (rc)
                goto err_irq;
        bdx_enable_interrupts(priv);
 
@@ -451,7 +464,7 @@ static int bdx_hw_reset_direct(void __iomem *regs)
                        readl(regs + regRXD_CFG0_0);
                        return 0;
                }
-       ERR("tehuti: HW reset failed\n");
+       pr_err("HW reset failed\n");
        return 1;               /* failure */
 }
 
@@ -475,7 +488,7 @@ static int bdx_hw_reset(struct bdx_priv *priv)
                        READ_REG(priv, regRXD_CFG0_0);
                        return 0;
                }
-       ERR("tehuti: HW reset failed\n");
+       pr_err("HW reset failed\n");
        return 1;               /* failure */
 }
 
@@ -499,8 +512,7 @@ static int bdx_sw_reset(struct bdx_priv *priv)
                mdelay(10);
        }
        if (i == 50)
-               ERR("%s: SW reset timeout. continuing anyway\n",
-                   priv->ndev->name);
+               netdev_err(priv->ndev, "SW reset timeout. continuing anyway\n");
 
        /* 6. disable intrs */
        WRITE_REG(priv, regRDINTCM0, 0);
@@ -559,7 +571,7 @@ static int bdx_close(struct net_device *ndev)
        struct bdx_priv *priv = NULL;
 
        ENTER;
-       priv = ndev->priv;
+       priv = netdev_priv(ndev);
 
        napi_disable(&priv->napi);
 
@@ -588,23 +600,20 @@ static int bdx_open(struct net_device *ndev)
        int rc;
 
        ENTER;
-       priv = ndev->priv;
+       priv = netdev_priv(ndev);
        bdx_reset(priv);
        if (netif_running(ndev))
                netif_stop_queue(priv->ndev);
 
-       if ((rc = bdx_tx_init(priv)))
-               goto err;
-
-       if ((rc = bdx_rx_init(priv)))
-               goto err;
-
-       if ((rc = bdx_fw_load(priv)))
+       if ((rc = bdx_tx_init(priv)) ||
+           (rc = bdx_rx_init(priv)) ||
+           (rc = bdx_fw_load(priv)))
                goto err;
 
        bdx_rx_alloc_skbs(priv, &priv->rxf_fifo0);
 
-       if ((rc = bdx_hw_start(priv)))
+       rc = bdx_hw_start(priv);
+       if (rc)
                goto err;
 
        napi_enable(&priv->napi);
@@ -618,16 +627,15 @@ err:
        RET(rc);
 }
 
-static void __init bdx_firmware_endianess(void)
+static int bdx_range_check(struct bdx_priv *priv, u32 offset)
 {
-       int i;
-       for (i = 0; i < sizeof(s_firmLoad) / sizeof(u32); i++)
-               s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]);
+       return (offset > (u32) (BDX_REGS_SIZE / priv->nic->port_num)) ?
+               -EINVAL : 0;
 }
 
 static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        u32 data[3];
        int error;
 
@@ -637,15 +645,21 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
        if (cmd != SIOCDEVPRIVATE) {
                error = copy_from_user(data, ifr->ifr_data, sizeof(data));
                if (error) {
-                       ERR("cant copy from user\n");
+                       pr_err("cant copy from user\n");
                        RET(error);
                }
                DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);
        }
 
+       if (!capable(CAP_SYS_RAWIO))
+               return -EPERM;
+
        switch (data[0]) {
 
        case BDX_OP_READ:
+               error = bdx_range_check(priv, data[1]);
+               if (error < 0)
+                       return error;
                data[2] = READ_REG(priv, data[1]);
                DBG("read_reg(0x%x)=0x%x (dec %d)\n", data[1], data[2],
                    data[2]);
@@ -655,6 +669,9 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
                break;
 
        case BDX_OP_WRITE:
+               error = bdx_range_check(priv, data[1]);
+               if (error < 0)
+                       return error;
                WRITE_REG(priv, data[1], data[2]);
                DBG("write_reg(0x%x, 0x%x)\n", data[1], data[2]);
                break;
@@ -683,13 +700,13 @@ static int bdx_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
  */
 static void __bdx_vlan_rx_vid(struct net_device *ndev, uint16_t vid, int enable)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        u32 reg, bit, val;
 
        ENTER;
        DBG2("vid=%d value=%d\n", (int)vid, enable);
        if (unlikely(vid >= 4096)) {
-               ERR("tehuti: invalid VID: %u (> 4096)\n", vid);
+               pr_err("invalid VID: %u (> 4096)\n", vid);
                RET();
        }
        reg = regVLAN_0 + (vid / 32) * 4;
@@ -733,7 +750,7 @@ static void bdx_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid)
 static void
 bdx_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
 
        ENTER;
        DBG("device='%s', group='%p'\n", ndev->name, grp);
@@ -750,7 +767,6 @@ bdx_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp)
  */
 static int bdx_change_mtu(struct net_device *ndev, int new_mtu)
 {
-       BDX_ASSERT(ndev == 0);
        ENTER;
 
        if (new_mtu == ndev->mtu)
@@ -758,8 +774,8 @@ static int bdx_change_mtu(struct net_device *ndev, int new_mtu)
 
        /* enforce minimum frame size */
        if (new_mtu < ETH_ZLEN) {
-               ERR("%s: %s mtu %d is less then minimal %d\n",
-                   BDX_DRV_NAME, ndev->name, new_mtu, ETH_ZLEN);
+               netdev_err(ndev, "mtu %d is less then minimal %d\n",
+                          new_mtu, ETH_ZLEN);
                RET(-EINVAL);
        }
 
@@ -773,7 +789,7 @@ static int bdx_change_mtu(struct net_device *ndev, int new_mtu)
 
 static void bdx_setmulti(struct net_device *ndev)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
 
        u32 rxf_val =
            GMAC_RX_FILTER_AM | GMAC_RX_FILTER_AB | GMAC_RX_FILTER_OSEN;
@@ -790,9 +806,9 @@ static void bdx_setmulti(struct net_device *ndev)
                /* set IMF to accept all multicast frmaes */
                for (i = 0; i < MAC_MCST_HASH_NUM; i++)
                        WRITE_REG(priv, regRX_MCST_HASH0 + i * 4, ~0);
-       } else if (ndev->mc_count) {
+       } else if (!netdev_mc_empty(ndev)) {
                u8 hash;
-               struct dev_mc_list *mclist;
+               struct netdev_hw_addr *ha;
                u32 reg, val;
 
                /* set IMF to deny all multicast frames */
@@ -808,13 +824,11 @@ static void bdx_setmulti(struct net_device *ndev)
                /* TBD: sort addreses and write them in ascending order
                 * into RX_MAC_MCST regs. we skip this phase now and accept ALL
                 * multicast frames throu IMF */
-               mclist = ndev->mc_list;
-
                /* accept the rest of addresses throu IMF */
-               for (; mclist; mclist = mclist->next) {
+               netdev_for_each_mc_addr(ha, ndev) {
                        hash = 0;
                        for (i = 0; i < ETH_ALEN; i++)
-                               hash ^= mclist->dmi_addr[i];
+                               hash ^= ha->addr[i];
                        reg = regRX_MCST_HASH0 + ((hash >> 5) << 2);
                        val = READ_REG(priv, reg);
                        val |= (1 << (hash % 32));
@@ -822,7 +836,7 @@ static void bdx_setmulti(struct net_device *ndev)
                }
 
        } else {
-               DBG("only own mac %d\n", ndev->mc_count);
+               DBG("only own mac %d\n", netdev_mc_count(ndev));
                rxf_val |= GMAC_RX_FILTER_AB;
        }
        WRITE_REG(priv, regGMAC_RXF_A, rxf_val);
@@ -833,7 +847,7 @@ static void bdx_setmulti(struct net_device *ndev)
 
 static int bdx_set_mac(struct net_device *ndev, void *p)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        struct sockaddr *addr = p;
 
        ENTER;
@@ -915,7 +929,7 @@ static void bdx_update_stats(struct bdx_priv *priv)
 
 static struct net_device_stats *bdx_get_stats(struct net_device *ndev)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        struct net_device_stats *net_stat = &priv->net_stats;
        return net_stat;
 }
@@ -930,8 +944,7 @@ static void print_rxfd(struct rxf_desc *rxfd);
 
 static void bdx_rxdb_destroy(struct rxdb *db)
 {
-       if (db)
-               vfree(db);
+       vfree(db);
 }
 
 static struct rxdb *bdx_rxdb_create(int nelem)
@@ -991,7 +1004,7 @@ static inline void bdx_rxdb_free_elem(struct rxdb *db, int n)
  * skb for rx. It assumes that Rx is desabled in HW
  * funcs are grouped for better cache usage
  *
- * RxD fifo is smaller then RxF fifo by design. Upon high load, RxD will be
+ * RxD fifo is smaller than RxF fifo by design. Upon high load, RxD will be
  * filled and packets will be dropped by nic without getting into host or
  * cousing interrupt. Anyway, in that condition, host has no chance to proccess
  * all packets, but dropping in nic is cheaper, since it takes 0 cpu cycles
@@ -1002,7 +1015,7 @@ static inline void bdx_rxdb_free_elem(struct rxdb *db, int n)
 static int bdx_rx_init(struct bdx_priv *priv)
 {
        ENTER;
-       BDX_ASSERT(priv == 0);
+
        if (bdx_fifo_init(priv, &priv->rxd_fifo0.m, priv->rxd_size,
                          regRXD_CFG0_0, regRXD_CFG1_0,
                          regRXD_RPTR_0, regRXD_WPTR_0))
@@ -1011,17 +1024,16 @@ static int bdx_rx_init(struct bdx_priv *priv)
                          regRXF_CFG0_0, regRXF_CFG1_0,
                          regRXF_RPTR_0, regRXF_WPTR_0))
                goto err_mem;
-       if (!
-           (priv->rxdb =
-            bdx_rxdb_create(priv->rxf_fifo0.m.memsz /
-                            sizeof(struct rxf_desc))))
+       priv->rxdb = bdx_rxdb_create(priv->rxf_fifo0.m.memsz /
+                                    sizeof(struct rxf_desc));
+       if (!priv->rxdb)
                goto err_mem;
 
        priv->rxf_fifo0.m.pktsz = priv->ndev->mtu + VLAN_ETH_HLEN;
        return 0;
 
 err_mem:
-       ERR("%s: %s: Rx init failed\n", BDX_DRV_NAME, priv->ndev->name);
+       netdev_err(priv->ndev, "Rx init failed\n");
        return -ENOMEM;
 }
 
@@ -1098,8 +1110,9 @@ static void bdx_rx_alloc_skbs(struct bdx_priv *priv, struct rxf_fifo *f)
        ENTER;
        dno = bdx_rxdb_available(db) - 1;
        while (dno > 0) {
-               if (!(skb = dev_alloc_skb(f->m.pktsz + NET_IP_ALIGN))) {
-                       ERR("NO MEM: dev_alloc_skb failed\n");
+               skb = dev_alloc_skb(f->m.pktsz + NET_IP_ALIGN);
+               if (!skb) {
+                       pr_err("NO MEM: dev_alloc_skb failed\n");
                        break;
                }
                skb->dev = priv->ndev;
@@ -1151,7 +1164,7 @@ NETIF_RX_MUX(struct bdx_priv *priv, u32 rxd_val1, u16 rxd_vlan,
                                          GET_RXD_VLAN_ID(rxd_vlan))->name);
                /* NAPI variant of receive functions */
                vlan_hwaccel_receive_skb(skb, priv->vlgrp,
-                                        GET_RXD_VLAN_ID(rxd_vlan));
+                                        GET_RXD_VLAN_TCI(rxd_vlan));
        } else {
                netif_receive_skb(skb);
        }
@@ -1223,7 +1236,6 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
        ENTER;
        max_done = budget;
 
-       priv->ndev->last_rx = jiffies;
        f->m.wptr = READ_REG(priv, f->m.reg_WPTR) & TXF_WPTR_WR_PTR;
 
        size = f->m.wptr - f->m.rptr;
@@ -1291,7 +1303,6 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
                priv->net_stats.rx_bytes += len;
 
                skb_put(skb, len);
-               skb->dev = priv->ndev;
                skb->ip_summed = CHECKSUM_UNNECESSARY;
                skb->protocol = eth_type_trans(skb, priv->ndev);
 
@@ -1321,9 +1332,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget)
 static void print_rxdd(struct rxd_desc *rxdd, u32 rxd_val1, u16 len,
                       u16 rxd_vlan)
 {
-       DBG("ERROR: rxdd bc %d rxfq %d to %d type %d err %d rxp %d "
-           "pkt_id %d vtag %d len %d vlan_id %d cfi %d prio %d "
-           "va_lo %d va_hi %d\n",
+       DBG("ERROR: rxdd bc %d rxfq %d to %d type %d err %d rxp %d pkt_id %d vtag %d len %d vlan_id %d cfi %d prio %d va_lo %d va_hi %d\n",
            GET_RXD_BC(rxd_val1), GET_RXD_RXFQ(rxd_val1), GET_RXD_TO(rxd_val1),
            GET_RXD_TYPE(rxd_val1), GET_RXD_ERR(rxd_val1),
            GET_RXD_RXP(rxd_val1), GET_RXD_PKT_ID(rxd_val1),
@@ -1465,10 +1474,8 @@ static void bdx_tx_db_close(struct txdb *d)
 {
        BDX_ASSERT(d == NULL);
 
-       if (d->start) {
-               vfree(d->start);
-               d->start = NULL;
-       }
+       vfree(d->start);
+       d->start = NULL;
 }
 
 /*************************************************************************
@@ -1501,7 +1508,7 @@ bdx_tx_map_skb(struct bdx_priv *priv, struct sk_buff *skb,
        int nr_frags = skb_shinfo(skb)->nr_frags;
        int i;
 
-       db->wptr->len = skb->len - skb->data_len;
+       db->wptr->len = skb_headlen(skb);
        db->wptr->addr.dma = pci_map_single(priv->pdev, skb->data,
                                            db->wptr->len, PCI_DMA_TODEVICE);
        pbl->len = CPU_CHIP_SWAP32(db->wptr->len);
@@ -1577,7 +1584,7 @@ static int bdx_tx_init(struct bdx_priv *priv)
        return 0;
 
 err_mem:
-       ERR("tehuti: %s: Tx init failed\n", priv->ndev->name);
+       netdev_err(priv->ndev, "Tx init failed\n");
        return -ENOMEM;
 }
 
@@ -1595,7 +1602,7 @@ static inline int bdx_tx_space(struct bdx_priv *priv)
        fsize = f->m.rptr - f->m.wptr;
        if (fsize <= 0)
                fsize = f->m.memsz + fsize;
-       return (fsize);
+       return fsize;
 }
 
 /* bdx_tx_transmit - send packet to NIC
@@ -1608,9 +1615,10 @@ static inline int bdx_tx_space(struct bdx_priv *priv)
  *   the driver. Note: the driver must NOT put the skb in its DMA ring.
  * o NETDEV_TX_LOCKED Locking failed, please retry quickly.
  */
-static int bdx_tx_transmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb,
+                                  struct net_device *ndev)
 {
-       struct bdx_priv *priv = ndev->priv;
+       struct bdx_priv *priv = netdev_priv(ndev);
        struct txd_fifo *f = &priv->txd_fifo0;
        int txd_checksum = 7;   /* full checksum */
        int txd_lgsnd = 0;
@@ -1701,8 +1709,9 @@ static int bdx_tx_transmit(struct sk_buff *skb, struct net_device *ndev)
        WRITE_REG(priv, f->m.reg_WPTR, f->m.wptr & TXF_WPTR_WR_PTR);
 
 #endif
-       ndev->trans_start = jiffies;
-
+#ifdef BDX_LLTX
+       ndev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+#endif
        priv->net_stats.tx_packets++;
        priv->net_stats.tx_bytes += skb->len;
 
@@ -1747,7 +1756,6 @@ static void bdx_tx_cleanup(struct bdx_priv *priv)
                tx_level -= db->rptr->len;      /* '-' koz len is negative */
 
                /* now should come skb pointer - free it */
-               BDX_ASSERT(db->rptr->addr.skb == 0);
                dev_kfree_skb_irq(db->rptr->addr.skb);
                bdx_tx_db_inc_rptr(db);
        }
@@ -1769,9 +1777,9 @@ static void bdx_tx_cleanup(struct bdx_priv *priv)
        }
 #endif
 
-       if (unlikely(netif_queue_stopped(priv->ndev)
-                    && netif_carrier_ok(priv->ndev)
-                    && (priv->tx_level >= BDX_MIN_TX_LEVEL))) {
+       if (unlikely(netif_queue_stopped(priv->ndev) &&
+                    netif_carrier_ok(priv->ndev) &&
+                    (priv->tx_level >= BDX_MIN_TX_LEVEL))) {
                DBG("%s: %s: TX Q WAKE level %d\n",
                    BDX_DRV_NAME, priv->ndev->name, priv->tx_level);
                netif_wake_queue(priv->ndev);
@@ -1815,7 +1823,7 @@ static void bdx_tx_free(struct bdx_priv *priv)
  *
  * Pushes desc to TxD fifo and overlaps it if needed.
  * NOTE: this func does not check for available space. this is responsibility
- *    of the caller. Neither does it check that data size is smaller then
+ *    of the caller. Neither does it check that data size is smaller than
  *    fifo size.
  */
 static void bdx_tx_push_desc(struct bdx_priv *priv, void *data, int size)
@@ -1842,7 +1850,7 @@ static void bdx_tx_push_desc(struct bdx_priv *priv, void *data, int size)
  * @data - desc's data
  * @size - desc's size
  *
- * NOTE: this func does check for available space and, if neccessary, waits for
+ * NOTE: this func does check for available space and, if necessary, waits for
  *   NIC to read existing data before writing new one.
  */
 static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size)
@@ -1863,7 +1871,7 @@ static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size)
                        udelay(50);     /* give hw a chance to clean fifo */
                        continue;
                }
-               avail = MIN(avail, size);
+               avail = min(avail, size);
                DBG("about to push  %d bytes starting %p size %d\n", avail,
                    data, size);
                bdx_tx_push_desc(priv, data, avail);
@@ -1873,6 +1881,21 @@ static void bdx_tx_push_desc_safe(struct bdx_priv *priv, void *data, int size)
        RET();
 }
 
+static const struct net_device_ops bdx_netdev_ops = {
+       .ndo_open               = bdx_open,
+       .ndo_stop               = bdx_close,
+       .ndo_start_xmit         = bdx_tx_transmit,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_do_ioctl           = bdx_ioctl,
+       .ndo_set_multicast_list = bdx_setmulti,
+       .ndo_get_stats          = bdx_get_stats,
+       .ndo_change_mtu         = bdx_change_mtu,
+       .ndo_set_mac_address    = bdx_set_mac,
+       .ndo_vlan_rx_register   = bdx_vlan_rx_register,
+       .ndo_vlan_rx_add_vid    = bdx_vlan_rx_add_vid,
+       .ndo_vlan_rx_kill_vid   = bdx_vlan_rx_kill_vid,
+};
+
 /**
  * bdx_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -1907,23 +1930,24 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                RET(-ENOMEM);
 
     /************** pci *****************/
-       if ((err = pci_enable_device(pdev)))    /* it trigers interrupt, dunno why. */
-               RET(err);                       /* it's not a problem though */
+       err = pci_enable_device(pdev);
+       if (err)                        /* it triggers interrupt, dunno why. */
+               goto err_pci;           /* it's not a problem though */
 
-       if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
-           !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
+       if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) &&
+           !(err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))) {
                pci_using_dac = 1;
        } else {
-               if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) ||
-                   (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
-                       printk(KERN_ERR "tehuti: No usable DMA configuration"
-                                       ", aborting\n");
+               if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) ||
+                   (err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))) {
+                       pr_err("No usable DMA configuration, aborting\n");
                        goto err_dma;
                }
                pci_using_dac = 0;
        }
 
-       if ((err = pci_request_regions(pdev, BDX_DRV_NAME)))
+       err = pci_request_regions(pdev, BDX_DRV_NAME);
+       if (err)
                goto err_dma;
 
        pci_set_master(pdev);
@@ -1931,25 +1955,26 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        pciaddr = pci_resource_start(pdev, 0);
        if (!pciaddr) {
                err = -EIO;
-               ERR("tehuti: no MMIO resource\n");
+               pr_err("no MMIO resource\n");
                goto err_out_res;
        }
-       if ((regionSize = pci_resource_len(pdev, 0)) < BDX_REGS_SIZE) {
+       regionSize = pci_resource_len(pdev, 0);
+       if (regionSize < BDX_REGS_SIZE) {
                err = -EIO;
-               ERR("tehuti: MMIO resource (%x) too small\n", regionSize);
+               pr_err("MMIO resource (%x) too small\n", regionSize);
                goto err_out_res;
        }
 
        nic->regs = ioremap(pciaddr, regionSize);
        if (!nic->regs) {
                err = -EIO;
-               ERR("tehuti: ioremap failed\n");
+               pr_err("ioremap failed\n");
                goto err_out_res;
        }
 
        if (pdev->irq < 2) {
                err = -EIO;
-               ERR("tehuti: invalid irq (%d)\n", pdev->irq);
+               pr_err("invalid irq (%d)\n", pdev->irq);
                goto err_out_iomap;
        }
        pci_set_drvdata(pdev, nic);
@@ -1966,8 +1991,9 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        nic->irq_type = IRQ_INTX;
 #ifdef BDX_MSI
        if ((readl(nic->regs + FPGA_VER) & 0xFFF) >= 378) {
-               if ((err = pci_enable_msi(pdev)))
-                       ERR("Tehuti: Can't eneble msi. error is %d\n", err);
+               err = pci_enable_msi(pdev);
+               if (err)
+                       pr_err("Can't eneble msi. error is %d\n", err);
                else
                        nic->irq_type = IRQ_MSI;
        } else
@@ -1976,24 +2002,15 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
     /************** netdev **************/
        for (port = 0; port < nic->port_num; port++) {
-               if (!(ndev = alloc_etherdev(sizeof(struct bdx_priv)))) {
+               ndev = alloc_etherdev(sizeof(struct bdx_priv));
+               if (!ndev) {
                        err = -ENOMEM;
-                       printk(KERN_ERR "tehuti: alloc_etherdev failed\n");
+                       pr_err("alloc_etherdev failed\n");
                        goto err_out_iomap;
                }
 
-               ndev->open = bdx_open;
-               ndev->stop = bdx_close;
-               ndev->hard_start_xmit = bdx_tx_transmit;
-               ndev->do_ioctl = bdx_ioctl;
-               ndev->set_multicast_list = bdx_setmulti;
-               ndev->get_stats = bdx_get_stats;
-               ndev->change_mtu = bdx_change_mtu;
-               ndev->set_mac_address = bdx_set_mac;
+               ndev->netdev_ops = &bdx_netdev_ops;
                ndev->tx_queue_len = BDX_NDEV_TXQ_LEN;
-               ndev->vlan_rx_register = bdx_vlan_rx_register;
-               ndev->vlan_rx_add_vid = bdx_vlan_rx_add_vid;
-               ndev->vlan_rx_kill_vid = bdx_vlan_rx_kill_vid;
 
                bdx_ethtool_ops(ndev);  /* ethtool interface */
 
@@ -2014,7 +2031,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        ndev->features |= NETIF_F_HIGHDMA;
 
        /************** priv ****************/
-               priv = nic->priv[port] = ndev->priv;
+               priv = nic->priv[port] = netdev_priv(ndev);
 
                memset(priv, 0, sizeof(struct bdx_priv));
                priv->pBdxRegs = nic->regs + port * 0x8000;
@@ -2055,12 +2072,13 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
                /*bdx_hw_reset(priv); */
                if (bdx_read_mac(priv)) {
-                       printk(KERN_ERR "tehuti: load MAC address failed\n");
+                       pr_err("load MAC address failed\n");
                        goto err_out_iomap;
                }
                SET_NETDEV_DEV(ndev, &pdev->dev);
-               if ((err = register_netdev(ndev))) {
-                       printk(KERN_ERR "tehuti: register_netdev failed\n");
+               err = register_netdev(ndev);
+               if (err) {
+                       pr_err("register_netdev failed\n");
                        goto err_out_free;
                }
                netif_carrier_off(ndev);
@@ -2078,18 +2096,13 @@ err_out_res:
        pci_release_regions(pdev);
 err_dma:
        pci_disable_device(pdev);
+err_pci:
        vfree(nic);
 
        RET(err);
 }
 
 /****************** Ethtool interface *********************/
-/* get strings for tests */
-static const char
- bdx_test_names[][ETH_GSTRING_LEN] = {
-       "No tests defined"
-};
-
 /* get strings for statistics counters */
 static const char
  bdx_stat_names[][ETH_GSTRING_LEN] = {
@@ -2136,7 +2149,7 @@ static int bdx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
        u32 rdintcm;
        u32 tdintcm;
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
        rdintcm = priv->rdintcm;
        tdintcm = priv->tdintcm;
@@ -2167,16 +2180,15 @@ static int bdx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 static void
 bdx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
 {
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
-       strncat(drvinfo->driver, BDX_DRV_NAME, sizeof(drvinfo->driver));
-       strncat(drvinfo->version, BDX_DRV_VERSION, sizeof(drvinfo->version));
-       strncat(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
-       strncat(drvinfo->bus_info, pci_name(priv->pdev),
+       strlcat(drvinfo->driver, BDX_DRV_NAME, sizeof(drvinfo->driver));
+       strlcat(drvinfo->version, BDX_DRV_VERSION, sizeof(drvinfo->version));
+       strlcat(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+       strlcat(drvinfo->bus_info, pci_name(priv->pdev),
                sizeof(drvinfo->bus_info));
 
-       drvinfo->n_stats = ((priv->stats_flag) ?
-                           (sizeof(bdx_stat_names) / ETH_GSTRING_LEN) : 0);
+       drvinfo->n_stats = ((priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names) : 0);
        drvinfo->testinfo_len = 0;
        drvinfo->regdump_len = 0;
        drvinfo->eedump_len = 0;
@@ -2210,7 +2222,7 @@ bdx_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecoal)
 {
        u32 rdintcm;
        u32 tdintcm;
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
        rdintcm = priv->rdintcm;
        tdintcm = priv->tdintcm;
@@ -2239,7 +2251,7 @@ bdx_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecoal)
 {
        u32 rdintcm;
        u32 tdintcm;
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
        int rx_coal;
        int tx_coal;
        int rx_max_coal;
@@ -2259,8 +2271,8 @@ bdx_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecoal)
            (((tx_max_coal * BDX_TXF_DESC_SZ) + PCK_TH_MULT - 1)
             / PCK_TH_MULT);
 
-       if ((rx_coal > 0x7FFF) || (tx_coal > 0x7FFF)
-           || (rx_max_coal > 0xF) || (tx_max_coal > 0xF))
+       if ((rx_coal > 0x7FFF) || (tx_coal > 0x7FFF) ||
+           (rx_max_coal > 0xF) || (tx_max_coal > 0xF))
                return -EINVAL;
 
        rdintcm = INT_REG_VAL(rx_coal, GET_INT_COAL_RC(priv->rdintcm),
@@ -2280,13 +2292,13 @@ bdx_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ecoal)
 /* Convert RX fifo size to number of pending packets */
 static inline int bdx_rx_fifo_size_to_packets(int rx_size)
 {
-       return ((FIFO_SIZE * (1 << rx_size)) / sizeof(struct rxf_desc));
+       return (FIFO_SIZE * (1 << rx_size)) / sizeof(struct rxf_desc);
 }
 
 /* Convert TX fifo size to number of pending packets */
 static inline int bdx_tx_fifo_size_to_packets(int tx_size)
 {
-       return ((FIFO_SIZE * (1 << tx_size)) / BDX_TXF_DESC_SZ);
+       return (FIFO_SIZE * (1 << tx_size)) / BDX_TXF_DESC_SZ;
 }
 
 /*
@@ -2297,7 +2309,7 @@ static inline int bdx_tx_fifo_size_to_packets(int tx_size)
 static void
 bdx_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
 {
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
        /*max_pending - the maximum-sized FIFO we allow */
        ring->rx_max_pending = bdx_rx_fifo_size_to_packets(3);
@@ -2314,7 +2326,7 @@ bdx_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
 static int
 bdx_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
 {
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
        int rx_size = 0;
        int tx_size = 0;
 
@@ -2333,8 +2345,8 @@ bdx_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
                tx_size = 3;
 
        /*Is there anything to do? */
-       if ((rx_size == priv->rxf_size)
-           && (tx_size == priv->txd_size))
+       if ((rx_size == priv->rxf_size) &&
+           (tx_size == priv->txd_size))
                return 0;
 
        priv->rxf_size = rx_size;
@@ -2360,9 +2372,6 @@ bdx_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
 static void bdx_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 {
        switch (stringset) {
-       case ETH_SS_TEST:
-               memcpy(data, *bdx_test_names, sizeof(bdx_test_names));
-               break;
        case ETH_SS_STATS:
                memcpy(data, *bdx_stat_names, sizeof(bdx_stat_names));
                break;
@@ -2370,16 +2379,21 @@ static void bdx_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 }
 
 /*
- * bdx_get_stats_count - return number of 64bit statistics counters
+ * bdx_get_sset_count - return number of statistics or tests
  * @netdev
  */
-static int bdx_get_stats_count(struct net_device *netdev)
+static int bdx_get_sset_count(struct net_device *netdev, int stringset)
 {
-       struct bdx_priv *priv = netdev->priv;
-       BDX_ASSERT(sizeof(bdx_stat_names) / ETH_GSTRING_LEN
-                  != sizeof(struct bdx_stats) / sizeof(u64));
-       return ((priv->stats_flag) ? (sizeof(bdx_stat_names) / ETH_GSTRING_LEN)
-               : 0);
+       struct bdx_priv *priv = netdev_priv(netdev);
+
+       switch (stringset) {
+       case ETH_SS_STATS:
+               BDX_ASSERT(ARRAY_SIZE(bdx_stat_names)
+                          != sizeof(struct bdx_stats) / sizeof(u64));
+               return (priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names)  : 0;
+       }
+
+       return -EINVAL;
 }
 
 /*
@@ -2391,7 +2405,7 @@ static int bdx_get_stats_count(struct net_device *netdev)
 static void bdx_get_ethtool_stats(struct net_device *netdev,
                                  struct ethtool_stats *stats, u64 *data)
 {
-       struct bdx_priv *priv = netdev->priv;
+       struct bdx_priv *priv = netdev_priv(netdev);
 
        if (priv->stats_flag) {
 
@@ -2409,7 +2423,7 @@ static void bdx_get_ethtool_stats(struct net_device *netdev,
  */
 static void bdx_ethtool_ops(struct net_device *netdev)
 {
-       static struct ethtool_ops bdx_ethtool_ops = {
+       static const struct ethtool_ops bdx_ethtool_ops = {
                .get_settings = bdx_get_settings,
                .get_drvinfo = bdx_get_drvinfo,
                .get_link = ethtool_op_get_link,
@@ -2422,7 +2436,7 @@ static void bdx_ethtool_ops(struct net_device *netdev)
                .get_sg = ethtool_op_get_sg,
                .get_tso = ethtool_op_get_tso,
                .get_strings = bdx_get_strings,
-               .get_stats_count = bdx_get_stats_count,
+               .get_sset_count = bdx_get_sset_count,
                .get_ethtool_stats = bdx_get_ethtool_stats,
        };
 
@@ -2477,16 +2491,13 @@ static struct pci_driver bdx_pci_driver = {
  */
 static void __init print_driver_id(void)
 {
-       printk(KERN_INFO "%s: %s, %s\n", BDX_DRV_NAME, BDX_DRV_DESC,
-              BDX_DRV_VERSION);
-       printk(KERN_INFO "%s: Options: hw_csum %s\n", BDX_DRV_NAME,
-              BDX_MSI_STRING);
+       pr_info("%s, %s\n", BDX_DRV_DESC, BDX_DRV_VERSION);
+       pr_info("Options: hw_csum %s\n", BDX_MSI_STRING);
 }
 
 static int __init bdx_module_init(void)
 {
        ENTER;
-       bdx_firmware_endianess();
        init_txd_sizes();
        print_driver_id();
        RET(pci_register_driver(&bdx_pci_driver));
@@ -2506,3 +2517,4 @@ module_exit(bdx_module_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(BDX_DRV_DESC);
+MODULE_FIRMWARE("tehuti/firmware.bin");