Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / drivers / net / benet / be_main.c
index 9a1cd28..c36cd2f 100644 (file)
@@ -429,9 +429,12 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len)
        wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK;
 }
 
-static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
-               bool vlan, u32 wrb_cnt, u32 len)
+static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr,
+               struct sk_buff *skb, u32 wrb_cnt, u32 len)
 {
+       u8 vlan_prio = 0;
+       u16 vlan_tag = 0;
+
        memset(hdr, 0, sizeof(*hdr));
 
        AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1);
@@ -449,10 +452,15 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb,
                        AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1);
        }
 
-       if (vlan && vlan_tx_tag_present(skb)) {
+       if (adapter->vlan_grp && vlan_tx_tag_present(skb)) {
                AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1);
-               AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag,
-                       hdr, vlan_tx_tag_get(skb));
+               vlan_tag = vlan_tx_tag_get(skb);
+               vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
+               /* If vlan priority provided by OS is NOT in available bmap */
+               if (!(adapter->vlan_prio_bmap & (1 << vlan_prio)))
+                       vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) |
+                                       adapter->recommended_prio;
+               AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag);
        }
 
        AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1);
@@ -532,8 +540,7 @@ static int make_tx_wrbs(struct be_adapter *adapter,
                queue_head_inc(txq);
        }
 
-       wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false,
-               wrb_cnt, copied);
+       wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied);
        be_dws_cpu_to_le(hdr, sizeof(*hdr));
 
        return copied;
@@ -626,7 +633,7 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num)
 
        if (adapter->vlans_added <= adapter->max_vlans)  {
                /* Construct VLAN Table to give to HW */
-               for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+               for (i = 0; i < VLAN_N_VID; i++) {
                        if (adapter->vlan_tag[i]) {
                                vtag[ntags] = cpu_to_le16(i);
                                ntags++;
@@ -842,20 +849,16 @@ static void be_rx_stats_update(struct be_rx_obj *rxo,
                stats->rx_mcast_pkts++;
 }
 
-static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
+static inline bool csum_passed(struct be_eth_rx_compl *rxcp)
 {
-       u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk;
+       u8 l4_cksm, ipv6, ipcksm;
 
        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));
+       ipv6 = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp);
 
-       return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true;
+       /* Ignore ipcksm for ipv6 pkts */
+       return l4_cksm && (ipcksm || ipv6);
 }
 
 static struct be_rx_page_info *
@@ -1010,10 +1013,10 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 
        skb_fill_rx_data(adapter, rxo, skb, rxcp, num_rcvd);
 
-       if (do_pkt_csum(rxcp, adapter->rx_csum))
-               skb_checksum_none_assert(skb);
-       else
+       if (likely(adapter->rx_csum && csum_passed(rxcp)))
                skb->ip_summed = CHECKSUM_UNNECESSARY;
+       else
+               skb_checksum_none_assert(skb);
 
        skb->truesize = skb->len + sizeof(struct sk_buff);
        skb->protocol = eth_type_trans(skb, adapter->netdev);
@@ -1667,7 +1670,7 @@ static inline bool do_gro(struct be_adapter *adapter, struct be_rx_obj *rxo,
        return (tcp_frame && !err) ? true : false;
 }
 
-int be_poll_rx(struct napi_struct *napi, int budget)
+static int be_poll_rx(struct napi_struct *napi, int budget)
 {
        struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi);
        struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq);
@@ -1799,6 +1802,20 @@ static void be_worker(struct work_struct *work)
        struct be_rx_obj *rxo;
        int i;
 
+       /* when interrupts are not yet enabled, just reap any pending
+       * mcc completions */
+       if (!netif_running(adapter->netdev)) {
+               int mcc_compl, status = 0;
+
+               mcc_compl = be_process_mcc(adapter, &status);
+
+               if (mcc_compl) {
+                       struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
+                       be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
+               }
+               goto reschedule;
+       }
+
        if (!adapter->stats_ioctl_sent)
                be_cmd_get_stats(adapter, &adapter->stats_cmd);
 
@@ -1817,6 +1834,7 @@ static void be_worker(struct work_struct *work)
        if (!adapter->ue_detected)
                be_detect_dump_ue(adapter);
 
+reschedule:
        schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
 }
 
@@ -2012,8 +2030,6 @@ static int be_close(struct net_device *netdev)
        struct be_eq_obj *tx_eq = &adapter->tx_eq;
        int vec, i;
 
-       cancel_delayed_work_sync(&adapter->work);
-
        be_async_mcc_disable(adapter);
 
        netif_stop_queue(netdev);
@@ -2078,8 +2094,6 @@ 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)
@@ -2292,9 +2306,6 @@ static int be_clear(struct be_adapter *adapter)
 
 
 #define FW_FILE_HDR_SIGN       "ServerEngines Corp. "
-char flash_cookie[2][16] =     {"*** SE FLAS",
-                               "H DIRECTORY *** "};
-
 static bool be_flash_redboot(struct be_adapter *adapter,
                        const u8 *p, u32 img_start, int image_size,
                        int hdr_size)
@@ -2552,7 +2563,6 @@ static void be_netdev_init(struct net_device *netdev)
        netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc,
                BE_NAPI_WEIGHT);
 
-       netif_carrier_off(netdev);
        netif_stop_queue(netdev);
 }
 
@@ -2708,6 +2718,8 @@ static void __devexit be_remove(struct pci_dev *pdev)
        if (!adapter)
                return;
 
+       cancel_delayed_work_sync(&adapter->work);
+
        unregister_netdev(adapter->netdev);
 
        be_clear(adapter);
@@ -2861,8 +2873,10 @@ static int __devinit be_probe(struct pci_dev *pdev,
        status = register_netdev(netdev);
        if (status != 0)
                goto unsetup;
+       netif_carrier_off(netdev);
 
        dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
+       schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
        return 0;
 
 unsetup: