diff options
Diffstat (limited to 'drivers/infiniband/hw/nes/nes.c')
-rw-r--r-- | drivers/infiniband/hw/nes/nes.c | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 0c9f0aa5d4ea..2d668c69f6d9 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
@@ -144,6 +144,7 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
144 | struct nes_device *nesdev; | 144 | struct nes_device *nesdev; |
145 | struct net_device *netdev; | 145 | struct net_device *netdev; |
146 | struct nes_vnic *nesvnic; | 146 | struct nes_vnic *nesvnic; |
147 | unsigned int is_bonded; | ||
147 | 148 | ||
148 | nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %pI4, netmask %pI4.\n", | 149 | nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %pI4, netmask %pI4.\n", |
149 | &ifa->ifa_address, &ifa->ifa_mask); | 150 | &ifa->ifa_address, &ifa->ifa_mask); |
@@ -152,7 +153,9 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
152 | nesdev, nesdev->netdev[0]->name); | 153 | nesdev, nesdev->netdev[0]->name); |
153 | netdev = nesdev->netdev[0]; | 154 | netdev = nesdev->netdev[0]; |
154 | nesvnic = netdev_priv(netdev); | 155 | nesvnic = netdev_priv(netdev); |
155 | if (netdev == event_netdev) { | 156 | is_bonded = netif_is_bond_slave(netdev) && |
157 | (netdev->master == event_netdev); | ||
158 | if ((netdev == event_netdev) || is_bonded) { | ||
156 | if (nesvnic->rdma_enabled == 0) { | 159 | if (nesvnic->rdma_enabled == 0) { |
157 | nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since" | 160 | nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since" |
158 | " RDMA is not enabled.\n", | 161 | " RDMA is not enabled.\n", |
@@ -169,7 +172,10 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
169 | nes_manage_arp_cache(netdev, netdev->dev_addr, | 172 | nes_manage_arp_cache(netdev, netdev->dev_addr, |
170 | ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE); | 173 | ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE); |
171 | nesvnic->local_ipaddr = 0; | 174 | nesvnic->local_ipaddr = 0; |
172 | return NOTIFY_OK; | 175 | if (is_bonded) |
176 | continue; | ||
177 | else | ||
178 | return NOTIFY_OK; | ||
173 | break; | 179 | break; |
174 | case NETDEV_UP: | 180 | case NETDEV_UP: |
175 | nes_debug(NES_DBG_NETDEV, "event:UP\n"); | 181 | nes_debug(NES_DBG_NETDEV, "event:UP\n"); |
@@ -178,15 +184,24 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
178 | nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n"); | 184 | nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n"); |
179 | return NOTIFY_OK; | 185 | return NOTIFY_OK; |
180 | } | 186 | } |
187 | /* fall through */ | ||
188 | case NETDEV_CHANGEADDR: | ||
181 | /* Add the address to the IP table */ | 189 | /* Add the address to the IP table */ |
182 | nesvnic->local_ipaddr = ifa->ifa_address; | 190 | if (netdev->master) |
191 | nesvnic->local_ipaddr = | ||
192 | ((struct in_device *)netdev->master->ip_ptr)->ifa_list->ifa_address; | ||
193 | else | ||
194 | nesvnic->local_ipaddr = ifa->ifa_address; | ||
183 | 195 | ||
184 | nes_write_indexed(nesdev, | 196 | nes_write_indexed(nesdev, |
185 | NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), | 197 | NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), |
186 | ntohl(ifa->ifa_address)); | 198 | ntohl(nesvnic->local_ipaddr)); |
187 | nes_manage_arp_cache(netdev, netdev->dev_addr, | 199 | nes_manage_arp_cache(netdev, netdev->dev_addr, |
188 | ntohl(nesvnic->local_ipaddr), NES_ARP_ADD); | 200 | ntohl(nesvnic->local_ipaddr), NES_ARP_ADD); |
189 | return NOTIFY_OK; | 201 | if (is_bonded) |
202 | continue; | ||
203 | else | ||
204 | return NOTIFY_OK; | ||
190 | break; | 205 | break; |
191 | default: | 206 | default: |
192 | break; | 207 | break; |
@@ -660,6 +675,8 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i | |||
660 | } | 675 | } |
661 | nes_notifiers_registered++; | 676 | nes_notifiers_registered++; |
662 | 677 | ||
678 | INIT_DELAYED_WORK(&nesdev->work, nes_recheck_link_status); | ||
679 | |||
663 | /* Initialize network devices */ | 680 | /* Initialize network devices */ |
664 | if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL) | 681 | if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL) |
665 | goto bail7; | 682 | goto bail7; |
@@ -677,7 +694,7 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i | |||
677 | nesdev->netdev_count++; | 694 | nesdev->netdev_count++; |
678 | nesdev->nesadapter->netdev_count++; | 695 | nesdev->nesadapter->netdev_count++; |
679 | 696 | ||
680 | printk(KERN_ERR PFX "%s: NetEffect RNIC driver successfully loaded.\n", | 697 | printk(KERN_INFO PFX "%s: NetEffect RNIC driver successfully loaded.\n", |
681 | pci_name(pcidev)); | 698 | pci_name(pcidev)); |
682 | return 0; | 699 | return 0; |
683 | 700 | ||
@@ -742,6 +759,7 @@ static void __devexit nes_remove(struct pci_dev *pcidev) | |||
742 | struct nes_device *nesdev = pci_get_drvdata(pcidev); | 759 | struct nes_device *nesdev = pci_get_drvdata(pcidev); |
743 | struct net_device *netdev; | 760 | struct net_device *netdev; |
744 | int netdev_index = 0; | 761 | int netdev_index = 0; |
762 | unsigned long flags; | ||
745 | 763 | ||
746 | if (nesdev->netdev_count) { | 764 | if (nesdev->netdev_count) { |
747 | netdev = nesdev->netdev[netdev_index]; | 765 | netdev = nesdev->netdev[netdev_index]; |
@@ -768,6 +786,14 @@ static void __devexit nes_remove(struct pci_dev *pcidev) | |||
768 | free_irq(pcidev->irq, nesdev); | 786 | free_irq(pcidev->irq, nesdev); |
769 | tasklet_kill(&nesdev->dpc_tasklet); | 787 | tasklet_kill(&nesdev->dpc_tasklet); |
770 | 788 | ||
789 | spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); | ||
790 | if (nesdev->link_recheck) { | ||
791 | spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); | ||
792 | cancel_delayed_work_sync(&nesdev->work); | ||
793 | } else { | ||
794 | spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); | ||
795 | } | ||
796 | |||
771 | /* Deallocate the Adapter Structure */ | 797 | /* Deallocate the Adapter Structure */ |
772 | nes_destroy_adapter(nesdev->nesadapter); | 798 | nes_destroy_adapter(nesdev->nesadapter); |
773 | 799 | ||
@@ -1112,7 +1138,9 @@ static ssize_t nes_store_wqm_quanta(struct device_driver *ddp, | |||
1112 | u32 i = 0; | 1138 | u32 i = 0; |
1113 | struct nes_device *nesdev; | 1139 | struct nes_device *nesdev; |
1114 | 1140 | ||
1115 | strict_strtoul(buf, 0, &wqm_quanta_value); | 1141 | if (kstrtoul(buf, 0, &wqm_quanta_value) < 0) |
1142 | return -EINVAL; | ||
1143 | |||
1116 | list_for_each_entry(nesdev, &nes_dev_list, list) { | 1144 | list_for_each_entry(nesdev, &nes_dev_list, list) { |
1117 | if (i == ee_flsh_adapter) { | 1145 | if (i == ee_flsh_adapter) { |
1118 | nesdev->nesadapter->wqm_quanta = wqm_quanta_value; | 1146 | nesdev->nesadapter->wqm_quanta = wqm_quanta_value; |