diff options
author | Maciej Sosnowski <maciej.sosnowski@intel.com> | 2010-11-24 12:29:38 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2011-01-16 16:23:34 -0500 |
commit | ea623455b736d82f476460647e8b5fe5dc36f4f2 (patch) | |
tree | c1e2343adc9b2e8f7e11d58dc561370905d60bb8 /drivers/infiniband/hw/nes/nes_nic.c | |
parent | 2a4c97ead4b375a64063523210939b87ad225b85 (diff) |
RDMA/nes: Generate IB_EVENT_PORT_ERR/PORT_ACTIVE events
Depending on link state change, IB_EVENT_PORT_ERR or
IB_EVENT_PORT_ACTIVE should be generated when handling MAC interrupts.
Plugging in a cable happens to result in series of interrupts changing
driver's link state a number of times before finally staying at link
up (e.g. link up, link down, link up, link down, ..., link up). To
prevent sending series of redundant IB_EVENT_PORT_ACTIVE and
IB_EVENT_PORT_ERR events, we use a timer to debounce them in
nes_port_ibevent().
Signed-off-by: Maciej Sosnowski <maciej.sosnowski@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_nic.c')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_nic.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 5a4c3648472..81052fbcd9b 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -144,6 +144,7 @@ static int nes_netdev_open(struct net_device *netdev) | |||
144 | u32 nic_active_bit; | 144 | u32 nic_active_bit; |
145 | u32 nic_active; | 145 | u32 nic_active; |
146 | struct list_head *list_pos, *list_temp; | 146 | struct list_head *list_pos, *list_temp; |
147 | unsigned long flags; | ||
147 | 148 | ||
148 | assert(nesdev != NULL); | 149 | assert(nesdev != NULL); |
149 | 150 | ||
@@ -233,18 +234,27 @@ static int nes_netdev_open(struct net_device *netdev) | |||
233 | first_nesvnic = nesvnic; | 234 | first_nesvnic = nesvnic; |
234 | } | 235 | } |
235 | 236 | ||
236 | if (nesvnic->of_device_registered) { | ||
237 | nesdev->iw_status = 1; | ||
238 | nesdev->nesadapter->send_term_ok = 1; | ||
239 | nes_port_ibevent(nesvnic); | ||
240 | } | ||
241 | |||
242 | if (first_nesvnic->linkup) { | 237 | if (first_nesvnic->linkup) { |
243 | /* Enable network packets */ | 238 | /* Enable network packets */ |
244 | nesvnic->linkup = 1; | 239 | nesvnic->linkup = 1; |
245 | netif_start_queue(netdev); | 240 | netif_start_queue(netdev); |
246 | netif_carrier_on(netdev); | 241 | netif_carrier_on(netdev); |
247 | } | 242 | } |
243 | |||
244 | spin_lock_irqsave(&nesvnic->port_ibevent_lock, flags); | ||
245 | if (nesvnic->of_device_registered) { | ||
246 | nesdev->nesadapter->send_term_ok = 1; | ||
247 | if (nesvnic->linkup == 1) { | ||
248 | if (nesdev->iw_status == 0) { | ||
249 | nesdev->iw_status = 1; | ||
250 | nes_port_ibevent(nesvnic); | ||
251 | } | ||
252 | } else { | ||
253 | nesdev->iw_status = 0; | ||
254 | } | ||
255 | } | ||
256 | spin_unlock_irqrestore(&nesvnic->port_ibevent_lock, flags); | ||
257 | |||
248 | napi_enable(&nesvnic->napi); | 258 | napi_enable(&nesvnic->napi); |
249 | nesvnic->netdev_open = 1; | 259 | nesvnic->netdev_open = 1; |
250 | 260 | ||
@@ -263,6 +273,7 @@ static int nes_netdev_stop(struct net_device *netdev) | |||
263 | u32 nic_active; | 273 | u32 nic_active; |
264 | struct nes_vnic *first_nesvnic = NULL; | 274 | struct nes_vnic *first_nesvnic = NULL; |
265 | struct list_head *list_pos, *list_temp; | 275 | struct list_head *list_pos, *list_temp; |
276 | unsigned long flags; | ||
266 | 277 | ||
267 | nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n", | 278 | nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n", |
268 | nesvnic, nesdev, netdev, netdev->name); | 279 | nesvnic, nesdev, netdev, netdev->name); |
@@ -315,12 +326,17 @@ static int nes_netdev_stop(struct net_device *netdev) | |||
315 | nic_active &= nic_active_mask; | 326 | nic_active &= nic_active_mask; |
316 | nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); | 327 | nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); |
317 | 328 | ||
318 | 329 | spin_lock_irqsave(&nesvnic->port_ibevent_lock, flags); | |
319 | if (nesvnic->of_device_registered) { | 330 | if (nesvnic->of_device_registered) { |
320 | nesdev->nesadapter->send_term_ok = 0; | 331 | nesdev->nesadapter->send_term_ok = 0; |
321 | nesdev->iw_status = 0; | 332 | nesdev->iw_status = 0; |
322 | nes_port_ibevent(nesvnic); | 333 | if (nesvnic->linkup == 1) |
334 | nes_port_ibevent(nesvnic); | ||
323 | } | 335 | } |
336 | del_timer_sync(&nesvnic->event_timer); | ||
337 | nesvnic->event_timer.function = NULL; | ||
338 | spin_unlock_irqrestore(&nesvnic->port_ibevent_lock, flags); | ||
339 | |||
324 | nes_destroy_nic_qp(nesvnic); | 340 | nes_destroy_nic_qp(nesvnic); |
325 | 341 | ||
326 | nesvnic->netdev_open = 0; | 342 | nesvnic->netdev_open = 0; |
@@ -1750,7 +1766,10 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1750 | nesvnic->rdma_enabled = 0; | 1766 | nesvnic->rdma_enabled = 0; |
1751 | } | 1767 | } |
1752 | nesvnic->nic_cq.cq_number = nesvnic->nic.qp_id; | 1768 | nesvnic->nic_cq.cq_number = nesvnic->nic.qp_id; |
1769 | init_timer(&nesvnic->event_timer); | ||
1770 | nesvnic->event_timer.function = NULL; | ||
1753 | spin_lock_init(&nesvnic->tx_lock); | 1771 | spin_lock_init(&nesvnic->tx_lock); |
1772 | spin_lock_init(&nesvnic->port_ibevent_lock); | ||
1754 | nesdev->netdev[nesdev->netdev_count] = netdev; | 1773 | nesdev->netdev[nesdev->netdev_count] = netdev; |
1755 | 1774 | ||
1756 | nes_debug(NES_DBG_INIT, "Adding nesvnic (%p) to the adapters nesvnic_list for MAC%d.\n", | 1775 | nes_debug(NES_DBG_INIT, "Adding nesvnic (%p) to the adapters nesvnic_list for MAC%d.\n", |