Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
[firefly-linux-kernel-4.4.55.git] / drivers / net / ehea / ehea_main.c
index 809ccc9ff09cc8913a8e19ab1982cf76e7d69000..02698a1c80b057a4f57eba4e5e72f40c2c7da293 100644 (file)
@@ -791,11 +791,17 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota)
                cqe_counter++;
                rmb();
                if (cqe->status & EHEA_CQE_STAT_ERR_MASK) {
-                       ehea_error("Send Completion Error: Resetting port");
+                       ehea_error("Bad send completion status=0x%04X",
+                                  cqe->status);
+
                        if (netif_msg_tx_err(pr->port))
                                ehea_dump(cqe, sizeof(*cqe), "Send CQE");
-                       ehea_schedule_port_reset(pr->port);
-                       break;
+
+                       if (cqe->status & EHEA_CQE_STAT_RESET_MASK) {
+                               ehea_error("Resetting port");
+                               ehea_schedule_port_reset(pr->port);
+                               break;
+                       }
                }
 
                if (netif_msg_tx_done(pr->port))
@@ -814,7 +820,7 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota)
                quota--;
 
                cqe = ehea_poll_cq(send_cq);
-       };
+       }
 
        ehea_update_feca(send_cq, cqe_counter);
        atomic_add(swqe_av, &pr->swqe_avail);
@@ -901,6 +907,8 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
        struct ehea_eqe *eqe;
        struct ehea_qp *qp;
        u32 qp_token;
+       u64 resource_type, aer, aerr;
+       int reset_port = 0;
 
        eqe = ehea_poll_eq(port->qp_eq);
 
@@ -910,11 +918,24 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
                           eqe->entry, qp_token);
 
                qp = port->port_res[qp_token].qp;
-               ehea_error_data(port->adapter, qp->fw_handle);
+
+               resource_type = ehea_error_data(port->adapter, qp->fw_handle,
+                                               &aer, &aerr);
+
+               if (resource_type == EHEA_AER_RESTYPE_QP) {
+                       if ((aer & EHEA_AER_RESET_MASK) ||
+                           (aerr & EHEA_AERR_RESET_MASK))
+                                reset_port = 1;
+               } else
+                       reset_port = 1;   /* Reset in case of CQ or EQ error */
+
                eqe = ehea_poll_eq(port->qp_eq);
        }
 
-       ehea_schedule_port_reset(port);
+       if (reset_port) {
+               ehea_error("Resetting port");
+               ehea_schedule_port_reset(port);
+       }
 
        return IRQ_HANDLED;
 }
@@ -1618,7 +1639,7 @@ static void write_swqe2_TSO(struct sk_buff *skb,
 {
        struct ehea_vsgentry *sg1entry = &swqe->u.immdata_desc.sg_entry;
        u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0];
-       int skb_data_size = skb->len - skb->data_len;
+       int skb_data_size = skb_headlen(skb);
        int headersize;
 
        /* Packet is TCP with TSO enabled */
@@ -1629,7 +1650,7 @@ static void write_swqe2_TSO(struct sk_buff *skb,
         */
        headersize = ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
 
-       skb_data_size = skb->len - skb->data_len;
+       skb_data_size = skb_headlen(skb);
 
        if (skb_data_size >= headersize) {
                /* copy immediate data */
@@ -1651,7 +1672,7 @@ static void write_swqe2_TSO(struct sk_buff *skb,
 static void write_swqe2_nonTSO(struct sk_buff *skb,
                               struct ehea_swqe *swqe, u32 lkey)
 {
-       int skb_data_size = skb->len - skb->data_len;
+       int skb_data_size = skb_headlen(skb);
        u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0];
        struct ehea_vsgentry *sg1entry = &swqe->u.immdata_desc.sg_entry;
 
@@ -1860,7 +1881,6 @@ static void ehea_promiscuous(struct net_device *dev, int enable)
        port->promisc = enable;
 out:
        free_page((unsigned long)cb7);
-       return;
 }
 
 static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr,
@@ -1967,7 +1987,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr)
 static void ehea_set_multicast_list(struct net_device *dev)
 {
        struct ehea_port *port = netdev_priv(dev);
-       struct dev_mc_list *k_mcl_entry;
+       struct netdev_hw_addr *ha;
        int ret;
 
        if (dev->flags & IFF_PROMISC) {
@@ -1998,13 +2018,12 @@ static void ehea_set_multicast_list(struct net_device *dev)
                        goto out;
                }
 
-               netdev_for_each_mc_addr(k_mcl_entry, dev)
-                       ehea_add_multicast_entry(port, k_mcl_entry->dmi_addr);
+               netdev_for_each_mc_addr(ha, dev)
+                       ehea_add_multicast_entry(port, ha->addr);
 
        }
 out:
        ehea_update_bcmc_registrations();
-       return;
 }
 
 static int ehea_change_mtu(struct net_device *dev, int new_mtu)
@@ -2108,8 +2127,8 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev,
        } else {
                /* first copy data from the skb->data buffer ... */
                skb_copy_from_linear_data(skb, imm_data,
-                                         skb->len - skb->data_len);
-               imm_data += skb->len - skb->data_len;
+                                         skb_headlen(skb));
+               imm_data += skb_headlen(skb);
 
                /* ... then copy data from the fragments */
                for (i = 0; i < nfrags; i++) {
@@ -2220,7 +2239,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
                }
                spin_unlock_irqrestore(&pr->netif_queue, flags);
        }
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
        spin_unlock(&pr->xmit_lock);
 
        return NETDEV_TX_OK;
@@ -2317,7 +2336,6 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
                ehea_error("modify_ehea_port failed");
 out:
        free_page((unsigned long)cb1);
-       return;
 }
 
 int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp)
@@ -2860,7 +2878,6 @@ static void ehea_reset_port(struct work_struct *work)
        netif_wake_queue(dev);
 out:
        mutex_unlock(&port->port_lock);
-       return;
 }
 
 static void ehea_rereg_mrs(struct work_struct *work)
@@ -2868,7 +2885,6 @@ static void ehea_rereg_mrs(struct work_struct *work)
        int ret, i;
        struct ehea_adapter *adapter;
 
-       mutex_lock(&dlpar_mem_lock);
        ehea_info("LPAR memory changed - re-initializing driver");
 
        list_for_each_entry(adapter, &adapter_list, list)
@@ -2938,7 +2954,6 @@ static void ehea_rereg_mrs(struct work_struct *work)
                }
        ehea_info("re-initializing driver complete");
 out:
-       mutex_unlock(&dlpar_mem_lock);
        return;
 }
 
@@ -3238,7 +3253,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
                        ehea_remove_adapter_mr(adapter);
 
                i++;
-       };
+       }
        return 0;
 }
 
@@ -3257,7 +3272,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
                if (dn_log_port_id)
                        if (*dn_log_port_id == logical_port_id)
                                return eth_dn;
-       };
+       }
 
        return NULL;
 }
@@ -3521,7 +3536,14 @@ void ehea_crash_handler(void)
 static int ehea_mem_notifier(struct notifier_block *nb,
                              unsigned long action, void *data)
 {
+       int ret = NOTIFY_BAD;
        struct memory_notify *arg = data;
+
+       if (!mutex_trylock(&dlpar_mem_lock)) {
+               ehea_info("ehea_mem_notifier must not be called parallelized");
+               goto out;
+       }
+
        switch (action) {
        case MEM_CANCEL_OFFLINE:
                ehea_info("memory offlining canceled");
@@ -3530,14 +3552,14 @@ static int ehea_mem_notifier(struct notifier_block *nb,
                ehea_info("memory is going online");
                set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
                if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages))
-                       return NOTIFY_BAD;
+                       goto out_unlock;
                ehea_rereg_mrs(NULL);
                break;
        case MEM_GOING_OFFLINE:
                ehea_info("memory is going offline");
                set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
                if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages))
-                       return NOTIFY_BAD;
+                       goto out_unlock;
                ehea_rereg_mrs(NULL);
                break;
        default:
@@ -3545,8 +3567,12 @@ static int ehea_mem_notifier(struct notifier_block *nb,
        }
 
        ehea_update_firmware_handles();
+       ret = NOTIFY_OK;
 
-       return NOTIFY_OK;
+out_unlock:
+       mutex_unlock(&dlpar_mem_lock);
+out:
+       return ret;
 }
 
 static struct notifier_block ehea_mem_nb = {