From owner-svn-src-all@freebsd.org Sat Jan 2 17:14:23 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C3D98A5E1E5; Sat, 2 Jan 2016 17:14:23 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A0C2C1E01; Sat, 2 Jan 2016 17:14:23 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u02HEM6k042498; Sat, 2 Jan 2016 17:14:22 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u02HEMMK042496; Sat, 2 Jan 2016 17:14:22 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201601021714.u02HEMMK042496@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Sat, 2 Jan 2016 17:14:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r293050 - head/sys/dev/ath X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Jan 2016 17:14:23 -0000 Author: adrian Date: Sat Jan 2 17:14:22 2016 New Revision: 293050 URL: https://svnweb.freebsd.org/changeset/base/293050 Log: [ath] add explicit bus barriers. The ath hal and driver code all assume the world is an x86 or the bus layer does an explicit bus flush after each operation (eg netbsd.) However, we don't do that. So, to be "correct" on platforms like sparc64, mips and ppc (and maybe ARM, I am not sure), just do explicit barriers after each operation. Now, this does slow things down a tad on embedded platforms but I'd rather things be "correct" versus "fast." At some later point if someone wishes it to be fast then we should add the barrier calls to the HAL and driver. Tested: * carambola 2 (AR9331.) Modified: head/sys/dev/ath/ah_osdep.c head/sys/dev/ath/ah_osdep.h Modified: head/sys/dev/ath/ah_osdep.c ============================================================================== --- head/sys/dev/ath/ah_osdep.c Sat Jan 2 16:40:37 2016 (r293049) +++ head/sys/dev/ath/ah_osdep.c Sat Jan 2 17:14:22 2016 (r293050) @@ -291,6 +291,7 @@ ath_hal_reg_write(struct ath_hal *ah, u_ if (ah->ah_config.ah_serialise_reg_war) mtx_lock_spin(&ah_regser_mtx); bus_space_write_4(tag, h, reg, val); + OS_BUS_BARRIER_REG(ah, reg, OS_BUS_BARRIER_WRITE); if (ah->ah_config.ah_serialise_reg_war) mtx_unlock_spin(&ah_regser_mtx); } @@ -311,6 +312,7 @@ ath_hal_reg_read(struct ath_hal *ah, u_i if (ah->ah_config.ah_serialise_reg_war) mtx_lock_spin(&ah_regser_mtx); + OS_BUS_BARRIER_REG(ah, reg, OS_BUS_BARRIER_READ); val = bus_space_read_4(tag, h, reg); if (ah->ah_config.ah_serialise_reg_war) mtx_unlock_spin(&ah_regser_mtx); @@ -371,6 +373,7 @@ ath_hal_reg_write(struct ath_hal *ah, u_ if (ah->ah_config.ah_serialise_reg_war) mtx_lock_spin(&ah_regser_mtx); bus_space_write_4(tag, h, reg, val); + OS_BUS_BARRIER_REG(ah, reg, OS_BUS_BARRIER_WRITE); if (ah->ah_config.ah_serialise_reg_war) mtx_unlock_spin(&ah_regser_mtx); } @@ -391,6 +394,7 @@ ath_hal_reg_read(struct ath_hal *ah, u_i if (ah->ah_config.ah_serialise_reg_war) mtx_lock_spin(&ah_regser_mtx); + OS_BUS_BARRIER_REG(ah, reg, OS_BUS_BARRIER_READ); val = bus_space_read_4(tag, h, reg); if (ah->ah_config.ah_serialise_reg_war) mtx_unlock_spin(&ah_regser_mtx); Modified: head/sys/dev/ath/ah_osdep.h ============================================================================== --- head/sys/dev/ath/ah_osdep.h Sat Jan 2 16:40:37 2016 (r293049) +++ head/sys/dev/ath/ah_osdep.h Sat Jan 2 17:14:22 2016 (r293050) @@ -110,6 +110,27 @@ struct ath_hal; do { } while (0) /* + * Read and write barriers. Some platforms require more strongly ordered + * operations and unfortunately most of the HAL is written assuming everything + * is either an x86 or the bus layer will do the barriers for you. + * + * Read barriers should occur before each read, and write barriers + * occur after each write. + * + * Later on for SDIO/USB parts we will methodize this and make them no-ops; + * register accesses will go via USB commands. + */ +#define OS_BUS_BARRIER_READ BUS_SPACE_BARRIER_READ +#define OS_BUS_BARRIER_WRITE BUS_SPACE_BARRIER_WRITE +#define OS_BUS_BARRIER_RW \ + (BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) +#define OS_BUS_BARRIER(_ah, _start, _len, _t) \ + bus_space_barrier((bus_space_tag_t)(_ah)->ah_st, \ + (bus_space_handle_t)(_ah)->ah_sh, (_start), (_len), (_t)) +#define OS_BUS_BARRIER_REG(_ah, _reg, _t) \ + OS_BUS_BARRIER((_ah), (_reg), 4, (_t)) + +/* * Register read/write operations are either handled through * platform-dependent routines (or when debugging is enabled * with AH_DEBUG); or they are inline expanded using the macros @@ -123,11 +144,17 @@ extern void ath_hal_reg_write(struct ath extern u_int32_t ath_hal_reg_read(struct ath_hal *ah, u_int reg); #else #define OS_REG_WRITE(_ah, _reg, _val) \ + do { \ bus_space_write_4((bus_space_tag_t)(_ah)->ah_st, \ - (bus_space_handle_t)(_ah)->ah_sh, (_reg), (_val)) + (bus_space_handle_t)(_ah)->ah_sh, (_reg), (_val)); \ + OS_BUS_BARRIER_REG((_ah), (_reg), OS_BUS_BARRIER_WRITE); \ + } while (0) #define OS_REG_READ(_ah, _reg) \ + do { \ + OS_BUS_BARRIER_REG((_ah), (_reg), OS_BUS_BARRIER_READ); \ bus_space_read_4((bus_space_tag_t)(_ah)->ah_st, \ - (bus_space_handle_t)(_ah)->ah_sh, (_reg)) + (bus_space_handle_t)(_ah)->ah_sh, (_reg)); \ + } while (0) #endif #ifdef AH_DEBUG_ALQ