Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / drivers / net / benet / be_main.c
index 2373d39..c411bb1 100644 (file)
@@ -44,7 +44,7 @@ static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = {
 };
 MODULE_DEVICE_TABLE(pci, be_dev_ids);
 /* UE Status Low CSR */
-static char *ue_status_low_desc[] = {
+static const char * const ue_status_low_desc[] = {
        "CEV",
        "CTX",
        "DBUF",
@@ -79,7 +79,7 @@ static char *ue_status_low_desc[] = {
        "MPU_INTPEND"
 };
 /* UE Status High CSR */
-static char *ue_status_hi_desc[] = {
+static const char * const ue_status_hi_desc[] = {
        "LPCMEMHOST",
        "MGMT_MAC",
        "PCS0ONLINE",
@@ -103,7 +103,7 @@ static char *ue_status_hi_desc[] = {
        "HOST7",
        "HOST8",
        "HOST9",
-       "NETC"
+       "NETC",
        "Unknown",
        "Unknown",
        "Unknown",
@@ -431,6 +431,7 @@ void netdev_stats_update(struct be_adapter *adapter)
                pkts += rx_stats(rxo)->rx_pkts;
                bytes += rx_stats(rxo)->rx_bytes;
                mcast += rx_stats(rxo)->rx_mcast_pkts;
+               drops += rx_stats(rxo)->rx_dropped;
                /*  no space in linux buffers: best possible approximation */
                if (adapter->generation == BE_GEN3) {
                        if (!(lancer_chip(adapter))) {
@@ -653,7 +654,7 @@ static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
                        AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
        }
 
-       if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
+       if (vlan_tx_tag_present(skb)) {
                AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
                vlan_tag = vlan_tx_tag_get(skb);
                vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
@@ -846,13 +847,6 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
        return status;
 }
 
-static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp)
-{
-       struct be_adapter *adapter = netdev_priv(netdev);
-
-       adapter->vlan_grp = grp;
-}
-
 static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
@@ -871,7 +865,6 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
        struct be_adapter *adapter = netdev_priv(netdev);
 
        adapter->vlans_added--;
-       vlan_group_set_device(adapter->vlan_grp, vid, NULL);
 
        if (!be_physfn(adapter))
                return;
@@ -1181,8 +1174,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 
        skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN);
        if (unlikely(!skb)) {
-               if (net_ratelimit())
-                       dev_warn(&adapter->pdev->dev, "skb alloc failed\n");
+               rxo->stats.rx_dropped++;
                be_rx_compl_discard(adapter, rxo, rxcp);
                return;
        }
@@ -1200,16 +1192,10 @@ static void be_rx_compl_process(struct be_adapter *adapter,
                skb->rxhash = rxcp->rss_hash;
 
 
-       if (unlikely(rxcp->vlanf)) {
-               if (!adapter->vlan_grp || adapter->vlans_added == 0) {
-                       kfree_skb(skb);
-                       return;
-               }
-               vlan_hwaccel_receive_skb(skb, adapter->vlan_grp,
-                                       rxcp->vlan_tag);
-       } else {
-               netif_receive_skb(skb);
-       }
+       if (unlikely(rxcp->vlanf))
+               __vlan_hwaccel_put_tag(skb, rxcp->vlan_tag);
+
+       netif_receive_skb(skb);
 }
 
 /* Process the RX completion indicated by rxcp when GRO is enabled */
@@ -1263,11 +1249,10 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
        if (adapter->netdev->features & NETIF_F_RXHASH)
                skb->rxhash = rxcp->rss_hash;
 
-       if (likely(!rxcp->vlanf))
-               napi_gro_frags(&eq_obj->napi);
-       else
-               vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp,
-                               rxcp->vlan_tag);
+       if (unlikely(rxcp->vlanf))
+               __vlan_hwaccel_put_tag(skb, rxcp->vlan_tag);
+
+       napi_gro_frags(&eq_obj->napi);
 }
 
 static void be_parse_rx_compl_v1(struct be_adapter *adapter,
@@ -1572,6 +1557,7 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo)
                memset(page_info, 0, sizeof(*page_info));
        }
        BUG_ON(atomic_read(&rxq->used));
+       rxq->tail = rxq->head = 0;
 }
 
 static void be_tx_compl_clean(struct be_adapter *adapter,
@@ -1752,29 +1738,16 @@ static void be_rx_queues_destroy(struct be_adapter *adapter)
        int i;
 
        for_all_rx_queues(adapter, rxo, i) {
-               q = &rxo->q;
-               if (q->created) {
-                       be_cmd_q_destroy(adapter, q, QTYPE_RXQ);
-                       /* After the rxq is invalidated, wait for a grace time
-                        * of 1ms for all dma to end and the flush compl to
-                        * arrive
-                        */
-                       mdelay(1);
-                       be_rx_q_clean(adapter, rxo);
-               }
-               be_queue_free(adapter, q);
+               be_queue_free(adapter, &rxo->q);
 
                q = &rxo->cq;
                if (q->created)
                        be_cmd_q_destroy(adapter, q, QTYPE_CQ);
                be_queue_free(adapter, q);
 
-               /* Clear any residual events */
                q = &rxo->rx_eq.q;
-               if (q->created) {
-                       be_eq_clean(adapter, &rxo->rx_eq);
+               if (q->created)
                        be_cmd_q_destroy(adapter, q, QTYPE_EQ);
-               }
                be_queue_free(adapter, q);
        }
 }
@@ -1833,30 +1806,14 @@ static int be_rx_queues_create(struct be_adapter *adapter)
                rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3);
                if (rc)
                        goto err;
-               /* Rx Q */
+
+               /* Rx Q - will be created in be_open() */
                q = &rxo->q;
                rc = be_queue_alloc(adapter, q, RX_Q_LEN,
                                sizeof(struct be_eth_rx_d));
                if (rc)
                        goto err;
 
-               rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size,
-                       BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle,
-                       (i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id);
-               if (rc)
-                       goto err;
-       }
-
-       if (be_multi_rxq(adapter)) {
-               u8 rsstable[MAX_RSS_QS];
-
-               for_all_rss_queues(adapter, rxo, i)
-                       rsstable[i] = rxo->rss_id;
-
-               rc = be_cmd_rss_config(adapter, rsstable,
-                       adapter->num_rx_qs - 1);
-               if (rc)
-                       goto err;
        }
 
        return 0;
@@ -2302,6 +2259,31 @@ done:
        adapter->isr_registered = false;
 }
 
+static void be_rx_queues_clear(struct be_adapter *adapter)
+{
+       struct be_queue_info *q;
+       struct be_rx_obj *rxo;
+       int i;
+
+       for_all_rx_queues(adapter, rxo, i) {
+               q = &rxo->q;
+               if (q->created) {
+                       be_cmd_rxq_destroy(adapter, q);
+                       /* After the rxq is invalidated, wait for a grace time
+                        * of 1ms for all dma to end and the flush compl to
+                        * arrive
+                        */
+                       mdelay(1);
+                       be_rx_q_clean(adapter, rxo);
+               }
+
+               /* Clear any residual events */
+               q = &rxo->rx_eq.q;
+               if (q->created)
+                       be_eq_clean(adapter, &rxo->rx_eq);
+       }
+}
+
 static int be_close(struct net_device *netdev)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
@@ -2350,6 +2332,40 @@ static int be_close(struct net_device *netdev)
        for_all_tx_queues(adapter, txo, i)
                be_tx_compl_clean(adapter, txo);
 
+       be_rx_queues_clear(adapter);
+       return 0;
+}
+
+static int be_rx_queues_setup(struct be_adapter *adapter)
+{
+       struct be_rx_obj *rxo;
+       int rc, i;
+       u8 rsstable[MAX_RSS_QS];
+
+       for_all_rx_queues(adapter, rxo, i) {
+               rc = be_cmd_rxq_create(adapter, &rxo->q, rxo->cq.id,
+                       rx_frag_size, BE_MAX_JUMBO_FRAME_SIZE,
+                       adapter->if_handle,
+                       (i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id);
+               if (rc)
+                       return rc;
+       }
+
+       if (be_multi_rxq(adapter)) {
+               for_all_rss_queues(adapter, rxo, i)
+                       rsstable[i] = rxo->rss_id;
+
+               rc = be_cmd_rss_config(adapter, rsstable,
+                       adapter->num_rx_qs - 1);
+               if (rc)
+                       return rc;
+       }
+
+       /* First time posting */
+       for_all_rx_queues(adapter, rxo, i) {
+               be_post_rx_frags(rxo, GFP_KERNEL);
+               napi_enable(&rxo->rx_eq.napi);
+       }
        return 0;
 }
 
@@ -2363,10 +2379,10 @@ static int be_open(struct net_device *netdev)
        u8 mac_speed;
        u16 link_speed;
 
-       for_all_rx_queues(adapter, rxo, i) {
-               be_post_rx_frags(rxo, GFP_KERNEL);
-               napi_enable(&rxo->rx_eq.napi);
-       }
+       status = be_rx_queues_setup(adapter);
+       if (status)
+               goto err;
+
        napi_enable(&tx_eq->napi);
 
        be_irq_register(adapter);
@@ -2495,6 +2511,8 @@ static int be_setup(struct be_adapter *adapter)
        int status;
        u8 mac[ETH_ALEN];
 
+       be_cmd_req_native_mode(adapter);
+
        cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED |
                                BE_IF_FLAGS_BROADCAST |
                                BE_IF_FLAGS_MULTICAST;
@@ -2554,6 +2572,9 @@ static int be_setup(struct be_adapter *adapter)
        if (status != 0)
                goto tx_qs_destroy;
 
+       /* Allow all priorities by default. A GRP5 evt may modify this */
+       adapter->vlan_prio_bmap = 0xff;
+
        status = be_mcc_queues_create(adapter);
        if (status != 0)
                goto rx_qs_destroy;
@@ -2599,6 +2620,8 @@ static int be_clear(struct be_adapter *adapter)
 
        be_cmd_if_destroy(adapter, adapter->if_handle,  0);
 
+       adapter->be3_native = 0;
+
        /* tell fw we're done with firing cmds */
        be_cmd_fw_clean(adapter);
        return 0;
@@ -2916,7 +2939,6 @@ static struct net_device_ops be_netdev_ops = {
        .ndo_set_mac_address    = be_mac_addr_set,
        .ndo_change_mtu         = be_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_vlan_rx_register   = be_vlan_register,
        .ndo_vlan_rx_add_vid    = be_vlan_add_vid,
        .ndo_vlan_rx_kill_vid   = be_vlan_rem_vid,
        .ndo_set_vf_mac         = be_set_vf_mac,
@@ -3197,8 +3219,6 @@ static int be_get_config(struct be_adapter *adapter)
        if (status)
                return status;
 
-       be_cmd_check_native_mode(adapter);
-
        if ((num_vfs && adapter->sriov_enabled) ||
                (adapter->function_mode & 0x400) ||
                lancer_chip(adapter) || !be_physfn(adapter)) {
@@ -3383,6 +3403,12 @@ static int __devinit be_probe(struct pci_dev *pdev,
        if (status)
                goto stats_clean;
 
+       /* The INTR bit may be set in the card when probed by a kdump kernel
+        * after a crash.
+        */
+       if (!lancer_chip(adapter))
+               be_intr_set(adapter, false);
+
        be_msix_enable(adapter);
 
        INIT_DELAYED_WORK(&adapter->work, be_worker);
@@ -3419,10 +3445,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
        }
 
        dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
-       /* By default all priorities are enabled.
-        * Needed in case of no GRP5 evt support
-        */
-       adapter->vlan_prio_bmap = 0xff;
 
        schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
        return 0;