]> Pileus Git - ~andy/linux/blobdiff - drivers/net/ehea/ehea_main.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[~andy/linux] / drivers / net / ehea / ehea_main.c
index 809ccc9ff09cc8913a8e19ab1982cf76e7d69000..8b92acb448c2691e7d2ca4de669c61e4a33677e9 100644 (file)
@@ -122,8 +122,11 @@ static struct of_device_id ehea_device_table[] = {
 MODULE_DEVICE_TABLE(of, ehea_device_table);
 
 static struct of_platform_driver ehea_driver = {
-       .name = "ehea",
-       .match_table = ehea_device_table,
+       .driver = {
+               .name = "ehea",
+               .owner = THIS_MODULE,
+               .of_match_table = ehea_device_table,
+       },
        .probe = ehea_probe_adapter,
        .remove = ehea_remove,
 };
@@ -791,11 +794,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 +823,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);
@@ -858,6 +867,7 @@ static int ehea_poll(struct napi_struct *napi, int budget)
                ehea_reset_cq_ep(pr->send_cq);
                ehea_reset_cq_n1(pr->recv_cq);
                ehea_reset_cq_n1(pr->send_cq);
+               rmb();
                cqe = ehea_poll_rq1(pr->qp, &wqe_index);
                cqe_skb = ehea_poll_cq(pr->send_cq);
 
@@ -901,6 +911,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 +922,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 +1643,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 +1654,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 +1676,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 +1885,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 +1991,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 +2022,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 +2131,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 +2243,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 +2340,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)
@@ -2838,6 +2860,7 @@ static void ehea_reset_port(struct work_struct *work)
                container_of(work, struct ehea_port, reset_task);
        struct net_device *dev = port->netdev;
 
+       mutex_lock(&dlpar_mem_lock);
        port->resets++;
        mutex_lock(&port->port_lock);
        netif_stop_queue(dev);
@@ -2860,7 +2883,7 @@ static void ehea_reset_port(struct work_struct *work)
        netif_wake_queue(dev);
 out:
        mutex_unlock(&port->port_lock);
-       return;
+       mutex_unlock(&dlpar_mem_lock);
 }
 
 static void ehea_rereg_mrs(struct work_struct *work)
@@ -2868,7 +2891,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 +2960,6 @@ static void ehea_rereg_mrs(struct work_struct *work)
                }
        ehea_info("re-initializing driver complete");
 out:
-       mutex_unlock(&dlpar_mem_lock);
        return;
 }
 
@@ -3035,7 +3056,7 @@ static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id,
 static void __devinit logical_port_release(struct device *dev)
 {
        struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev);
-       of_node_put(port->ofdev.node);
+       of_node_put(port->ofdev.dev.of_node);
 }
 
 static struct device *ehea_register_port(struct ehea_port *port,
@@ -3043,7 +3064,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
 {
        int ret;
 
-       port->ofdev.node = of_node_get(dn);
+       port->ofdev.dev.of_node = of_node_get(dn);
        port->ofdev.dev.parent = &port->adapter->ofdev->dev;
        port->ofdev.dev.bus = &ibmebus_bus_type;
 
@@ -3210,7 +3231,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
        const u32 *dn_log_port_id;
        int i = 0;
 
-       lhea_dn = adapter->ofdev->node;
+       lhea_dn = adapter->ofdev->dev.of_node;
        while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
 
                dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
@@ -3238,7 +3259,7 @@ static int ehea_setup_ports(struct ehea_adapter *adapter)
                        ehea_remove_adapter_mr(adapter);
 
                i++;
-       };
+       }
        return 0;
 }
 
@@ -3249,7 +3270,7 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
        struct device_node *eth_dn = NULL;
        const u32 *dn_log_port_id;
 
-       lhea_dn = adapter->ofdev->node;
+       lhea_dn = adapter->ofdev->dev.of_node;
        while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
 
                dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
@@ -3257,7 +3278,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;
 }
@@ -3379,7 +3400,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
        const u64 *adapter_handle;
        int ret;
 
-       if (!dev || !dev->node) {
+       if (!dev || !dev->dev.of_node) {
                ehea_error("Invalid ibmebus device probed");
                return -EINVAL;
        }
@@ -3395,14 +3416,14 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
 
        adapter->ofdev = dev;
 
-       adapter_handle = of_get_property(dev->node, "ibm,hea-handle",
+       adapter_handle = of_get_property(dev->dev.of_node, "ibm,hea-handle",
                                         NULL);
        if (adapter_handle)
                adapter->handle = *adapter_handle;
 
        if (!adapter->handle) {
                dev_err(&dev->dev, "failed getting handle for adapter"
-                       " '%s'\n", dev->node->full_name);
+                       " '%s'\n", dev->dev.of_node->full_name);
                ret = -ENODEV;
                goto out_free_ad;
        }
@@ -3521,7 +3542,11 @@ 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;
+
+       mutex_lock(&dlpar_mem_lock);
+
        switch (action) {
        case MEM_CANCEL_OFFLINE:
                ehea_info("memory offlining canceled");
@@ -3530,14 +3555,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 +3570,11 @@ 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);
+       return ret;
 }
 
 static struct notifier_block ehea_mem_nb = {