Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Oct 2015 23:48:03 +0000 (UTC)
From:      "Conrad E. Meyer" <cem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r289347 - head/sys/dev/ntb/ntb_hw
Message-ID:  <201510142348.t9ENm3V0050817@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cem
Date: Wed Oct 14 23:48:03 2015
New Revision: 289347
URL: https://svnweb.freebsd.org/changeset/base/289347

Log:
  NTB: Abstract doorbell register access
  
  The doorbell registers (and associated mask) are 16-bit on Xeon but
  64-bit on SoC.  Abstract IO access to doorbell registers with
  'db_ioread' and 'db_iowrite' (names and idea borrowed from the dual
  BSD/GPL Linux driver).
  
  Sponsored by:	EMC / Isilon Storage Division

Modified:
  head/sys/dev/ntb/ntb_hw/ntb_hw.c

Modified: head/sys/dev/ntb/ntb_hw/ntb_hw.c
==============================================================================
--- head/sys/dev/ntb/ntb_hw/ntb_hw.c	Wed Oct 14 23:47:52 2015	(r289346)
+++ head/sys/dev/ntb/ntb_hw/ntb_hw.c	Wed Oct 14 23:48:03 2015	(r289347)
@@ -211,6 +211,8 @@ static void handle_xeon_irq(void *arg);
 static void handle_xeon_event_irq(void *arg);
 static void ntb_handle_legacy_interrupt(void *arg);
 static void ntb_irq_work(void *arg);
+static uint64_t db_ioread(struct ntb_softc *, uint32_t regoff);
+static void db_iowrite(struct ntb_softc *, uint32_t regoff, uint64_t val);
 static void mask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx);
 static void unmask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx);
 static int ntb_create_callbacks(struct ntb_softc *ntb, uint32_t num_vectors);
@@ -601,18 +603,19 @@ static int
 ntb_setup_interrupts(struct ntb_softc *ntb)
 {
 	uint32_t desired_vectors, num_vectors;
+	uint64_t mask;
 	int rc;
 
 	ntb->allocated_interrupts = 0;
+
 	/*
 	 * On SOC, disable all interrupts.  On XEON, disable all but Link
 	 * Interrupt.  The rest will be unmasked as callbacks are registered.
 	 */
-	if (ntb->type == NTB_SOC)
-		ntb_reg_write(8, ntb->reg_ofs.ldb_mask, ~0);
-	else
-		ntb_reg_write(2, ntb->reg_ofs.ldb_mask,
-		    (uint16_t) ~(1 << XEON_LINK_DB));
+	mask = 0;
+	if (ntb->type == NTB_XEON)
+		mask = (1 << XEON_LINK_DB);
+	db_iowrite(ntb, ntb->reg_ofs.ldb_mask, ~mask);
 
 	num_vectors = desired_vectors = MIN(pci_msix_count(ntb->device),
 	    ntb->limits.max_db_bits);
@@ -700,24 +703,53 @@ ntb_teardown_interrupts(struct ntb_softc
 	pci_release_msi(ntb->device);
 }
 
+/*
+ * Doorbell register and mask are 64-bit on SoC, 16-bit on Xeon.  Abstract it
+ * out to make code clearer.
+ */
+static uint64_t
+db_ioread(struct ntb_softc *ntb, uint32_t regoff)
+{
+
+	if (ntb->type == NTB_SOC)
+		return (ntb_reg_read(8, regoff));
+
+	KASSERT(ntb->type == NTB_XEON, ("bad ntb type"));
+
+	return (ntb_reg_read(2, regoff));
+}
+
+static void
+db_iowrite(struct ntb_softc *ntb, uint32_t regoff, uint64_t val)
+{
+
+	if (ntb->type == NTB_SOC) {
+		ntb_reg_write(8, regoff, val);
+		return;
+	}
+
+	KASSERT(ntb->type == NTB_XEON, ("bad ntb type"));
+	ntb_reg_write(2, regoff, (uint16_t)val);
+}
+
 static void
 mask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx)
 {
-	unsigned long mask;
+	uint64_t mask;
 
-	mask = ntb_reg_read(2, ntb->reg_ofs.ldb_mask);
+	mask = db_ioread(ntb, ntb->reg_ofs.ldb_mask);
 	mask |= 1 << (idx * ntb->bits_per_vector);
-	ntb_reg_write(2, ntb->reg_ofs.ldb_mask, mask);
+	db_iowrite(ntb, ntb->reg_ofs.ldb_mask, mask);
 }
 
 static void
 unmask_ldb_interrupt(struct ntb_softc *ntb, unsigned int idx)
 {
-	unsigned long mask;
+	uint64_t mask;
 
-	mask = ntb_reg_read(2, ntb->reg_ofs.ldb_mask);
+	mask = db_ioread(ntb, ntb->reg_ofs.ldb_mask);
 	mask &= ~(1 << (idx * ntb->bits_per_vector));
-	ntb_reg_write(2, ntb->reg_ofs.ldb_mask, mask);
+	db_iowrite(ntb, ntb->reg_ofs.ldb_mask, mask);
 }
 
 static void
@@ -726,7 +758,7 @@ handle_soc_irq(void *arg)
 	struct ntb_db_cb *db_cb = arg;
 	struct ntb_softc *ntb = db_cb->ntb;
 
-	ntb_reg_write(8, ntb->reg_ofs.ldb, (uint64_t) 1 << db_cb->db_num);
+	db_iowrite(ntb, ntb->reg_ofs.ldb, (uint64_t) 1 << db_cb->db_num);
 
 	if (db_cb->callback != NULL) {
 		mask_ldb_interrupt(ntb, db_cb->db_num);
@@ -746,7 +778,7 @@ handle_xeon_irq(void *arg)
 	 * vectors, with the 4th having a single bit for link
 	 * interrupts.
 	 */
-	ntb_reg_write(2, ntb->reg_ofs.ldb,
+	db_iowrite(ntb, ntb->reg_ofs.ldb,
 	    ((1 << ntb->bits_per_vector) - 1) <<
 	    (db_cb->db_num * ntb->bits_per_vector));
 
@@ -768,40 +800,31 @@ handle_xeon_event_irq(void *arg)
 		device_printf(ntb->device, "Error determining link status\n");
 
 	/* bit 15 is always the link bit */
-	ntb_reg_write(2, ntb->reg_ofs.ldb, 1 << XEON_LINK_DB);
+	db_iowrite(ntb, ntb->reg_ofs.ldb, 1 << XEON_LINK_DB);
 }
 
 static void
 ntb_handle_legacy_interrupt(void *arg)
 {
 	struct ntb_softc *ntb = arg;
-	unsigned int i = 0;
-	uint64_t ldb64;
-	uint16_t ldb16;
-
-	if (ntb->type == NTB_SOC) {
-		ldb64 = ntb_reg_read(8, ntb->reg_ofs.ldb);
+	unsigned int i;
+	uint64_t ldb;
 
-		while (ldb64) {
-			i = ffs(ldb64);
-			ldb64 &= ldb64 - 1;
-			handle_soc_irq(&ntb->db_cb[i]);
-		}
-	} else {
-		ldb16 = ntb_reg_read(2, ntb->reg_ofs.ldb);
+	ldb = db_ioread(ntb, ntb->reg_ofs.ldb);
 
-		if ((ldb16 & XEON_DB_HW_LINK) != 0) {
-			handle_xeon_event_irq(ntb);
-			ldb16 &= ~XEON_DB_HW_LINK;
-		}
+	if (ntb->type == NTB_XEON && (ldb & XEON_DB_HW_LINK) != 0) {
+		handle_xeon_event_irq(ntb);
+		ldb &= ~XEON_DB_HW_LINK;
+	}
 
-		while (ldb16 != 0) {
-			i = ffs(ldb16);
-			ldb16 &= ldb16 - 1;
+	while (ldb != 0) {
+		i = ffs(ldb);
+		ldb &= ldb - 1;
+		if (ntb->type == NTB_SOC)
+			handle_soc_irq(&ntb->db_cb[i]);
+		else
 			handle_xeon_irq(&ntb->db_cb[i]);
-		}
 	}
-
 }
 
 static int
@@ -1669,25 +1692,24 @@ ntb_set_mw_addr(struct ntb_softc *ntb, u
  *
  * This function allows triggering of a doorbell on the secondary/external
  * side that will initiate an interrupt on the remote host
- *
- * RETURNS: An appropriate ERRNO error value on error, or zero for success.
  */
 void
 ntb_ring_doorbell(struct ntb_softc *ntb, unsigned int db)
 {
+	uint64_t bit;
 
 	if (ntb->type == NTB_SOC)
-		ntb_reg_write(8, ntb->reg_ofs.rdb, (uint64_t) 1 << db);
-	else {
-		if (HAS_FEATURE(NTB_REGS_THRU_MW))
-			ntb_mw_write(2, XEON_SHADOW_PDOORBELL_OFFSET,
-			    ((1 << ntb->bits_per_vector) - 1) <<
-			    (db * ntb->bits_per_vector));
-		else
-			ntb_reg_write(2, ntb->reg_ofs.rdb,
-			    ((1 << ntb->bits_per_vector) - 1) <<
-			    (db * ntb->bits_per_vector));
+		bit = 1 << db;
+	else
+		bit = ((1 << ntb->bits_per_vector) - 1) <<
+		    (db * ntb->bits_per_vector);
+
+	if (HAS_FEATURE(NTB_REGS_THRU_MW)) {
+		ntb_mw_write(2, XEON_SHADOW_PDOORBELL_OFFSET, bit);
+		return;
 	}
+
+	db_iowrite(ntb, ntb->reg_ofs.rdb, bit);
 }
 
 /**



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510142348.t9ENm3V0050817>