diff options
Diffstat (limited to 'drivers/infiniband/hw/nes/nes.c')
-rw-r--r-- | drivers/infiniband/hw/nes/nes.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 0c9f0aa5d4ea..e17f52c21947 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,8 @@ 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 = (netdev->master == event_netdev); |
157 | if ((netdev == event_netdev) || is_bonded) { | ||
156 | if (nesvnic->rdma_enabled == 0) { | 158 | if (nesvnic->rdma_enabled == 0) { |
157 | nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since" | 159 | nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since" |
158 | " RDMA is not enabled.\n", | 160 | " RDMA is not enabled.\n", |
@@ -169,7 +171,10 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
169 | nes_manage_arp_cache(netdev, netdev->dev_addr, | 171 | nes_manage_arp_cache(netdev, netdev->dev_addr, |
170 | ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE); | 172 | ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE); |
171 | nesvnic->local_ipaddr = 0; | 173 | nesvnic->local_ipaddr = 0; |
172 | return NOTIFY_OK; | 174 | if (is_bonded) |
175 | continue; | ||
176 | else | ||
177 | return NOTIFY_OK; | ||
173 | break; | 178 | break; |
174 | case NETDEV_UP: | 179 | case NETDEV_UP: |
175 | nes_debug(NES_DBG_NETDEV, "event:UP\n"); | 180 | nes_debug(NES_DBG_NETDEV, "event:UP\n"); |
@@ -178,15 +183,24 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
178 | nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n"); | 183 | nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n"); |
179 | return NOTIFY_OK; | 184 | return NOTIFY_OK; |
180 | } | 185 | } |
186 | /* fall through */ | ||
187 | case NETDEV_CHANGEADDR: | ||
181 | /* Add the address to the IP table */ | 188 | /* Add the address to the IP table */ |
182 | nesvnic->local_ipaddr = ifa->ifa_address; | 189 | if (netdev->master) |
190 | nesvnic->local_ipaddr = | ||
191 | ((struct in_device *)netdev->master->ip_ptr)->ifa_list->ifa_address; | ||
192 | else | ||
193 | nesvnic->local_ipaddr = ifa->ifa_address; | ||
183 | 194 | ||
184 | nes_write_indexed(nesdev, | 195 | nes_write_indexed(nesdev, |
185 | NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), | 196 | NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), |
186 | ntohl(ifa->ifa_address)); | 197 | ntohl(nesvnic->local_ipaddr)); |
187 | nes_manage_arp_cache(netdev, netdev->dev_addr, | 198 | nes_manage_arp_cache(netdev, netdev->dev_addr, |
188 | ntohl(nesvnic->local_ipaddr), NES_ARP_ADD); | 199 | ntohl(nesvnic->local_ipaddr), NES_ARP_ADD); |
189 | return NOTIFY_OK; | 200 | if (is_bonded) |
201 | continue; | ||
202 | else | ||
203 | return NOTIFY_OK; | ||
190 | break; | 204 | break; |
191 | default: | 205 | default: |
192 | break; | 206 | break; |