2020-09-08 14:34:49 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2013-03-29 05:46:33 +00:00
/*
* QLogic qlcnic NIC Driver
* Copyright ( c ) 2009 - 2013 QLogic Corporation
*/
2015-08-07 07:17:02 -04:00
# include <linux/types.h>
2013-03-29 05:46:33 +00:00
# include "qlcnic_sriov.h"
# include "qlcnic.h"
2014-01-10 11:48:52 -05:00
# define QLCNIC_SRIOV_VF_MAX_MAC 7
2013-04-19 07:01:11 +00:00
# define QLC_VF_MIN_TX_RATE 100
# define QLC_VF_MAX_TX_RATE 9999
2014-01-10 11:48:52 -05:00
# define QLC_MAC_OPCODE_MASK 0x7
2014-01-10 11:48:53 -05:00
# define QLC_VF_FLOOD_BIT BIT_16
# define QLC_FLOOD_MODE 0x5
2014-02-21 13:20:13 -05:00
# define QLC_SRIOV_ALLOW_VLAN0 BIT_19
2014-04-25 17:43:58 -04:00
# define QLC_INTR_COAL_TYPE_MASK 0x7
2013-03-29 05:46:33 +00:00
static int qlcnic_sriov_pf_get_vport_handle ( struct qlcnic_adapter * , u8 ) ;
2013-03-29 05:46:36 +00:00
struct qlcnic_sriov_cmd_handler {
int ( * fn ) ( struct qlcnic_bc_trans * , struct qlcnic_cmd_args * ) ;
} ;
2013-03-29 05:46:37 +00:00
struct qlcnic_sriov_fw_cmd_handler {
u32 cmd ;
int ( * fn ) ( struct qlcnic_bc_trans * , struct qlcnic_cmd_args * ) ;
} ;
2013-03-29 05:46:33 +00:00
static int qlcnic_sriov_pf_set_vport_info ( struct qlcnic_adapter * adapter ,
struct qlcnic_info * npar_info ,
u16 vport_id )
{
struct qlcnic_cmd_args cmd ;
int err ;
if ( qlcnic_alloc_mbx_args ( & cmd , adapter , QLCNIC_CMD_SET_NIC_INFO ) )
return - ENOMEM ;
cmd . req . arg [ 1 ] = ( vport_id < < 16 ) | 0x1 ;
cmd . req . arg [ 2 ] = npar_info - > bit_offsets ;
cmd . req . arg [ 2 ] | = npar_info - > min_tx_bw < < 16 ;
cmd . req . arg [ 3 ] = npar_info - > max_tx_bw | ( npar_info - > max_tx_ques < < 16 ) ;
cmd . req . arg [ 4 ] = npar_info - > max_tx_mac_filters ;
cmd . req . arg [ 4 ] | = npar_info - > max_rx_mcast_mac_filters < < 16 ;
cmd . req . arg [ 5 ] = npar_info - > max_rx_ucast_mac_filters |
( npar_info - > max_rx_ip_addr < < 16 ) ;
cmd . req . arg [ 6 ] = npar_info - > max_rx_lro_flow |
( npar_info - > max_rx_status_rings < < 16 ) ;
cmd . req . arg [ 7 ] = npar_info - > max_rx_buf_rings |
( npar_info - > max_rx_ques < < 16 ) ;
cmd . req . arg [ 8 ] = npar_info - > max_tx_vlan_keys ;
cmd . req . arg [ 8 ] | = npar_info - > max_local_ipv6_addrs < < 16 ;
cmd . req . arg [ 9 ] = npar_info - > max_remote_ipv6_addrs ;
err = qlcnic_issue_cmd ( adapter , & cmd ) ;
if ( err )
dev_err ( & adapter - > pdev - > dev ,
" Failed to set vport info, err=%d \n " , err ) ;
qlcnic_free_mbx_args ( & cmd ) ;
return err ;
}
static int qlcnic_sriov_pf_cal_res_limit ( struct qlcnic_adapter * adapter ,
struct qlcnic_info * info , u16 func )
{
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
struct qlcnic_resources * res = & sriov - > ff_max ;
2013-12-17 09:01:53 -05:00
u16 num_macs = sriov - > num_allowed_vlans + 1 ;
2013-04-19 07:01:11 +00:00
int ret = - EIO , vpid , id ;
struct qlcnic_vport * vp ;
2013-12-17 09:01:53 -05:00
u32 num_vfs , max , temp ;
2013-03-29 05:46:33 +00:00
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter , func ) ;
if ( vpid < 0 )
return - EINVAL ;
num_vfs = sriov - > num_vfs ;
max = num_vfs + 1 ;
info - > bit_offsets = 0xffff ;
info - > max_tx_ques = res - > num_tx_queues / max ;
2013-12-17 09:01:53 -05:00
if ( qlcnic_83xx_pf_check ( adapter ) )
2014-05-09 02:51:31 -04:00
num_macs = QLCNIC_83XX_SRIOV_VF_MAX_MAC ;
2013-03-29 05:46:33 +00:00
info - > max_rx_mcast_mac_filters = res - > num_rx_mcast_mac_filters ;
if ( adapter - > ahw - > pci_func = = func ) {
2013-04-19 07:01:11 +00:00
info - > min_tx_bw = 0 ;
info - > max_tx_bw = MAX_BW ;
2014-01-06 17:37:45 -05:00
2013-12-17 09:01:53 -05:00
temp = res - > num_rx_ucast_mac_filters - num_macs * num_vfs ;
info - > max_rx_ucast_mac_filters = temp ;
temp = res - > num_tx_mac_filters - num_macs * num_vfs ;
info - > max_tx_mac_filters = temp ;
temp = num_macs * num_vfs * QLCNIC_SRIOV_VF_MAX_MAC ;
temp = res - > num_rx_mcast_mac_filters - temp ;
info - > max_rx_mcast_mac_filters = temp ;
2014-01-02 13:38:44 -05:00
info - > max_tx_ques = res - > num_tx_queues - sriov - > num_vfs ;
2013-03-29 05:46:33 +00:00
} else {
2013-04-19 07:01:11 +00:00
id = qlcnic_sriov_func_to_index ( adapter , func ) ;
if ( id < 0 )
return id ;
vp = sriov - > vf_info [ id ] . vp ;
info - > min_tx_bw = vp - > min_tx_bw ;
info - > max_tx_bw = vp - > max_tx_bw ;
2014-01-06 17:37:45 -05:00
2013-12-17 09:01:53 -05:00
info - > max_rx_ucast_mac_filters = num_macs ;
info - > max_tx_mac_filters = num_macs ;
temp = num_macs * QLCNIC_SRIOV_VF_MAX_MAC ;
info - > max_rx_mcast_mac_filters = temp ;
2014-01-06 17:37:45 -05:00
2014-01-02 13:38:44 -05:00
info - > max_tx_ques = QLCNIC_SINGLE_RING ;
2013-03-29 05:46:33 +00:00
}
info - > max_rx_ip_addr = res - > num_destip / max ;
info - > max_rx_status_rings = res - > num_rx_status_rings / max ;
info - > max_rx_buf_rings = res - > num_rx_buf_rings / max ;
info - > max_rx_ques = res - > num_rx_queues / max ;
info - > max_rx_lro_flow = res - > num_lro_flows_supported / max ;
info - > max_tx_vlan_keys = res - > num_txvlan_keys ;
info - > max_local_ipv6_addrs = res - > max_local_ipv6_addrs ;
info - > max_remote_ipv6_addrs = res - > max_remote_ipv6_addrs ;
ret = qlcnic_sriov_pf_set_vport_info ( adapter , info , vpid ) ;
if ( ret )
return ret ;
return 0 ;
}
static void qlcnic_sriov_pf_set_ff_max_res ( struct qlcnic_adapter * adapter ,
struct qlcnic_info * info )
{
struct qlcnic_resources * ff_max = & adapter - > ahw - > sriov - > ff_max ;
ff_max - > num_tx_mac_filters = info - > max_tx_mac_filters ;
ff_max - > num_rx_ucast_mac_filters = info - > max_rx_ucast_mac_filters ;
ff_max - > num_rx_mcast_mac_filters = info - > max_rx_mcast_mac_filters ;
ff_max - > num_txvlan_keys = info - > max_tx_vlan_keys ;
ff_max - > num_rx_queues = info - > max_rx_ques ;
ff_max - > num_tx_queues = info - > max_tx_ques ;
ff_max - > num_lro_flows_supported = info - > max_rx_lro_flow ;
ff_max - > num_destip = info - > max_rx_ip_addr ;
ff_max - > num_rx_buf_rings = info - > max_rx_buf_rings ;
ff_max - > num_rx_status_rings = info - > max_rx_status_rings ;
ff_max - > max_remote_ipv6_addrs = info - > max_remote_ipv6_addrs ;
ff_max - > max_local_ipv6_addrs = info - > max_local_ipv6_addrs ;
}
2013-12-17 09:01:53 -05:00
static void qlcnic_sriov_set_vf_max_vlan ( struct qlcnic_adapter * adapter ,
struct qlcnic_info * npar_info )
{
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
int temp , total_fn ;
temp = npar_info - > max_rx_mcast_mac_filters ;
total_fn = sriov - > num_vfs + 1 ;
temp = temp / ( QLCNIC_SRIOV_VF_MAX_MAC * total_fn ) ;
sriov - > num_allowed_vlans = temp - 1 ;
if ( qlcnic_83xx_pf_check ( adapter ) )
sriov - > num_allowed_vlans = 1 ;
netdev_info ( adapter - > netdev , " Max Guest VLANs supported per VF = %d \n " ,
sriov - > num_allowed_vlans ) ;
}
2013-03-29 05:46:33 +00:00
static int qlcnic_sriov_get_pf_info ( struct qlcnic_adapter * adapter ,
struct qlcnic_info * npar_info )
{
int err ;
struct qlcnic_cmd_args cmd ;
if ( qlcnic_alloc_mbx_args ( & cmd , adapter , QLCNIC_CMD_GET_NIC_INFO ) )
return - ENOMEM ;
cmd . req . arg [ 1 ] = 0x2 ;
err = qlcnic_issue_cmd ( adapter , & cmd ) ;
if ( err ) {
dev_err ( & adapter - > pdev - > dev ,
" Failed to get PF info, err=%d \n " , err ) ;
goto out ;
}
npar_info - > total_pf = cmd . rsp . arg [ 2 ] & 0xff ;
npar_info - > total_rss_engines = ( cmd . rsp . arg [ 2 ] > > 8 ) & 0xff ;
npar_info - > max_vports = MSW ( cmd . rsp . arg [ 2 ] ) ;
npar_info - > max_tx_ques = LSW ( cmd . rsp . arg [ 3 ] ) ;
npar_info - > max_tx_mac_filters = MSW ( cmd . rsp . arg [ 3 ] ) ;
npar_info - > max_rx_mcast_mac_filters = LSW ( cmd . rsp . arg [ 4 ] ) ;
npar_info - > max_rx_ucast_mac_filters = MSW ( cmd . rsp . arg [ 4 ] ) ;
npar_info - > max_rx_ip_addr = LSW ( cmd . rsp . arg [ 5 ] ) ;
npar_info - > max_rx_lro_flow = MSW ( cmd . rsp . arg [ 5 ] ) ;
npar_info - > max_rx_status_rings = LSW ( cmd . rsp . arg [ 6 ] ) ;
npar_info - > max_rx_buf_rings = MSW ( cmd . rsp . arg [ 6 ] ) ;
npar_info - > max_rx_ques = LSW ( cmd . rsp . arg [ 7 ] ) ;
npar_info - > max_tx_vlan_keys = MSW ( cmd . rsp . arg [ 7 ] ) ;
npar_info - > max_local_ipv6_addrs = LSW ( cmd . rsp . arg [ 8 ] ) ;
npar_info - > max_remote_ipv6_addrs = MSW ( cmd . rsp . arg [ 8 ] ) ;
2013-12-17 09:01:53 -05:00
qlcnic_sriov_set_vf_max_vlan ( adapter , npar_info ) ;
2013-04-02 05:34:42 +00:00
qlcnic_sriov_pf_set_ff_max_res ( adapter , npar_info ) ;
2013-03-29 05:46:33 +00:00
dev_info ( & adapter - > pdev - > dev ,
" \n \t total_pf: %d, \n "
" \n \t total_rss_engines: %d max_vports: %d max_tx_ques %d, \n "
" \t max_tx_mac_filters: %d max_rx_mcast_mac_filters: %d, \n "
" \t max_rx_ucast_mac_filters: 0x%x, max_rx_ip_addr: %d, \n "
" \t max_rx_lro_flow: %d max_rx_status_rings: %d, \n "
" \t max_rx_buf_rings: %d, max_rx_ques: %d, max_tx_vlan_keys %d \n "
" \t max_local_ipv6_addrs: %d, max_remote_ipv6_addrs: %d \n " ,
npar_info - > total_pf , npar_info - > total_rss_engines ,
npar_info - > max_vports , npar_info - > max_tx_ques ,
npar_info - > max_tx_mac_filters ,
npar_info - > max_rx_mcast_mac_filters ,
npar_info - > max_rx_ucast_mac_filters , npar_info - > max_rx_ip_addr ,
npar_info - > max_rx_lro_flow , npar_info - > max_rx_status_rings ,
npar_info - > max_rx_buf_rings , npar_info - > max_rx_ques ,
npar_info - > max_tx_vlan_keys , npar_info - > max_local_ipv6_addrs ,
npar_info - > max_remote_ipv6_addrs ) ;
out :
qlcnic_free_mbx_args ( & cmd ) ;
return err ;
}
static void qlcnic_sriov_pf_reset_vport_handle ( struct qlcnic_adapter * adapter ,
u8 func )
{
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
2013-03-29 05:46:36 +00:00
struct qlcnic_vport * vp ;
int index ;
2013-03-29 05:46:33 +00:00
2013-03-29 05:46:36 +00:00
if ( adapter - > ahw - > pci_func = = func ) {
2013-03-29 05:46:33 +00:00
sriov - > vp_handle = 0 ;
2013-03-29 05:46:36 +00:00
} else {
index = qlcnic_sriov_func_to_index ( adapter , func ) ;
if ( index < 0 )
return ;
vp = sriov - > vf_info [ index ] . vp ;
vp - > handle = 0 ;
}
2013-03-29 05:46:33 +00:00
}
static void qlcnic_sriov_pf_set_vport_handle ( struct qlcnic_adapter * adapter ,
u16 vport_handle , u8 func )
{
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
2013-03-29 05:46:36 +00:00
struct qlcnic_vport * vp ;
int index ;
2013-03-29 05:46:33 +00:00
2013-03-29 05:46:36 +00:00
if ( adapter - > ahw - > pci_func = = func ) {
2013-03-29 05:46:33 +00:00
sriov - > vp_handle = vport_handle ;
2013-03-29 05:46:36 +00:00
} else {
index = qlcnic_sriov_func_to_index ( adapter , func ) ;
if ( index < 0 )
return ;
vp = sriov - > vf_info [ index ] . vp ;
vp - > handle = vport_handle ;
}
2013-03-29 05:46:33 +00:00
}
static int qlcnic_sriov_pf_get_vport_handle ( struct qlcnic_adapter * adapter ,
u8 func )
{
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
2013-03-29 05:46:36 +00:00
struct qlcnic_vf_info * vf_info ;
int index ;
2013-03-29 05:46:33 +00:00
2013-03-29 05:46:36 +00:00
if ( adapter - > ahw - > pci_func = = func ) {
2013-03-29 05:46:33 +00:00
return sriov - > vp_handle ;
2013-03-29 05:46:36 +00:00
} else {
index = qlcnic_sriov_func_to_index ( adapter , func ) ;
if ( index > = 0 ) {
vf_info = & sriov - > vf_info [ index ] ;
return vf_info - > vp - > handle ;
}
}
2013-03-29 05:46:33 +00:00
return - EINVAL ;
}
static int qlcnic_sriov_pf_config_vport ( struct qlcnic_adapter * adapter ,
u8 flag , u16 func )
{
struct qlcnic_cmd_args cmd ;
int ret ;
int vpid ;
if ( qlcnic_alloc_mbx_args ( & cmd , adapter , QLCNIC_CMD_CONFIG_VPORT ) )
return - ENOMEM ;
if ( flag ) {
cmd . req . arg [ 3 ] = func < < 8 ;
} else {
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter , func ) ;
if ( vpid < 0 ) {
ret = - EINVAL ;
goto out ;
}
cmd . req . arg [ 3 ] = ( ( vpid & 0xffff ) < < 8 ) | 1 ;
}
ret = qlcnic_issue_cmd ( adapter , & cmd ) ;
if ( ret ) {
dev_err ( & adapter - > pdev - > dev ,
" Failed %s vport, err %d for func 0x%x \n " ,
( flag ? " enable " : " disable " ) , ret , func ) ;
goto out ;
}
if ( flag ) {
vpid = cmd . rsp . arg [ 2 ] & 0xffff ;
qlcnic_sriov_pf_set_vport_handle ( adapter , vpid , func ) ;
} else {
qlcnic_sriov_pf_reset_vport_handle ( adapter , func ) ;
}
out :
qlcnic_free_mbx_args ( & cmd ) ;
return ret ;
}
2013-04-19 07:01:12 +00:00
static int qlcnic_sriov_pf_cfg_vlan_filtering ( struct qlcnic_adapter * adapter ,
u8 enable )
{
struct qlcnic_cmd_args cmd ;
int err ;
err = qlcnic_alloc_mbx_args ( & cmd , adapter , QLCNIC_CMD_SET_NIC_INFO ) ;
if ( err )
return err ;
cmd . req . arg [ 1 ] = 0x4 ;
2014-02-21 13:20:13 -05:00
if ( enable ) {
2014-05-09 02:51:31 -04:00
adapter - > flags | = QLCNIC_VLAN_FILTERING ;
2013-04-19 07:01:12 +00:00
cmd . req . arg [ 1 ] | = BIT_16 ;
2014-02-21 13:20:13 -05:00
if ( qlcnic_84xx_check ( adapter ) )
cmd . req . arg [ 1 ] | = QLC_SRIOV_ALLOW_VLAN0 ;
2014-05-09 02:51:31 -04:00
} else {
adapter - > flags & = ~ QLCNIC_VLAN_FILTERING ;
2014-02-21 13:20:13 -05:00
}
2013-04-19 07:01:12 +00:00
err = qlcnic_issue_cmd ( adapter , & cmd ) ;
if ( err )
dev_err ( & adapter - > pdev - > dev ,
" Failed to configure VLAN filtering, err=%d \n " , err ) ;
qlcnic_free_mbx_args ( & cmd ) ;
return err ;
}
2014-01-10 11:48:53 -05:00
/* On configuring VF flood bit, PFD will receive traffic from all VFs */
static int qlcnic_sriov_pf_cfg_flood ( struct qlcnic_adapter * adapter )
{
struct qlcnic_cmd_args cmd ;
int err ;
err = qlcnic_alloc_mbx_args ( & cmd , adapter , QLCNIC_CMD_SET_NIC_INFO ) ;
if ( err )
return err ;
cmd . req . arg [ 1 ] = QLC_FLOOD_MODE | QLC_VF_FLOOD_BIT ;
err = qlcnic_issue_cmd ( adapter , & cmd ) ;
if ( err )
dev_err ( & adapter - > pdev - > dev ,
" Failed to configure VF Flood bit on PF, err=%d \n " ,
err ) ;
qlcnic_free_mbx_args ( & cmd ) ;
return err ;
}
2013-03-29 05:46:33 +00:00
static int qlcnic_sriov_pf_cfg_eswitch ( struct qlcnic_adapter * adapter ,
u8 func , u8 enable )
{
struct qlcnic_cmd_args cmd ;
int err = - EIO ;
if ( qlcnic_alloc_mbx_args ( & cmd , adapter , QLCNIC_CMD_TOGGLE_ESWITCH ) )
return - ENOMEM ;
cmd . req . arg [ 0 ] | = ( 3 < < 29 ) ;
cmd . req . arg [ 1 ] = ( ( func & 0xf ) < < 2 ) | BIT_6 | BIT_1 ;
if ( enable )
cmd . req . arg [ 1 ] | = BIT_0 ;
err = qlcnic_issue_cmd ( adapter , & cmd ) ;
if ( err ! = QLCNIC_RCODE_SUCCESS ) {
dev_err ( & adapter - > pdev - > dev ,
" Failed to enable sriov eswitch%d \n " , err ) ;
err = - EIO ;
}
qlcnic_free_mbx_args ( & cmd ) ;
return err ;
}
2013-04-19 07:01:09 +00:00
static void qlcnic_sriov_pf_del_flr_queue ( struct qlcnic_adapter * adapter )
{
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
struct qlcnic_back_channel * bc = & sriov - > bc ;
int i ;
for ( i = 0 ; i < sriov - > num_vfs ; i + + )
cancel_work_sync ( & sriov - > vf_info [ i ] . flr_work ) ;
destroy_workqueue ( bc - > bc_flr_wq ) ;
}
static int qlcnic_sriov_pf_create_flr_queue ( struct qlcnic_adapter * adapter )
{
struct qlcnic_back_channel * bc = & adapter - > ahw - > sriov - > bc ;
struct workqueue_struct * wq ;
wq = create_singlethread_workqueue ( " qlcnic-flr " ) ;
if ( wq = = NULL ) {
dev_err ( & adapter - > pdev - > dev , " Cannot create FLR workqueue \n " ) ;
return - ENOMEM ;
}
bc - > bc_flr_wq = wq ;
return 0 ;
}
2013-03-29 05:46:33 +00:00
void qlcnic_sriov_pf_cleanup ( struct qlcnic_adapter * adapter )
{
u8 func = adapter - > ahw - > pci_func ;
if ( ! qlcnic_sriov_enable_check ( adapter ) )
return ;
2013-04-19 07:01:09 +00:00
qlcnic_sriov_pf_del_flr_queue ( adapter ) ;
2013-03-29 05:46:36 +00:00
qlcnic_sriov_cfg_bc_intr ( adapter , 0 ) ;
2013-03-29 05:46:33 +00:00
qlcnic_sriov_pf_config_vport ( adapter , 0 , func ) ;
qlcnic_sriov_pf_cfg_eswitch ( adapter , func , 0 ) ;
2013-04-19 07:01:12 +00:00
qlcnic_sriov_pf_cfg_vlan_filtering ( adapter , 0 ) ;
2013-03-29 05:46:33 +00:00
__qlcnic_sriov_cleanup ( adapter ) ;
adapter - > ahw - > op_mode = QLCNIC_MGMT_FUNC ;
clear_bit ( __QLCNIC_SRIOV_ENABLE , & adapter - > state ) ;
}
void qlcnic_sriov_pf_disable ( struct qlcnic_adapter * adapter )
{
if ( ! qlcnic_sriov_pf_check ( adapter ) )
return ;
if ( ! qlcnic_sriov_enable_check ( adapter ) )
return ;
pci_disable_sriov ( adapter - > pdev ) ;
netdev_info ( adapter - > netdev ,
" SR-IOV is disabled successfully on port %d \n " ,
adapter - > portnum ) ;
}
static int qlcnic_pci_sriov_disable ( struct qlcnic_adapter * adapter )
{
struct net_device * netdev = adapter - > netdev ;
2014-04-14 10:02:23 -04:00
if ( pci_vfs_assigned ( adapter - > pdev ) ) {
netdev_err ( adapter - > netdev ,
" SR-IOV VFs belonging to port %d are assigned to VMs. SR-IOV can not be disabled on this port \n " ,
adapter - > portnum ) ;
netdev_info ( adapter - > netdev ,
" Please detach SR-IOV VFs belonging to port %d from VMs, and then try to disable SR-IOV on this port \n " ,
adapter - > portnum ) ;
return - EPERM ;
}
2014-05-09 02:51:29 -04:00
qlcnic_sriov_pf_disable ( adapter ) ;
2013-10-01 02:23:48 -04:00
rtnl_lock ( ) ;
2013-03-29 05:46:33 +00:00
if ( netif_running ( netdev ) )
__qlcnic_down ( adapter , netdev ) ;
2013-12-17 09:01:53 -05:00
qlcnic_sriov_free_vlans ( adapter ) ;
2013-03-29 05:46:33 +00:00
qlcnic_sriov_pf_cleanup ( adapter ) ;
/* After disabling SRIOV re-init the driver in default mode
configure opmode based on op_mode of function
*/
2013-10-01 02:23:48 -04:00
if ( qlcnic_83xx_configure_opmode ( adapter ) ) {
rtnl_unlock ( ) ;
2013-03-29 05:46:33 +00:00
return - EIO ;
2013-10-01 02:23:48 -04:00
}
2013-03-29 05:46:33 +00:00
if ( netif_running ( netdev ) )
__qlcnic_up ( adapter , netdev ) ;
2013-10-01 02:23:48 -04:00
rtnl_unlock ( ) ;
2013-03-29 05:46:33 +00:00
return 0 ;
}
static int qlcnic_sriov_pf_init ( struct qlcnic_adapter * adapter )
{
struct qlcnic_hardware_context * ahw = adapter - > ahw ;
struct qlcnic_info nic_info , pf_info , vp_info ;
int err ;
u8 func = ahw - > pci_func ;
if ( ! qlcnic_sriov_enable_check ( adapter ) )
return 0 ;
2013-04-19 07:01:12 +00:00
err = qlcnic_sriov_pf_cfg_vlan_filtering ( adapter , 1 ) ;
2013-03-29 05:46:33 +00:00
if ( err )
2013-04-19 07:01:09 +00:00
return err ;
2013-03-29 05:46:33 +00:00
2014-01-10 11:48:53 -05:00
if ( qlcnic_84xx_check ( adapter ) ) {
err = qlcnic_sriov_pf_cfg_flood ( adapter ) ;
if ( err )
goto disable_vlan_filtering ;
}
2013-04-19 07:01:12 +00:00
err = qlcnic_sriov_pf_cfg_eswitch ( adapter , func , 1 ) ;
if ( err )
goto disable_vlan_filtering ;
2013-03-29 05:46:33 +00:00
err = qlcnic_sriov_pf_config_vport ( adapter , 1 , func ) ;
if ( err )
goto disable_eswitch ;
err = qlcnic_sriov_get_pf_info ( adapter , & pf_info ) ;
if ( err )
goto delete_vport ;
err = qlcnic_get_nic_info ( adapter , & nic_info , func ) ;
if ( err )
goto delete_vport ;
err = qlcnic_sriov_pf_cal_res_limit ( adapter , & vp_info , func ) ;
if ( err )
goto delete_vport ;
2013-03-29 05:46:36 +00:00
err = qlcnic_sriov_cfg_bc_intr ( adapter , 1 ) ;
if ( err )
goto delete_vport ;
2013-03-29 05:46:33 +00:00
ahw - > physical_port = ( u8 ) nic_info . phys_port ;
ahw - > switch_mode = nic_info . switch_mode ;
ahw - > max_mtu = nic_info . max_mtu ;
ahw - > capabilities = nic_info . capabilities ;
ahw - > nic_mode = QLC_83XX_SRIOV_MODE ;
return err ;
delete_vport :
qlcnic_sriov_pf_config_vport ( adapter , 0 , func ) ;
disable_eswitch :
qlcnic_sriov_pf_cfg_eswitch ( adapter , func , 0 ) ;
2013-04-19 07:01:12 +00:00
disable_vlan_filtering :
qlcnic_sriov_pf_cfg_vlan_filtering ( adapter , 0 ) ;
2013-03-29 05:46:33 +00:00
return err ;
}
static int qlcnic_sriov_pf_enable ( struct qlcnic_adapter * adapter , int num_vfs )
{
int err ;
if ( ! qlcnic_sriov_enable_check ( adapter ) )
return 0 ;
err = pci_enable_sriov ( adapter - > pdev , num_vfs ) ;
if ( err )
qlcnic_sriov_pf_cleanup ( adapter ) ;
return err ;
}
static int __qlcnic_pci_sriov_enable ( struct qlcnic_adapter * adapter ,
int num_vfs )
{
int err = 0 ;
set_bit ( __QLCNIC_SRIOV_ENABLE , & adapter - > state ) ;
adapter - > ahw - > op_mode = QLCNIC_SRIOV_PF_FUNC ;
2013-04-19 07:01:09 +00:00
err = qlcnic_sriov_init ( adapter , num_vfs ) ;
if ( err )
goto clear_op_mode ;
2013-03-29 05:46:33 +00:00
2013-04-19 07:01:09 +00:00
err = qlcnic_sriov_pf_create_flr_queue ( adapter ) ;
if ( err )
goto sriov_cleanup ;
err = qlcnic_sriov_pf_init ( adapter ) ;
if ( err )
goto del_flr_queue ;
2013-03-29 05:46:33 +00:00
2021-12-17 17:39:11 +08:00
err = qlcnic_sriov_alloc_vlans ( adapter ) ;
if ( err )
goto del_flr_queue ;
2013-12-17 09:01:53 -05:00
2013-03-29 05:46:33 +00:00
return err ;
2013-04-19 07:01:09 +00:00
del_flr_queue :
qlcnic_sriov_pf_del_flr_queue ( adapter ) ;
sriov_cleanup :
__qlcnic_sriov_cleanup ( adapter ) ;
clear_op_mode :
clear_bit ( __QLCNIC_SRIOV_ENABLE , & adapter - > state ) ;
adapter - > ahw - > op_mode = QLCNIC_MGMT_FUNC ;
return err ;
2013-03-29 05:46:33 +00:00
}
static int qlcnic_pci_sriov_enable ( struct qlcnic_adapter * adapter , int num_vfs )
{
struct net_device * netdev = adapter - > netdev ;
int err ;
if ( ! ( adapter - > flags & QLCNIC_MSIX_ENABLED ) ) {
netdev_err ( netdev ,
" SR-IOV cannot be enabled, when legacy interrupts are enabled \n " ) ;
return - EIO ;
}
2013-10-01 02:23:48 -04:00
rtnl_lock ( ) ;
2013-03-29 05:46:33 +00:00
if ( netif_running ( netdev ) )
__qlcnic_down ( adapter , netdev ) ;
err = __qlcnic_pci_sriov_enable ( adapter , num_vfs ) ;
2014-05-09 02:51:29 -04:00
if ( err )
goto error ;
2013-03-29 05:46:33 +00:00
2014-05-09 02:51:29 -04:00
if ( netif_running ( netdev ) )
__qlcnic_up ( adapter , netdev ) ;
rtnl_unlock ( ) ;
err = qlcnic_sriov_pf_enable ( adapter , num_vfs ) ;
if ( ! err ) {
2013-04-19 07:01:09 +00:00
netdev_info ( netdev ,
2013-03-29 05:46:33 +00:00
" SR-IOV is enabled successfully on port %d \n " ,
adapter - > portnum ) ;
2013-04-19 07:01:09 +00:00
/* Return number of vfs enabled */
2014-05-09 02:51:29 -04:00
return num_vfs ;
2013-03-29 05:46:33 +00:00
}
2014-05-09 02:51:29 -04:00
rtnl_lock ( ) ;
2013-03-29 05:46:33 +00:00
if ( netif_running ( netdev ) )
2014-05-09 02:51:29 -04:00
__qlcnic_down ( adapter , netdev ) ;
2013-03-29 05:46:33 +00:00
error :
2014-05-09 02:51:29 -04:00
if ( ! qlcnic_83xx_configure_opmode ( adapter ) ) {
if ( netif_running ( netdev ) )
__qlcnic_up ( adapter , netdev ) ;
}
2013-10-01 02:23:48 -04:00
rtnl_unlock ( ) ;
2014-05-09 02:51:29 -04:00
netdev_info ( netdev , " Failed to enable SR-IOV on port %d \n " ,
adapter - > portnum ) ;
2013-03-29 05:46:33 +00:00
return err ;
}
int qlcnic_pci_sriov_configure ( struct pci_dev * dev , int num_vfs )
{
struct qlcnic_adapter * adapter = pci_get_drvdata ( dev ) ;
int err ;
if ( test_and_set_bit ( __QLCNIC_RESETTING , & adapter - > state ) )
return - EBUSY ;
if ( num_vfs = = 0 )
err = qlcnic_pci_sriov_disable ( adapter ) ;
else
err = qlcnic_pci_sriov_enable ( adapter , num_vfs ) ;
clear_bit ( __QLCNIC_RESETTING , & adapter - > state ) ;
return err ;
}
2013-03-29 05:46:36 +00:00
2013-04-19 07:01:12 +00:00
static int qlcnic_sriov_set_vf_acl ( struct qlcnic_adapter * adapter , u8 func )
{
struct qlcnic_cmd_args cmd ;
struct qlcnic_vport * vp ;
int err , id ;
2013-05-23 21:04:25 +00:00
u8 * mac ;
2013-04-19 07:01:12 +00:00
id = qlcnic_sriov_func_to_index ( adapter , func ) ;
if ( id < 0 )
return id ;
vp = adapter - > ahw - > sriov - > vf_info [ id ] . vp ;
err = qlcnic_alloc_mbx_args ( & cmd , adapter , QLCNIC_CMD_SET_NIC_INFO ) ;
if ( err )
return err ;
cmd . req . arg [ 1 ] = 0x3 | func < < 16 ;
2013-05-23 21:04:25 +00:00
if ( vp - > spoofchk = = true ) {
mac = vp - > mac ;
cmd . req . arg [ 2 ] | = BIT_1 | BIT_3 | BIT_8 ;
cmd . req . arg [ 4 ] = mac [ 5 ] | mac [ 4 ] < < 8 | mac [ 3 ] < < 16 |
mac [ 2 ] < < 24 ;
cmd . req . arg [ 5 ] = mac [ 1 ] | mac [ 0 ] < < 8 ;
}
2013-04-19 07:01:12 +00:00
if ( vp - > vlan_mode = = QLC_PVID_MODE ) {
cmd . req . arg [ 2 ] | = BIT_6 ;
2013-12-17 09:01:53 -05:00
cmd . req . arg [ 3 ] | = vp - > pvid < < 8 ;
2013-04-19 07:01:12 +00:00
}
err = qlcnic_issue_cmd ( adapter , & cmd ) ;
if ( err )
dev_err ( & adapter - > pdev - > dev , " Failed to set ACL, err=%d \n " ,
err ) ;
qlcnic_free_mbx_args ( & cmd ) ;
return err ;
}
2013-03-29 05:46:36 +00:00
static int qlcnic_sriov_set_vf_vport_info ( struct qlcnic_adapter * adapter ,
u16 func )
{
struct qlcnic_info defvp_info ;
int err ;
err = qlcnic_sriov_pf_cal_res_limit ( adapter , & defvp_info , func ) ;
if ( err )
return - EIO ;
2013-04-19 07:01:12 +00:00
err = qlcnic_sriov_set_vf_acl ( adapter , func ) ;
if ( err )
return err ;
2013-03-29 05:46:36 +00:00
return 0 ;
}
static int qlcnic_sriov_pf_channel_cfg_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
2013-07-19 16:56:34 -04:00
struct qlcnic_vport * vp = vf - > vp ;
struct qlcnic_adapter * adapter ;
2013-12-17 09:01:53 -05:00
struct qlcnic_sriov * sriov ;
2013-03-29 05:46:36 +00:00
u16 func = vf - > pci_func ;
2013-12-17 09:01:53 -05:00
size_t size ;
2013-07-19 16:56:34 -04:00
int err ;
2013-03-29 05:46:36 +00:00
2013-07-19 16:56:34 -04:00
adapter = vf - > adapter ;
2013-12-17 09:01:53 -05:00
sriov = adapter - > ahw - > sriov ;
2013-03-29 05:46:36 +00:00
if ( trans - > req_hdr - > cmd_op = = QLCNIC_BC_CMD_CHANNEL_INIT ) {
err = qlcnic_sriov_pf_config_vport ( adapter , 1 , func ) ;
if ( ! err ) {
err = qlcnic_sriov_set_vf_vport_info ( adapter , func ) ;
if ( err )
qlcnic_sriov_pf_config_vport ( adapter , 0 , func ) ;
}
} else {
2013-12-17 09:01:53 -05:00
if ( vp - > vlan_mode = = QLC_GUEST_VLAN_MODE ) {
size = sizeof ( * vf - > sriov_vlans ) ;
size = size * sriov - > num_allowed_vlans ;
memset ( vf - > sriov_vlans , 0 , size ) ;
}
2013-03-29 05:46:36 +00:00
err = qlcnic_sriov_pf_config_vport ( adapter , 0 , func ) ;
}
if ( err )
goto err_out ;
cmd - > rsp . arg [ 0 ] | = ( 1 < < 25 ) ;
if ( trans - > req_hdr - > cmd_op = = QLCNIC_BC_CMD_CHANNEL_INIT )
set_bit ( QLC_BC_VF_STATE , & vf - > state ) ;
else
clear_bit ( QLC_BC_VF_STATE , & vf - > state ) ;
return err ;
err_out :
cmd - > rsp . arg [ 0 ] | = ( 2 < < 25 ) ;
return err ;
}
2013-03-29 05:46:37 +00:00
static int qlcnic_sriov_cfg_vf_def_mac ( struct qlcnic_adapter * adapter ,
2013-12-17 09:01:53 -05:00
struct qlcnic_vf_info * vf ,
u16 vlan , u8 op )
2013-03-29 05:46:37 +00:00
{
2014-05-09 02:51:30 -04:00
struct qlcnic_cmd_args * cmd ;
2013-03-29 05:46:37 +00:00
struct qlcnic_macvlan_mbx mv ;
2013-12-17 09:01:53 -05:00
struct qlcnic_vport * vp ;
2013-03-29 05:46:37 +00:00
u8 * addr ;
int err ;
u32 * buf ;
int vpid ;
2013-12-17 09:01:53 -05:00
vp = vf - > vp ;
2014-05-09 02:51:30 -04:00
cmd = kzalloc ( sizeof ( * cmd ) , GFP_ATOMIC ) ;
if ( ! cmd )
2013-03-29 05:46:37 +00:00
return - ENOMEM ;
2014-05-09 02:51:30 -04:00
err = qlcnic_alloc_mbx_args ( cmd , adapter , QLCNIC_CMD_CONFIG_MAC_VLAN ) ;
if ( err )
goto free_cmd ;
cmd - > type = QLC_83XX_MBX_CMD_NO_WAIT ;
2013-12-17 09:01:53 -05:00
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter , vf - > pci_func ) ;
2013-03-29 05:46:37 +00:00
if ( vpid < 0 ) {
err = - EINVAL ;
2014-05-09 02:51:30 -04:00
goto free_args ;
2013-03-29 05:46:37 +00:00
}
if ( vlan )
op = ( ( op = = QLCNIC_MAC_ADD | | op = = QLCNIC_MAC_VLAN_ADD ) ?
QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL ) ;
2014-05-09 02:51:30 -04:00
cmd - > req . arg [ 1 ] = op | ( 1 < < 8 ) | ( 3 < < 6 ) ;
cmd - > req . arg [ 1 ] | = ( ( vpid & 0xffff ) < < 16 ) | BIT_31 ;
2013-03-29 05:46:37 +00:00
addr = vp - > mac ;
2013-04-19 07:01:08 +00:00
mv . vlan = vlan ;
2013-03-29 05:46:37 +00:00
mv . mac_addr0 = addr [ 0 ] ;
mv . mac_addr1 = addr [ 1 ] ;
mv . mac_addr2 = addr [ 2 ] ;
mv . mac_addr3 = addr [ 3 ] ;
mv . mac_addr4 = addr [ 4 ] ;
mv . mac_addr5 = addr [ 5 ] ;
2014-05-09 02:51:30 -04:00
buf = & cmd - > req . arg [ 2 ] ;
2013-03-29 05:46:37 +00:00
memcpy ( buf , & mv , sizeof ( struct qlcnic_macvlan_mbx ) ) ;
2014-05-09 02:51:30 -04:00
err = qlcnic_issue_cmd ( adapter , cmd ) ;
2013-03-29 05:46:37 +00:00
2014-05-09 02:51:30 -04:00
if ( ! err )
return err ;
2013-03-29 05:46:37 +00:00
2014-05-09 02:51:30 -04:00
free_args :
qlcnic_free_mbx_args ( cmd ) ;
free_cmd :
kfree ( cmd ) ;
2013-03-29 05:46:37 +00:00
return err ;
}
static int qlcnic_sriov_validate_create_rx_ctx ( struct qlcnic_cmd_args * cmd )
{
if ( ( cmd - > req . arg [ 0 ] > > 29 ) ! = 0x3 )
return - EINVAL ;
return 0 ;
}
2013-12-17 09:01:53 -05:00
static void qlcnic_83xx_cfg_default_mac_vlan ( struct qlcnic_adapter * adapter ,
struct qlcnic_vf_info * vf ,
int opcode )
{
struct qlcnic_sriov * sriov ;
u16 vlan ;
int i ;
sriov = adapter - > ahw - > sriov ;
2014-05-09 02:51:30 -04:00
spin_lock_bh ( & vf - > vlan_list_lock ) ;
2013-12-17 09:01:53 -05:00
if ( vf - > num_vlan ) {
for ( i = 0 ; i < sriov - > num_allowed_vlans ; i + + ) {
vlan = vf - > sriov_vlans [ i ] ;
if ( vlan )
qlcnic_sriov_cfg_vf_def_mac ( adapter , vf , vlan ,
opcode ) ;
}
}
2014-05-09 02:51:30 -04:00
spin_unlock_bh ( & vf - > vlan_list_lock ) ;
2013-12-17 09:01:53 -05:00
if ( vf - > vp - > vlan_mode ! = QLC_PVID_MODE ) {
if ( qlcnic_83xx_pf_check ( adapter ) & &
qlcnic_sriov_check_any_vlan ( vf ) )
return ;
qlcnic_sriov_cfg_vf_def_mac ( adapter , vf , 0 , opcode ) ;
}
}
2013-03-29 05:46:37 +00:00
static int qlcnic_sriov_pf_create_rx_ctx_cmd ( struct qlcnic_bc_trans * tran ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = tran - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
struct qlcnic_rcv_mbx_out * mbx_out ;
int err ;
err = qlcnic_sriov_validate_create_rx_ctx ( cmd ) ;
if ( err ) {
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
return err ;
}
cmd - > req . arg [ 6 ] = vf - > vp - > handle ;
err = qlcnic_issue_cmd ( adapter , cmd ) ;
if ( ! err ) {
mbx_out = ( struct qlcnic_rcv_mbx_out * ) & cmd - > rsp . arg [ 1 ] ;
vf - > rx_ctx_id = mbx_out - > ctx_id ;
2013-12-17 09:01:53 -05:00
qlcnic_83xx_cfg_default_mac_vlan ( adapter , vf , QLCNIC_MAC_ADD ) ;
2013-03-29 05:46:37 +00:00
} else {
vf - > rx_ctx_id = 0 ;
}
return err ;
}
static int qlcnic_sriov_pf_mac_address_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
u8 type , * mac ;
type = cmd - > req . arg [ 1 ] ;
switch ( type ) {
case QLCNIC_SET_STATION_MAC :
case QLCNIC_SET_FAC_DEF_MAC :
cmd - > rsp . arg [ 0 ] = ( 2 < < 25 ) ;
break ;
case QLCNIC_GET_CURRENT_MAC :
cmd - > rsp . arg [ 0 ] = ( 1 < < 25 ) ;
mac = vf - > vp - > mac ;
cmd - > rsp . arg [ 2 ] = mac [ 1 ] | ( ( mac [ 0 ] < < 8 ) & 0xff00 ) ;
cmd - > rsp . arg [ 1 ] = mac [ 5 ] | ( ( mac [ 4 ] < < 8 ) & 0xff00 ) |
( ( mac [ 3 ] ) < < 16 & 0xff0000 ) |
( ( mac [ 2 ] ) < < 24 & 0xff000000 ) ;
}
return 0 ;
}
static int qlcnic_sriov_validate_create_tx_ctx ( struct qlcnic_cmd_args * cmd )
{
if ( ( cmd - > req . arg [ 0 ] > > 29 ) ! = 0x3 )
return - EINVAL ;
return 0 ;
}
static int qlcnic_sriov_pf_create_tx_ctx_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
struct qlcnic_tx_mbx_out * mbx_out ;
int err ;
err = qlcnic_sriov_validate_create_tx_ctx ( cmd ) ;
if ( err ) {
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
return err ;
}
cmd - > req . arg [ 5 ] | = vf - > vp - > handle < < 16 ;
err = qlcnic_issue_cmd ( adapter , cmd ) ;
if ( ! err ) {
mbx_out = ( struct qlcnic_tx_mbx_out * ) & cmd - > rsp . arg [ 2 ] ;
vf - > tx_ctx_id = mbx_out - > ctx_id ;
} else {
vf - > tx_ctx_id = 0 ;
}
return err ;
}
static int qlcnic_sriov_validate_del_rx_ctx ( struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
if ( ( cmd - > req . arg [ 0 ] > > 29 ) ! = 0x3 )
return - EINVAL ;
if ( ( cmd - > req . arg [ 1 ] & 0xffff ) ! = vf - > rx_ctx_id )
return - EINVAL ;
return 0 ;
}
static int qlcnic_sriov_pf_del_rx_ctx_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_del_rx_ctx ( vf , cmd ) ;
if ( err ) {
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
return err ;
}
2013-12-17 09:01:53 -05:00
qlcnic_83xx_cfg_default_mac_vlan ( adapter , vf , QLCNIC_MAC_DEL ) ;
2013-03-29 05:46:37 +00:00
cmd - > req . arg [ 1 ] | = vf - > vp - > handle < < 16 ;
err = qlcnic_issue_cmd ( adapter , cmd ) ;
if ( ! err )
vf - > rx_ctx_id = 0 ;
return err ;
}
static int qlcnic_sriov_validate_del_tx_ctx ( struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
if ( ( cmd - > req . arg [ 0 ] > > 29 ) ! = 0x3 )
return - EINVAL ;
if ( ( cmd - > req . arg [ 1 ] & 0xffff ) ! = vf - > tx_ctx_id )
return - EINVAL ;
return 0 ;
}
static int qlcnic_sriov_pf_del_tx_ctx_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_del_tx_ctx ( vf , cmd ) ;
if ( err ) {
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
return err ;
}
cmd - > req . arg [ 1 ] | = vf - > vp - > handle < < 16 ;
err = qlcnic_issue_cmd ( adapter , cmd ) ;
if ( ! err )
vf - > tx_ctx_id = 0 ;
return err ;
}
static int qlcnic_sriov_validate_cfg_lro ( struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
if ( ( cmd - > req . arg [ 1 ] > > 16 ) ! = vf - > rx_ctx_id )
return - EINVAL ;
return 0 ;
}
static int qlcnic_sriov_pf_cfg_lro_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_cfg_lro ( vf , cmd ) ;
if ( err ) {
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
return err ;
}
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
static int qlcnic_sriov_pf_cfg_ip_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
2019-07-03 09:32:14 +01:00
int err ;
2013-03-29 05:46:37 +00:00
cmd - > req . arg [ 1 ] | = vf - > vp - > handle < < 16 ;
cmd - > req . arg [ 1 ] | = BIT_31 ;
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
static int qlcnic_sriov_validate_cfg_intrpt ( struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
if ( ( ( cmd - > req . arg [ 1 ] > > 8 ) & 0xff ) ! = vf - > pci_func )
return - EINVAL ;
if ( ! ( cmd - > req . arg [ 1 ] & BIT_16 ) )
return - EINVAL ;
if ( ( cmd - > req . arg [ 1 ] & 0xff ) ! = 0x1 )
return - EINVAL ;
return 0 ;
}
static int qlcnic_sriov_pf_cfg_intrpt_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_cfg_intrpt ( vf , cmd ) ;
if ( err )
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
else
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
static int qlcnic_sriov_validate_mtu ( struct qlcnic_adapter * adapter ,
struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
if ( cmd - > req . arg [ 1 ] ! = vf - > rx_ctx_id )
return - EINVAL ;
if ( cmd - > req . arg [ 2 ] > adapter - > ahw - > max_mtu )
return - EINVAL ;
return 0 ;
}
static int qlcnic_sriov_pf_set_mtu_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_mtu ( adapter , vf , cmd ) ;
if ( err )
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
else
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
static int qlcnic_sriov_validate_get_nic_info ( struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
if ( cmd - > req . arg [ 1 ] & BIT_31 ) {
if ( ( ( cmd - > req . arg [ 1 ] > > 16 ) & 0x7fff ) ! = vf - > pci_func )
return - EINVAL ;
} else {
cmd - > req . arg [ 1 ] | = vf - > vp - > handle < < 16 ;
}
return 0 ;
}
static int qlcnic_sriov_pf_get_nic_info_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_get_nic_info ( vf , cmd ) ;
if ( err ) {
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
return err ;
}
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
static int qlcnic_sriov_validate_cfg_rss ( struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
if ( cmd - > req . arg [ 1 ] ! = vf - > rx_ctx_id )
return - EINVAL ;
return 0 ;
}
static int qlcnic_sriov_pf_cfg_rss_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_cfg_rss ( vf , cmd ) ;
if ( err )
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
else
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
static int qlcnic_sriov_validate_cfg_intrcoal ( struct qlcnic_adapter * adapter ,
struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_nic_intr_coalesce * coal = & adapter - > ahw - > coal ;
u16 ctx_id , pkts , time ;
2014-04-25 17:43:58 -04:00
int err = - EINVAL ;
u8 type ;
2013-03-29 05:46:37 +00:00
2014-04-25 17:43:58 -04:00
type = cmd - > req . arg [ 1 ] & QLC_INTR_COAL_TYPE_MASK ;
2013-03-29 05:46:37 +00:00
ctx_id = cmd - > req . arg [ 1 ] > > 16 ;
pkts = cmd - > req . arg [ 2 ] & 0xffff ;
time = cmd - > req . arg [ 2 ] > > 16 ;
2014-04-25 17:43:58 -04:00
switch ( type ) {
case QLCNIC_INTR_COAL_TYPE_RX :
if ( ctx_id ! = vf - > rx_ctx_id | | pkts > coal - > rx_packets | |
time < coal - > rx_time_us )
goto err_label ;
break ;
case QLCNIC_INTR_COAL_TYPE_TX :
if ( ctx_id ! = vf - > tx_ctx_id | | pkts > coal - > tx_packets | |
time < coal - > tx_time_us )
goto err_label ;
break ;
default :
netdev_err ( adapter - > netdev , " Invalid coalescing type 0x%x received \n " ,
type ) ;
return err ;
}
2013-03-29 05:46:37 +00:00
return 0 ;
2014-04-25 17:43:58 -04:00
err_label :
netdev_err ( adapter - > netdev , " Expected: rx_ctx_id 0x%x rx_packets 0x%x rx_time_us 0x%x tx_ctx_id 0x%x tx_packets 0x%x tx_time_us 0x%x \n " ,
vf - > rx_ctx_id , coal - > rx_packets , coal - > rx_time_us ,
vf - > tx_ctx_id , coal - > tx_packets , coal - > tx_time_us ) ;
netdev_err ( adapter - > netdev , " Received: ctx_id 0x%x packets 0x%x time_us 0x%x type 0x%x \n " ,
ctx_id , pkts , time , type ) ;
return err ;
2013-03-29 05:46:37 +00:00
}
static int qlcnic_sriov_pf_cfg_intrcoal_cmd ( struct qlcnic_bc_trans * tran ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = tran - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_cfg_intrcoal ( adapter , vf , cmd ) ;
if ( err ) {
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
return err ;
}
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
static int qlcnic_sriov_validate_cfg_macvlan ( struct qlcnic_adapter * adapter ,
struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
2013-04-19 07:01:12 +00:00
struct qlcnic_vport * vp = vf - > vp ;
u8 op , new_op ;
2013-03-29 05:46:37 +00:00
if ( ! ( cmd - > req . arg [ 1 ] & BIT_8 ) )
return - EINVAL ;
cmd - > req . arg [ 1 ] | = ( vf - > vp - > handle < < 16 ) ;
cmd - > req . arg [ 1 ] | = BIT_31 ;
2013-04-19 07:01:12 +00:00
if ( vp - > vlan_mode = = QLC_PVID_MODE ) {
op = cmd - > req . arg [ 1 ] & 0x7 ;
cmd - > req . arg [ 1 ] & = ~ 0x7 ;
new_op = ( op = = QLCNIC_MAC_ADD | | op = = QLCNIC_MAC_VLAN_ADD ) ?
QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL ;
2013-12-17 09:01:53 -05:00
cmd - > req . arg [ 3 ] | = vp - > pvid < < 16 ;
2013-04-19 07:01:12 +00:00
cmd - > req . arg [ 1 ] | = new_op ;
}
2013-03-29 05:46:37 +00:00
return 0 ;
}
static int qlcnic_sriov_pf_cfg_macvlan_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_cfg_macvlan ( adapter , vf , cmd ) ;
if ( err ) {
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
return err ;
}
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
static int qlcnic_sriov_validate_linkevent ( struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
if ( ( cmd - > req . arg [ 1 ] > > 16 ) ! = vf - > rx_ctx_id )
return - EINVAL ;
return 0 ;
}
static int qlcnic_sriov_pf_linkevent_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
err = qlcnic_sriov_validate_linkevent ( vf , cmd ) ;
if ( err ) {
cmd - > rsp . arg [ 0 ] | = ( 0x6 < < 25 ) ;
return err ;
}
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
static int qlcnic_sriov_pf_cfg_promisc_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
int err ;
cmd - > req . arg [ 1 ] | = vf - > vp - > handle < < 16 ;
cmd - > req . arg [ 1 ] | = BIT_31 ;
err = qlcnic_issue_cmd ( adapter , cmd ) ;
return err ;
}
2013-04-19 07:01:12 +00:00
static int qlcnic_sriov_pf_get_acl_cmd ( struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = trans - > vf ;
struct qlcnic_vport * vp = vf - > vp ;
2018-12-17 17:27:16 +08:00
u8 mode = vp - > vlan_mode ;
2013-08-30 13:51:16 -04:00
struct qlcnic_adapter * adapter ;
2013-12-17 09:01:53 -05:00
struct qlcnic_sriov * sriov ;
2013-08-30 13:51:16 -04:00
adapter = vf - > adapter ;
2013-12-17 09:01:53 -05:00
sriov = adapter - > ahw - > sriov ;
2013-04-19 07:01:12 +00:00
2013-07-26 16:24:01 -04:00
cmd - > rsp . arg [ 0 ] | = 1 < < 25 ;
2013-04-19 07:01:12 +00:00
2013-08-30 13:51:16 -04:00
/* For 84xx adapter in case of PVID , PFD should send vlan mode as
* QLC_NO_VLAN_MODE to VFD which is zero in mailbox response
*/
if ( qlcnic_84xx_check ( adapter ) & & mode = = QLC_PVID_MODE )
return 0 ;
2013-04-19 07:01:12 +00:00
switch ( mode ) {
case QLC_GUEST_VLAN_MODE :
cmd - > rsp . arg [ 1 ] = mode | 1 < < 8 ;
2013-12-17 09:01:53 -05:00
cmd - > rsp . arg [ 2 ] = sriov - > num_allowed_vlans < < 16 ;
2013-04-19 07:01:12 +00:00
break ;
case QLC_PVID_MODE :
2013-12-17 09:01:53 -05:00
cmd - > rsp . arg [ 1 ] = mode | 1 < < 8 | vp - > pvid < < 16 ;
2013-04-19 07:01:12 +00:00
break ;
}
return 0 ;
}
static int qlcnic_sriov_pf_del_guest_vlan ( struct qlcnic_adapter * adapter ,
2013-12-17 09:01:53 -05:00
struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
2013-04-19 07:01:12 +00:00
{
2013-12-17 09:01:53 -05:00
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
u16 vlan ;
2013-04-19 07:01:12 +00:00
2013-12-17 09:01:53 -05:00
if ( ! qlcnic_sriov_check_any_vlan ( vf ) )
2013-04-19 07:01:12 +00:00
return - EINVAL ;
2013-12-17 09:01:53 -05:00
vlan = cmd - > req . arg [ 1 ] > > 16 ;
2013-04-19 07:01:12 +00:00
if ( ! vf - > rx_ctx_id ) {
2013-12-17 09:01:53 -05:00
qlcnic_sriov_del_vlan_id ( sriov , vf , vlan ) ;
2013-04-19 07:01:12 +00:00
return 0 ;
}
2013-12-17 09:01:53 -05:00
qlcnic_sriov_cfg_vf_def_mac ( adapter , vf , vlan , QLCNIC_MAC_DEL ) ;
qlcnic_sriov_del_vlan_id ( sriov , vf , vlan ) ;
if ( qlcnic_83xx_pf_check ( adapter ) )
qlcnic_sriov_cfg_vf_def_mac ( adapter , vf ,
0 , QLCNIC_MAC_ADD ) ;
2013-04-19 07:01:12 +00:00
return 0 ;
}
static int qlcnic_sriov_pf_add_guest_vlan ( struct qlcnic_adapter * adapter ,
struct qlcnic_vf_info * vf ,
struct qlcnic_cmd_args * cmd )
{
2013-12-17 09:01:53 -05:00
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
2013-04-19 07:01:12 +00:00
int err = - EIO ;
2013-12-17 09:01:53 -05:00
u16 vlan ;
2013-04-19 07:01:12 +00:00
2013-12-17 09:01:53 -05:00
if ( qlcnic_83xx_pf_check ( adapter ) & & qlcnic_sriov_check_any_vlan ( vf ) )
2013-04-19 07:01:12 +00:00
return err ;
2013-12-17 09:01:53 -05:00
vlan = cmd - > req . arg [ 1 ] > > 16 ;
2013-04-19 07:01:12 +00:00
if ( ! vf - > rx_ctx_id ) {
2013-12-17 09:01:53 -05:00
qlcnic_sriov_add_vlan_id ( sriov , vf , vlan ) ;
2013-04-19 07:01:12 +00:00
return 0 ;
}
2013-12-17 09:01:53 -05:00
if ( qlcnic_83xx_pf_check ( adapter ) ) {
err = qlcnic_sriov_cfg_vf_def_mac ( adapter , vf , 0 ,
QLCNIC_MAC_DEL ) ;
if ( err )
return err ;
}
2013-04-19 07:01:12 +00:00
2013-12-17 09:01:53 -05:00
err = qlcnic_sriov_cfg_vf_def_mac ( adapter , vf , vlan , QLCNIC_MAC_ADD ) ;
2013-04-19 07:01:12 +00:00
if ( err ) {
2013-12-17 09:01:53 -05:00
if ( qlcnic_83xx_pf_check ( adapter ) )
qlcnic_sriov_cfg_vf_def_mac ( adapter , vf , 0 ,
QLCNIC_MAC_ADD ) ;
return err ;
2013-04-19 07:01:12 +00:00
}
2013-12-17 09:01:53 -05:00
qlcnic_sriov_add_vlan_id ( sriov , vf , vlan ) ;
2013-04-19 07:01:12 +00:00
return err ;
}
static int qlcnic_sriov_pf_cfg_guest_vlan_cmd ( struct qlcnic_bc_trans * tran ,
struct qlcnic_cmd_args * cmd )
{
struct qlcnic_vf_info * vf = tran - > vf ;
struct qlcnic_adapter * adapter = vf - > adapter ;
struct qlcnic_vport * vp = vf - > vp ;
int err = - EIO ;
u8 op ;
if ( vp - > vlan_mode ! = QLC_GUEST_VLAN_MODE ) {
cmd - > rsp . arg [ 0 ] | = 2 < < 25 ;
return err ;
}
op = cmd - > req . arg [ 1 ] & 0xf ;
if ( op )
err = qlcnic_sriov_pf_add_guest_vlan ( adapter , vf , cmd ) ;
else
2013-12-17 09:01:53 -05:00
err = qlcnic_sriov_pf_del_guest_vlan ( adapter , vf , cmd ) ;
2013-04-19 07:01:12 +00:00
cmd - > rsp . arg [ 0 ] | = err ? 2 < < 25 : 1 < < 25 ;
return err ;
}
2013-03-29 05:46:37 +00:00
static const int qlcnic_pf_passthru_supp_cmds [ ] = {
QLCNIC_CMD_GET_STATISTICS ,
QLCNIC_CMD_GET_PORT_CONFIG ,
QLCNIC_CMD_GET_LINK_STATUS ,
2013-08-23 13:38:27 -04:00
QLCNIC_CMD_INIT_NIC_FUNC ,
QLCNIC_CMD_STOP_NIC_FUNC ,
2013-03-29 05:46:37 +00:00
} ;
2013-03-29 05:46:36 +00:00
static const struct qlcnic_sriov_cmd_handler qlcnic_pf_bc_cmd_hdlr [ ] = {
[ QLCNIC_BC_CMD_CHANNEL_INIT ] = { & qlcnic_sriov_pf_channel_cfg_cmd } ,
[ QLCNIC_BC_CMD_CHANNEL_TERM ] = { & qlcnic_sriov_pf_channel_cfg_cmd } ,
2013-04-19 07:01:12 +00:00
[ QLCNIC_BC_CMD_GET_ACL ] = { & qlcnic_sriov_pf_get_acl_cmd } ,
[ QLCNIC_BC_CMD_CFG_GUEST_VLAN ] = { & qlcnic_sriov_pf_cfg_guest_vlan_cmd } ,
2013-03-29 05:46:36 +00:00
} ;
2013-03-29 05:46:37 +00:00
static const struct qlcnic_sriov_fw_cmd_handler qlcnic_pf_fw_cmd_hdlr [ ] = {
{ QLCNIC_CMD_CREATE_RX_CTX , qlcnic_sriov_pf_create_rx_ctx_cmd } ,
{ QLCNIC_CMD_CREATE_TX_CTX , qlcnic_sriov_pf_create_tx_ctx_cmd } ,
{ QLCNIC_CMD_MAC_ADDRESS , qlcnic_sriov_pf_mac_address_cmd } ,
{ QLCNIC_CMD_DESTROY_RX_CTX , qlcnic_sriov_pf_del_rx_ctx_cmd } ,
{ QLCNIC_CMD_DESTROY_TX_CTX , qlcnic_sriov_pf_del_tx_ctx_cmd } ,
{ QLCNIC_CMD_CONFIGURE_HW_LRO , qlcnic_sriov_pf_cfg_lro_cmd } ,
{ QLCNIC_CMD_CONFIGURE_IP_ADDR , qlcnic_sriov_pf_cfg_ip_cmd } ,
{ QLCNIC_CMD_CONFIG_INTRPT , qlcnic_sriov_pf_cfg_intrpt_cmd } ,
{ QLCNIC_CMD_SET_MTU , qlcnic_sriov_pf_set_mtu_cmd } ,
{ QLCNIC_CMD_GET_NIC_INFO , qlcnic_sriov_pf_get_nic_info_cmd } ,
{ QLCNIC_CMD_CONFIGURE_RSS , qlcnic_sriov_pf_cfg_rss_cmd } ,
{ QLCNIC_CMD_CONFIG_INTR_COAL , qlcnic_sriov_pf_cfg_intrcoal_cmd } ,
{ QLCNIC_CMD_CONFIG_MAC_VLAN , qlcnic_sriov_pf_cfg_macvlan_cmd } ,
{ QLCNIC_CMD_GET_LINK_EVENT , qlcnic_sriov_pf_linkevent_cmd } ,
{ QLCNIC_CMD_CONFIGURE_MAC_RX_MODE , qlcnic_sriov_pf_cfg_promisc_cmd } ,
} ;
2013-03-29 05:46:36 +00:00
void qlcnic_sriov_pf_process_bc_cmd ( struct qlcnic_adapter * adapter ,
struct qlcnic_bc_trans * trans ,
struct qlcnic_cmd_args * cmd )
{
u8 size , cmd_op ;
cmd_op = trans - > req_hdr - > cmd_op ;
if ( trans - > req_hdr - > op_type = = QLC_BC_CMD ) {
size = ARRAY_SIZE ( qlcnic_pf_bc_cmd_hdlr ) ;
if ( cmd_op < size ) {
qlcnic_pf_bc_cmd_hdlr [ cmd_op ] . fn ( trans , cmd ) ;
return ;
}
2013-03-29 05:46:37 +00:00
} else {
int i ;
size = ARRAY_SIZE ( qlcnic_pf_fw_cmd_hdlr ) ;
for ( i = 0 ; i < size ; i + + ) {
if ( cmd_op = = qlcnic_pf_fw_cmd_hdlr [ i ] . cmd ) {
qlcnic_pf_fw_cmd_hdlr [ i ] . fn ( trans , cmd ) ;
return ;
}
}
size = ARRAY_SIZE ( qlcnic_pf_passthru_supp_cmds ) ;
for ( i = 0 ; i < size ; i + + ) {
if ( cmd_op = = qlcnic_pf_passthru_supp_cmds [ i ] ) {
qlcnic_issue_cmd ( adapter , cmd ) ;
return ;
}
}
2013-03-29 05:46:36 +00:00
}
cmd - > rsp . arg [ 0 ] | = ( 0x9 < < 25 ) ;
}
2013-03-29 05:46:37 +00:00
void qlcnic_pf_set_interface_id_create_rx_ctx ( struct qlcnic_adapter * adapter ,
u32 * int_id )
{
u16 vpid ;
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter ,
adapter - > ahw - > pci_func ) ;
* int_id | = vpid ;
}
void qlcnic_pf_set_interface_id_del_rx_ctx ( struct qlcnic_adapter * adapter ,
u32 * int_id )
{
u16 vpid ;
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter ,
adapter - > ahw - > pci_func ) ;
* int_id | = vpid < < 16 ;
}
void qlcnic_pf_set_interface_id_create_tx_ctx ( struct qlcnic_adapter * adapter ,
u32 * int_id )
{
int vpid ;
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter ,
adapter - > ahw - > pci_func ) ;
* int_id | = vpid < < 16 ;
}
void qlcnic_pf_set_interface_id_del_tx_ctx ( struct qlcnic_adapter * adapter ,
u32 * int_id )
{
u16 vpid ;
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter ,
adapter - > ahw - > pci_func ) ;
* int_id | = vpid < < 16 ;
}
void qlcnic_pf_set_interface_id_promisc ( struct qlcnic_adapter * adapter ,
u32 * int_id )
{
u16 vpid ;
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter ,
adapter - > ahw - > pci_func ) ;
* int_id | = ( vpid < < 16 ) | BIT_31 ;
}
void qlcnic_pf_set_interface_id_ipaddr ( struct qlcnic_adapter * adapter ,
u32 * int_id )
{
u16 vpid ;
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter ,
adapter - > ahw - > pci_func ) ;
* int_id | = ( vpid < < 16 ) | BIT_31 ;
}
void qlcnic_pf_set_interface_id_macaddr ( struct qlcnic_adapter * adapter ,
u32 * int_id )
{
u16 vpid ;
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter ,
adapter - > ahw - > pci_func ) ;
* int_id | = ( vpid < < 16 ) | BIT_31 ;
}
2013-04-19 07:01:09 +00:00
static void qlcnic_sriov_del_rx_ctx ( struct qlcnic_adapter * adapter ,
struct qlcnic_vf_info * vf )
{
struct qlcnic_cmd_args cmd ;
int vpid ;
if ( ! vf - > rx_ctx_id )
return ;
if ( qlcnic_alloc_mbx_args ( & cmd , adapter , QLCNIC_CMD_DESTROY_RX_CTX ) )
return ;
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter , vf - > pci_func ) ;
if ( vpid > = 0 ) {
cmd . req . arg [ 1 ] = vf - > rx_ctx_id | ( vpid & 0xffff ) < < 16 ;
if ( qlcnic_issue_cmd ( adapter , & cmd ) )
dev_err ( & adapter - > pdev - > dev ,
" Failed to delete Tx ctx in firmware for func 0x%x \n " ,
vf - > pci_func ) ;
else
vf - > rx_ctx_id = 0 ;
}
qlcnic_free_mbx_args ( & cmd ) ;
}
static void qlcnic_sriov_del_tx_ctx ( struct qlcnic_adapter * adapter ,
struct qlcnic_vf_info * vf )
{
struct qlcnic_cmd_args cmd ;
int vpid ;
if ( ! vf - > tx_ctx_id )
return ;
if ( qlcnic_alloc_mbx_args ( & cmd , adapter , QLCNIC_CMD_DESTROY_TX_CTX ) )
return ;
vpid = qlcnic_sriov_pf_get_vport_handle ( adapter , vf - > pci_func ) ;
if ( vpid > = 0 ) {
cmd . req . arg [ 1 ] | = vf - > tx_ctx_id | ( vpid & 0xffff ) < < 16 ;
if ( qlcnic_issue_cmd ( adapter , & cmd ) )
dev_err ( & adapter - > pdev - > dev ,
" Failed to delete Tx ctx in firmware for func 0x%x \n " ,
vf - > pci_func ) ;
else
vf - > tx_ctx_id = 0 ;
}
qlcnic_free_mbx_args ( & cmd ) ;
}
static int qlcnic_sriov_add_act_list_irqsave ( struct qlcnic_sriov * sriov ,
struct qlcnic_vf_info * vf ,
struct qlcnic_bc_trans * trans )
{
struct qlcnic_trans_list * t_list = & vf - > rcv_act ;
unsigned long flag ;
spin_lock_irqsave ( & t_list - > lock , flag ) ;
__qlcnic_sriov_add_act_list ( sriov , vf , trans ) ;
spin_unlock_irqrestore ( & t_list - > lock , flag ) ;
return 0 ;
}
static void __qlcnic_sriov_process_flr ( struct qlcnic_vf_info * vf )
{
struct qlcnic_adapter * adapter = vf - > adapter ;
qlcnic_sriov_cleanup_list ( & vf - > rcv_pend ) ;
cancel_work_sync ( & vf - > trans_work ) ;
qlcnic_sriov_cleanup_list ( & vf - > rcv_act ) ;
if ( test_bit ( QLC_BC_VF_SOFT_FLR , & vf - > state ) ) {
qlcnic_sriov_del_tx_ctx ( adapter , vf ) ;
qlcnic_sriov_del_rx_ctx ( adapter , vf ) ;
}
qlcnic_sriov_pf_config_vport ( adapter , 0 , vf - > pci_func ) ;
clear_bit ( QLC_BC_VF_FLR , & vf - > state ) ;
if ( test_bit ( QLC_BC_VF_SOFT_FLR , & vf - > state ) ) {
qlcnic_sriov_add_act_list_irqsave ( adapter - > ahw - > sriov , vf ,
vf - > flr_trans ) ;
clear_bit ( QLC_BC_VF_SOFT_FLR , & vf - > state ) ;
vf - > flr_trans = NULL ;
}
}
static void qlcnic_sriov_pf_process_flr ( struct work_struct * work )
{
struct qlcnic_vf_info * vf ;
vf = container_of ( work , struct qlcnic_vf_info , flr_work ) ;
__qlcnic_sriov_process_flr ( vf ) ;
return ;
}
static void qlcnic_sriov_schedule_flr ( struct qlcnic_sriov * sriov ,
struct qlcnic_vf_info * vf ,
work_func_t func )
{
if ( test_bit ( __QLCNIC_RESETTING , & vf - > adapter - > state ) )
return ;
INIT_WORK ( & vf - > flr_work , func ) ;
queue_work ( sriov - > bc . bc_flr_wq , & vf - > flr_work ) ;
}
static void qlcnic_sriov_handle_soft_flr ( struct qlcnic_adapter * adapter ,
struct qlcnic_bc_trans * trans ,
struct qlcnic_vf_info * vf )
{
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
set_bit ( QLC_BC_VF_FLR , & vf - > state ) ;
clear_bit ( QLC_BC_VF_STATE , & vf - > state ) ;
set_bit ( QLC_BC_VF_SOFT_FLR , & vf - > state ) ;
vf - > flr_trans = trans ;
qlcnic_sriov_schedule_flr ( sriov , vf , qlcnic_sriov_pf_process_flr ) ;
netdev_info ( adapter - > netdev , " Software FLR for PCI func %d \n " ,
vf - > pci_func ) ;
}
bool qlcnic_sriov_soft_flr_check ( struct qlcnic_adapter * adapter ,
struct qlcnic_bc_trans * trans ,
struct qlcnic_vf_info * vf )
{
struct qlcnic_bc_hdr * hdr = trans - > req_hdr ;
if ( ( hdr - > cmd_op = = QLCNIC_BC_CMD_CHANNEL_INIT ) & &
( hdr - > op_type = = QLC_BC_CMD ) & &
test_bit ( QLC_BC_VF_STATE , & vf - > state ) ) {
qlcnic_sriov_handle_soft_flr ( adapter , trans , vf ) ;
return true ;
}
return false ;
}
void qlcnic_sriov_pf_handle_flr ( struct qlcnic_sriov * sriov ,
struct qlcnic_vf_info * vf )
{
struct net_device * dev = vf - > adapter - > netdev ;
2013-07-19 16:56:34 -04:00
struct qlcnic_vport * vp = vf - > vp ;
2013-04-19 07:01:09 +00:00
if ( ! test_and_clear_bit ( QLC_BC_VF_STATE , & vf - > state ) ) {
clear_bit ( QLC_BC_VF_FLR , & vf - > state ) ;
return ;
}
if ( test_and_set_bit ( QLC_BC_VF_FLR , & vf - > state ) ) {
netdev_info ( dev , " FLR for PCI func %d in progress \n " ,
vf - > pci_func ) ;
return ;
}
2013-07-19 16:56:34 -04:00
if ( vp - > vlan_mode = = QLC_GUEST_VLAN_MODE )
2013-12-17 09:01:53 -05:00
memset ( vf - > sriov_vlans , 0 ,
sizeof ( * vf - > sriov_vlans ) * sriov - > num_allowed_vlans ) ;
2013-07-19 16:56:34 -04:00
2013-04-19 07:01:09 +00:00
qlcnic_sriov_schedule_flr ( sriov , vf , qlcnic_sriov_pf_process_flr ) ;
netdev_info ( dev , " FLR received for PCI func %d \n " , vf - > pci_func ) ;
}
2013-04-19 07:01:10 +00:00
void qlcnic_sriov_pf_reset ( struct qlcnic_adapter * adapter )
{
struct qlcnic_hardware_context * ahw = adapter - > ahw ;
struct qlcnic_sriov * sriov = ahw - > sriov ;
struct qlcnic_vf_info * vf ;
u16 num_vfs = sriov - > num_vfs ;
int i ;
for ( i = 0 ; i < num_vfs ; i + + ) {
vf = & sriov - > vf_info [ i ] ;
vf - > rx_ctx_id = 0 ;
vf - > tx_ctx_id = 0 ;
cancel_work_sync ( & vf - > flr_work ) ;
__qlcnic_sriov_process_flr ( vf ) ;
clear_bit ( QLC_BC_VF_STATE , & vf - > state ) ;
}
qlcnic_sriov_pf_reset_vport_handle ( adapter , ahw - > pci_func ) ;
QLCWRX ( ahw , QLCNIC_MBX_INTR_ENBL , ( ahw - > num_msix - 1 ) < < 8 ) ;
}
int qlcnic_sriov_pf_reinit ( struct qlcnic_adapter * adapter )
{
struct qlcnic_hardware_context * ahw = adapter - > ahw ;
int err ;
if ( ! qlcnic_sriov_enable_check ( adapter ) )
return 0 ;
ahw - > op_mode = QLCNIC_SRIOV_PF_FUNC ;
err = qlcnic_sriov_pf_init ( adapter ) ;
if ( err )
return err ;
dev_info ( & adapter - > pdev - > dev , " %s: op_mode %d \n " ,
__func__ , ahw - > op_mode ) ;
return err ;
}
2013-04-19 07:01:11 +00:00
int qlcnic_sriov_set_vf_mac ( struct net_device * netdev , int vf , u8 * mac )
{
struct qlcnic_adapter * adapter = netdev_priv ( netdev ) ;
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
2013-07-19 16:56:30 -04:00
int i , num_vfs ;
2013-04-19 07:01:11 +00:00
struct qlcnic_vf_info * vf_info ;
u8 * curr_mac ;
if ( ! qlcnic_sriov_pf_check ( adapter ) )
return - EOPNOTSUPP ;
2013-07-19 16:56:30 -04:00
num_vfs = sriov - > num_vfs ;
2013-04-19 07:01:11 +00:00
if ( ! is_valid_ether_addr ( mac ) | | vf > = num_vfs )
return - EINVAL ;
drivers/net: Convert uses of compare_ether_addr to ether_addr_equal
Use the new bool function ether_addr_equal to add
some clarity and reduce the likelihood for misuse
of compare_ether_addr for sorting.
Done via cocci script: (and a little typing)
$ cat compare_ether_addr.cocci
@@
expression a,b;
@@
- !compare_ether_addr(a, b)
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- compare_ether_addr(a, b)
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) == 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) != 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !!ether_addr_equal(a, b)
+ ether_addr_equal(a, b)
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2013-09-01 11:51:23 -07:00
if ( ether_addr_equal ( adapter - > mac_addr , mac ) ) {
2013-04-19 07:01:11 +00:00
netdev_err ( netdev , " MAC address is already in use by the PF \n " ) ;
return - EINVAL ;
}
for ( i = 0 ; i < num_vfs ; i + + ) {
vf_info = & sriov - > vf_info [ i ] ;
drivers/net: Convert uses of compare_ether_addr to ether_addr_equal
Use the new bool function ether_addr_equal to add
some clarity and reduce the likelihood for misuse
of compare_ether_addr for sorting.
Done via cocci script: (and a little typing)
$ cat compare_ether_addr.cocci
@@
expression a,b;
@@
- !compare_ether_addr(a, b)
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- compare_ether_addr(a, b)
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) == 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) != 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !!ether_addr_equal(a, b)
+ ether_addr_equal(a, b)
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2013-09-01 11:51:23 -07:00
if ( ether_addr_equal ( vf_info - > vp - > mac , mac ) ) {
2013-04-19 07:01:11 +00:00
netdev_err ( netdev ,
" MAC address is already in use by VF %d \n " ,
i ) ;
return - EINVAL ;
}
}
vf_info = & sriov - > vf_info [ vf ] ;
curr_mac = vf_info - > vp - > mac ;
if ( test_bit ( QLC_BC_VF_STATE , & vf_info - > state ) ) {
netdev_err ( netdev ,
" MAC address change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation \n " ,
vf ) ;
return - EOPNOTSUPP ;
}
memcpy ( curr_mac , mac , netdev - > addr_len ) ;
netdev_info ( netdev , " MAC Address %pM is configured for VF %d \n " ,
mac , vf ) ;
return 0 ;
}
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
int qlcnic_sriov_set_vf_tx_rate ( struct net_device * netdev , int vf ,
int min_tx_rate , int max_tx_rate )
2013-04-19 07:01:11 +00:00
{
struct qlcnic_adapter * adapter = netdev_priv ( netdev ) ;
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
struct qlcnic_vf_info * vf_info ;
struct qlcnic_info nic_info ;
struct qlcnic_vport * vp ;
u16 vpid ;
if ( ! qlcnic_sriov_pf_check ( adapter ) )
return - EOPNOTSUPP ;
if ( vf > = sriov - > num_vfs )
return - EINVAL ;
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
vf_info = & sriov - > vf_info [ vf ] ;
vp = vf_info - > vp ;
vpid = vp - > handle ;
if ( ! min_tx_rate )
min_tx_rate = QLC_VF_MIN_TX_RATE ;
2022-06-09 10:47:17 +02:00
if ( max_tx_rate & & max_tx_rate > = 10000 ) {
2013-04-19 07:01:11 +00:00
netdev_err ( netdev ,
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
" Invalid max Tx rate, allowed range is [%d - %d] " ,
min_tx_rate , QLC_VF_MAX_TX_RATE ) ;
2013-04-19 07:01:11 +00:00
return - EINVAL ;
}
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
if ( ! max_tx_rate )
max_tx_rate = 10000 ;
2013-04-19 07:01:11 +00:00
2022-06-09 10:47:17 +02:00
if ( min_tx_rate & & min_tx_rate < QLC_VF_MIN_TX_RATE ) {
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
netdev_err ( netdev ,
" Invalid min Tx rate, allowed range is [%d - %d] " ,
QLC_VF_MIN_TX_RATE , max_tx_rate ) ;
return - EINVAL ;
}
2013-04-19 07:01:11 +00:00
if ( test_bit ( QLC_BC_VF_STATE , & vf_info - > state ) ) {
if ( qlcnic_sriov_get_vf_vport_info ( adapter , & nic_info , vpid ) )
return - EIO ;
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
nic_info . max_tx_bw = max_tx_rate / 100 ;
nic_info . min_tx_bw = min_tx_rate / 100 ;
2013-04-19 07:01:11 +00:00
nic_info . bit_offsets = BIT_0 ;
if ( qlcnic_sriov_pf_set_vport_info ( adapter , & nic_info , vpid ) )
return - EIO ;
}
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
vp - > max_tx_bw = max_tx_rate / 100 ;
netdev_info ( netdev ,
" Setting Max Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d \n " ,
max_tx_rate , vp - > max_tx_bw , vf ) ;
vp - > min_tx_bw = min_tx_rate / 100 ;
2013-04-19 07:01:11 +00:00
netdev_info ( netdev ,
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
" Setting Min Tx rate %d (Mbps), %d %% of PF bandwidth, for VF %d \n " ,
min_tx_rate , vp - > min_tx_bw , vf ) ;
2013-04-19 07:01:11 +00:00
return 0 ;
}
2013-04-19 07:01:12 +00:00
int qlcnic_sriov_set_vf_vlan ( struct net_device * netdev , int vf ,
2016-09-22 12:11:15 +03:00
u16 vlan , u8 qos , __be16 vlan_proto )
2013-04-19 07:01:12 +00:00
{
struct qlcnic_adapter * adapter = netdev_priv ( netdev ) ;
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
struct qlcnic_vf_info * vf_info ;
struct qlcnic_vport * vp ;
if ( ! qlcnic_sriov_pf_check ( adapter ) )
return - EOPNOTSUPP ;
if ( vf > = sriov - > num_vfs | | qos > 7 )
return - EINVAL ;
2016-09-22 12:11:15 +03:00
if ( vlan_proto ! = htons ( ETH_P_8021Q ) )
return - EPROTONOSUPPORT ;
2013-04-19 07:01:12 +00:00
if ( vlan > MAX_VLAN_ID ) {
netdev_err ( netdev ,
" Invalid VLAN ID, allowed range is [0 - %d] \n " ,
MAX_VLAN_ID ) ;
return - EINVAL ;
}
vf_info = & sriov - > vf_info [ vf ] ;
vp = vf_info - > vp ;
if ( test_bit ( QLC_BC_VF_STATE , & vf_info - > state ) ) {
netdev_err ( netdev ,
" VLAN change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation \n " ,
vf ) ;
return - EOPNOTSUPP ;
}
2013-12-17 09:01:53 -05:00
memset ( vf_info - > sriov_vlans , 0 ,
sizeof ( * vf_info - > sriov_vlans ) * sriov - > num_allowed_vlans ) ;
2013-04-19 07:01:12 +00:00
switch ( vlan ) {
case 4095 :
vp - > vlan_mode = QLC_GUEST_VLAN_MODE ;
break ;
case 0 :
vp - > vlan_mode = QLC_NO_VLAN_MODE ;
vp - > qos = 0 ;
break ;
default :
vp - > vlan_mode = QLC_PVID_MODE ;
2013-12-17 09:01:53 -05:00
qlcnic_sriov_add_vlan_id ( sriov , vf_info , vlan ) ;
2013-04-19 07:01:12 +00:00
vp - > qos = qos ;
2013-12-17 09:01:53 -05:00
vp - > pvid = vlan ;
2013-04-19 07:01:12 +00:00
}
netdev_info ( netdev , " Setting VLAN %d, QoS %d, for VF %d \n " ,
vlan , qos , vf ) ;
return 0 ;
}
2013-08-30 13:51:17 -04:00
static __u32 qlcnic_sriov_get_vf_vlan ( struct qlcnic_adapter * adapter ,
struct qlcnic_vport * vp , int vf )
2013-07-26 16:24:02 -04:00
{
__u32 vlan = 0 ;
switch ( vp - > vlan_mode ) {
case QLC_PVID_MODE :
2013-12-17 09:01:53 -05:00
vlan = vp - > pvid ;
2013-07-26 16:24:02 -04:00
break ;
case QLC_GUEST_VLAN_MODE :
vlan = MAX_VLAN_ID ;
break ;
case QLC_NO_VLAN_MODE :
vlan = 0 ;
break ;
default :
netdev_info ( adapter - > netdev , " Invalid VLAN mode = %d for VF %d \n " ,
vp - > vlan_mode , vf ) ;
}
return vlan ;
}
2013-04-19 07:01:11 +00:00
int qlcnic_sriov_get_vf_config ( struct net_device * netdev ,
int vf , struct ifla_vf_info * ivi )
{
struct qlcnic_adapter * adapter = netdev_priv ( netdev ) ;
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
struct qlcnic_vport * vp ;
if ( ! qlcnic_sriov_pf_check ( adapter ) )
return - EOPNOTSUPP ;
if ( vf > = sriov - > num_vfs )
return - EINVAL ;
vp = sriov - > vf_info [ vf ] . vp ;
memcpy ( & ivi - > mac , vp - > mac , ETH_ALEN ) ;
2013-07-26 16:24:02 -04:00
ivi - > vlan = qlcnic_sriov_get_vf_vlan ( adapter , vp , vf ) ;
2013-04-19 07:01:12 +00:00
ivi - > qos = vp - > qos ;
2013-05-23 21:04:25 +00:00
ivi - > spoofchk = vp - > spoofchk ;
2013-04-19 07:01:11 +00:00
if ( vp - > max_tx_bw = = MAX_BW )
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
ivi - > max_tx_rate = 0 ;
else
ivi - > max_tx_rate = vp - > max_tx_bw * 100 ;
if ( vp - > min_tx_bw = = MIN_BW )
ivi - > min_tx_rate = 0 ;
2013-04-19 07:01:11 +00:00
else
net-next:v4: Add support to configure SR-IOV VF minimum and maximum Tx rate through ip tool.
o min_tx_rate puts lower limit on the VF bandwidth. VF is guaranteed
to have a bandwidth of at least this value.
max_tx_rate puts cap on the VF bandwidth. VF can have a bandwidth
of up to this value.
o A new handler set_vf_rate for attr IFLA_VF_RATE has been introduced
which takes 4 arguments:
netdev, VF number, min_tx_rate, max_tx_rate
o ndo_set_vf_rate replaces ndo_set_vf_tx_rate handler.
o Drivers that currently implement ndo_set_vf_tx_rate should now call
ndo_set_vf_rate instead and reject attempt to set a minimum bandwidth
greater than 0 for IFLA_VF_TX_RATE when IFLA_VF_RATE is not yet
implemented by driver.
o If user enters only one of either min_tx_rate or max_tx_rate, then,
userland should read back the other value from driver and set both
for IFLA_VF_RATE.
Drivers that have not yet implemented IFLA_VF_RATE should always
return min_tx_rate as 0 when read from ip tool.
o If both IFLA_VF_TX_RATE and IFLA_VF_RATE options are specified, then
IFLA_VF_RATE should override.
o Idea is to have consistent display of rate values to user.
o Usage example: -
./ip link set p4p1 vf 0 rate 900
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 900 (Mbps), max_tx_rate 900Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 300 min_tx_rate 200
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f0 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5a, tx rate 300 (Mbps), max_tx_rate 300Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
./ip link set p4p1 vf 0 max_tx_rate 600 rate 300
./ip link show p4p1
32: p4p1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode
DEFAULT qlen 1000
link/ether 00:0e:1e:08:b0:f brd ff:ff:ff:ff:ff:ff
vf 0 MAC 3e:a0:ca:bd:ae:5, tx rate 600 (Mbps), max_tx_rate 600Mbps,
min_tx_rate 200Mbps
vf 1 MAC f6:c6:7c:3f:3d:6c
vf 2 MAC 56:32:43:98:d7:71
vf 3 MAC d6:be:c3:b5:85:ff
vf 4 MAC ee:a9:9a:1e:19:14
vf 5 MAC 4a:d0:4c:07:52:18
vf 6 MAC 3a:76:44:93:62:f9
vf 7 MAC 82:e9:e7:e3:15:1a
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-22 09:59:05 -04:00
ivi - > min_tx_rate = vp - > min_tx_bw * 100 ;
2013-04-19 07:01:11 +00:00
ivi - > vf = vf ;
return 0 ;
}
2013-05-23 21:04:25 +00:00
int qlcnic_sriov_set_vf_spoofchk ( struct net_device * netdev , int vf , bool chk )
{
struct qlcnic_adapter * adapter = netdev_priv ( netdev ) ;
struct qlcnic_sriov * sriov = adapter - > ahw - > sriov ;
struct qlcnic_vf_info * vf_info ;
struct qlcnic_vport * vp ;
if ( ! qlcnic_sriov_pf_check ( adapter ) )
return - EOPNOTSUPP ;
if ( vf > = sriov - > num_vfs )
return - EINVAL ;
vf_info = & sriov - > vf_info [ vf ] ;
vp = vf_info - > vp ;
if ( test_bit ( QLC_BC_VF_STATE , & vf_info - > state ) ) {
netdev_err ( netdev ,
" Spoof check change failed for VF %d, as VF driver is loaded. Please unload VF driver and retry the operation \n " ,
vf ) ;
return - EOPNOTSUPP ;
}
vp - > spoofchk = chk ;
return 0 ;
}