]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/benet/be_main.c
be2net: Patch to determine if function is VF while running in guest OS.
[net-next-2.6.git] / drivers / net / benet / be_main.c
index 058d7f95f5ae17df77c65c473a9683d4ec2a737a..e6ca92334d6d0bbb72de8ddc03930388986efaf5 100644 (file)
@@ -89,6 +89,8 @@ static void be_rxq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
        u32 val = 0;
        val |= qid & DB_RQ_RING_ID_MASK;
        val |= posted << DB_RQ_NUM_POSTED_SHIFT;
+
+       wmb();
        iowrite32(val, adapter->db + DB_RQ_OFFSET);
 }
 
@@ -97,6 +99,8 @@ static void be_txq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
        u32 val = 0;
        val |= qid & DB_TXULP_RING_ID_MASK;
        val |= (posted & DB_TXULP_NUM_POSTED_MASK) << DB_TXULP_NUM_POSTED_SHIFT;
+
+       wmb();
        iowrite32(val, adapter->db + DB_TXULP1_OFFSET);
 }
 
@@ -373,10 +377,12 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
 
        AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
 
-       if (skb_shinfo(skb)->gso_segs > 1 && skb_shinfo(skb)->gso_size) {
+       if (skb_is_gso(skb)) {
                AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso, hdr, 1);
                AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso_mss,
                        hdr, skb_shinfo(skb)->gso_size);
+               if (skb_is_gso_v6(skb))
+                       AMAP_SET_BITS(struct amap_eth_hdr_wrb, lso6, hdr, 1);
        } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
                if (is_tcp_pkt(skb))
                        AMAP_SET_BITS(struct amap_eth_hdr_wrb, tcpcs, hdr, 1);
@@ -971,6 +977,7 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
        if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0)
                return NULL;
 
+       rmb();
        be_dws_le_to_cpu(rxcp, sizeof(*rxcp));
 
        queue_tail_inc(&adapter->rx_obj.cq);
@@ -1064,6 +1071,7 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
        if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0)
                return NULL;
 
+       rmb();
        be_dws_le_to_cpu(txcp, sizeof(*txcp));
 
        txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0;
@@ -1111,6 +1119,7 @@ static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
        if (!eqe->evt)
                return NULL;
 
+       rmb();
        eqe->evt = le32_to_cpu(eqe->evt);
        queue_tail_inc(&eq_obj->q);
        return eqe;
@@ -1622,6 +1631,7 @@ static void be_sriov_enable(struct be_adapter *adapter)
 {
 #ifdef CONFIG_PCI_IOV
        int status;
+       be_check_sriov_fn_type(adapter);
        if (be_physfn(adapter) && num_vfs) {
                status = pci_enable_sriov(adapter->pdev, num_vfs);
                adapter->sriov_enabled = status ? false : true;
@@ -1735,6 +1745,44 @@ done:
        adapter->isr_registered = false;
 }
 
+static int be_close(struct net_device *netdev)
+{
+       struct be_adapter *adapter = netdev_priv(netdev);
+       struct be_eq_obj *rx_eq = &adapter->rx_eq;
+       struct be_eq_obj *tx_eq = &adapter->tx_eq;
+       int vec;
+
+       cancel_delayed_work_sync(&adapter->work);
+
+       be_async_mcc_disable(adapter);
+
+       netif_stop_queue(netdev);
+       netif_carrier_off(netdev);
+       adapter->link_up = false;
+
+       be_intr_set(adapter, false);
+
+       if (adapter->msix_enabled) {
+               vec = be_msix_vec_get(adapter, tx_eq->q.id);
+               synchronize_irq(vec);
+               vec = be_msix_vec_get(adapter, rx_eq->q.id);
+               synchronize_irq(vec);
+       } else {
+               synchronize_irq(netdev->irq);
+       }
+       be_irq_unregister(adapter);
+
+       napi_disable(&rx_eq->napi);
+       napi_disable(&tx_eq->napi);
+
+       /* Wait for all pending tx completions to arrive so that
+        * all tx skbs are freed.
+        */
+       be_tx_compl_clean(adapter);
+
+       return 0;
+}
+
 static int be_open(struct net_device *netdev)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
@@ -1765,27 +1813,29 @@ static int be_open(struct net_device *netdev)
        /* Now that interrupts are on we can process async mcc */
        be_async_mcc_enable(adapter);
 
+       schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
+
        status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
                        &link_speed);
        if (status)
-               goto ret_sts;
+               goto err;
        be_link_status_update(adapter, link_up);
 
-       if (be_physfn(adapter))
+       if (be_physfn(adapter)) {
                status = be_vid_config(adapter);
-       if (status)
-               goto ret_sts;
+               if (status)
+                       goto err;
 
-       if (be_physfn(adapter)) {
                status = be_cmd_set_flow_control(adapter,
                                adapter->tx_fc, adapter->rx_fc);
                if (status)
-                       goto ret_sts;
+                       goto err;
        }
 
-       schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
-ret_sts:
-       return status;
+       return 0;
+err:
+       be_close(adapter->netdev);
+       return -EIO;
 }
 
 static int be_setup_wol(struct be_adapter *adapter, bool enable)
@@ -1861,7 +1911,7 @@ static int be_setup(struct be_adapter *adapter)
                                goto if_destroy;
                        }
                        vf++;
-               } while (vf < num_vfs);
+               }
        } else if (!be_physfn(adapter)) {
                status = be_cmd_mac_addr_query(adapter, mac,
                        MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle);
@@ -1913,43 +1963,6 @@ static int be_clear(struct be_adapter *adapter)
        return 0;
 }
 
-static int be_close(struct net_device *netdev)
-{
-       struct be_adapter *adapter = netdev_priv(netdev);
-       struct be_eq_obj *rx_eq = &adapter->rx_eq;
-       struct be_eq_obj *tx_eq = &adapter->tx_eq;
-       int vec;
-
-       cancel_delayed_work_sync(&adapter->work);
-
-       be_async_mcc_disable(adapter);
-
-       netif_stop_queue(netdev);
-       netif_carrier_off(netdev);
-       adapter->link_up = false;
-
-       be_intr_set(adapter, false);
-
-       if (adapter->msix_enabled) {
-               vec = be_msix_vec_get(adapter, tx_eq->q.id);
-               synchronize_irq(vec);
-               vec = be_msix_vec_get(adapter, rx_eq->q.id);
-               synchronize_irq(vec);
-       } else {
-               synchronize_irq(netdev->irq);
-       }
-       be_irq_unregister(adapter);
-
-       napi_disable(&rx_eq->napi);
-       napi_disable(&tx_eq->napi);
-
-       /* Wait for all pending tx completions to arrive so that
-        * all tx skbs are freed.
-        */
-       be_tx_compl_clean(adapter);
-
-       return 0;
-}
 
 #define FW_FILE_HDR_SIGN       "ServerEngines Corp. "
 char flash_cookie[2][16] =     {"*** SE FLAS",
@@ -2183,7 +2196,7 @@ 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_HW_CSUM |
-               NETIF_F_GRO;
+               NETIF_F_GRO | NETIF_F_TSO6;
 
        netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM;
 
@@ -2319,6 +2332,7 @@ static int be_ctrl_init(struct be_adapter *adapter)
        spin_lock_init(&adapter->mcc_lock);
        spin_lock_init(&adapter->mcc_cq_lock);
 
+       init_completion(&adapter->flash_compl);
        pci_save_state(adapter->pdev);
        return 0;
 
@@ -2487,10 +2501,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
                status = be_cmd_POST(adapter);
                if (status)
                        goto ctrl_clean;
-
-               status = be_cmd_reset_function(adapter);
-               if (status)
-                       goto ctrl_clean;
        }
 
        /* tell fw we're ready to fire cmds */
@@ -2498,6 +2508,12 @@ static int __devinit be_probe(struct pci_dev *pdev,
        if (status)
                goto ctrl_clean;
 
+       if (be_physfn(adapter)) {
+               status = be_cmd_reset_function(adapter);
+               if (status)
+                       goto ctrl_clean;
+       }
+
        status = be_stats_init(adapter);
        if (status)
                goto ctrl_clean;