2019-06-01 10:08:54 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2017-02-15 06:28:23 -08:00
/*
* QLogic FCoE Offload Driver
2018-04-25 06:09:04 -07:00
* Copyright ( c ) 2016 - 2018 Cavium Inc .
2017-02-15 06:28:23 -08:00
*/
# include "qedf.h"
2017-05-31 06:33:53 -07:00
inline bool qedf_is_vport ( struct qedf_ctx * qedf )
{
return qedf - > lport - > vport ! = NULL ;
}
/* Get base qedf for physical port from vport */
static struct qedf_ctx * qedf_get_base_qedf ( struct qedf_ctx * qedf )
{
struct fc_lport * lport ;
struct fc_lport * base_lport ;
if ( ! ( qedf_is_vport ( qedf ) ) )
return NULL ;
lport = qedf - > lport ;
base_lport = shost_priv ( vport_to_shost ( lport - > vport ) ) ;
return lport_priv ( base_lport ) ;
}
2021-06-16 11:44:17 +08:00
static ssize_t fcoe_mac_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
2017-02-15 06:28:23 -08:00
{
struct fc_lport * lport = shost_priv ( class_to_shost ( dev ) ) ;
u32 port_id ;
u8 lport_src_id [ 3 ] ;
u8 fcoe_mac [ 6 ] ;
port_id = fc_host_port_id ( lport - > host ) ;
lport_src_id [ 2 ] = ( port_id & 0x000000FF ) ;
lport_src_id [ 1 ] = ( port_id & 0x0000FF00 ) > > 8 ;
lport_src_id [ 0 ] = ( port_id & 0x00FF0000 ) > > 16 ;
fc_fcoe_set_mac ( fcoe_mac , lport_src_id ) ;
return scnprintf ( buf , PAGE_SIZE , " %pM \n " , fcoe_mac ) ;
}
2021-06-16 11:44:17 +08:00
static ssize_t fka_period_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
2017-05-31 06:33:53 -07:00
{
struct fc_lport * lport = shost_priv ( class_to_shost ( dev ) ) ;
struct qedf_ctx * qedf = lport_priv ( lport ) ;
int fka_period = - 1 ;
if ( qedf_is_vport ( qedf ) )
qedf = qedf_get_base_qedf ( qedf ) ;
if ( qedf - > ctlr . sel_fcf )
fka_period = qedf - > ctlr . sel_fcf - > fka_period ;
return scnprintf ( buf , PAGE_SIZE , " %d \n " , fka_period ) ;
}
2021-06-16 11:44:17 +08:00
static DEVICE_ATTR_RO ( fcoe_mac ) ;
static DEVICE_ATTR_RO ( fka_period ) ;
2017-02-15 06:28:23 -08:00
2021-10-12 16:35:49 -07:00
static struct attribute * qedf_host_attrs [ ] = {
& dev_attr_fcoe_mac . attr ,
& dev_attr_fka_period . attr ,
2017-02-15 06:28:23 -08:00
NULL ,
} ;
2021-10-12 16:35:49 -07:00
static const struct attribute_group qedf_host_attr_group = {
. attrs = qedf_host_attrs
} ;
const struct attribute_group * qedf_host_groups [ ] = {
& qedf_host_attr_group ,
NULL
} ;
2017-02-15 06:28:23 -08:00
extern const struct qed_fcoe_ops * qed_ops ;
void qedf_capture_grc_dump ( struct qedf_ctx * qedf )
{
struct qedf_ctx * base_qedf ;
/* Make sure we use the base qedf to take the GRC dump */
if ( qedf_is_vport ( qedf ) )
base_qedf = qedf_get_base_qedf ( qedf ) ;
else
base_qedf = qedf ;
if ( test_bit ( QEDF_GRCDUMP_CAPTURE , & base_qedf - > flags ) ) {
QEDF_INFO ( & ( base_qedf - > dbg_ctx ) , QEDF_LOG_INFO ,
" GRC Dump already captured. \n " ) ;
return ;
}
qedf_get_grc_dump ( base_qedf - > cdev , qed_ops - > common ,
& base_qedf - > grcdump , & base_qedf - > grcdump_size ) ;
QEDF_ERR ( & ( base_qedf - > dbg_ctx ) , " GRC Dump captured. \n " ) ;
set_bit ( QEDF_GRCDUMP_CAPTURE , & base_qedf - > flags ) ;
qedf_uevent_emit ( base_qedf - > lport - > host , QEDF_UEVENT_CODE_GRCDUMP ,
NULL ) ;
}
static ssize_t
qedf_sysfs_read_grcdump ( struct file * filep , struct kobject * kobj ,
struct bin_attribute * ba , char * buf , loff_t off ,
size_t count )
{
ssize_t ret = 0 ;
struct fc_lport * lport = shost_priv ( dev_to_shost ( container_of ( kobj ,
struct device , kobj ) ) ) ;
struct qedf_ctx * qedf = lport_priv ( lport ) ;
if ( test_bit ( QEDF_GRCDUMP_CAPTURE , & qedf - > flags ) ) {
ret = memory_read_from_buffer ( buf , count , & off ,
qedf - > grcdump , qedf - > grcdump_size ) ;
} else {
QEDF_ERR ( & ( qedf - > dbg_ctx ) , " GRC Dump not captured! \n " ) ;
}
return ret ;
}
static ssize_t
qedf_sysfs_write_grcdump ( struct file * filep , struct kobject * kobj ,
struct bin_attribute * ba , char * buf , loff_t off ,
size_t count )
{
struct fc_lport * lport = NULL ;
struct qedf_ctx * qedf = NULL ;
long reading ;
int ret = 0 ;
char msg [ 40 ] ;
if ( off ! = 0 )
return ret ;
lport = shost_priv ( dev_to_shost ( container_of ( kobj ,
struct device , kobj ) ) ) ;
qedf = lport_priv ( lport ) ;
buf [ 1 ] = 0 ;
ret = kstrtol ( buf , 10 , & reading ) ;
if ( ret ) {
QEDF_ERR ( & ( qedf - > dbg_ctx ) , " Invalid input, err(%d) \n " , ret ) ;
return ret ;
}
memset ( msg , 0 , sizeof ( msg ) ) ;
switch ( reading ) {
case 0 :
memset ( qedf - > grcdump , 0 , qedf - > grcdump_size ) ;
clear_bit ( QEDF_GRCDUMP_CAPTURE , & qedf - > flags ) ;
break ;
case 1 :
qedf_capture_grc_dump ( qedf ) ;
break ;
}
return count ;
}
static struct bin_attribute sysfs_grcdump_attr = {
. attr = {
. name = " grcdump " ,
. mode = S_IRUSR | S_IWUSR ,
} ,
. size = 0 ,
. read = qedf_sysfs_read_grcdump ,
. write = qedf_sysfs_write_grcdump ,
} ;
static struct sysfs_bin_attrs bin_file_entries [ ] = {
{ " grcdump " , & sysfs_grcdump_attr } ,
{ NULL } ,
} ;
void qedf_create_sysfs_ctx_attr ( struct qedf_ctx * qedf )
{
qedf_create_sysfs_attr ( qedf - > lport - > host , bin_file_entries ) ;
}
void qedf_remove_sysfs_ctx_attr ( struct qedf_ctx * qedf )
{
qedf_remove_sysfs_attr ( qedf - > lport - > host , bin_file_entries ) ;
}