aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_main.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c176
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h5
3 files changed, 189 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index c643d2bbb7b9..58d5a07d0ff4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -214,6 +214,8 @@ static void mlx4_en_remove(struct mlx4_dev *dev, void *endev_ptr)
214 iounmap(mdev->uar_map); 214 iounmap(mdev->uar_map);
215 mlx4_uar_free(dev, &mdev->priv_uar); 215 mlx4_uar_free(dev, &mdev->priv_uar);
216 mlx4_pd_free(dev, mdev->priv_pdn); 216 mlx4_pd_free(dev, mdev->priv_pdn);
217 if (mdev->nb.notifier_call)
218 unregister_netdevice_notifier(&mdev->nb);
217 kfree(mdev); 219 kfree(mdev);
218} 220}
219 221
@@ -298,6 +300,12 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
298 if (mlx4_en_init_netdev(mdev, i, &mdev->profile.prof[i])) 300 if (mlx4_en_init_netdev(mdev, i, &mdev->profile.prof[i]))
299 mdev->pndev[i] = NULL; 301 mdev->pndev[i] = NULL;
300 } 302 }
303 /* register notifier */
304 mdev->nb.notifier_call = mlx4_en_netdev_event;
305 if (register_netdevice_notifier(&mdev->nb)) {
306 mdev->nb.notifier_call = NULL;
307 mlx4_err(mdev, "Failed to create notifier\n");
308 }
301 309
302 return mdev; 310 return mdev;
303 311
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index e075ff1f4e80..028937b2a199 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2062,6 +2062,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
2062 /* Detach the netdev so tasks would not attempt to access it */ 2062 /* Detach the netdev so tasks would not attempt to access it */
2063 mutex_lock(&mdev->state_lock); 2063 mutex_lock(&mdev->state_lock);
2064 mdev->pndev[priv->port] = NULL; 2064 mdev->pndev[priv->port] = NULL;
2065 mdev->upper[priv->port] = NULL;
2065 mutex_unlock(&mdev->state_lock); 2066 mutex_unlock(&mdev->state_lock);
2066 2067
2067 mlx4_en_free_resources(priv); 2068 mlx4_en_free_resources(priv);
@@ -2441,6 +2442,180 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
2441#endif 2442#endif
2442}; 2443};
2443 2444
2445struct mlx4_en_bond {
2446 struct work_struct work;
2447 struct mlx4_en_priv *priv;
2448 int is_bonded;
2449 struct mlx4_port_map port_map;
2450};
2451
2452static void mlx4_en_bond_work(struct work_struct *work)
2453{
2454 struct mlx4_en_bond *bond = container_of(work,
2455 struct mlx4_en_bond,
2456 work);
2457 int err = 0;
2458 struct mlx4_dev *dev = bond->priv->mdev->dev;
2459
2460 if (bond->is_bonded) {
2461 if (!mlx4_is_bonded(dev)) {
2462 err = mlx4_bond(dev);
2463 if (err)
2464 en_err(bond->priv, "Fail to bond device\n");
2465 }
2466 if (!err) {
2467 err = mlx4_port_map_set(dev, &bond->port_map);
2468 if (err)
2469 en_err(bond->priv, "Fail to set port map [%d][%d]: %d\n",
2470 bond->port_map.port1,
2471 bond->port_map.port2,
2472 err);
2473 }
2474 } else if (mlx4_is_bonded(dev)) {
2475 err = mlx4_unbond(dev);
2476 if (err)
2477 en_err(bond->priv, "Fail to unbond device\n");
2478 }
2479 dev_put(bond->priv->dev);
2480 kfree(bond);
2481}
2482
2483static int mlx4_en_queue_bond_work(struct mlx4_en_priv *priv, int is_bonded,
2484 u8 v2p_p1, u8 v2p_p2)
2485{
2486 struct mlx4_en_bond *bond = NULL;
2487
2488 bond = kzalloc(sizeof(*bond), GFP_ATOMIC);
2489 if (!bond)
2490 return -ENOMEM;
2491
2492 INIT_WORK(&bond->work, mlx4_en_bond_work);
2493 bond->priv = priv;
2494 bond->is_bonded = is_bonded;
2495 bond->port_map.port1 = v2p_p1;
2496 bond->port_map.port2 = v2p_p2;
2497 dev_hold(priv->dev);
2498 queue_work(priv->mdev->workqueue, &bond->work);
2499 return 0;
2500}
2501
2502int mlx4_en_netdev_event(struct notifier_block *this,
2503 unsigned long event, void *ptr)
2504{
2505 struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
2506 u8 port = 0;
2507 struct mlx4_en_dev *mdev;
2508 struct mlx4_dev *dev;
2509 int i, num_eth_ports = 0;
2510 bool do_bond = true;
2511 struct mlx4_en_priv *priv;
2512 u8 v2p_port1 = 0;
2513 u8 v2p_port2 = 0;
2514
2515 if (!net_eq(dev_net(ndev), &init_net))
2516 return NOTIFY_DONE;
2517
2518 mdev = container_of(this, struct mlx4_en_dev, nb);
2519 dev = mdev->dev;
2520
2521 /* Go into this mode only when two network devices set on two ports
2522 * of the same mlx4 device are slaves of the same bonding master
2523 */
2524 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
2525 ++num_eth_ports;
2526 if (!port && (mdev->pndev[i] == ndev))
2527 port = i;
2528 mdev->upper[i] = mdev->pndev[i] ?
2529 netdev_master_upper_dev_get(mdev->pndev[i]) : NULL;
2530 /* condition not met: network device is a slave */
2531 if (!mdev->upper[i])
2532 do_bond = false;
2533 if (num_eth_ports < 2)
2534 continue;
2535 /* condition not met: same master */
2536 if (mdev->upper[i] != mdev->upper[i-1])
2537 do_bond = false;
2538 }
2539 /* condition not met: 2 salves */
2540 do_bond = (num_eth_ports == 2) ? do_bond : false;
2541
2542 /* handle only events that come with enough info */
2543 if ((do_bond && (event != NETDEV_BONDING_INFO)) || !port)
2544 return NOTIFY_DONE;
2545
2546 priv = netdev_priv(ndev);
2547 if (do_bond) {
2548 struct netdev_notifier_bonding_info *notifier_info = ptr;
2549 struct netdev_bonding_info *bonding_info =
2550 &notifier_info->bonding_info;
2551
2552 /* required mode 1, 2 or 4 */
2553 if ((bonding_info->master.bond_mode != BOND_MODE_ACTIVEBACKUP) &&
2554 (bonding_info->master.bond_mode != BOND_MODE_XOR) &&
2555 (bonding_info->master.bond_mode != BOND_MODE_8023AD))
2556 do_bond = false;
2557
2558 /* require exactly 2 slaves */
2559 if (bonding_info->master.num_slaves != 2)
2560 do_bond = false;
2561
2562 /* calc v2p */
2563 if (do_bond) {
2564 if (bonding_info->master.bond_mode ==
2565 BOND_MODE_ACTIVEBACKUP) {
2566 /* in active-backup mode virtual ports are
2567 * mapped to the physical port of the active
2568 * slave */
2569 if (bonding_info->slave.state ==
2570 BOND_STATE_BACKUP) {
2571 if (port == 1) {
2572 v2p_port1 = 2;
2573 v2p_port2 = 2;
2574 } else {
2575 v2p_port1 = 1;
2576 v2p_port2 = 1;
2577 }
2578 } else { /* BOND_STATE_ACTIVE */
2579 if (port == 1) {
2580 v2p_port1 = 1;
2581 v2p_port2 = 1;
2582 } else {
2583 v2p_port1 = 2;
2584 v2p_port2 = 2;
2585 }
2586 }
2587 } else { /* Active-Active */
2588 /* in active-active mode a virtual port is
2589 * mapped to the native physical port if and only
2590 * if the physical port is up */
2591 __s8 link = bonding_info->slave.link;
2592
2593 if (port == 1)
2594 v2p_port2 = 2;
2595 else
2596 v2p_port1 = 1;
2597 if ((link == BOND_LINK_UP) ||
2598 (link == BOND_LINK_FAIL)) {
2599 if (port == 1)
2600 v2p_port1 = 1;
2601 else
2602 v2p_port2 = 2;
2603 } else { /* BOND_LINK_DOWN || BOND_LINK_BACK */
2604 if (port == 1)
2605 v2p_port1 = 2;
2606 else
2607 v2p_port2 = 1;
2608 }
2609 }
2610 }
2611 }
2612
2613 mlx4_en_queue_bond_work(priv, do_bond,
2614 v2p_port1, v2p_port2);
2615
2616 return NOTIFY_DONE;
2617}
2618
2444int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, 2619int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
2445 struct mlx4_en_port_profile *prof) 2620 struct mlx4_en_port_profile *prof)
2446{ 2621{
@@ -2623,6 +2798,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
2623 } 2798 }
2624 2799
2625 mdev->pndev[port] = dev; 2800 mdev->pndev[port] = dev;
2801 mdev->upper[port] = NULL;
2626 2802
2627 netif_carrier_off(dev); 2803 netif_carrier_off(dev);
2628 mlx4_en_set_default_moderation(priv); 2804 mlx4_en_set_default_moderation(priv);
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 944a112dff37..2a8268e6be15 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -390,6 +390,7 @@ struct mlx4_en_dev {
390 struct pci_dev *pdev; 390 struct pci_dev *pdev;
391 struct mutex state_lock; 391 struct mutex state_lock;
392 struct net_device *pndev[MLX4_MAX_PORTS + 1]; 392 struct net_device *pndev[MLX4_MAX_PORTS + 1];
393 struct net_device *upper[MLX4_MAX_PORTS + 1];
393 u32 port_cnt; 394 u32 port_cnt;
394 bool device_up; 395 bool device_up;
395 struct mlx4_en_profile profile; 396 struct mlx4_en_profile profile;
@@ -410,6 +411,7 @@ struct mlx4_en_dev {
410 unsigned long overflow_period; 411 unsigned long overflow_period;
411 struct ptp_clock *ptp_clock; 412 struct ptp_clock *ptp_clock;
412 struct ptp_clock_info ptp_clock_info; 413 struct ptp_clock_info ptp_clock_info;
414 struct notifier_block nb;
413}; 415};
414 416
415 417
@@ -845,6 +847,9 @@ int mlx4_en_reset_config(struct net_device *dev,
845 struct hwtstamp_config ts_config, 847 struct hwtstamp_config ts_config,
846 netdev_features_t new_features); 848 netdev_features_t new_features);
847 849
850int mlx4_en_netdev_event(struct notifier_block *this,
851 unsigned long event, void *ptr);
852
848/* 853/*
849 * Functions for time stamping 854 * Functions for time stamping
850 */ 855 */