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 /* Most of 64-bit registers are in LSW, MSW form. 57 Counters are normally implemented by HW as latched pairs: 58 reading LSW first locks MSW, to overcome LSW overflow 59 */ 60 u64 aq_hw_read_reg64(struct aq_hw_s *hw, u32 reg) 61 { 62 u64 value = aq_hw_read_reg(hw, reg); 63 64 value |= (u64)aq_hw_read_reg(hw, reg + 4) << 32; 65 return value; 66 } 67 68 int aq_hw_err_from_flags(struct aq_hw_s *hw) 69 { 70 int err = 0; 71 72 if (aq_utils_obj_test(&hw->flags, AQ_HW_FLAG_ERR_UNPLUG)) { 73 err = -ENXIO; 74 goto err_exit; 75 } 76 if (aq_utils_obj_test(&hw->flags, AQ_HW_FLAG_ERR_HW)) { 77 err = -EIO; 78 goto err_exit; 79 } 80 81 err_exit: 82 return err; 83 } 84