1 /* 2 * aQuantia Corporation Network Driver 3 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 */ 9 10 /* File aq_hw_utils.c: Definitions of helper functions used across 11 * hardware layer. 12 */ 13 14 #include "aq_hw_utils.h" 15 #include "aq_hw.h" 16 #include "aq_nic.h" 17 18 void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, 19 u32 shift, u32 val) 20 { 21 if (msk ^ ~0) { 22 u32 reg_old, reg_new; 23 24 reg_old = aq_hw_read_reg(aq_hw, addr); 25 reg_new = (reg_old & (~msk)) | (val << shift); 26 27 if (reg_old != reg_new) 28 aq_hw_write_reg(aq_hw, addr, reg_new); 29 } else { 30 aq_hw_write_reg(aq_hw, addr, val); 31 } 32 } 33 34 u32 aq_hw_read_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, u32 shift) 35 { 36 return ((aq_hw_read_reg(aq_hw, addr) & msk) >> shift); 37 } 38 39 u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg) 40 { 41 u32 value = readl(hw->mmio + reg); 42 43 if ((~0U) == value && 44 (~0U) == readl(hw->mmio + 45 hw->aq_nic_cfg->aq_hw_caps->hw_alive_check_addr)) 46 aq_utils_obj_set(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG); 47 48 return value; 49 } 50 51 void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value) 52 { 53 writel(value, hw->mmio + reg); 54 } 55 56 int aq_hw_err_from_flags(struct aq_hw_s *hw) 57 { 58 int err = 0; 59 60 if (aq_utils_obj_test(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG)) { 61 err = -ENXIO; 62 goto err_exit; 63 } 64 if (aq_utils_obj_test(&hw->flags, AQ_HW_FLAG_ERR_HW)) { 65 err = -EIO; 66 goto err_exit; 67 } 68 69 err_exit: 70 return err; 71 } 72