diff options
Diffstat (limited to 'drivers/net/ethernet/ibm/ehea/ehea_main.c')
-rw-r--r-- | drivers/net/ethernet/ibm/ehea/ehea_main.c | 62 |
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 3516e17a399d..f4d2da0db1b1 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c | |||
@@ -290,16 +290,18 @@ static void ehea_update_bcmc_registrations(void) | |||
290 | 290 | ||
291 | arr[i].adh = adapter->handle; | 291 | arr[i].adh = adapter->handle; |
292 | arr[i].port_id = port->logical_port_id; | 292 | arr[i].port_id = port->logical_port_id; |
293 | arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | | 293 | arr[i].reg_type = EHEA_BCMC_MULTICAST | |
294 | EHEA_BCMC_MULTICAST | | ||
295 | EHEA_BCMC_UNTAGGED; | 294 | EHEA_BCMC_UNTAGGED; |
295 | if (mc_entry->macaddr == 0) | ||
296 | arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL; | ||
296 | arr[i++].macaddr = mc_entry->macaddr; | 297 | arr[i++].macaddr = mc_entry->macaddr; |
297 | 298 | ||
298 | arr[i].adh = adapter->handle; | 299 | arr[i].adh = adapter->handle; |
299 | arr[i].port_id = port->logical_port_id; | 300 | arr[i].port_id = port->logical_port_id; |
300 | arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | | 301 | arr[i].reg_type = EHEA_BCMC_MULTICAST | |
301 | EHEA_BCMC_MULTICAST | | ||
302 | EHEA_BCMC_VLANID_ALL; | 302 | EHEA_BCMC_VLANID_ALL; |
303 | if (mc_entry->macaddr == 0) | ||
304 | arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL; | ||
303 | arr[i++].macaddr = mc_entry->macaddr; | 305 | arr[i++].macaddr = mc_entry->macaddr; |
304 | num_registrations -= 2; | 306 | num_registrations -= 2; |
305 | } | 307 | } |
@@ -1838,8 +1840,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr, | |||
1838 | u64 hret; | 1840 | u64 hret; |
1839 | u8 reg_type; | 1841 | u8 reg_type; |
1840 | 1842 | ||
1841 | reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST | 1843 | reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED; |
1842 | | EHEA_BCMC_UNTAGGED; | 1844 | if (mc_mac_addr == 0) |
1845 | reg_type |= EHEA_BCMC_SCOPE_ALL; | ||
1843 | 1846 | ||
1844 | hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, | 1847 | hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, |
1845 | port->logical_port_id, | 1848 | port->logical_port_id, |
@@ -1847,8 +1850,9 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr, | |||
1847 | if (hret) | 1850 | if (hret) |
1848 | goto out; | 1851 | goto out; |
1849 | 1852 | ||
1850 | reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST | 1853 | reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL; |
1851 | | EHEA_BCMC_VLANID_ALL; | 1854 | if (mc_mac_addr == 0) |
1855 | reg_type |= EHEA_BCMC_SCOPE_ALL; | ||
1852 | 1856 | ||
1853 | hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, | 1857 | hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, |
1854 | port->logical_port_id, | 1858 | port->logical_port_id, |
@@ -1898,7 +1902,7 @@ static void ehea_allmulti(struct net_device *dev, int enable) | |||
1898 | netdev_err(dev, | 1902 | netdev_err(dev, |
1899 | "failed enabling IFF_ALLMULTI\n"); | 1903 | "failed enabling IFF_ALLMULTI\n"); |
1900 | } | 1904 | } |
1901 | } else | 1905 | } else { |
1902 | if (!enable) { | 1906 | if (!enable) { |
1903 | /* Disable ALLMULTI */ | 1907 | /* Disable ALLMULTI */ |
1904 | hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC); | 1908 | hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC); |
@@ -1908,6 +1912,7 @@ static void ehea_allmulti(struct net_device *dev, int enable) | |||
1908 | netdev_err(dev, | 1912 | netdev_err(dev, |
1909 | "failed disabling IFF_ALLMULTI\n"); | 1913 | "failed disabling IFF_ALLMULTI\n"); |
1910 | } | 1914 | } |
1915 | } | ||
1911 | } | 1916 | } |
1912 | 1917 | ||
1913 | static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) | 1918 | static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) |
@@ -1941,11 +1946,7 @@ static void ehea_set_multicast_list(struct net_device *dev) | |||
1941 | struct netdev_hw_addr *ha; | 1946 | struct netdev_hw_addr *ha; |
1942 | int ret; | 1947 | int ret; |
1943 | 1948 | ||
1944 | if (port->promisc) { | 1949 | ehea_promiscuous(dev, !!(dev->flags & IFF_PROMISC)); |
1945 | ehea_promiscuous(dev, 1); | ||
1946 | return; | ||
1947 | } | ||
1948 | ehea_promiscuous(dev, 0); | ||
1949 | 1950 | ||
1950 | if (dev->flags & IFF_ALLMULTI) { | 1951 | if (dev->flags & IFF_ALLMULTI) { |
1951 | ehea_allmulti(dev, 1); | 1952 | ehea_allmulti(dev, 1); |
@@ -2463,6 +2464,7 @@ static int ehea_down(struct net_device *dev) | |||
2463 | return 0; | 2464 | return 0; |
2464 | 2465 | ||
2465 | ehea_drop_multicast_list(dev); | 2466 | ehea_drop_multicast_list(dev); |
2467 | ehea_allmulti(dev, 0); | ||
2466 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); | 2468 | ehea_broadcast_reg_helper(port, H_DEREG_BCMC); |
2467 | 2469 | ||
2468 | ehea_free_interrupts(dev); | 2470 | ehea_free_interrupts(dev); |
@@ -3261,6 +3263,7 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, | |||
3261 | struct ehea_adapter *adapter; | 3263 | struct ehea_adapter *adapter; |
3262 | const u64 *adapter_handle; | 3264 | const u64 *adapter_handle; |
3263 | int ret; | 3265 | int ret; |
3266 | int i; | ||
3264 | 3267 | ||
3265 | if (!dev || !dev->dev.of_node) { | 3268 | if (!dev || !dev->dev.of_node) { |
3266 | pr_err("Invalid ibmebus device probed\n"); | 3269 | pr_err("Invalid ibmebus device probed\n"); |
@@ -3314,17 +3317,9 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, | |||
3314 | tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, | 3317 | tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, |
3315 | (unsigned long)adapter); | 3318 | (unsigned long)adapter); |
3316 | 3319 | ||
3317 | ret = ibmebus_request_irq(adapter->neq->attr.ist1, | ||
3318 | ehea_interrupt_neq, IRQF_DISABLED, | ||
3319 | "ehea_neq", adapter); | ||
3320 | if (ret) { | ||
3321 | dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); | ||
3322 | goto out_kill_eq; | ||
3323 | } | ||
3324 | |||
3325 | ret = ehea_create_device_sysfs(dev); | 3320 | ret = ehea_create_device_sysfs(dev); |
3326 | if (ret) | 3321 | if (ret) |
3327 | goto out_free_irq; | 3322 | goto out_kill_eq; |
3328 | 3323 | ||
3329 | ret = ehea_setup_ports(adapter); | 3324 | ret = ehea_setup_ports(adapter); |
3330 | if (ret) { | 3325 | if (ret) { |
@@ -3332,15 +3327,30 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, | |||
3332 | goto out_rem_dev_sysfs; | 3327 | goto out_rem_dev_sysfs; |
3333 | } | 3328 | } |
3334 | 3329 | ||
3330 | ret = ibmebus_request_irq(adapter->neq->attr.ist1, | ||
3331 | ehea_interrupt_neq, IRQF_DISABLED, | ||
3332 | "ehea_neq", adapter); | ||
3333 | if (ret) { | ||
3334 | dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); | ||
3335 | goto out_shutdown_ports; | ||
3336 | } | ||
3337 | |||
3338 | /* Handle any events that might be pending. */ | ||
3339 | tasklet_hi_schedule(&adapter->neq_tasklet); | ||
3340 | |||
3335 | ret = 0; | 3341 | ret = 0; |
3336 | goto out; | 3342 | goto out; |
3337 | 3343 | ||
3344 | out_shutdown_ports: | ||
3345 | for (i = 0; i < EHEA_MAX_PORTS; i++) | ||
3346 | if (adapter->port[i]) { | ||
3347 | ehea_shutdown_single_port(adapter->port[i]); | ||
3348 | adapter->port[i] = NULL; | ||
3349 | } | ||
3350 | |||
3338 | out_rem_dev_sysfs: | 3351 | out_rem_dev_sysfs: |
3339 | ehea_remove_device_sysfs(dev); | 3352 | ehea_remove_device_sysfs(dev); |
3340 | 3353 | ||
3341 | out_free_irq: | ||
3342 | ibmebus_free_irq(adapter->neq->attr.ist1, adapter); | ||
3343 | |||
3344 | out_kill_eq: | 3354 | out_kill_eq: |
3345 | ehea_destroy_eq(adapter->neq); | 3355 | ehea_destroy_eq(adapter->neq); |
3346 | 3356 | ||