2019-06-01 10:08:37 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2017-01-23 22:09:17 -08:00
/*
* aQuantia Corporation Network Driver
* Copyright ( C ) 2014 - 2017 aQuantia Corporation . All rights reserved
*/
/* File aq_hw_utils.c: Definitions of helper functions used across
* hardware layer .
*/
# include "aq_hw_utils.h"
# include "aq_hw.h"
2018-01-19 17:03:23 +03:00
# include "aq_nic.h"
2017-01-23 22:09:17 -08:00
void aq_hw_write_reg_bit ( struct aq_hw_s * aq_hw , u32 addr , u32 msk ,
u32 shift , u32 val )
{
if ( msk ^ ~ 0 ) {
u32 reg_old , reg_new ;
reg_old = aq_hw_read_reg ( aq_hw , addr ) ;
reg_new = ( reg_old & ( ~ msk ) ) | ( val < < shift ) ;
if ( reg_old ! = reg_new )
aq_hw_write_reg ( aq_hw , addr , reg_new ) ;
} else {
aq_hw_write_reg ( aq_hw , addr , val ) ;
}
}
u32 aq_hw_read_reg_bit ( struct aq_hw_s * aq_hw , u32 addr , u32 msk , u32 shift )
{
return ( ( aq_hw_read_reg ( aq_hw , addr ) & msk ) > > shift ) ;
}
u32 aq_hw_read_reg ( struct aq_hw_s * hw , u32 reg )
{
u32 value = readl ( hw - > mmio + reg ) ;
2018-01-19 17:03:23 +03:00
if ( ( ~ 0U ) = = value & &
( ~ 0U ) = = readl ( hw - > mmio +
hw - > aq_nic_cfg - > aq_hw_caps - > hw_alive_check_addr ) )
2018-01-15 16:41:14 +03:00
aq_utils_obj_set ( & hw - > flags , AQ_HW_FLAG_ERR_UNPLUG ) ;
2017-01-23 22:09:17 -08:00
return value ;
}
void aq_hw_write_reg ( struct aq_hw_s * hw , u32 reg , u32 value )
{
writel ( value , hw - > mmio + reg ) ;
}
2019-04-29 10:05:07 +00:00
/* Most of 64-bit registers are in LSW, MSW form.
Counters are normally implemented by HW as latched pairs :
reading LSW first locks MSW , to overcome LSW overflow
*/
u64 aq_hw_read_reg64 ( struct aq_hw_s * hw , u32 reg )
{
u64 value = aq_hw_read_reg ( hw , reg ) ;
value | = ( u64 ) aq_hw_read_reg ( hw , reg + 4 ) < < 32 ;
return value ;
}
2017-01-23 22:09:17 -08:00
int aq_hw_err_from_flags ( struct aq_hw_s * hw )
{
int err = 0 ;
2018-01-15 16:41:14 +03:00
if ( aq_utils_obj_test ( & hw - > flags , AQ_HW_FLAG_ERR_UNPLUG ) ) {
2017-01-23 22:09:17 -08:00
err = - ENXIO ;
goto err_exit ;
}
2018-01-15 16:41:14 +03:00
if ( aq_utils_obj_test ( & hw - > flags , AQ_HW_FLAG_ERR_HW ) ) {
2017-01-23 22:09:17 -08:00
err = - EIO ;
goto err_exit ;
}
err_exit :
return err ;
}