aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2011-07-20 10:55:24 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-21 15:38:32 -0400
commit415199f2bd977fa4065d4e836b4b7543f7993bc3 (patch)
tree2dfb4dfcc7097fcdd02d7923e6fdecebc4af0985 /drivers/net/cnic.c
parent74e49bbdabbac34c77b280152b1de9bef9bf9be7 (diff)
cnic: Add VLAN ID as a parameter during netevent upcall
The bnx2fc driver needs to handle netdev events on VLAN devices. Signed-off-by: Michael Chan <mchan@broadcom.com> Reviewed-by: Bhanu Prakash Gollapudi <bprakash@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r--drivers/net/cnic.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 9be0c261b8b0..94a2e541006d 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -5334,6 +5334,27 @@ static struct cnic_dev *is_cnic_dev(struct net_device *dev)
5334 return cdev; 5334 return cdev;
5335} 5335}
5336 5336
5337static void cnic_rcv_netevent(struct cnic_local *cp, unsigned long event,
5338 u16 vlan_id)
5339{
5340 int if_type;
5341
5342 rcu_read_lock();
5343 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
5344 struct cnic_ulp_ops *ulp_ops;
5345 void *ctx;
5346
5347 ulp_ops = rcu_dereference(cp->ulp_ops[if_type]);
5348 if (!ulp_ops || !ulp_ops->indicate_netevent)
5349 continue;
5350
5351 ctx = cp->ulp_handle[if_type];
5352
5353 ulp_ops->indicate_netevent(ctx, event, vlan_id);
5354 }
5355 rcu_read_unlock();
5356}
5357
5337/** 5358/**
5338 * netdev event handler 5359 * netdev event handler
5339 */ 5360 */
@@ -5342,7 +5363,6 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
5342{ 5363{
5343 struct net_device *netdev = ptr; 5364 struct net_device *netdev = ptr;
5344 struct cnic_dev *dev; 5365 struct cnic_dev *dev;
5345 int if_type;
5346 int new_dev = 0; 5366 int new_dev = 0;
5347 5367
5348 dev = cnic_from_netdev(netdev); 5368 dev = cnic_from_netdev(netdev);
@@ -5372,20 +5392,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
5372 cnic_ulp_start(dev); 5392 cnic_ulp_start(dev);
5373 } 5393 }
5374 5394
5375 rcu_read_lock(); 5395 cnic_rcv_netevent(cp, event, 0);
5376 for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
5377 struct cnic_ulp_ops *ulp_ops;
5378 void *ctx;
5379
5380 ulp_ops = rcu_dereference(cp->ulp_ops[if_type]);
5381 if (!ulp_ops || !ulp_ops->indicate_netevent)
5382 continue;
5383
5384 ctx = cp->ulp_handle[if_type];
5385
5386 ulp_ops->indicate_netevent(ctx, event);
5387 }
5388 rcu_read_unlock();
5389 5396
5390 if (event == NETDEV_GOING_DOWN) { 5397 if (event == NETDEV_GOING_DOWN) {
5391 cnic_ulp_stop(dev); 5398 cnic_ulp_stop(dev);
@@ -5401,6 +5408,19 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
5401 goto done; 5408 goto done;
5402 } 5409 }
5403 cnic_put(dev); 5410 cnic_put(dev);
5411 } else {
5412 struct net_device *realdev;
5413 u16 vid;
5414
5415 vid = cnic_get_vlan(netdev, &realdev);
5416 if (realdev) {
5417 dev = cnic_from_netdev(realdev);
5418 if (dev) {
5419 vid |= VLAN_TAG_PRESENT;
5420 cnic_rcv_netevent(dev->cnic_priv, event, vid);
5421 cnic_put(dev);
5422 }
5423 }
5404 } 5424 }
5405done: 5425done:
5406 return NOTIFY_DONE; 5426 return NOTIFY_DONE;