net: wireless: sd8797: Marvell sd8797 Wi-Fi driver
[linux-2.6.git] / drivers / net / 8139cp.c
index a09e6ce..cc4c210 100644 (file)
@@ -60,6 +60,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-/* VLAN tagging feature enable/disable */
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define CP_VLAN_TAG_USED 1
-#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \
-       do { (tx_desc)->opts2 = cpu_to_le32(vlan_tag_value); } while (0)
-#else
-#define CP_VLAN_TAG_USED 0
-#define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \
-       do { (tx_desc)->opts2 = 0; } while (0)
-#endif
-
 /* These identify the driver base version and may not be removed. */
 static char version[] =
 DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
@@ -322,7 +312,7 @@ struct cp_dma_stats {
        __le32                  rx_ok_mcast;
        __le16                  tx_abort;
        __le16                  tx_underrun;
-} __attribute__((packed));
+} __packed;
 
 struct cp_extra_stats {
        unsigned long           rx_frags;
@@ -355,9 +345,6 @@ struct cp_private {
        unsigned                rx_buf_sz;
        unsigned                wol_enabled : 1; /* Is Wake-on-LAN enabled? */
 
-#if CP_VLAN_TAG_USED
-       struct vlan_group       *vlgrp;
-#endif
        dma_addr_t              ring_dma;
 
        struct mii_if_info      mii_if;
@@ -422,24 +409,6 @@ static struct {
 };
 
 
-#if CP_VLAN_TAG_USED
-static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
-       struct cp_private *cp = netdev_priv(dev);
-       unsigned long flags;
-
-       spin_lock_irqsave(&cp->lock, flags);
-       cp->vlgrp = grp;
-       if (grp)
-               cp->cpcmd |= RxVlanOn;
-       else
-               cp->cpcmd &= ~RxVlanOn;
-
-       cpw16(CpCmd, cp->cpcmd);
-       spin_unlock_irqrestore(&cp->lock, flags);
-}
-#endif /* CP_VLAN_TAG_USED */
-
 static inline void cp_set_rxbufsize (struct cp_private *cp)
 {
        unsigned int mtu = cp->dev->mtu;
@@ -454,18 +423,17 @@ static inline void cp_set_rxbufsize (struct cp_private *cp)
 static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
                              struct cp_desc *desc)
 {
+       u32 opts2 = le32_to_cpu(desc->opts2);
+
        skb->protocol = eth_type_trans (skb, cp->dev);
 
        cp->dev->stats.rx_packets++;
        cp->dev->stats.rx_bytes += skb->len;
 
-#if CP_VLAN_TAG_USED
-       if (cp->vlgrp && (desc->opts2 & cpu_to_le32(RxVlanTagged))) {
-               vlan_hwaccel_receive_skb(skb, cp->vlgrp,
-                                        swab16(le32_to_cpu(desc->opts2) & 0xffff));
-       } else
-#endif
-               netif_receive_skb(skb);
+       if (opts2 & RxVlanTagged)
+               __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff));
+
+       napi_gro_receive(&cp->napi, skb);
 }
 
 static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
@@ -490,13 +458,11 @@ static inline unsigned int cp_rx_csum_ok (u32 status)
 {
        unsigned int protocol = (status >> 16) & 0x3;
 
-       if (likely((protocol == RxProtoTCP) && (!(status & TCPFail))))
-               return 1;
-       else if ((protocol == RxProtoUDP) && (!(status & UDPFail)))
+       if (((protocol == RxProtoTCP) && !(status & TCPFail)) ||
+           ((protocol == RxProtoUDP) && !(status & UDPFail)))
                return 1;
-       else if ((protocol == RxProtoIP) && (!(status & IPFail)))
-               return 1;
-       return 0;
+       else
+               return 0;
 }
 
 static int cp_rx_poll(struct napi_struct *napi, int budget)
@@ -561,7 +527,7 @@ rx_status_loop:
                if (cp_rx_csum_ok(status))
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                else
-                       skb->ip_summed = CHECKSUM_NONE;
+                       skb_checksum_none_assert(skb);
 
                skb_put(skb, len);
 
@@ -598,8 +564,8 @@ rx_next:
                        goto rx_status_loop;
 
                spin_lock_irqsave(&cp->lock, flags);
-               cpw16_f(IntrMask, cp_intr_mask);
                __napi_complete(napi);
+               cpw16_f(IntrMask, cp_intr_mask);
                spin_unlock_irqrestore(&cp->lock, flags);
        }
 
@@ -731,6 +697,12 @@ static void cp_tx (struct cp_private *cp)
                netif_wake_queue(cp->dev);
 }
 
+static inline u32 cp_tx_vlan_tag(struct sk_buff *skb)
+{
+       return vlan_tx_tag_present(skb) ?
+               TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
+}
+
 static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
                                        struct net_device *dev)
 {
@@ -738,9 +710,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
        unsigned entry;
        u32 eor, flags;
        unsigned long intr_flags;
-#if CP_VLAN_TAG_USED
-       u32 vlan_tag = 0;
-#endif
+       __le32 opts2;
        int mss = 0;
 
        spin_lock_irqsave(&cp->lock, intr_flags);
@@ -753,15 +723,11 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
                return NETDEV_TX_BUSY;
        }
 
-#if CP_VLAN_TAG_USED
-       if (cp->vlgrp && vlan_tx_tag_present(skb))
-               vlan_tag = TxVlanTag | swab16(vlan_tx_tag_get(skb));
-#endif
-
        entry = cp->tx_head;
        eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
-       if (dev->features & NETIF_F_TSO)
-               mss = skb_shinfo(skb)->gso_size;
+       mss = skb_shinfo(skb)->gso_size;
+
+       opts2 = cpu_to_le32(cp_tx_vlan_tag(skb));
 
        if (skb_shinfo(skb)->nr_frags == 0) {
                struct cp_desc *txd = &cp->tx_ring[entry];
@@ -770,7 +736,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
 
                len = skb->len;
                mapping = dma_map_single(&cp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE);
-               CP_VLAN_TX_TAG(txd, vlan_tag);
+               txd->opts2 = opts2;
                txd->addr = cpu_to_le64(mapping);
                wmb();
 
@@ -841,7 +807,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
                                ctrl |= LastFrag;
 
                        txd = &cp->tx_ring[entry];
-                       CP_VLAN_TX_TAG(txd, vlan_tag);
+                       txd->opts2 = opts2;
                        txd->addr = cpu_to_le64(mapping);
                        wmb();
 
@@ -853,7 +819,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
                }
 
                txd = &cp->tx_ring[first_entry];
-               CP_VLAN_TX_TAG(txd, vlan_tag);
+               txd->opts2 = opts2;
                txd->addr = cpu_to_le64(first_mapping);
                wmb();
 
@@ -882,7 +848,6 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
        spin_unlock_irqrestore(&cp->lock, intr_flags);
 
        cpw8(TxPoll, NormalTxPoll);
-       dev->trans_start = jiffies;
 
        return NETDEV_TX_OK;
 }
@@ -910,11 +875,11 @@ static void __cp_set_rx_mode (struct net_device *dev)
                rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
                mc_filter[1] = mc_filter[0] = 0xffffffff;
        } else {
-               struct dev_mc_list *mclist;
+               struct netdev_hw_addr *ha;
                rx_mode = AcceptBroadcast | AcceptMyPhys;
                mc_filter[1] = mc_filter[0] = 0;
-               netdev_for_each_mc_addr(mclist, dev) {
-                       int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+               netdev_for_each_mc_addr(ha, dev) {
+                       int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
 
                        mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
                        rx_mode |= AcceptMulticast;
@@ -1225,8 +1190,6 @@ static void cp_tx_timeout(struct net_device *dev)
        netif_wake_queue(dev);
 
        spin_unlock_irqrestore(&cp->lock, flags);
-
-       return;
 }
 
 #ifdef BROKEN
@@ -1421,32 +1384,28 @@ static void cp_set_msglevel(struct net_device *dev, u32 value)
        cp->msg_enable = value;
 }
 
-static u32 cp_get_rx_csum(struct net_device *dev)
+static int cp_set_features(struct net_device *dev, u32 features)
 {
        struct cp_private *cp = netdev_priv(dev);
-       return (cpr16(CpCmd) & RxChkSum) ? 1 : 0;
-}
+       unsigned long flags;
 
-static int cp_set_rx_csum(struct net_device *dev, u32 data)
-{
-       struct cp_private *cp = netdev_priv(dev);
-       u16 cmd = cp->cpcmd, newcmd;
+       if (!((dev->features ^ features) & NETIF_F_RXCSUM))
+               return 0;
 
-       newcmd = cmd;
+       spin_lock_irqsave(&cp->lock, flags);
 
-       if (data)
-               newcmd |= RxChkSum;
+       if (features & NETIF_F_RXCSUM)
+               cp->cpcmd |= RxChkSum;
        else
-               newcmd &= ~RxChkSum;
+               cp->cpcmd &= ~RxChkSum;
 
-       if (newcmd != cmd) {
-               unsigned long flags;
+       if (features & NETIF_F_HW_VLAN_RX)
+               cp->cpcmd |= RxVlanOn;
+       else
+               cp->cpcmd &= ~RxVlanOn;
 
-               spin_lock_irqsave(&cp->lock, flags);
-               cp->cpcmd = newcmd;
-               cpw16_f(CpCmd, newcmd);
-               spin_unlock_irqrestore(&cp->lock, flags);
-       }
+       cpw16_f(CpCmd, cp->cpcmd);
+       spin_unlock_irqrestore(&cp->lock, flags);
 
        return 0;
 }
@@ -1559,11 +1518,6 @@ static const struct ethtool_ops cp_ethtool_ops = {
        .get_link               = ethtool_op_get_link,
        .get_msglevel           = cp_get_msglevel,
        .set_msglevel           = cp_set_msglevel,
-       .get_rx_csum            = cp_get_rx_csum,
-       .set_rx_csum            = cp_set_rx_csum,
-       .set_tx_csum            = ethtool_op_set_tx_csum, /* local! */
-       .set_sg                 = ethtool_op_set_sg,
-       .set_tso                = ethtool_op_set_tso,
        .get_regs               = cp_get_regs,
        .get_wol                = cp_get_wol,
        .set_wol                = cp_set_wol,
@@ -1836,9 +1790,7 @@ static const struct net_device_ops cp_netdev_ops = {
        .ndo_do_ioctl           = cp_ioctl,
        .ndo_start_xmit         = cp_start_xmit,
        .ndo_tx_timeout         = cp_tx_timeout,
-#if CP_VLAN_TAG_USED
-       .ndo_vlan_rx_register   = cp_vlan_rx_register,
-#endif
+       .ndo_set_features       = cp_set_features,
 #ifdef BROKEN
        .ndo_change_mtu         = cp_change_mtu,
 #endif
@@ -1939,6 +1891,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        cp->cpcmd = (pci_using_dac ? PCIDAC : 0) |
                    PCIMulRW | RxChkSum | CpRxOn | CpTxOn;
 
+       dev->features |= NETIF_F_RXCSUM;
+       dev->hw_features |= NETIF_F_RXCSUM;
+
        regs = ioremap(pciaddr, CP_REGS_SIZE);
        if (!regs) {
                rc = -EIO;
@@ -1964,16 +1919,16 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->ethtool_ops = &cp_ethtool_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
 
-#if CP_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-#endif
 
        if (pci_using_dac)
                dev->features |= NETIF_F_HIGHDMA;
 
-#if 0 /* disabled by default until verified */
-       dev->features |= NETIF_F_TSO;
-#endif
+       /* disabled by default until verified */
+       dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+               NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+       dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+               NETIF_F_HIGHDMA;
 
        dev->irq = pdev->irq;