diff options
Diffstat (limited to 'drivers/net/ehea/ehea_main.c')
-rw-r--r-- | drivers/net/ehea/ehea_main.c | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index d1b6d4e7495d..0920b796bd78 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -118,6 +118,7 @@ static struct of_device_id ehea_device_table[] = { | |||
118 | }, | 118 | }, |
119 | {}, | 119 | {}, |
120 | }; | 120 | }; |
121 | MODULE_DEVICE_TABLE(of, ehea_device_table); | ||
121 | 122 | ||
122 | static struct of_platform_driver ehea_driver = { | 123 | static struct of_platform_driver ehea_driver = { |
123 | .name = "ehea", | 124 | .name = "ehea", |
@@ -137,6 +138,12 @@ void ehea_dump(void *adr, int len, char *msg) | |||
137 | } | 138 | } |
138 | } | 139 | } |
139 | 140 | ||
141 | void ehea_schedule_port_reset(struct ehea_port *port) | ||
142 | { | ||
143 | if (!test_bit(__EHEA_DISABLE_PORT_RESET, &port->flags)) | ||
144 | schedule_work(&port->reset_task); | ||
145 | } | ||
146 | |||
140 | static void ehea_update_firmware_handles(void) | 147 | static void ehea_update_firmware_handles(void) |
141 | { | 148 | { |
142 | struct ehea_fw_handle_entry *arr = NULL; | 149 | struct ehea_fw_handle_entry *arr = NULL; |
@@ -241,7 +248,7 @@ static void ehea_update_bcmc_registrations(void) | |||
241 | } | 248 | } |
242 | 249 | ||
243 | if (num_registrations) { | 250 | if (num_registrations) { |
244 | arr = kzalloc(num_registrations * sizeof(*arr), GFP_KERNEL); | 251 | arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC); |
245 | if (!arr) | 252 | if (!arr) |
246 | return; /* Keep the existing array */ | 253 | return; /* Keep the existing array */ |
247 | } else | 254 | } else |
@@ -301,7 +308,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev) | |||
301 | 308 | ||
302 | memset(stats, 0, sizeof(*stats)); | 309 | memset(stats, 0, sizeof(*stats)); |
303 | 310 | ||
304 | cb2 = kzalloc(PAGE_SIZE, GFP_KERNEL); | 311 | cb2 = kzalloc(PAGE_SIZE, GFP_ATOMIC); |
305 | if (!cb2) { | 312 | if (!cb2) { |
306 | ehea_error("no mem for cb2"); | 313 | ehea_error("no mem for cb2"); |
307 | goto out; | 314 | goto out; |
@@ -587,7 +594,7 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq, | |||
587 | "Resetting port.", pr->qp->init_attr.qp_nr); | 594 | "Resetting port.", pr->qp->init_attr.qp_nr); |
588 | ehea_dump(cqe, sizeof(*cqe), "CQE"); | 595 | ehea_dump(cqe, sizeof(*cqe), "CQE"); |
589 | } | 596 | } |
590 | schedule_work(&pr->port->reset_task); | 597 | ehea_schedule_port_reset(pr->port); |
591 | return 1; | 598 | return 1; |
592 | } | 599 | } |
593 | 600 | ||
@@ -616,7 +623,7 @@ static int get_skb_hdr(struct sk_buff *skb, void **iphdr, | |||
616 | *tcph = tcp_hdr(skb); | 623 | *tcph = tcp_hdr(skb); |
617 | 624 | ||
618 | /* check if ip header and tcp header are complete */ | 625 | /* check if ip header and tcp header are complete */ |
619 | if (iph->tot_len < ip_len + tcp_hdrlen(skb)) | 626 | if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb)) |
620 | return -1; | 627 | return -1; |
621 | 628 | ||
622 | *hdr_flags = LRO_IPV4 | LRO_TCP; | 629 | *hdr_flags = LRO_IPV4 | LRO_TCP; |
@@ -765,7 +772,7 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) | |||
765 | ehea_error("Send Completion Error: Resetting port"); | 772 | ehea_error("Send Completion Error: Resetting port"); |
766 | if (netif_msg_tx_err(pr->port)) | 773 | if (netif_msg_tx_err(pr->port)) |
767 | ehea_dump(cqe, sizeof(*cqe), "Send CQE"); | 774 | ehea_dump(cqe, sizeof(*cqe), "Send CQE"); |
768 | schedule_work(&pr->port->reset_task); | 775 | ehea_schedule_port_reset(pr->port); |
769 | break; | 776 | break; |
770 | } | 777 | } |
771 | 778 | ||
@@ -885,7 +892,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) | |||
885 | eqe = ehea_poll_eq(port->qp_eq); | 892 | eqe = ehea_poll_eq(port->qp_eq); |
886 | } | 893 | } |
887 | 894 | ||
888 | schedule_work(&port->reset_task); | 895 | ehea_schedule_port_reset(port); |
889 | 896 | ||
890 | return IRQ_HANDLED; | 897 | return IRQ_HANDLED; |
891 | } | 898 | } |
@@ -1763,25 +1770,29 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) | |||
1763 | 1770 | ||
1764 | memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len); | 1771 | memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len); |
1765 | 1772 | ||
1766 | mutex_lock(&ehea_bcmc_regs.lock); | 1773 | spin_lock(&ehea_bcmc_regs.lock); |
1767 | 1774 | ||
1768 | /* Deregister old MAC in pHYP */ | 1775 | /* Deregister old MAC in pHYP */ |
1769 | ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | 1776 | if (port->state == EHEA_PORT_UP) { |
1770 | if (ret) | 1777 | ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); |
1771 | goto out_upregs; | 1778 | if (ret) |
1779 | goto out_upregs; | ||
1780 | } | ||
1772 | 1781 | ||
1773 | port->mac_addr = cb0->port_mac_addr << 16; | 1782 | port->mac_addr = cb0->port_mac_addr << 16; |
1774 | 1783 | ||
1775 | /* Register new MAC in pHYP */ | 1784 | /* Register new MAC in pHYP */ |
1776 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); | 1785 | if (port->state == EHEA_PORT_UP) { |
1777 | if (ret) | 1786 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); |
1778 | goto out_upregs; | 1787 | if (ret) |
1788 | goto out_upregs; | ||
1789 | } | ||
1779 | 1790 | ||
1780 | ret = 0; | 1791 | ret = 0; |
1781 | 1792 | ||
1782 | out_upregs: | 1793 | out_upregs: |
1783 | ehea_update_bcmc_registrations(); | 1794 | ehea_update_bcmc_registrations(); |
1784 | mutex_unlock(&ehea_bcmc_regs.lock); | 1795 | spin_unlock(&ehea_bcmc_regs.lock); |
1785 | out_free: | 1796 | out_free: |
1786 | kfree(cb0); | 1797 | kfree(cb0); |
1787 | out: | 1798 | out: |
@@ -1943,7 +1954,7 @@ static void ehea_set_multicast_list(struct net_device *dev) | |||
1943 | } | 1954 | } |
1944 | ehea_promiscuous(dev, 0); | 1955 | ehea_promiscuous(dev, 0); |
1945 | 1956 | ||
1946 | mutex_lock(&ehea_bcmc_regs.lock); | 1957 | spin_lock(&ehea_bcmc_regs.lock); |
1947 | 1958 | ||
1948 | if (dev->flags & IFF_ALLMULTI) { | 1959 | if (dev->flags & IFF_ALLMULTI) { |
1949 | ehea_allmulti(dev, 1); | 1960 | ehea_allmulti(dev, 1); |
@@ -1974,7 +1985,7 @@ static void ehea_set_multicast_list(struct net_device *dev) | |||
1974 | } | 1985 | } |
1975 | out: | 1986 | out: |
1976 | ehea_update_bcmc_registrations(); | 1987 | ehea_update_bcmc_registrations(); |
1977 | mutex_unlock(&ehea_bcmc_regs.lock); | 1988 | spin_unlock(&ehea_bcmc_regs.lock); |
1978 | return; | 1989 | return; |
1979 | } | 1990 | } |
1980 | 1991 | ||
@@ -2213,8 +2224,6 @@ static void ehea_vlan_rx_register(struct net_device *dev, | |||
2213 | goto out; | 2224 | goto out; |
2214 | } | 2225 | } |
2215 | 2226 | ||
2216 | memset(cb1->vlan_filter, 0, sizeof(cb1->vlan_filter)); | ||
2217 | |||
2218 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, | 2227 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, |
2219 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); | 2228 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); |
2220 | if (hret != H_SUCCESS) | 2229 | if (hret != H_SUCCESS) |
@@ -2495,7 +2504,7 @@ static int ehea_up(struct net_device *dev) | |||
2495 | } | 2504 | } |
2496 | } | 2505 | } |
2497 | 2506 | ||
2498 | mutex_lock(&ehea_bcmc_regs.lock); | 2507 | spin_lock(&ehea_bcmc_regs.lock); |
2499 | 2508 | ||
2500 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); | 2509 | ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); |
2501 | if (ret) { | 2510 | if (ret) { |
@@ -2518,7 +2527,7 @@ out: | |||
2518 | ehea_info("Failed starting %s. ret=%i", dev->name, ret); | 2527 | ehea_info("Failed starting %s. ret=%i", dev->name, ret); |
2519 | 2528 | ||
2520 | ehea_update_bcmc_registrations(); | 2529 | ehea_update_bcmc_registrations(); |
2521 | mutex_unlock(&ehea_bcmc_regs.lock); | 2530 | spin_unlock(&ehea_bcmc_regs.lock); |
2522 | 2531 | ||
2523 | ehea_update_firmware_handles(); | 2532 | ehea_update_firmware_handles(); |
2524 | mutex_unlock(&ehea_fw_handles.lock); | 2533 | mutex_unlock(&ehea_fw_handles.lock); |
@@ -2573,7 +2582,7 @@ static int ehea_down(struct net_device *dev) | |||
2573 | 2582 | ||
2574 | mutex_lock(&ehea_fw_handles.lock); | 2583 | mutex_lock(&ehea_fw_handles.lock); |
2575 | 2584 | ||
2576 | mutex_lock(&ehea_bcmc_regs.lock); | 2585 | spin_lock(&ehea_bcmc_regs.lock); |
2577 | ehea_drop_multicast_list(dev); | 2586 | ehea_drop_multicast_list(dev); |
2578 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | 2587 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); |
2579 | 2588 | ||
@@ -2582,7 +2591,7 @@ static int ehea_down(struct net_device *dev) | |||
2582 | port->state = EHEA_PORT_DOWN; | 2591 | port->state = EHEA_PORT_DOWN; |
2583 | 2592 | ||
2584 | ehea_update_bcmc_registrations(); | 2593 | ehea_update_bcmc_registrations(); |
2585 | mutex_unlock(&ehea_bcmc_regs.lock); | 2594 | spin_unlock(&ehea_bcmc_regs.lock); |
2586 | 2595 | ||
2587 | ret = ehea_clean_all_portres(port); | 2596 | ret = ehea_clean_all_portres(port); |
2588 | if (ret) | 2597 | if (ret) |
@@ -2603,12 +2612,14 @@ static int ehea_stop(struct net_device *dev) | |||
2603 | if (netif_msg_ifdown(port)) | 2612 | if (netif_msg_ifdown(port)) |
2604 | ehea_info("disabling port %s", dev->name); | 2613 | ehea_info("disabling port %s", dev->name); |
2605 | 2614 | ||
2606 | flush_scheduled_work(); | 2615 | set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); |
2616 | cancel_work_sync(&port->reset_task); | ||
2607 | mutex_lock(&port->port_lock); | 2617 | mutex_lock(&port->port_lock); |
2608 | netif_stop_queue(dev); | 2618 | netif_stop_queue(dev); |
2609 | port_napi_disable(port); | 2619 | port_napi_disable(port); |
2610 | ret = ehea_down(dev); | 2620 | ret = ehea_down(dev); |
2611 | mutex_unlock(&port->port_lock); | 2621 | mutex_unlock(&port->port_lock); |
2622 | clear_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); | ||
2612 | return ret; | 2623 | return ret; |
2613 | } | 2624 | } |
2614 | 2625 | ||
@@ -2938,7 +2949,7 @@ static void ehea_tx_watchdog(struct net_device *dev) | |||
2938 | 2949 | ||
2939 | if (netif_carrier_ok(dev) && | 2950 | if (netif_carrier_ok(dev) && |
2940 | !test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)) | 2951 | !test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)) |
2941 | schedule_work(&port->reset_task); | 2952 | ehea_schedule_port_reset(port); |
2942 | } | 2953 | } |
2943 | 2954 | ||
2944 | int ehea_sense_adapter_attr(struct ehea_adapter *adapter) | 2955 | int ehea_sense_adapter_attr(struct ehea_adapter *adapter) |
@@ -3178,11 +3189,12 @@ out_err: | |||
3178 | 3189 | ||
3179 | static void ehea_shutdown_single_port(struct ehea_port *port) | 3190 | static void ehea_shutdown_single_port(struct ehea_port *port) |
3180 | { | 3191 | { |
3192 | struct ehea_adapter *adapter = port->adapter; | ||
3181 | unregister_netdev(port->netdev); | 3193 | unregister_netdev(port->netdev); |
3182 | ehea_unregister_port(port); | 3194 | ehea_unregister_port(port); |
3183 | kfree(port->mc_list); | 3195 | kfree(port->mc_list); |
3184 | free_netdev(port->netdev); | 3196 | free_netdev(port->netdev); |
3185 | port->adapter->active_ports--; | 3197 | adapter->active_ports--; |
3186 | } | 3198 | } |
3187 | 3199 | ||
3188 | static int ehea_setup_ports(struct ehea_adapter *adapter) | 3200 | static int ehea_setup_ports(struct ehea_adapter *adapter) |
@@ -3586,7 +3598,7 @@ int __init ehea_module_init(void) | |||
3586 | memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs)); | 3598 | memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs)); |
3587 | 3599 | ||
3588 | mutex_init(&ehea_fw_handles.lock); | 3600 | mutex_init(&ehea_fw_handles.lock); |
3589 | mutex_init(&ehea_bcmc_regs.lock); | 3601 | spin_lock_init(&ehea_bcmc_regs.lock); |
3590 | 3602 | ||
3591 | ret = check_module_parm(); | 3603 | ret = check_module_parm(); |
3592 | if (ret) | 3604 | if (ret) |