@@ -1490,6 +1490,69 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave,
14901490 return ret ;
14911491}
14921492
1493+ static int mlx4_master_activate_admin_state (struct mlx4_priv * priv , int slave )
1494+ {
1495+ int port , err ;
1496+ struct mlx4_vport_state * vp_admin ;
1497+ struct mlx4_vport_oper_state * vp_oper ;
1498+
1499+ for (port = 1 ; port <= MLX4_MAX_PORTS ; port ++ ) {
1500+ vp_oper = & priv -> mfunc .master .vf_oper [slave ].vport [port ];
1501+ vp_admin = & priv -> mfunc .master .vf_admin [slave ].vport [port ];
1502+ vp_oper -> state = * vp_admin ;
1503+ if (MLX4_VGT != vp_admin -> default_vlan ) {
1504+ err = __mlx4_register_vlan (& priv -> dev , port ,
1505+ vp_admin -> default_vlan , & (vp_oper -> vlan_idx ));
1506+ if (err ) {
1507+ vp_oper -> vlan_idx = NO_INDX ;
1508+ mlx4_warn ((& priv -> dev ),
1509+ "No vlan resorces slave %d, port %d\n" ,
1510+ slave , port );
1511+ return err ;
1512+ }
1513+ mlx4_dbg ((& (priv -> dev )), "alloc vlan %d idx %d slave %d port %d\n" ,
1514+ (int )(vp_oper -> state .default_vlan ),
1515+ vp_oper -> vlan_idx , slave , port );
1516+ }
1517+ if (vp_admin -> spoofchk ) {
1518+ vp_oper -> mac_idx = __mlx4_register_mac (& priv -> dev ,
1519+ port ,
1520+ vp_admin -> mac );
1521+ if (0 > vp_oper -> mac_idx ) {
1522+ err = vp_oper -> mac_idx ;
1523+ vp_oper -> mac_idx = NO_INDX ;
1524+ mlx4_warn ((& priv -> dev ),
1525+ "No mac resorces slave %d, port %d\n" ,
1526+ slave , port );
1527+ return err ;
1528+ }
1529+ mlx4_dbg ((& (priv -> dev )), "alloc mac %llx idx %d slave %d port %d\n" ,
1530+ vp_oper -> state .mac , vp_oper -> mac_idx , slave , port );
1531+ }
1532+ }
1533+ return 0 ;
1534+ }
1535+
1536+ static void mlx4_master_deactivate_admin_state (struct mlx4_priv * priv , int slave )
1537+ {
1538+ int port ;
1539+ struct mlx4_vport_oper_state * vp_oper ;
1540+
1541+ for (port = 1 ; port <= MLX4_MAX_PORTS ; port ++ ) {
1542+ vp_oper = & priv -> mfunc .master .vf_oper [slave ].vport [port ];
1543+ if (NO_INDX != vp_oper -> vlan_idx ) {
1544+ __mlx4_unregister_vlan (& priv -> dev ,
1545+ port , vp_oper -> vlan_idx );
1546+ vp_oper -> vlan_idx = NO_INDX ;
1547+ }
1548+ if (NO_INDX != vp_oper -> mac_idx ) {
1549+ __mlx4_unregister_mac (& priv -> dev , port , vp_oper -> mac_idx );
1550+ vp_oper -> mac_idx = NO_INDX ;
1551+ }
1552+ }
1553+ return ;
1554+ }
1555+
14931556static void mlx4_master_do_cmd (struct mlx4_dev * dev , int slave , u8 cmd ,
14941557 u16 param , u8 toggle )
14951558{
@@ -1510,6 +1573,7 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
15101573 if (cmd == MLX4_COMM_CMD_RESET ) {
15111574 mlx4_warn (dev , "Received reset from slave:%d\n" , slave );
15121575 slave_state [slave ].active = false;
1576+ mlx4_master_deactivate_admin_state (priv , slave );
15131577 for (i = 0 ; i < MLX4_EVENT_TYPES_NUM ; ++ i ) {
15141578 slave_state [slave ].event_eq [i ].eqn = -1 ;
15151579 slave_state [slave ].event_eq [i ].token = 0 ;
@@ -1556,6 +1620,8 @@ static void mlx4_master_do_cmd(struct mlx4_dev *dev, int slave, u8 cmd,
15561620 if (slave_state [slave ].last_cmd != MLX4_COMM_CMD_VHCR2 )
15571621 goto reset_slave ;
15581622 slave_state [slave ].vhcr_dma |= param ;
1623+ if (mlx4_master_activate_admin_state (priv , slave ))
1624+ goto reset_slave ;
15591625 slave_state [slave ].active = true;
15601626 mlx4_dispatch_event (dev , MLX4_DEV_EVENT_SLAVE_INIT , slave );
15611627 break ;
@@ -1732,6 +1798,18 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
17321798 if (!priv -> mfunc .master .slave_state )
17331799 goto err_comm ;
17341800
1801+ priv -> mfunc .master .vf_admin =
1802+ kzalloc (dev -> num_slaves *
1803+ sizeof (struct mlx4_vf_admin_state ), GFP_KERNEL );
1804+ if (!priv -> mfunc .master .vf_admin )
1805+ goto err_comm_admin ;
1806+
1807+ priv -> mfunc .master .vf_oper =
1808+ kzalloc (dev -> num_slaves *
1809+ sizeof (struct mlx4_vf_oper_state ), GFP_KERNEL );
1810+ if (!priv -> mfunc .master .vf_oper )
1811+ goto err_comm_oper ;
1812+
17351813 for (i = 0 ; i < dev -> num_slaves ; ++ i ) {
17361814 s_state = & priv -> mfunc .master .slave_state [i ];
17371815 s_state -> last_cmd = MLX4_COMM_CMD_RESET ;
@@ -1752,6 +1830,10 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
17521830 goto err_slaves ;
17531831 }
17541832 INIT_LIST_HEAD (& s_state -> mcast_filters [port ]);
1833+ priv -> mfunc .master .vf_admin [i ].vport [port ].default_vlan = MLX4_VGT ;
1834+ priv -> mfunc .master .vf_oper [i ].vport [port ].state .default_vlan = MLX4_VGT ;
1835+ priv -> mfunc .master .vf_oper [i ].vport [port ].vlan_idx = NO_INDX ;
1836+ priv -> mfunc .master .vf_oper [i ].vport [port ].mac_idx = NO_INDX ;
17551837 }
17561838 spin_lock_init (& s_state -> lock );
17571839 }
@@ -1800,6 +1882,10 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
18001882 for (port = 1 ; port <= MLX4_MAX_PORTS ; port ++ )
18011883 kfree (priv -> mfunc .master .slave_state [i ].vlan_filter [port ]);
18021884 }
1885+ kfree (priv -> mfunc .master .vf_oper );
1886+ err_comm_oper :
1887+ kfree (priv -> mfunc .master .vf_admin );
1888+ err_comm_admin :
18031889 kfree (priv -> mfunc .master .slave_state );
18041890err_comm :
18051891 iounmap (priv -> mfunc .comm );
@@ -1874,6 +1960,8 @@ void mlx4_multi_func_cleanup(struct mlx4_dev *dev)
18741960 kfree (priv -> mfunc .master .slave_state [i ].vlan_filter [port ]);
18751961 }
18761962 kfree (priv -> mfunc .master .slave_state );
1963+ kfree (priv -> mfunc .master .vf_admin );
1964+ kfree (priv -> mfunc .master .vf_oper );
18771965 }
18781966
18791967 iounmap (priv -> mfunc .comm );
@@ -1984,3 +2072,115 @@ u32 mlx4_comm_get_version(void)
19842072{
19852073 return ((u32 ) CMD_CHAN_IF_REV << 8 ) | (u32 ) CMD_CHAN_VER ;
19862074}
2075+
2076+ static int mlx4_get_slave_indx (struct mlx4_dev * dev , int vf )
2077+ {
2078+ if ((vf < 0 ) || (vf >= dev -> num_vfs )) {
2079+ mlx4_err (dev , "Bad vf number:%d (number of activated vf: %d)\n" , vf , dev -> num_vfs );
2080+ return - EINVAL ;
2081+ }
2082+
2083+ return vf + 1 ;
2084+ }
2085+
2086+ int mlx4_set_vf_mac (struct mlx4_dev * dev , int port , int vf , u64 mac )
2087+ {
2088+ struct mlx4_priv * priv = mlx4_priv (dev );
2089+ struct mlx4_vport_state * s_info ;
2090+ int slave ;
2091+
2092+ if (!mlx4_is_master (dev ))
2093+ return - EPROTONOSUPPORT ;
2094+
2095+ slave = mlx4_get_slave_indx (dev , vf );
2096+ if (slave < 0 )
2097+ return - EINVAL ;
2098+
2099+ s_info = & priv -> mfunc .master .vf_admin [slave ].vport [port ];
2100+ s_info -> mac = mac ;
2101+ mlx4_info (dev , "default mac on vf %d port %d to %llX will take afect only after vf restart\n" ,
2102+ vf , port , s_info -> mac );
2103+ return 0 ;
2104+ }
2105+ EXPORT_SYMBOL_GPL (mlx4_set_vf_mac );
2106+
2107+ int mlx4_set_vf_vlan (struct mlx4_dev * dev , int port , int vf , u16 vlan , u8 qos )
2108+ {
2109+ struct mlx4_priv * priv = mlx4_priv (dev );
2110+ struct mlx4_vport_state * s_info ;
2111+ int slave ;
2112+
2113+ if ((!mlx4_is_master (dev )) ||
2114+ !(dev -> caps .flags2 & MLX4_DEV_CAP_FLAG2_VLAN_CONTROL ))
2115+ return - EPROTONOSUPPORT ;
2116+
2117+ if ((vlan > 4095 ) || (qos > 7 ))
2118+ return - EINVAL ;
2119+
2120+ slave = mlx4_get_slave_indx (dev , vf );
2121+ if (slave < 0 )
2122+ return - EINVAL ;
2123+
2124+ s_info = & priv -> mfunc .master .vf_admin [slave ].vport [port ];
2125+ if ((0 == vlan ) && (0 == qos ))
2126+ s_info -> default_vlan = MLX4_VGT ;
2127+ else
2128+ s_info -> default_vlan = vlan ;
2129+ s_info -> default_qos = qos ;
2130+ return 0 ;
2131+ }
2132+ EXPORT_SYMBOL_GPL (mlx4_set_vf_vlan );
2133+
2134+ int mlx4_set_vf_spoofchk (struct mlx4_dev * dev , int port , int vf , bool setting )
2135+ {
2136+ struct mlx4_priv * priv = mlx4_priv (dev );
2137+ struct mlx4_vport_state * s_info ;
2138+ int slave ;
2139+
2140+ if ((!mlx4_is_master (dev )) ||
2141+ !(dev -> caps .flags2 & MLX4_DEV_CAP_FLAG2_FSM ))
2142+ return - EPROTONOSUPPORT ;
2143+
2144+ slave = mlx4_get_slave_indx (dev , vf );
2145+ if (slave < 0 )
2146+ return - EINVAL ;
2147+
2148+ s_info = & priv -> mfunc .master .vf_admin [slave ].vport [port ];
2149+ s_info -> spoofchk = setting ;
2150+
2151+ return 0 ;
2152+ }
2153+ EXPORT_SYMBOL_GPL (mlx4_set_vf_spoofchk );
2154+
2155+ int mlx4_get_vf_config (struct mlx4_dev * dev , int port , int vf , struct ifla_vf_info * ivf )
2156+ {
2157+ struct mlx4_priv * priv = mlx4_priv (dev );
2158+ struct mlx4_vport_state * s_info ;
2159+ int slave ;
2160+
2161+ if (!mlx4_is_master (dev ))
2162+ return - EPROTONOSUPPORT ;
2163+
2164+ slave = mlx4_get_slave_indx (dev , vf );
2165+ if (slave < 0 )
2166+ return - EINVAL ;
2167+
2168+ s_info = & priv -> mfunc .master .vf_admin [slave ].vport [port ];
2169+ ivf -> vf = vf ;
2170+
2171+ /* need to convert it to a func */
2172+ ivf -> mac [0 ] = ((s_info -> mac >> (5 * 8 )) & 0xff );
2173+ ivf -> mac [1 ] = ((s_info -> mac >> (4 * 8 )) & 0xff );
2174+ ivf -> mac [2 ] = ((s_info -> mac >> (3 * 8 )) & 0xff );
2175+ ivf -> mac [3 ] = ((s_info -> mac >> (2 * 8 )) & 0xff );
2176+ ivf -> mac [4 ] = ((s_info -> mac >> (1 * 8 )) & 0xff );
2177+ ivf -> mac [5 ] = ((s_info -> mac ) & 0xff );
2178+
2179+ ivf -> vlan = s_info -> default_vlan ;
2180+ ivf -> qos = s_info -> default_qos ;
2181+ ivf -> tx_rate = s_info -> tx_rate ;
2182+ ivf -> spoofchk = s_info -> spoofchk ;
2183+
2184+ return 0 ;
2185+ }
2186+ EXPORT_SYMBOL_GPL (mlx4_get_vf_config );
0 commit comments