diff options
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mcg.c | 85 | ||||
| -rw-r--r-- | include/linux/mlx4/device.h | 12 |
2 files changed, 70 insertions, 27 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 07712f976c8f..00b4e7be7c7e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
| @@ -645,17 +645,28 @@ static int find_entry(struct mlx4_dev *dev, u8 port, | |||
| 645 | return err; | 645 | return err; |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | static const u8 __promisc_mode[] = { | ||
| 649 | [MLX4_FS_REGULAR] = 0x0, | ||
| 650 | [MLX4_FS_ALL_DEFAULT] = 0x1, | ||
| 651 | [MLX4_FS_MC_DEFAULT] = 0x3, | ||
| 652 | [MLX4_FS_UC_SNIFFER] = 0x4, | ||
| 653 | [MLX4_FS_MC_SNIFFER] = 0x5, | ||
| 654 | }; | ||
| 655 | |||
| 656 | int mlx4_map_sw_to_hw_steering_mode(struct mlx4_dev *dev, | ||
| 657 | enum mlx4_net_trans_promisc_mode flow_type) | ||
| 658 | { | ||
| 659 | if (flow_type >= MLX4_FS_MODE_NUM || flow_type < 0) { | ||
| 660 | mlx4_err(dev, "Invalid flow type. type = %d\n", flow_type); | ||
| 661 | return -EINVAL; | ||
| 662 | } | ||
| 663 | return __promisc_mode[flow_type]; | ||
| 664 | } | ||
| 665 | EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_mode); | ||
| 666 | |||
| 648 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, | 667 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, |
| 649 | struct mlx4_net_trans_rule_hw_ctrl *hw) | 668 | struct mlx4_net_trans_rule_hw_ctrl *hw) |
| 650 | { | 669 | { |
| 651 | static const u8 __promisc_mode[] = { | ||
| 652 | [MLX4_FS_REGULAR] = 0x0, | ||
| 653 | [MLX4_FS_ALL_DEFAULT] = 0x1, | ||
| 654 | [MLX4_FS_MC_DEFAULT] = 0x3, | ||
| 655 | [MLX4_FS_UC_SNIFFER] = 0x4, | ||
| 656 | [MLX4_FS_MC_SNIFFER] = 0x5, | ||
| 657 | }; | ||
| 658 | |||
| 659 | u8 flags = 0; | 670 | u8 flags = 0; |
| 660 | 671 | ||
| 661 | flags = ctrl->queue_mode == MLX4_NET_TRANS_Q_LIFO ? 1 : 0; | 672 | flags = ctrl->queue_mode == MLX4_NET_TRANS_Q_LIFO ? 1 : 0; |
| @@ -678,29 +689,51 @@ const u16 __sw_id_hw[] = { | |||
| 678 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 | 689 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 |
| 679 | }; | 690 | }; |
| 680 | 691 | ||
| 692 | int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev, | ||
| 693 | enum mlx4_net_trans_rule_id id) | ||
| 694 | { | ||
| 695 | if (id >= MLX4_NET_TRANS_RULE_NUM || id < 0) { | ||
| 696 | mlx4_err(dev, "Invalid network rule id. id = %d\n", id); | ||
| 697 | return -EINVAL; | ||
| 698 | } | ||
| 699 | return __sw_id_hw[id]; | ||
| 700 | } | ||
| 701 | EXPORT_SYMBOL_GPL(mlx4_map_sw_to_hw_steering_id); | ||
| 702 | |||
| 703 | static const int __rule_hw_sz[] = { | ||
| 704 | [MLX4_NET_TRANS_RULE_ID_ETH] = | ||
| 705 | sizeof(struct mlx4_net_trans_rule_hw_eth), | ||
| 706 | [MLX4_NET_TRANS_RULE_ID_IB] = | ||
| 707 | sizeof(struct mlx4_net_trans_rule_hw_ib), | ||
| 708 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0, | ||
| 709 | [MLX4_NET_TRANS_RULE_ID_IPV4] = | ||
| 710 | sizeof(struct mlx4_net_trans_rule_hw_ipv4), | ||
| 711 | [MLX4_NET_TRANS_RULE_ID_TCP] = | ||
| 712 | sizeof(struct mlx4_net_trans_rule_hw_tcp_udp), | ||
| 713 | [MLX4_NET_TRANS_RULE_ID_UDP] = | ||
| 714 | sizeof(struct mlx4_net_trans_rule_hw_tcp_udp) | ||
| 715 | }; | ||
| 716 | |||
| 717 | int mlx4_hw_rule_sz(struct mlx4_dev *dev, | ||
| 718 | enum mlx4_net_trans_rule_id id) | ||
| 719 | { | ||
| 720 | if (id >= MLX4_NET_TRANS_RULE_NUM || id < 0) { | ||
| 721 | mlx4_err(dev, "Invalid network rule id. id = %d\n", id); | ||
| 722 | return -EINVAL; | ||
| 723 | } | ||
| 724 | |||
| 725 | return __rule_hw_sz[id]; | ||
| 726 | } | ||
| 727 | EXPORT_SYMBOL_GPL(mlx4_hw_rule_sz); | ||
| 728 | |||
| 681 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, | 729 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, |
| 682 | struct _rule_hw *rule_hw) | 730 | struct _rule_hw *rule_hw) |
| 683 | { | 731 | { |
| 684 | static const size_t __rule_hw_sz[] = { | 732 | if (mlx4_hw_rule_sz(dev, spec->id) < 0) |
| 685 | [MLX4_NET_TRANS_RULE_ID_ETH] = | ||
| 686 | sizeof(struct mlx4_net_trans_rule_hw_eth), | ||
| 687 | [MLX4_NET_TRANS_RULE_ID_IB] = | ||
| 688 | sizeof(struct mlx4_net_trans_rule_hw_ib), | ||
| 689 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0, | ||
| 690 | [MLX4_NET_TRANS_RULE_ID_IPV4] = | ||
| 691 | sizeof(struct mlx4_net_trans_rule_hw_ipv4), | ||
| 692 | [MLX4_NET_TRANS_RULE_ID_TCP] = | ||
| 693 | sizeof(struct mlx4_net_trans_rule_hw_tcp_udp), | ||
| 694 | [MLX4_NET_TRANS_RULE_ID_UDP] = | ||
| 695 | sizeof(struct mlx4_net_trans_rule_hw_tcp_udp) | ||
| 696 | }; | ||
| 697 | if (spec->id >= MLX4_NET_TRANS_RULE_NUM) { | ||
| 698 | mlx4_err(dev, "Invalid network rule id. id = %d\n", spec->id); | ||
| 699 | return -EINVAL; | 733 | return -EINVAL; |
| 700 | } | 734 | memset(rule_hw, 0, mlx4_hw_rule_sz(dev, spec->id)); |
| 701 | memset(rule_hw, 0, __rule_hw_sz[spec->id]); | ||
| 702 | rule_hw->id = cpu_to_be16(__sw_id_hw[spec->id]); | 735 | rule_hw->id = cpu_to_be16(__sw_id_hw[spec->id]); |
| 703 | rule_hw->size = __rule_hw_sz[spec->id] >> 2; | 736 | rule_hw->size = mlx4_hw_rule_sz(dev, spec->id) >> 2; |
| 704 | 737 | ||
| 705 | switch (spec->id) { | 738 | switch (spec->id) { |
| 706 | case MLX4_NET_TRANS_RULE_ID_ETH: | 739 | case MLX4_NET_TRANS_RULE_ID_ETH: |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 08e5bc1387e1..ad4a53fbdddf 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
| @@ -901,7 +901,7 @@ enum mlx4_net_trans_promisc_mode { | |||
| 901 | MLX4_FS_MC_DEFAULT, | 901 | MLX4_FS_MC_DEFAULT, |
| 902 | MLX4_FS_UC_SNIFFER, | 902 | MLX4_FS_UC_SNIFFER, |
| 903 | MLX4_FS_MC_SNIFFER, | 903 | MLX4_FS_MC_SNIFFER, |
| 904 | 904 | MLX4_FS_MODE_NUM, /* should be last */ | |
| 905 | }; | 905 | }; |
| 906 | 906 | ||
| 907 | struct mlx4_spec_eth { | 907 | struct mlx4_spec_eth { |
| @@ -1044,6 +1044,11 @@ struct _rule_hw { | |||
| 1044 | }; | 1044 | }; |
| 1045 | }; | 1045 | }; |
| 1046 | 1046 | ||
| 1047 | /* translating DMFS verbs sniffer rule to the FW API would need two reg IDs */ | ||
| 1048 | struct mlx4_flow_handle { | ||
| 1049 | u64 reg_id[2]; | ||
| 1050 | }; | ||
| 1051 | |||
| 1047 | int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, u32 qpn, | 1052 | int mlx4_flow_steer_promisc_add(struct mlx4_dev *dev, u8 port, u32 qpn, |
| 1048 | enum mlx4_net_trans_promisc_mode mode); | 1053 | enum mlx4_net_trans_promisc_mode mode); |
| 1049 | int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port, | 1054 | int mlx4_flow_steer_promisc_remove(struct mlx4_dev *dev, u8 port, |
| @@ -1093,6 +1098,11 @@ void mlx4_counter_free(struct mlx4_dev *dev, u32 idx); | |||
| 1093 | int mlx4_flow_attach(struct mlx4_dev *dev, | 1098 | int mlx4_flow_attach(struct mlx4_dev *dev, |
| 1094 | struct mlx4_net_trans_rule *rule, u64 *reg_id); | 1099 | struct mlx4_net_trans_rule *rule, u64 *reg_id); |
| 1095 | int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id); | 1100 | int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id); |
| 1101 | int mlx4_map_sw_to_hw_steering_mode(struct mlx4_dev *dev, | ||
| 1102 | enum mlx4_net_trans_promisc_mode flow_type); | ||
| 1103 | int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev, | ||
| 1104 | enum mlx4_net_trans_rule_id id); | ||
| 1105 | int mlx4_hw_rule_sz(struct mlx4_dev *dev, enum mlx4_net_trans_rule_id id); | ||
| 1096 | 1106 | ||
| 1097 | void mlx4_sync_pkey_table(struct mlx4_dev *dev, int slave, int port, | 1107 | void mlx4_sync_pkey_table(struct mlx4_dev *dev, int slave, int port, |
| 1098 | int i, int val); | 1108 | int i, int val); |
