1010#include <linux/types.h>
1111
1212#define QLCNIC_SRIOV_VF_MAX_MAC 1
13+ #define QLC_VF_MIN_TX_RATE 100
14+ #define QLC_VF_MAX_TX_RATE 9999
1315
1416static int qlcnic_sriov_pf_get_vport_handle (struct qlcnic_adapter * , u8 );
1517
@@ -62,8 +64,9 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter,
6264{
6365 struct qlcnic_sriov * sriov = adapter -> ahw -> sriov ;
6466 struct qlcnic_resources * res = & sriov -> ff_max ;
65- int ret = - EIO , vpid ;
6667 u32 temp , num_vf_macs , num_vfs , max ;
68+ int ret = - EIO , vpid , id ;
69+ struct qlcnic_vport * vp ;
6770
6871 vpid = qlcnic_sriov_pf_get_vport_handle (adapter , func );
6972 if (vpid < 0 )
@@ -72,8 +75,6 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter,
7275 num_vfs = sriov -> num_vfs ;
7376 max = num_vfs + 1 ;
7477 info -> bit_offsets = 0xffff ;
75- info -> min_tx_bw = 0 ;
76- info -> max_tx_bw = MAX_BW ;
7778 info -> max_tx_ques = res -> num_tx_queues / max ;
7879 info -> max_rx_mcast_mac_filters = res -> num_rx_mcast_mac_filters ;
7980 num_vf_macs = QLCNIC_SRIOV_VF_MAX_MAC ;
@@ -83,7 +84,15 @@ static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter,
8384 info -> max_rx_ucast_mac_filters = temp ;
8485 temp = res -> num_tx_mac_filters - (num_vfs * num_vf_macs );
8586 info -> max_tx_mac_filters = temp ;
87+ info -> min_tx_bw = 0 ;
88+ info -> max_tx_bw = MAX_BW ;
8689 } else {
90+ id = qlcnic_sriov_func_to_index (adapter , func );
91+ if (id < 0 )
92+ return id ;
93+ vp = sriov -> vf_info [id ].vp ;
94+ info -> min_tx_bw = vp -> min_tx_bw ;
95+ info -> max_tx_bw = vp -> max_tx_bw ;
8796 info -> max_rx_ucast_mac_filters = num_vf_macs ;
8897 info -> max_tx_mac_filters = num_vf_macs ;
8998 }
@@ -1416,3 +1425,119 @@ int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *adapter)
14161425 __func__ , ahw -> op_mode );
14171426 return err ;
14181427}
1428+
1429+ int qlcnic_sriov_set_vf_mac (struct net_device * netdev , int vf , u8 * mac )
1430+ {
1431+ struct qlcnic_adapter * adapter = netdev_priv (netdev );
1432+ struct qlcnic_sriov * sriov = adapter -> ahw -> sriov ;
1433+ int i , num_vfs = sriov -> num_vfs ;
1434+ struct qlcnic_vf_info * vf_info ;
1435+ u8 * curr_mac ;
1436+
1437+ if (!qlcnic_sriov_pf_check (adapter ))
1438+ return - EOPNOTSUPP ;
1439+
1440+ if (!is_valid_ether_addr (mac ) || vf >= num_vfs )
1441+ return - EINVAL ;
1442+
1443+ if (!compare_ether_addr (adapter -> mac_addr , mac )) {
1444+ netdev_err (netdev , "MAC address is already in use by the PF\n" );
1445+ return - EINVAL ;
1446+ }
1447+
1448+ for (i = 0 ; i < num_vfs ; i ++ ) {
1449+ vf_info = & sriov -> vf_info [i ];
1450+ if (!compare_ether_addr (vf_info -> vp -> mac , mac )) {
1451+ netdev_err (netdev ,
1452+ "MAC address is already in use by VF %d\n" ,
1453+ i );
1454+ return - EINVAL ;
1455+ }
1456+ }
1457+
1458+ vf_info = & sriov -> vf_info [vf ];
1459+ curr_mac = vf_info -> vp -> mac ;
1460+
1461+ if (test_bit (QLC_BC_VF_STATE , & vf_info -> state )) {
1462+ netdev_err (netdev ,
1463+ "MAC address change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation\n" ,
1464+ vf );
1465+ return - EOPNOTSUPP ;
1466+ }
1467+
1468+ memcpy (curr_mac , mac , netdev -> addr_len );
1469+ netdev_info (netdev , "MAC Address %pM is configured for VF %d\n" ,
1470+ mac , vf );
1471+ return 0 ;
1472+ }
1473+
1474+ int qlcnic_sriov_set_vf_tx_rate (struct net_device * netdev , int vf , int tx_rate )
1475+ {
1476+ struct qlcnic_adapter * adapter = netdev_priv (netdev );
1477+ struct qlcnic_sriov * sriov = adapter -> ahw -> sriov ;
1478+ struct qlcnic_vf_info * vf_info ;
1479+ struct qlcnic_info nic_info ;
1480+ struct qlcnic_vport * vp ;
1481+ u16 vpid ;
1482+
1483+ if (!qlcnic_sriov_pf_check (adapter ))
1484+ return - EOPNOTSUPP ;
1485+
1486+ if (vf >= sriov -> num_vfs )
1487+ return - EINVAL ;
1488+
1489+ if (tx_rate >= 10000 || tx_rate < 100 ) {
1490+ netdev_err (netdev ,
1491+ "Invalid Tx rate, allowed range is [%d - %d]" ,
1492+ QLC_VF_MIN_TX_RATE , QLC_VF_MAX_TX_RATE );
1493+ return - EINVAL ;
1494+ }
1495+
1496+ if (tx_rate == 0 )
1497+ tx_rate = 10000 ;
1498+
1499+ vf_info = & sriov -> vf_info [vf ];
1500+ vp = vf_info -> vp ;
1501+ vpid = vp -> handle ;
1502+
1503+ if (test_bit (QLC_BC_VF_STATE , & vf_info -> state )) {
1504+ if (qlcnic_sriov_get_vf_vport_info (adapter , & nic_info , vpid ))
1505+ return - EIO ;
1506+
1507+ nic_info .max_tx_bw = tx_rate / 100 ;
1508+ nic_info .bit_offsets = BIT_0 ;
1509+
1510+ if (qlcnic_sriov_pf_set_vport_info (adapter , & nic_info , vpid ))
1511+ return - EIO ;
1512+ }
1513+
1514+ vp -> max_tx_bw = tx_rate / 100 ;
1515+ netdev_info (netdev ,
1516+ "Setting Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d\n" ,
1517+ tx_rate , vp -> max_tx_bw , vf );
1518+ return 0 ;
1519+ }
1520+
1521+ int qlcnic_sriov_get_vf_config (struct net_device * netdev ,
1522+ int vf , struct ifla_vf_info * ivi )
1523+ {
1524+ struct qlcnic_adapter * adapter = netdev_priv (netdev );
1525+ struct qlcnic_sriov * sriov = adapter -> ahw -> sriov ;
1526+ struct qlcnic_vport * vp ;
1527+
1528+ if (!qlcnic_sriov_pf_check (adapter ))
1529+ return - EOPNOTSUPP ;
1530+
1531+ if (vf >= sriov -> num_vfs )
1532+ return - EINVAL ;
1533+
1534+ vp = sriov -> vf_info [vf ].vp ;
1535+ memcpy (& ivi -> mac , vp -> mac , ETH_ALEN );
1536+ if (vp -> max_tx_bw == MAX_BW )
1537+ ivi -> tx_rate = 0 ;
1538+ else
1539+ ivi -> tx_rate = vp -> max_tx_bw * 100 ;
1540+
1541+ ivi -> vf = vf ;
1542+ return 0 ;
1543+ }
0 commit comments