diff options
author | Yan Burman <yanb@mellanox.com> | 2013-02-06 21:25:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-07 23:26:13 -0500 |
commit | 0eb74fdda4ff72535849f9d99a8eabe69dceaddf (patch) | |
tree | 957e7b6434ed83a48e7e4b043156064e2c9194ef | |
parent | 16a10ffd20a13215243bdba64c8e57ef277a55b9 (diff) |
net/mlx4_en: Re-arrange ndo_set_rx_mode related code
Currently, mlx4_en_do_set_multicast serves as the ndo_set_rx_mode entry for mlx4_en,
doing all related work. Split it to few calls, one per required functionality
(e.g multicast, promiscuous, etc) and rename some structures and calls
to use rx_mode notation instead of multicast.
Signed-off-by: Yan Burman <yanb@mellanox.com>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 271 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 2 |
2 files changed, 145 insertions, 128 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 63a1ef348387..80067d572c0c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -747,165 +747,142 @@ static void update_mclist_flags(struct mlx4_en_priv *priv, | |||
747 | } | 747 | } |
748 | } | 748 | } |
749 | 749 | ||
750 | static void mlx4_en_set_multicast(struct net_device *dev) | 750 | static void mlx4_en_set_rx_mode(struct net_device *dev) |
751 | { | 751 | { |
752 | struct mlx4_en_priv *priv = netdev_priv(dev); | 752 | struct mlx4_en_priv *priv = netdev_priv(dev); |
753 | 753 | ||
754 | if (!priv->port_up) | 754 | if (!priv->port_up) |
755 | return; | 755 | return; |
756 | 756 | ||
757 | queue_work(priv->mdev->workqueue, &priv->mcast_task); | 757 | queue_work(priv->mdev->workqueue, &priv->rx_mode_task); |
758 | } | 758 | } |
759 | 759 | ||
760 | static void mlx4_en_do_set_multicast(struct work_struct *work) | 760 | static void mlx4_en_set_promisc_mode(struct mlx4_en_priv *priv, |
761 | struct mlx4_en_dev *mdev) | ||
761 | { | 762 | { |
762 | struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, | ||
763 | mcast_task); | ||
764 | struct mlx4_en_dev *mdev = priv->mdev; | ||
765 | struct net_device *dev = priv->dev; | ||
766 | struct mlx4_en_mc_list *mclist, *tmp; | ||
767 | u64 mcast_addr = 0; | ||
768 | u8 mc_list[16] = {0}; | ||
769 | int err = 0; | 763 | int err = 0; |
770 | 764 | ||
771 | mutex_lock(&mdev->state_lock); | 765 | if (!(priv->flags & MLX4_EN_FLAG_PROMISC)) { |
772 | if (!mdev->device_up) { | ||
773 | en_dbg(HW, priv, "Card is not up, ignoring multicast change.\n"); | ||
774 | goto out; | ||
775 | } | ||
776 | if (!priv->port_up) { | ||
777 | en_dbg(HW, priv, "Port is down, ignoring multicast change.\n"); | ||
778 | goto out; | ||
779 | } | ||
780 | |||
781 | if (!netif_carrier_ok(dev)) { | ||
782 | if (!mlx4_en_QUERY_PORT(mdev, priv->port)) { | ||
783 | if (priv->port_state.link_state) { | ||
784 | priv->last_link_state = MLX4_DEV_EVENT_PORT_UP; | ||
785 | netif_carrier_on(dev); | ||
786 | en_dbg(LINK, priv, "Link Up\n"); | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | |||
791 | /* | ||
792 | * Promsicuous mode: disable all filters | ||
793 | */ | ||
794 | |||
795 | if (dev->flags & IFF_PROMISC) { | ||
796 | if (!(priv->flags & MLX4_EN_FLAG_PROMISC)) { | ||
797 | if (netif_msg_rx_status(priv)) | ||
798 | en_warn(priv, "Entering promiscuous mode\n"); | ||
799 | priv->flags |= MLX4_EN_FLAG_PROMISC; | ||
800 | |||
801 | /* Enable promiscouos mode */ | ||
802 | switch (mdev->dev->caps.steering_mode) { | ||
803 | case MLX4_STEERING_MODE_DEVICE_MANAGED: | ||
804 | err = mlx4_flow_steer_promisc_add(mdev->dev, | ||
805 | priv->port, | ||
806 | priv->base_qpn, | ||
807 | MLX4_FS_PROMISC_UPLINK); | ||
808 | if (err) | ||
809 | en_err(priv, "Failed enabling promiscuous mode\n"); | ||
810 | priv->flags |= MLX4_EN_FLAG_MC_PROMISC; | ||
811 | break; | ||
812 | |||
813 | case MLX4_STEERING_MODE_B0: | ||
814 | err = mlx4_unicast_promisc_add(mdev->dev, | ||
815 | priv->base_qpn, | ||
816 | priv->port); | ||
817 | if (err) | ||
818 | en_err(priv, "Failed enabling unicast promiscuous mode\n"); | ||
819 | |||
820 | /* Add the default qp number as multicast | ||
821 | * promisc | ||
822 | */ | ||
823 | if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { | ||
824 | err = mlx4_multicast_promisc_add(mdev->dev, | ||
825 | priv->base_qpn, | ||
826 | priv->port); | ||
827 | if (err) | ||
828 | en_err(priv, "Failed enabling multicast promiscuous mode\n"); | ||
829 | priv->flags |= MLX4_EN_FLAG_MC_PROMISC; | ||
830 | } | ||
831 | break; | ||
832 | |||
833 | case MLX4_STEERING_MODE_A0: | ||
834 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, | ||
835 | priv->port, | ||
836 | priv->base_qpn, | ||
837 | 1); | ||
838 | if (err) | ||
839 | en_err(priv, "Failed enabling promiscuous mode\n"); | ||
840 | break; | ||
841 | } | ||
842 | |||
843 | /* Disable port multicast filter (unconditionally) */ | ||
844 | err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, | ||
845 | 0, MLX4_MCAST_DISABLE); | ||
846 | if (err) | ||
847 | en_err(priv, "Failed disabling multicast filter\n"); | ||
848 | |||
849 | /* Disable port VLAN filter */ | ||
850 | err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); | ||
851 | if (err) | ||
852 | en_err(priv, "Failed disabling VLAN filter\n"); | ||
853 | } | ||
854 | goto out; | ||
855 | } | ||
856 | |||
857 | /* | ||
858 | * Not in promiscuous mode | ||
859 | */ | ||
860 | |||
861 | if (priv->flags & MLX4_EN_FLAG_PROMISC) { | ||
862 | if (netif_msg_rx_status(priv)) | 766 | if (netif_msg_rx_status(priv)) |
863 | en_warn(priv, "Leaving promiscuous mode\n"); | 767 | en_warn(priv, "Entering promiscuous mode\n"); |
864 | priv->flags &= ~MLX4_EN_FLAG_PROMISC; | 768 | priv->flags |= MLX4_EN_FLAG_PROMISC; |
865 | 769 | ||
866 | /* Disable promiscouos mode */ | 770 | /* Enable promiscouos mode */ |
867 | switch (mdev->dev->caps.steering_mode) { | 771 | switch (mdev->dev->caps.steering_mode) { |
868 | case MLX4_STEERING_MODE_DEVICE_MANAGED: | 772 | case MLX4_STEERING_MODE_DEVICE_MANAGED: |
869 | err = mlx4_flow_steer_promisc_remove(mdev->dev, | 773 | err = mlx4_flow_steer_promisc_add(mdev->dev, |
870 | priv->port, | 774 | priv->port, |
871 | MLX4_FS_PROMISC_UPLINK); | 775 | priv->base_qpn, |
776 | MLX4_FS_PROMISC_UPLINK); | ||
872 | if (err) | 777 | if (err) |
873 | en_err(priv, "Failed disabling promiscuous mode\n"); | 778 | en_err(priv, "Failed enabling promiscuous mode\n"); |
874 | priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; | 779 | priv->flags |= MLX4_EN_FLAG_MC_PROMISC; |
875 | break; | 780 | break; |
876 | 781 | ||
877 | case MLX4_STEERING_MODE_B0: | 782 | case MLX4_STEERING_MODE_B0: |
878 | err = mlx4_unicast_promisc_remove(mdev->dev, | 783 | err = mlx4_unicast_promisc_add(mdev->dev, |
879 | priv->base_qpn, | 784 | priv->base_qpn, |
880 | priv->port); | 785 | priv->port); |
881 | if (err) | 786 | if (err) |
882 | en_err(priv, "Failed disabling unicast promiscuous mode\n"); | 787 | en_err(priv, "Failed enabling unicast promiscuous mode\n"); |
883 | /* Disable Multicast promisc */ | 788 | |
884 | if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { | 789 | /* Add the default qp number as multicast |
885 | err = mlx4_multicast_promisc_remove(mdev->dev, | 790 | * promisc |
886 | priv->base_qpn, | 791 | */ |
887 | priv->port); | 792 | if (!(priv->flags & MLX4_EN_FLAG_MC_PROMISC)) { |
793 | err = mlx4_multicast_promisc_add(mdev->dev, | ||
794 | priv->base_qpn, | ||
795 | priv->port); | ||
888 | if (err) | 796 | if (err) |
889 | en_err(priv, "Failed disabling multicast promiscuous mode\n"); | 797 | en_err(priv, "Failed enabling multicast promiscuous mode\n"); |
890 | priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; | 798 | priv->flags |= MLX4_EN_FLAG_MC_PROMISC; |
891 | } | 799 | } |
892 | break; | 800 | break; |
893 | 801 | ||
894 | case MLX4_STEERING_MODE_A0: | 802 | case MLX4_STEERING_MODE_A0: |
895 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, | 803 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, |
896 | priv->port, | 804 | priv->port, |
897 | priv->base_qpn, 0); | 805 | priv->base_qpn, |
806 | 1); | ||
898 | if (err) | 807 | if (err) |
899 | en_err(priv, "Failed disabling promiscuous mode\n"); | 808 | en_err(priv, "Failed enabling promiscuous mode\n"); |
900 | break; | 809 | break; |
901 | } | 810 | } |
902 | 811 | ||
903 | /* Enable port VLAN filter */ | 812 | /* Disable port multicast filter (unconditionally) */ |
813 | err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, | ||
814 | 0, MLX4_MCAST_DISABLE); | ||
815 | if (err) | ||
816 | en_err(priv, "Failed disabling multicast filter\n"); | ||
817 | |||
818 | /* Disable port VLAN filter */ | ||
904 | err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); | 819 | err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); |
905 | if (err) | 820 | if (err) |
906 | en_err(priv, "Failed enabling VLAN filter\n"); | 821 | en_err(priv, "Failed disabling VLAN filter\n"); |
822 | } | ||
823 | } | ||
824 | |||
825 | static void mlx4_en_clear_promisc_mode(struct mlx4_en_priv *priv, | ||
826 | struct mlx4_en_dev *mdev) | ||
827 | { | ||
828 | int err = 0; | ||
829 | |||
830 | if (netif_msg_rx_status(priv)) | ||
831 | en_warn(priv, "Leaving promiscuous mode\n"); | ||
832 | priv->flags &= ~MLX4_EN_FLAG_PROMISC; | ||
833 | |||
834 | /* Disable promiscouos mode */ | ||
835 | switch (mdev->dev->caps.steering_mode) { | ||
836 | case MLX4_STEERING_MODE_DEVICE_MANAGED: | ||
837 | err = mlx4_flow_steer_promisc_remove(mdev->dev, | ||
838 | priv->port, | ||
839 | MLX4_FS_PROMISC_UPLINK); | ||
840 | if (err) | ||
841 | en_err(priv, "Failed disabling promiscuous mode\n"); | ||
842 | priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; | ||
843 | break; | ||
844 | |||
845 | case MLX4_STEERING_MODE_B0: | ||
846 | err = mlx4_unicast_promisc_remove(mdev->dev, | ||
847 | priv->base_qpn, | ||
848 | priv->port); | ||
849 | if (err) | ||
850 | en_err(priv, "Failed disabling unicast promiscuous mode\n"); | ||
851 | /* Disable Multicast promisc */ | ||
852 | if (priv->flags & MLX4_EN_FLAG_MC_PROMISC) { | ||
853 | err = mlx4_multicast_promisc_remove(mdev->dev, | ||
854 | priv->base_qpn, | ||
855 | priv->port); | ||
856 | if (err) | ||
857 | en_err(priv, "Failed disabling multicast promiscuous mode\n"); | ||
858 | priv->flags &= ~MLX4_EN_FLAG_MC_PROMISC; | ||
859 | } | ||
860 | break; | ||
861 | |||
862 | case MLX4_STEERING_MODE_A0: | ||
863 | err = mlx4_SET_PORT_qpn_calc(mdev->dev, | ||
864 | priv->port, | ||
865 | priv->base_qpn, 0); | ||
866 | if (err) | ||
867 | en_err(priv, "Failed disabling promiscuous mode\n"); | ||
868 | break; | ||
907 | } | 869 | } |
908 | 870 | ||
871 | /* Enable port VLAN filter */ | ||
872 | err = mlx4_SET_VLAN_FLTR(mdev->dev, priv); | ||
873 | if (err) | ||
874 | en_err(priv, "Failed enabling VLAN filter\n"); | ||
875 | } | ||
876 | |||
877 | static void mlx4_en_do_multicast(struct mlx4_en_priv *priv, | ||
878 | struct net_device *dev, | ||
879 | struct mlx4_en_dev *mdev) | ||
880 | { | ||
881 | struct mlx4_en_mc_list *mclist, *tmp; | ||
882 | u64 mcast_addr = 0; | ||
883 | u8 mc_list[16] = {0}; | ||
884 | int err = 0; | ||
885 | |||
909 | /* Enable/disable the multicast filter according to IFF_ALLMULTI */ | 886 | /* Enable/disable the multicast filter according to IFF_ALLMULTI */ |
910 | if (dev->flags & IFF_ALLMULTI) { | 887 | if (dev->flags & IFF_ALLMULTI) { |
911 | err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, | 888 | err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, |
@@ -1018,6 +995,46 @@ static void mlx4_en_do_set_multicast(struct work_struct *work) | |||
1018 | } | 995 | } |
1019 | } | 996 | } |
1020 | } | 997 | } |
998 | } | ||
999 | |||
1000 | static void mlx4_en_do_set_rx_mode(struct work_struct *work) | ||
1001 | { | ||
1002 | struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, | ||
1003 | rx_mode_task); | ||
1004 | struct mlx4_en_dev *mdev = priv->mdev; | ||
1005 | struct net_device *dev = priv->dev; | ||
1006 | |||
1007 | mutex_lock(&mdev->state_lock); | ||
1008 | if (!mdev->device_up) { | ||
1009 | en_dbg(HW, priv, "Card is not up, ignoring rx mode change.\n"); | ||
1010 | goto out; | ||
1011 | } | ||
1012 | if (!priv->port_up) { | ||
1013 | en_dbg(HW, priv, "Port is down, ignoring rx mode change.\n"); | ||
1014 | goto out; | ||
1015 | } | ||
1016 | |||
1017 | if (!netif_carrier_ok(dev)) { | ||
1018 | if (!mlx4_en_QUERY_PORT(mdev, priv->port)) { | ||
1019 | if (priv->port_state.link_state) { | ||
1020 | priv->last_link_state = MLX4_DEV_EVENT_PORT_UP; | ||
1021 | netif_carrier_on(dev); | ||
1022 | en_dbg(LINK, priv, "Link Up\n"); | ||
1023 | } | ||
1024 | } | ||
1025 | } | ||
1026 | |||
1027 | /* Promsicuous mode: disable all filters */ | ||
1028 | if (dev->flags & IFF_PROMISC) { | ||
1029 | mlx4_en_set_promisc_mode(priv, mdev); | ||
1030 | goto out; | ||
1031 | } | ||
1032 | |||
1033 | /* Not in promiscuous mode */ | ||
1034 | if (priv->flags & MLX4_EN_FLAG_PROMISC) | ||
1035 | mlx4_en_clear_promisc_mode(priv, mdev); | ||
1036 | |||
1037 | mlx4_en_do_multicast(priv, dev, mdev); | ||
1021 | out: | 1038 | out: |
1022 | mutex_unlock(&mdev->state_lock); | 1039 | mutex_unlock(&mdev->state_lock); |
1023 | } | 1040 | } |
@@ -1374,7 +1391,7 @@ int mlx4_en_start_port(struct net_device *dev) | |||
1374 | priv->flags &= ~(MLX4_EN_FLAG_PROMISC | MLX4_EN_FLAG_MC_PROMISC); | 1391 | priv->flags &= ~(MLX4_EN_FLAG_PROMISC | MLX4_EN_FLAG_MC_PROMISC); |
1375 | 1392 | ||
1376 | /* Schedule multicast task to populate multicast list */ | 1393 | /* Schedule multicast task to populate multicast list */ |
1377 | queue_work(mdev->workqueue, &priv->mcast_task); | 1394 | queue_work(mdev->workqueue, &priv->rx_mode_task); |
1378 | 1395 | ||
1379 | mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); | 1396 | mlx4_set_stats_bitmap(mdev->dev, &priv->stats_bitmap); |
1380 | 1397 | ||
@@ -1777,7 +1794,7 @@ static const struct net_device_ops mlx4_netdev_ops = { | |||
1777 | .ndo_start_xmit = mlx4_en_xmit, | 1794 | .ndo_start_xmit = mlx4_en_xmit, |
1778 | .ndo_select_queue = mlx4_en_select_queue, | 1795 | .ndo_select_queue = mlx4_en_select_queue, |
1779 | .ndo_get_stats = mlx4_en_get_stats, | 1796 | .ndo_get_stats = mlx4_en_get_stats, |
1780 | .ndo_set_rx_mode = mlx4_en_set_multicast, | 1797 | .ndo_set_rx_mode = mlx4_en_set_rx_mode, |
1781 | .ndo_set_mac_address = mlx4_en_set_mac, | 1798 | .ndo_set_mac_address = mlx4_en_set_mac, |
1782 | .ndo_validate_addr = eth_validate_addr, | 1799 | .ndo_validate_addr = eth_validate_addr, |
1783 | .ndo_change_mtu = mlx4_en_change_mtu, | 1800 | .ndo_change_mtu = mlx4_en_change_mtu, |
@@ -1847,7 +1864,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
1847 | priv->mac_index = -1; | 1864 | priv->mac_index = -1; |
1848 | priv->msg_enable = MLX4_EN_MSG_LEVEL; | 1865 | priv->msg_enable = MLX4_EN_MSG_LEVEL; |
1849 | spin_lock_init(&priv->stats_lock); | 1866 | spin_lock_init(&priv->stats_lock); |
1850 | INIT_WORK(&priv->mcast_task, mlx4_en_do_set_multicast); | 1867 | INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode); |
1851 | INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac); | 1868 | INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac); |
1852 | INIT_WORK(&priv->watchdog_task, mlx4_en_restart); | 1869 | INIT_WORK(&priv->watchdog_task, mlx4_en_restart); |
1853 | INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); | 1870 | INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 84ed328582ac..47c9876a2449 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -504,7 +504,7 @@ struct mlx4_en_priv { | |||
504 | struct mlx4_en_cq *tx_cq; | 504 | struct mlx4_en_cq *tx_cq; |
505 | struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; | 505 | struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; |
506 | struct mlx4_qp drop_qp; | 506 | struct mlx4_qp drop_qp; |
507 | struct work_struct mcast_task; | 507 | struct work_struct rx_mode_task; |
508 | struct work_struct mac_task; | 508 | struct work_struct mac_task; |
509 | struct work_struct watchdog_task; | 509 | struct work_struct watchdog_task; |
510 | struct work_struct linkstate_task; | 510 | struct work_struct linkstate_task; |