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 17 void aq_hw_write_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, 18 u32 shift, u32 val) 19 { 20 if (msk ^ ~0) { 21 u32 reg_old, reg_new; 22 23 reg_old = aq_hw_read_reg(aq_hw, addr); 24 reg_new = (reg_old & (~msk)) | (val << shift); 25 26 if (reg_old != reg_new) 27 aq_hw_write_reg(aq_hw, addr, reg_new); 28 } else { 29 aq_hw_write_reg(aq_hw, addr, val); 30 } 31 } 32 33 u32 aq_hw_read_reg_bit(struct aq_hw_s *aq_hw, u32 addr, u32 msk, u32 shift) 34 { 35 return ((aq_hw_read_reg(aq_hw, addr) & msk) >> shift); 36 } 37 38 u32 aq_hw_read_reg(struct aq_hw_s *hw, u32 reg) 39 { 40 u32 value = readl(hw->mmio + reg); 41 42 if ((~0U) == value && (~0U) == readl(hw->mmio + hw->not_ff_addr)) 43 aq_utils_obj_set(&hw->header.flags, AQ_HW_FLAG_ERR_UNPLUG); 44 45 return value; 46 } 47 48 void aq_hw_write_reg(struct aq_hw_s *hw, u32 reg, u32 value) 49 { 50 writel(value, hw->mmio + reg); 51 } 52 53 int aq_hw_err_from_flags(struct aq_hw_s *hw) 54 { 55 int err = 0; 56 57 if (aq_utils_obj_test(&hw->header.flags, AQ_HW_FLAG_ERR_UNPLUG)) { 58 err = -ENXIO; 59 goto err_exit; 60 } 61 if (aq_utils_obj_test(&hw->header.flags, AQ_HW_FLAG_ERR_HW)) { 62 err = -EIO; 63 goto err_exit; 64 } 65 66 err_exit: 67 return err; 68 } 69