All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3.18 0/7] b43: first series for 3.18
@ 2014-07-31 19:59 ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

John, this patchset continues improvements for b43. It doesn't fix any
particular bug/issue, so please queue it for 3.18. There is nothing
important enough to risk breaking wireless-next for 3.17.

Rafał Miłecki (7):
  b43: update flushing many writes performed in a row
  b43: don't duplicate common PHY read/write ops
  b43: flush some writes on Broadcom MIPS SoCs
  b43: N-PHY: update rev3+ gain control workarounds
  b43: N-PHY: add RF power tables for radio 0x2057 revs 9 & 14
  b43: implement PPR (Power Per Rate) management/API
  b43: N-PHY: support setting custom TX power

 drivers/net/wireless/b43/Makefile      |   1 +
 drivers/net/wireless/b43/b43.h         |  16 +++
 drivers/net/wireless/b43/bus.h         |  14 +++
 drivers/net/wireless/b43/main.c        |  17 ++-
 drivers/net/wireless/b43/phy_a.c       |   4 +-
 drivers/net/wireless/b43/phy_common.c  |  25 ++++-
 drivers/net/wireless/b43/phy_g.c       |   8 +-
 drivers/net/wireless/b43/phy_ht.c      |  20 +---
 drivers/net/wireless/b43/phy_lcn.c     |  20 +---
 drivers/net/wireless/b43/phy_lp.c      |  20 +---
 drivers/net/wireless/b43/phy_n.c       | 128 +++++++++++++++------
 drivers/net/wireless/b43/phy_n.h       |   4 +
 drivers/net/wireless/b43/ppr.c         | 199 +++++++++++++++++++++++++++++++++
 drivers/net/wireless/b43/ppr.h         |  45 ++++++++
 drivers/net/wireless/b43/tables_nphy.c | 128 +++++++++++++++++----
 drivers/net/wireless/b43/tables_nphy.h |   2 +
 16 files changed, 523 insertions(+), 128 deletions(-)
 create mode 100644 drivers/net/wireless/b43/ppr.c
 create mode 100644 drivers/net/wireless/b43/ppr.h

-- 
1.8.4.5


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3.18 0/7] b43: first series for 3.18
@ 2014-07-31 19:59 ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

John, this patchset continues improvements for b43. It doesn't fix any
particular bug/issue, so please queue it for 3.18. There is nothing
important enough to risk breaking wireless-next for 3.17.

Rafa? Mi?ecki (7):
  b43: update flushing many writes performed in a row
  b43: don't duplicate common PHY read/write ops
  b43: flush some writes on Broadcom MIPS SoCs
  b43: N-PHY: update rev3+ gain control workarounds
  b43: N-PHY: add RF power tables for radio 0x2057 revs 9 & 14
  b43: implement PPR (Power Per Rate) management/API
  b43: N-PHY: support setting custom TX power

 drivers/net/wireless/b43/Makefile      |   1 +
 drivers/net/wireless/b43/b43.h         |  16 +++
 drivers/net/wireless/b43/bus.h         |  14 +++
 drivers/net/wireless/b43/main.c        |  17 ++-
 drivers/net/wireless/b43/phy_a.c       |   4 +-
 drivers/net/wireless/b43/phy_common.c  |  25 ++++-
 drivers/net/wireless/b43/phy_g.c       |   8 +-
 drivers/net/wireless/b43/phy_ht.c      |  20 +---
 drivers/net/wireless/b43/phy_lcn.c     |  20 +---
 drivers/net/wireless/b43/phy_lp.c      |  20 +---
 drivers/net/wireless/b43/phy_n.c       | 128 +++++++++++++++------
 drivers/net/wireless/b43/phy_n.h       |   4 +
 drivers/net/wireless/b43/ppr.c         | 199 +++++++++++++++++++++++++++++++++
 drivers/net/wireless/b43/ppr.h         |  45 ++++++++
 drivers/net/wireless/b43/tables_nphy.c | 128 +++++++++++++++++----
 drivers/net/wireless/b43/tables_nphy.h |   2 +
 16 files changed, 523 insertions(+), 128 deletions(-)
 create mode 100644 drivers/net/wireless/b43/ppr.c
 create mode 100644 drivers/net/wireless/b43/ppr.h

-- 
1.8.4.5

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3.18 1/7] b43: update flushing many writes performed in a row
  2014-07-31 19:59 ` Rafał Miłecki
@ 2014-07-31 19:59   ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Flush radio writes as well and add some tiny optimizations (e.g.
masksetting PHY reg involves reading it, so reset the counter).

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 drivers/net/wireless/b43/bus.h        | 14 ++++++++++++++
 drivers/net/wireless/b43/phy_common.c | 13 ++++++++++---
 drivers/net/wireless/b43/phy_n.c      |  1 +
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h
index f3205c6..460d9d9 100644
--- a/drivers/net/wireless/b43/bus.h
+++ b/drivers/net/wireless/b43/bus.h
@@ -60,7 +60,21 @@ static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev)
 #else
 	return false;
 #endif
+};
+
+static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev)
+{
+#ifdef CONFIG_B43_BCMA
+	if (dev->bus_type == B43_BUS_BCMA)
+		return (dev->bdev->bus->hosttype == BCMA_HOSTTYPE_PCI);
+#endif
+#ifdef CONFIG_B43_SSB
+	if (dev->bus_type == B43_BUS_SSB)
+		return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI);
+#endif
+	return false;
 }
+
 static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev)
 {
 #ifdef CONFIG_B43_SSB
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 3cbef21..c868748 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -222,12 +222,18 @@ static inline void assert_mac_suspended(struct b43_wldev *dev)
 u16 b43_radio_read(struct b43_wldev *dev, u16 reg)
 {
 	assert_mac_suspended(dev);
+	dev->phy.writes_counter = 0;
 	return dev->phy.ops->radio_read(dev, reg);
 }
 
 void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
 	assert_mac_suspended(dev);
+	if (b43_bus_host_is_pci(dev->dev) &&
+	    ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) {
+		b43_read32(dev, B43_MMIO_MACCTL);
+		dev->phy.writes_counter = 1;
+	}
 	dev->phy.ops->radio_write(dev, reg, value);
 }
 
@@ -274,11 +280,12 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
 void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
 	assert_mac_suspended(dev);
-	dev->phy.ops->phy_write(dev, reg, value);
-	if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) {
+	if (b43_bus_host_is_pci(dev->dev) &&
+	    ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) {
 		b43_read16(dev, B43_MMIO_PHY_VER);
-		dev->phy.writes_counter = 0;
+		dev->phy.writes_counter = 1;
 	}
+	dev->phy.ops->phy_write(dev, reg, value);
 }
 
 void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index e2a3f0d..b04aa34 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -6517,6 +6517,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 	check_phyreg(dev, reg);
 	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
+	dev->phy.writes_counter = 1;
 }
 
 static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3.18 1/7] b43: update flushing many writes performed in a row
@ 2014-07-31 19:59   ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Flush radio writes as well and add some tiny optimizations (e.g.
masksetting PHY reg involves reading it, so reset the counter).

Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
---
 drivers/net/wireless/b43/bus.h        | 14 ++++++++++++++
 drivers/net/wireless/b43/phy_common.c | 13 ++++++++++---
 drivers/net/wireless/b43/phy_n.c      |  1 +
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h
index f3205c6..460d9d9 100644
--- a/drivers/net/wireless/b43/bus.h
+++ b/drivers/net/wireless/b43/bus.h
@@ -60,7 +60,21 @@ static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev)
 #else
 	return false;
 #endif
+};
+
+static inline bool b43_bus_host_is_pci(struct b43_bus_dev *dev)
+{
+#ifdef CONFIG_B43_BCMA
+	if (dev->bus_type == B43_BUS_BCMA)
+		return (dev->bdev->bus->hosttype == BCMA_HOSTTYPE_PCI);
+#endif
+#ifdef CONFIG_B43_SSB
+	if (dev->bus_type == B43_BUS_SSB)
+		return (dev->sdev->bus->bustype == SSB_BUSTYPE_PCI);
+#endif
+	return false;
 }
+
 static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev)
 {
 #ifdef CONFIG_B43_SSB
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 3cbef21..c868748 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -222,12 +222,18 @@ static inline void assert_mac_suspended(struct b43_wldev *dev)
 u16 b43_radio_read(struct b43_wldev *dev, u16 reg)
 {
 	assert_mac_suspended(dev);
+	dev->phy.writes_counter = 0;
 	return dev->phy.ops->radio_read(dev, reg);
 }
 
 void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
 	assert_mac_suspended(dev);
+	if (b43_bus_host_is_pci(dev->dev) &&
+	    ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) {
+		b43_read32(dev, B43_MMIO_MACCTL);
+		dev->phy.writes_counter = 1;
+	}
 	dev->phy.ops->radio_write(dev, reg, value);
 }
 
@@ -274,11 +280,12 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
 void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
 	assert_mac_suspended(dev);
-	dev->phy.ops->phy_write(dev, reg, value);
-	if (++dev->phy.writes_counter == B43_MAX_WRITES_IN_ROW) {
+	if (b43_bus_host_is_pci(dev->dev) &&
+	    ++dev->phy.writes_counter > B43_MAX_WRITES_IN_ROW) {
 		b43_read16(dev, B43_MMIO_PHY_VER);
-		dev->phy.writes_counter = 0;
+		dev->phy.writes_counter = 1;
 	}
+	dev->phy.ops->phy_write(dev, reg, value);
 }
 
 void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index e2a3f0d..b04aa34 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -6517,6 +6517,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 	check_phyreg(dev, reg);
 	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
+	dev->phy.writes_counter = 1;
 }
 
 static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3.18 2/7] b43: don't duplicate common PHY read/write ops
  2014-07-31 19:59 ` Rafał Miłecki
@ 2014-07-31 19:59   ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Most of the PHYs use the same way of accessing registers, so move that
code to the shared place. An exception is G-PHY which sometimes access
A-PHY regs and requires special handling.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 drivers/net/wireless/b43/phy_common.c | 14 ++++++++++++--
 drivers/net/wireless/b43/phy_ht.c     | 14 --------------
 drivers/net/wireless/b43/phy_lcn.c    | 14 --------------
 drivers/net/wireless/b43/phy_lp.c     | 14 --------------
 drivers/net/wireless/b43/phy_n.c      | 16 ----------------
 5 files changed, 12 insertions(+), 60 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index c868748..08ca524 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -274,7 +274,12 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
 {
 	assert_mac_suspended(dev);
 	dev->phy.writes_counter = 0;
-	return dev->phy.ops->phy_read(dev, reg);
+
+	if (dev->phy.ops->phy_read)
+		return dev->phy.ops->phy_read(dev, reg);
+
+	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
@@ -285,7 +290,12 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 		b43_read16(dev, B43_MMIO_PHY_VER);
 		dev->phy.writes_counter = 1;
 	}
-	dev->phy.ops->phy_write(dev, reg, value);
+
+	if (dev->phy.ops->phy_write)
+		return dev->phy.ops->phy_write(dev, reg, value);
+
+	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
 void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index f2974c6..8b0b4b6 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -1071,18 +1071,6 @@ static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
  * R/W ops.
  **************************************************/
 
-static u16 b43_phy_ht_op_read(struct b43_wldev *dev, u16 reg)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	return b43_read16(dev, B43_MMIO_PHY_DATA);
-}
-
-static void b43_phy_ht_op_write(struct b43_wldev *dev, u16 reg, u16 value)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	b43_write16(dev, B43_MMIO_PHY_DATA, value);
-}
-
 static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
@@ -1126,8 +1114,6 @@ const struct b43_phy_operations b43_phyops_ht = {
 	.free			= b43_phy_ht_op_free,
 	.prepare_structs	= b43_phy_ht_op_prepare_structs,
 	.init			= b43_phy_ht_op_init,
-	.phy_read		= b43_phy_ht_op_read,
-	.phy_write		= b43_phy_ht_op_write,
 	.phy_maskset		= b43_phy_ht_op_maskset,
 	.radio_read		= b43_phy_ht_op_radio_read,
 	.radio_write		= b43_phy_ht_op_radio_write,
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index e76bbdf..bf29c3e 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -810,18 +810,6 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
  * R/W ops.
  **************************************************/
 
-static u16 b43_phy_lcn_op_read(struct b43_wldev *dev, u16 reg)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	return b43_read16(dev, B43_MMIO_PHY_DATA);
-}
-
-static void b43_phy_lcn_op_write(struct b43_wldev *dev, u16 reg, u16 value)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	b43_write16(dev, B43_MMIO_PHY_DATA, value);
-}
-
 static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				   u16 set)
 {
@@ -855,8 +843,6 @@ const struct b43_phy_operations b43_phyops_lcn = {
 	.free			= b43_phy_lcn_op_free,
 	.prepare_structs	= b43_phy_lcn_op_prepare_structs,
 	.init			= b43_phy_lcn_op_init,
-	.phy_read		= b43_phy_lcn_op_read,
-	.phy_write		= b43_phy_lcn_op_write,
 	.phy_maskset		= b43_phy_lcn_op_maskset,
 	.radio_read		= b43_phy_lcn_op_radio_read,
 	.radio_write		= b43_phy_lcn_op_radio_write,
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 92190da..1e9bae6 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1985,18 +1985,6 @@ static void lpphy_calibration(struct b43_wldev *dev)
 	b43_mac_enable(dev);
 }
 
-static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	return b43_read16(dev, B43_MMIO_PHY_DATA);
-}
-
-static void b43_lpphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	b43_write16(dev, B43_MMIO_PHY_DATA, value);
-}
-
 static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
@@ -2713,8 +2701,6 @@ const struct b43_phy_operations b43_phyops_lp = {
 	.free			= b43_lpphy_op_free,
 	.prepare_structs	= b43_lpphy_op_prepare_structs,
 	.init			= b43_lpphy_op_init,
-	.phy_read		= b43_lpphy_op_read,
-	.phy_write		= b43_lpphy_op_write,
 	.phy_maskset		= b43_lpphy_op_maskset,
 	.radio_read		= b43_lpphy_op_radio_read,
 	.radio_write		= b43_lpphy_op_radio_write,
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index b04aa34..5565318 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -6497,20 +6497,6 @@ static inline void check_phyreg(struct b43_wldev *dev, u16 offset)
 #endif /* B43_DEBUG */
 }
 
-static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg)
-{
-	check_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	return b43_read16(dev, B43_MMIO_PHY_DATA);
-}
-
-static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
-{
-	check_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	b43_write16(dev, B43_MMIO_PHY_DATA, value);
-}
-
 static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
@@ -6653,8 +6639,6 @@ const struct b43_phy_operations b43_phyops_n = {
 	.free			= b43_nphy_op_free,
 	.prepare_structs	= b43_nphy_op_prepare_structs,
 	.init			= b43_nphy_op_init,
-	.phy_read		= b43_nphy_op_read,
-	.phy_write		= b43_nphy_op_write,
 	.phy_maskset		= b43_nphy_op_maskset,
 	.radio_read		= b43_nphy_op_radio_read,
 	.radio_write		= b43_nphy_op_radio_write,
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3.18 2/7] b43: don't duplicate common PHY read/write ops
@ 2014-07-31 19:59   ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Most of the PHYs use the same way of accessing registers, so move that
code to the shared place. An exception is G-PHY which sometimes access
A-PHY regs and requires special handling.

Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
---
 drivers/net/wireless/b43/phy_common.c | 14 ++++++++++++--
 drivers/net/wireless/b43/phy_ht.c     | 14 --------------
 drivers/net/wireless/b43/phy_lcn.c    | 14 --------------
 drivers/net/wireless/b43/phy_lp.c     | 14 --------------
 drivers/net/wireless/b43/phy_n.c      | 16 ----------------
 5 files changed, 12 insertions(+), 60 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index c868748..08ca524 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -274,7 +274,12 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
 {
 	assert_mac_suspended(dev);
 	dev->phy.writes_counter = 0;
-	return dev->phy.ops->phy_read(dev, reg);
+
+	if (dev->phy.ops->phy_read)
+		return dev->phy.ops->phy_read(dev, reg);
+
+	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
@@ -285,7 +290,12 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 		b43_read16(dev, B43_MMIO_PHY_VER);
 		dev->phy.writes_counter = 1;
 	}
-	dev->phy.ops->phy_write(dev, reg, value);
+
+	if (dev->phy.ops->phy_write)
+		return dev->phy.ops->phy_write(dev, reg, value);
+
+	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
 void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index f2974c6..8b0b4b6 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -1071,18 +1071,6 @@ static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
  * R/W ops.
  **************************************************/
 
-static u16 b43_phy_ht_op_read(struct b43_wldev *dev, u16 reg)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	return b43_read16(dev, B43_MMIO_PHY_DATA);
-}
-
-static void b43_phy_ht_op_write(struct b43_wldev *dev, u16 reg, u16 value)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	b43_write16(dev, B43_MMIO_PHY_DATA, value);
-}
-
 static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
@@ -1126,8 +1114,6 @@ const struct b43_phy_operations b43_phyops_ht = {
 	.free			= b43_phy_ht_op_free,
 	.prepare_structs	= b43_phy_ht_op_prepare_structs,
 	.init			= b43_phy_ht_op_init,
-	.phy_read		= b43_phy_ht_op_read,
-	.phy_write		= b43_phy_ht_op_write,
 	.phy_maskset		= b43_phy_ht_op_maskset,
 	.radio_read		= b43_phy_ht_op_radio_read,
 	.radio_write		= b43_phy_ht_op_radio_write,
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index e76bbdf..bf29c3e 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -810,18 +810,6 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
  * R/W ops.
  **************************************************/
 
-static u16 b43_phy_lcn_op_read(struct b43_wldev *dev, u16 reg)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	return b43_read16(dev, B43_MMIO_PHY_DATA);
-}
-
-static void b43_phy_lcn_op_write(struct b43_wldev *dev, u16 reg, u16 value)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	b43_write16(dev, B43_MMIO_PHY_DATA, value);
-}
-
 static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				   u16 set)
 {
@@ -855,8 +843,6 @@ const struct b43_phy_operations b43_phyops_lcn = {
 	.free			= b43_phy_lcn_op_free,
 	.prepare_structs	= b43_phy_lcn_op_prepare_structs,
 	.init			= b43_phy_lcn_op_init,
-	.phy_read		= b43_phy_lcn_op_read,
-	.phy_write		= b43_phy_lcn_op_write,
 	.phy_maskset		= b43_phy_lcn_op_maskset,
 	.radio_read		= b43_phy_lcn_op_radio_read,
 	.radio_write		= b43_phy_lcn_op_radio_write,
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 92190da..1e9bae6 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1985,18 +1985,6 @@ static void lpphy_calibration(struct b43_wldev *dev)
 	b43_mac_enable(dev);
 }
 
-static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	return b43_read16(dev, B43_MMIO_PHY_DATA);
-}
-
-static void b43_lpphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
-{
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	b43_write16(dev, B43_MMIO_PHY_DATA, value);
-}
-
 static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
@@ -2713,8 +2701,6 @@ const struct b43_phy_operations b43_phyops_lp = {
 	.free			= b43_lpphy_op_free,
 	.prepare_structs	= b43_lpphy_op_prepare_structs,
 	.init			= b43_lpphy_op_init,
-	.phy_read		= b43_lpphy_op_read,
-	.phy_write		= b43_lpphy_op_write,
 	.phy_maskset		= b43_lpphy_op_maskset,
 	.radio_read		= b43_lpphy_op_radio_read,
 	.radio_write		= b43_lpphy_op_radio_write,
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index b04aa34..5565318 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -6497,20 +6497,6 @@ static inline void check_phyreg(struct b43_wldev *dev, u16 offset)
 #endif /* B43_DEBUG */
 }
 
-static u16 b43_nphy_op_read(struct b43_wldev *dev, u16 reg)
-{
-	check_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	return b43_read16(dev, B43_MMIO_PHY_DATA);
-}
-
-static void b43_nphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
-{
-	check_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
-	b43_write16(dev, B43_MMIO_PHY_DATA, value);
-}
-
 static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
@@ -6653,8 +6639,6 @@ const struct b43_phy_operations b43_phyops_n = {
 	.free			= b43_nphy_op_free,
 	.prepare_structs	= b43_nphy_op_prepare_structs,
 	.init			= b43_nphy_op_init,
-	.phy_read		= b43_nphy_op_read,
-	.phy_write		= b43_nphy_op_write,
 	.phy_maskset		= b43_nphy_op_maskset,
 	.radio_read		= b43_nphy_op_radio_read,
 	.radio_write		= b43_nphy_op_radio_write,
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
  2014-07-31 19:59 ` Rafał Miłecki
@ 2014-07-31 19:59   ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Access to PHY and radio registers is indirect on Broadcom hardware and
it seems that addressing on MIPS SoCs may require flushing. Broadcom
code does that unconditionally on MIPS, so let's do the same to make
sure hardware won't miss anything important.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 drivers/net/wireless/b43/b43.h        |  8 ++++++++
 drivers/net/wireless/b43/main.c       | 17 ++++++++---------
 drivers/net/wireless/b43/phy_a.c      |  4 ++--
 drivers/net/wireless/b43/phy_common.c |  4 ++--
 drivers/net/wireless/b43/phy_g.c      |  8 ++++----
 drivers/net/wireless/b43/phy_ht.c     |  6 +++---
 drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
 drivers/net/wireless/b43/phy_lp.c     |  6 +++---
 drivers/net/wireless/b43/phy_n.c      |  6 +++---
 9 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 4113b69..ff0c666 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -1012,6 +1012,14 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
 	dev->dev->write16(dev->dev, offset, value);
 }
 
+static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
+{
+	b43_write16(dev, offset, value);
+#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
+	b43_read16(dev, offset);
+#endif
+}
+
 static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask,
 				 u16 set)
 {
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 2af1ac3..66ff718 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4466,10 +4466,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 	if (core_rev == 40 || core_rev == 42) {
 		radio_manuf = 0x17F;
 
-		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
+		b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 0);
 		radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 
-		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
+		b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 1);
 		radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 
 		radio_ver = 0; /* Is there version somewhere? */
@@ -4477,7 +4477,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 		u16 radio24[3];
 
 		for (tmp = 0; tmp < 3; tmp++) {
-			b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
+			b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, tmp);
 			radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 		}
 
@@ -4494,13 +4494,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 			else
 				tmp = 0x5205017F;
 		} else {
-			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-				    B43_RADIOCTL_ID);
+			b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+				     B43_RADIOCTL_ID);
 			tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
-			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-				    B43_RADIOCTL_ID);
-			tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
-				<< 16;
+			b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+				     B43_RADIOCTL_ID);
+			tmp |= b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
 		}
 		radio_manuf = (tmp & 0x00000FFF);
 		radio_id = (tmp & 0x0FFFF000) >> 12;
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 25e4043..99c036f 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -444,14 +444,14 @@ static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
 static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
 {
 	reg = adjust_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
 	reg = adjust_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 08ca524..1dfc682 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -278,7 +278,7 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
 	if (dev->phy.ops->phy_read)
 		return dev->phy.ops->phy_read(dev, reg);
 
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
@@ -294,7 +294,7 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 	if (dev->phy.ops->phy_write)
 		return dev->phy.ops->phy_write(dev, reg, value);
 
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index 8f5c14b..727ce6e 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -2555,13 +2555,13 @@ static void b43_gphy_op_exit(struct b43_wldev *dev)
 
 static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
@@ -2572,7 +2572,7 @@ static u16 b43_gphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* G-PHY needs 0x80 for read access. */
 	reg |= 0x80;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -2581,7 +2581,7 @@ static void b43_gphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 8b0b4b6..c4dc8b0 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -1074,7 +1074,7 @@ static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
 static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -1084,14 +1084,14 @@ static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* HT-PHY needs 0x200 for read access */
 	reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
 }
 
 static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
 				      u16 value)
 {
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index bf29c3e..97461cc 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -813,7 +813,7 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
 static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				   u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -823,14 +823,14 @@ static u16 b43_phy_lcn_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* LCN-PHY needs 0x200 for read access */
 	reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
 }
 
 static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg,
 				       u16 value)
 {
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 1e9bae6..058a9f2 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1988,7 +1988,7 @@ static void lpphy_calibration(struct b43_wldev *dev)
 static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -2004,7 +2004,7 @@ static u16 b43_lpphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	} else
 		reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -2013,7 +2013,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 5565318..df64032 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -6501,7 +6501,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
 	check_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
 	dev->phy.writes_counter = 1;
 }
@@ -6516,7 +6516,7 @@ static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	else
 		reg |= 0x100;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -6525,7 +6525,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
@ 2014-07-31 19:59   ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Access to PHY and radio registers is indirect on Broadcom hardware and
it seems that addressing on MIPS SoCs may require flushing. Broadcom
code does that unconditionally on MIPS, so let's do the same to make
sure hardware won't miss anything important.

Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
---
 drivers/net/wireless/b43/b43.h        |  8 ++++++++
 drivers/net/wireless/b43/main.c       | 17 ++++++++---------
 drivers/net/wireless/b43/phy_a.c      |  4 ++--
 drivers/net/wireless/b43/phy_common.c |  4 ++--
 drivers/net/wireless/b43/phy_g.c      |  8 ++++----
 drivers/net/wireless/b43/phy_ht.c     |  6 +++---
 drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
 drivers/net/wireless/b43/phy_lp.c     |  6 +++---
 drivers/net/wireless/b43/phy_n.c      |  6 +++---
 9 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 4113b69..ff0c666 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -1012,6 +1012,14 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
 	dev->dev->write16(dev->dev, offset, value);
 }
 
+static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
+{
+	b43_write16(dev, offset, value);
+#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
+	b43_read16(dev, offset);
+#endif
+}
+
 static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask,
 				 u16 set)
 {
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 2af1ac3..66ff718 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4466,10 +4466,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 	if (core_rev == 40 || core_rev == 42) {
 		radio_manuf = 0x17F;
 
-		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
+		b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 0);
 		radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 
-		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
+		b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 1);
 		radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 
 		radio_ver = 0; /* Is there version somewhere? */
@@ -4477,7 +4477,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 		u16 radio24[3];
 
 		for (tmp = 0; tmp < 3; tmp++) {
-			b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
+			b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, tmp);
 			radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 		}
 
@@ -4494,13 +4494,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 			else
 				tmp = 0x5205017F;
 		} else {
-			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-				    B43_RADIOCTL_ID);
+			b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+				     B43_RADIOCTL_ID);
 			tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
-			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-				    B43_RADIOCTL_ID);
-			tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
-				<< 16;
+			b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+				     B43_RADIOCTL_ID);
+			tmp |= b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
 		}
 		radio_manuf = (tmp & 0x00000FFF);
 		radio_id = (tmp & 0x0FFFF000) >> 12;
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 25e4043..99c036f 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -444,14 +444,14 @@ static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
 static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
 {
 	reg = adjust_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
 	reg = adjust_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 08ca524..1dfc682 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -278,7 +278,7 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
 	if (dev->phy.ops->phy_read)
 		return dev->phy.ops->phy_read(dev, reg);
 
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
@@ -294,7 +294,7 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 	if (dev->phy.ops->phy_write)
 		return dev->phy.ops->phy_write(dev, reg, value);
 
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index 8f5c14b..727ce6e 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -2555,13 +2555,13 @@ static void b43_gphy_op_exit(struct b43_wldev *dev)
 
 static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
@@ -2572,7 +2572,7 @@ static u16 b43_gphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* G-PHY needs 0x80 for read access. */
 	reg |= 0x80;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -2581,7 +2581,7 @@ static void b43_gphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 8b0b4b6..c4dc8b0 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -1074,7 +1074,7 @@ static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
 static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -1084,14 +1084,14 @@ static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* HT-PHY needs 0x200 for read access */
 	reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
 }
 
 static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
 				      u16 value)
 {
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index bf29c3e..97461cc 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -813,7 +813,7 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
 static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				   u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -823,14 +823,14 @@ static u16 b43_phy_lcn_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* LCN-PHY needs 0x200 for read access */
 	reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
 }
 
 static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg,
 				       u16 value)
 {
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 1e9bae6..058a9f2 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1988,7 +1988,7 @@ static void lpphy_calibration(struct b43_wldev *dev)
 static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -2004,7 +2004,7 @@ static u16 b43_lpphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	} else
 		reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -2013,7 +2013,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 5565318..df64032 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -6501,7 +6501,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
 	check_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
 	dev->phy.writes_counter = 1;
 }
@@ -6516,7 +6516,7 @@ static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	else
 		reg |= 0x100;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -6525,7 +6525,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3.18 4/7] b43: N-PHY: update rev3+ gain control workarounds
  2014-07-31 19:59 ` Rafał Miłecki
@ 2014-07-31 19:59   ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

This fixes workarounds on rev 6+ and cleans code slightly.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
 drivers/net/wireless/b43/tables_nphy.c | 61 +++++++++++++++++++++-------------
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 4b58850..f449cff 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -3197,7 +3197,7 @@ static struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][4] = {
 			{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
 			0x527E, /* invalid for external LNA! */
 			{ 0x513F, 0x513F, 0x513F, 0x513F }, /* invalid for external LNA! */
-			0x1076, 0x0066, 0x0000, /* low is invalid (the last one) */
+			0x007E, 0x0066, 0x0000, /* low is invalid (the last one) */
 			0x18, 0x18, 0x18,
 			0x01D0, 0x5,
 		},
@@ -3711,6 +3711,7 @@ const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
 struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
 	struct b43_wldev *dev, bool ghz5, bool ext_lna)
 {
+	struct b43_phy *phy = &dev->phy;
 	struct nphy_gain_ctl_workaround_entry *e;
 	u8 phy_idx;
 
@@ -3729,37 +3730,49 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
 	e = &nphy_gain_ctl_workaround[ghz5][phy_idx];
 
 	/* Some workarounds to the workarounds... */
-	if (ghz5 && dev->phy.rev >= 6) {
-		if (dev->phy.radio_rev == 11 &&
-		    !b43_is_40mhz(dev))
-			e->cliplo_gain = 0x2d;
-	} else if (!ghz5 && dev->phy.rev >= 5) {
-		static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
-						0x106c, 0x1074, 0x107c, 0x207c};
+	if (!ghz5) {
 		u8 tr_iso = dev->dev->bus_sprom->fem.ghz2.tr_iso;
 
-		if (ext_lna) {
+		if (tr_iso > 7)
+			tr_iso = 3;
+
+		if (phy->rev >= 6) {
+			static const int gain_data[] = { 0x106a, 0x106c, 0x1074,
+							 0x107c, 0x007e, 0x107e,
+							 0x207e, 0x307e, };
+
+			e->cliplo_gain = gain_data[tr_iso];
+		} else if (phy->rev == 5) {
+			static const int gain_data[] = { 0x0062, 0x0064, 0x006a,
+							 0x106a, 0x106c, 0x1074,
+							 0x107c, 0x207c, };
+
+			e->cliplo_gain = gain_data[tr_iso];
+		}
+
+		if (phy->rev >= 5 && ext_lna) {
 			e->rfseq_init[0] &= ~0x4000;
 			e->rfseq_init[1] &= ~0x4000;
 			e->rfseq_init[2] &= ~0x4000;
 			e->rfseq_init[3] &= ~0x4000;
 			e->init_gain &= ~0x4000;
 		}
-		if (tr_iso > 7)
-			tr_iso = 3;
-		e->cliplo_gain = gain_data[tr_iso];
-
-	} else if (ghz5 && dev->phy.rev == 4 && ext_lna) {
-		e->rfseq_init[0] &= ~0x4000;
-		e->rfseq_init[1] &= ~0x4000;
-		e->rfseq_init[2] &= ~0x4000;
-		e->rfseq_init[3] &= ~0x4000;
-		e->init_gain &= ~0x4000;
-		e->rfseq_init[0] |= 0x1000;
-		e->rfseq_init[1] |= 0x1000;
-		e->rfseq_init[2] |= 0x1000;
-		e->rfseq_init[3] |= 0x1000;
-		e->init_gain |= 0x1000;
+	} else {
+		if (phy->rev >= 6) {
+			if (phy->radio_rev == 11 && !b43_is_40mhz(dev))
+				e->crsminu = 0x2d;
+		} else if (phy->rev == 4 && ext_lna) {
+			e->rfseq_init[0] &= ~0x4000;
+			e->rfseq_init[1] &= ~0x4000;
+			e->rfseq_init[2] &= ~0x4000;
+			e->rfseq_init[3] &= ~0x4000;
+			e->init_gain &= ~0x4000;
+			e->rfseq_init[0] |= 0x1000;
+			e->rfseq_init[1] |= 0x1000;
+			e->rfseq_init[2] |= 0x1000;
+			e->rfseq_init[3] |= 0x1000;
+			e->init_gain |= 0x1000;
+		}
 	}
 
 	return e;
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3.18 4/7] b43: N-PHY: update rev3+ gain control workarounds
@ 2014-07-31 19:59   ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

This fixes workarounds on rev 6+ and cleans code slightly.

Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
---
 drivers/net/wireless/b43/tables_nphy.c | 61 +++++++++++++++++++++-------------
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 4b58850..f449cff 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -3197,7 +3197,7 @@ static struct nphy_gain_ctl_workaround_entry nphy_gain_ctl_workaround[2][4] = {
 			{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
 			0x527E, /* invalid for external LNA! */
 			{ 0x513F, 0x513F, 0x513F, 0x513F }, /* invalid for external LNA! */
-			0x1076, 0x0066, 0x0000, /* low is invalid (the last one) */
+			0x007E, 0x0066, 0x0000, /* low is invalid (the last one) */
 			0x18, 0x18, 0x18,
 			0x01D0, 0x5,
 		},
@@ -3711,6 +3711,7 @@ const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
 struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
 	struct b43_wldev *dev, bool ghz5, bool ext_lna)
 {
+	struct b43_phy *phy = &dev->phy;
 	struct nphy_gain_ctl_workaround_entry *e;
 	u8 phy_idx;
 
@@ -3729,37 +3730,49 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
 	e = &nphy_gain_ctl_workaround[ghz5][phy_idx];
 
 	/* Some workarounds to the workarounds... */
-	if (ghz5 && dev->phy.rev >= 6) {
-		if (dev->phy.radio_rev == 11 &&
-		    !b43_is_40mhz(dev))
-			e->cliplo_gain = 0x2d;
-	} else if (!ghz5 && dev->phy.rev >= 5) {
-		static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
-						0x106c, 0x1074, 0x107c, 0x207c};
+	if (!ghz5) {
 		u8 tr_iso = dev->dev->bus_sprom->fem.ghz2.tr_iso;
 
-		if (ext_lna) {
+		if (tr_iso > 7)
+			tr_iso = 3;
+
+		if (phy->rev >= 6) {
+			static const int gain_data[] = { 0x106a, 0x106c, 0x1074,
+							 0x107c, 0x007e, 0x107e,
+							 0x207e, 0x307e, };
+
+			e->cliplo_gain = gain_data[tr_iso];
+		} else if (phy->rev == 5) {
+			static const int gain_data[] = { 0x0062, 0x0064, 0x006a,
+							 0x106a, 0x106c, 0x1074,
+							 0x107c, 0x207c, };
+
+			e->cliplo_gain = gain_data[tr_iso];
+		}
+
+		if (phy->rev >= 5 && ext_lna) {
 			e->rfseq_init[0] &= ~0x4000;
 			e->rfseq_init[1] &= ~0x4000;
 			e->rfseq_init[2] &= ~0x4000;
 			e->rfseq_init[3] &= ~0x4000;
 			e->init_gain &= ~0x4000;
 		}
-		if (tr_iso > 7)
-			tr_iso = 3;
-		e->cliplo_gain = gain_data[tr_iso];
-
-	} else if (ghz5 && dev->phy.rev == 4 && ext_lna) {
-		e->rfseq_init[0] &= ~0x4000;
-		e->rfseq_init[1] &= ~0x4000;
-		e->rfseq_init[2] &= ~0x4000;
-		e->rfseq_init[3] &= ~0x4000;
-		e->init_gain &= ~0x4000;
-		e->rfseq_init[0] |= 0x1000;
-		e->rfseq_init[1] |= 0x1000;
-		e->rfseq_init[2] |= 0x1000;
-		e->rfseq_init[3] |= 0x1000;
-		e->init_gain |= 0x1000;
+	} else {
+		if (phy->rev >= 6) {
+			if (phy->radio_rev == 11 && !b43_is_40mhz(dev))
+				e->crsminu = 0x2d;
+		} else if (phy->rev == 4 && ext_lna) {
+			e->rfseq_init[0] &= ~0x4000;
+			e->rfseq_init[1] &= ~0x4000;
+			e->rfseq_init[2] &= ~0x4000;
+			e->rfseq_init[3] &= ~0x4000;
+			e->init_gain &= ~0x4000;
+			e->rfseq_init[0] |= 0x1000;
+			e->rfseq_init[1] |= 0x1000;
+			e->rfseq_init[2] |= 0x1000;
+			e->rfseq_init[3] |= 0x1000;
+			e->init_gain |= 0x1000;
+		}
 	}
 
 	return e;
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3.18 5/7] b43: N-PHY: add RF power tables for radio 0x2057 revs 9 & 14
  2014-07-31 19:59 ` Rafał Miłecki
@ 2014-07-31 19:59   ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Don't write them as we don't have gains configured correctly yet.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
These magic tables I add here may deserve some explanation. The problem
with fetching these tables was that wl.ko doesn't write them directly.
Instead it uses values from another table, extracts some bits from them
and then picks a proper value. This is why I couldn't get all values by
simply looking at MMIO dump and I had to guess few.

First I found writes of proper tables in MMIO dump:

1) Writing "txpwr" 32b values (cut to 5 out of 128)
phy_write(0x0072) <- 0x68c0	// This is (26 << 10) | 0xC0
phy_write(0x0074) <- 0x60ff
phy_write(0x0073) <- 0x0031	// This was 0x60ff0031 value
phy_write(0x0074) <- 0x60e7
phy_write(0x0073) <- 0x002c	// This was 0x60e7002c value
phy_write(0x0074) <- 0x60cf
phy_write(0x0073) <- 0x002a	// This was 0x60cf002a value
phy_write(0x0074) <- 0x60c7
phy_write(0x0073) <- 0x0029	// This was 0x60c70029 value
phy_write(0x0074) <- 0x60b7
phy_write(0x0073) <- 0x0029	// This was 0x60b70029 value
(...)

2) Writing RF power offset values (cut to 5 out of 128)
phy_write(0x0072) <- 0x6a40	// This is ((26 << 10) | 0x240) + 0
phy_write(0x0074) <- 0x0000
phy_write(0x0073) <- 0x0000
phy_write(0x0072) <- 0x6a41	// This is ((26 << 10) | 0x240) + 1
phy_write(0x0074) <- 0xffff
phy_write(0x0073) <- 0xfffd
phy_write(0x0072) <- 0x6a42	// This is ((26 << 10) | 0x240) + 2
phy_write(0x0074) <- 0xffff
phy_write(0x0073) <- 0xfff9
phy_write(0x0072) <- 0x6a43	// This is ((26 << 10) | 0x240) + 3
phy_write(0x0074) <- 0xffff
phy_write(0x0073) <- 0xfff7
phy_write(0x0072) <- 0x6a44	// This is ((26 << 10) | 0x240) + 4
phy_write(0x0074) <- 0xffff
phy_write(0x0073) <- 0xfff4
(...)

Then from every "txpwr" value I extracted "pad_gain" value using:
((table[i] >> 19) & 0x1f) and put corresponding write to the second
table next to it. Then I had to change hex value into signed int. It
went like this:
txpwr:0x60ff0031 pad_gain:31	0x00000000 0
txpwr:0x60e7002c pad_gain:28	0xfffffffd -3
txpwr:0x60cf002a pad_gain:25	0xfffffff9 -7
txpwr:0x60c70029 pad_gain:24	0xfffffff7 -9
txpwr:0x60b70029 pad_gain:22	0xfffffff4 -12
(...)
---
 drivers/net/wireless/b43/phy_n.c       | 21 +++++++++--
 drivers/net/wireless/b43/tables_nphy.c | 67 ++++++++++++++++++++++++++++++++++
 drivers/net/wireless/b43/tables_nphy.h |  2 +
 3 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index df64032..57a3ab2 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -4235,8 +4235,9 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
 
 	const u32 *table = NULL;
 	u32 rfpwr_offset;
-	u8 pga_gain;
+	u8 pga_gain, pad_gain;
 	int i;
+	const s16 *uninitialized_var(rf_pwr_offset_table);
 
 	table = b43_nphy_get_tx_gain_table(dev);
 	if (!table)
@@ -4252,13 +4253,27 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
 	nphy->gmval = (table[0] >> 16) & 0x7000;
 #endif
 
+	if (phy->rev >= 19) {
+		return;
+	} else if (phy->rev >= 7) {
+		rf_pwr_offset_table = b43_ntab_get_rf_pwr_offset_table(dev);
+		if (!rf_pwr_offset_table)
+			return;
+		/* TODO: Enable this once we have gains configured */
+		return;
+	}
+
 	for (i = 0; i < 128; i++) {
 		if (phy->rev >= 19) {
 			/* TODO */
 			return;
 		} else if (phy->rev >= 7) {
-			/* TODO */
-			return;
+			pga_gain = (table[i] >> 24) & 0xf;
+			pad_gain = (table[i] >> 19) & 0x1f;
+			if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+				rfpwr_offset = rf_pwr_offset_table[pad_gain];
+			else
+				rfpwr_offset = rf_pwr_offset_table[pga_gain];
 		} else {
 			pga_gain = (table[i] >> 24) & 0xF;
 			if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index f449cff..25d1cbd 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2878,6 +2878,40 @@ const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
 	-54, -46, -39, -31, -23, -15, -8, 0
 };
 
+/* Extracted from MMIO dump of 6.30.223.248
+ * Entries: 0, 15, 17, 21, 24, 26, 27, 29, 30 were guessed
+ */
+static const s16 b43_ntab_rf_pwr_offset_2057_rev9_2g[] = {
+	-133, -133, -107, -92, -81,
+	-73, -66, -61, -56, -52,
+	-48, -44, -41, -37, -34,
+	-31, -28, -25, -22, -19,
+	-17, -14, -12, -10, -9,
+	-7, -5, -4, -3, -2,
+	-1, 0,
+};
+
+/* Extracted from MMIO dump of 6.30.223.248 */
+static const s16 b43_ntab_rf_pwr_offset_2057_rev9_5g[] = {
+	-101, -94, -86, -79, -72,
+	-65, -57, -50, -42, -35,
+	-28, -21, -16, -9, -4,
+	0,
+};
+
+/* Extracted from MMIO dump of 6.30.223.248
+ * Entries: 0, 26, 28, 29, 30, 31 were guessed
+ */
+static const s16 b43_ntab_rf_pwr_offset_2057_rev14_2g[] = {
+	-111, -111, -111, -84, -70,
+	-59, -52, -45, -40, -36,
+	-32, -29, -26, -23, -21,
+	-18, -16, -15, -13, -11,
+	-10, -8, -7, -6, -5,
+	-4, -4, -3, -3, -2,
+	-2, -1,
+};
+
 const u16 tbl_iqcal_gainparams[2][9][8] = {
 	{
 		{ 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 },
@@ -3708,6 +3742,39 @@ const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
 	}
 }
 
+const s16 *b43_ntab_get_rf_pwr_offset_table(struct b43_wldev *dev)
+{
+	struct b43_phy *phy = &dev->phy;
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		switch (phy->rev) {
+		case 17:
+			if (phy->radio_rev == 14)
+				return b43_ntab_rf_pwr_offset_2057_rev14_2g;
+			break;
+		case 16:
+			if (phy->radio_rev == 9)
+				return b43_ntab_rf_pwr_offset_2057_rev9_2g;
+			break;
+		}
+
+		b43err(dev->wl,
+		       "No 2GHz RF power table available for this device\n");
+		return NULL;
+	} else {
+		switch (phy->rev) {
+		case 16:
+			if (phy->radio_rev == 9)
+				return b43_ntab_rf_pwr_offset_2057_rev9_5g;
+			break;
+		}
+
+		b43err(dev->wl,
+		       "No 5GHz RF power table available for this device\n");
+		return NULL;
+	}
+}
+
 struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
 	struct b43_wldev *dev, bool ghz5, bool ext_lna)
 {
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 3ce2e6f..b51f386 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -191,6 +191,8 @@ void b43_nphy_tables_init(struct b43_wldev *dev);
 
 const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev);
 
+const s16 *b43_ntab_get_rf_pwr_offset_table(struct b43_wldev *dev);
+
 extern const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[];
 
 extern const u16 tbl_iqcal_gainparams[2][9][8];
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 3.18 5/7] b43: N-PHY: add RF power tables for radio 0x2057 revs 9 & 14
@ 2014-07-31 19:59   ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Don't write them as we don't have gains configured correctly yet.

Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
---
These magic tables I add here may deserve some explanation. The problem
with fetching these tables was that wl.ko doesn't write them directly.
Instead it uses values from another table, extracts some bits from them
and then picks a proper value. This is why I couldn't get all values by
simply looking at MMIO dump and I had to guess few.

First I found writes of proper tables in MMIO dump:

1) Writing "txpwr" 32b values (cut to 5 out of 128)
phy_write(0x0072) <- 0x68c0	// This is (26 << 10) | 0xC0
phy_write(0x0074) <- 0x60ff
phy_write(0x0073) <- 0x0031	// This was 0x60ff0031 value
phy_write(0x0074) <- 0x60e7
phy_write(0x0073) <- 0x002c	// This was 0x60e7002c value
phy_write(0x0074) <- 0x60cf
phy_write(0x0073) <- 0x002a	// This was 0x60cf002a value
phy_write(0x0074) <- 0x60c7
phy_write(0x0073) <- 0x0029	// This was 0x60c70029 value
phy_write(0x0074) <- 0x60b7
phy_write(0x0073) <- 0x0029	// This was 0x60b70029 value
(...)

2) Writing RF power offset values (cut to 5 out of 128)
phy_write(0x0072) <- 0x6a40	// This is ((26 << 10) | 0x240) + 0
phy_write(0x0074) <- 0x0000
phy_write(0x0073) <- 0x0000
phy_write(0x0072) <- 0x6a41	// This is ((26 << 10) | 0x240) + 1
phy_write(0x0074) <- 0xffff
phy_write(0x0073) <- 0xfffd
phy_write(0x0072) <- 0x6a42	// This is ((26 << 10) | 0x240) + 2
phy_write(0x0074) <- 0xffff
phy_write(0x0073) <- 0xfff9
phy_write(0x0072) <- 0x6a43	// This is ((26 << 10) | 0x240) + 3
phy_write(0x0074) <- 0xffff
phy_write(0x0073) <- 0xfff7
phy_write(0x0072) <- 0x6a44	// This is ((26 << 10) | 0x240) + 4
phy_write(0x0074) <- 0xffff
phy_write(0x0073) <- 0xfff4
(...)

Then from every "txpwr" value I extracted "pad_gain" value using:
((table[i] >> 19) & 0x1f) and put corresponding write to the second
table next to it. Then I had to change hex value into signed int. It
went like this:
txpwr:0x60ff0031 pad_gain:31	0x00000000 0
txpwr:0x60e7002c pad_gain:28	0xfffffffd -3
txpwr:0x60cf002a pad_gain:25	0xfffffff9 -7
txpwr:0x60c70029 pad_gain:24	0xfffffff7 -9
txpwr:0x60b70029 pad_gain:22	0xfffffff4 -12
(...)
---
 drivers/net/wireless/b43/phy_n.c       | 21 +++++++++--
 drivers/net/wireless/b43/tables_nphy.c | 67 ++++++++++++++++++++++++++++++++++
 drivers/net/wireless/b43/tables_nphy.h |  2 +
 3 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index df64032..57a3ab2 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -4235,8 +4235,9 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
 
 	const u32 *table = NULL;
 	u32 rfpwr_offset;
-	u8 pga_gain;
+	u8 pga_gain, pad_gain;
 	int i;
+	const s16 *uninitialized_var(rf_pwr_offset_table);
 
 	table = b43_nphy_get_tx_gain_table(dev);
 	if (!table)
@@ -4252,13 +4253,27 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
 	nphy->gmval = (table[0] >> 16) & 0x7000;
 #endif
 
+	if (phy->rev >= 19) {
+		return;
+	} else if (phy->rev >= 7) {
+		rf_pwr_offset_table = b43_ntab_get_rf_pwr_offset_table(dev);
+		if (!rf_pwr_offset_table)
+			return;
+		/* TODO: Enable this once we have gains configured */
+		return;
+	}
+
 	for (i = 0; i < 128; i++) {
 		if (phy->rev >= 19) {
 			/* TODO */
 			return;
 		} else if (phy->rev >= 7) {
-			/* TODO */
-			return;
+			pga_gain = (table[i] >> 24) & 0xf;
+			pad_gain = (table[i] >> 19) & 0x1f;
+			if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+				rfpwr_offset = rf_pwr_offset_table[pad_gain];
+			else
+				rfpwr_offset = rf_pwr_offset_table[pga_gain];
 		} else {
 			pga_gain = (table[i] >> 24) & 0xF;
 			if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index f449cff..25d1cbd 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2878,6 +2878,40 @@ const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
 	-54, -46, -39, -31, -23, -15, -8, 0
 };
 
+/* Extracted from MMIO dump of 6.30.223.248
+ * Entries: 0, 15, 17, 21, 24, 26, 27, 29, 30 were guessed
+ */
+static const s16 b43_ntab_rf_pwr_offset_2057_rev9_2g[] = {
+	-133, -133, -107, -92, -81,
+	-73, -66, -61, -56, -52,
+	-48, -44, -41, -37, -34,
+	-31, -28, -25, -22, -19,
+	-17, -14, -12, -10, -9,
+	-7, -5, -4, -3, -2,
+	-1, 0,
+};
+
+/* Extracted from MMIO dump of 6.30.223.248 */
+static const s16 b43_ntab_rf_pwr_offset_2057_rev9_5g[] = {
+	-101, -94, -86, -79, -72,
+	-65, -57, -50, -42, -35,
+	-28, -21, -16, -9, -4,
+	0,
+};
+
+/* Extracted from MMIO dump of 6.30.223.248
+ * Entries: 0, 26, 28, 29, 30, 31 were guessed
+ */
+static const s16 b43_ntab_rf_pwr_offset_2057_rev14_2g[] = {
+	-111, -111, -111, -84, -70,
+	-59, -52, -45, -40, -36,
+	-32, -29, -26, -23, -21,
+	-18, -16, -15, -13, -11,
+	-10, -8, -7, -6, -5,
+	-4, -4, -3, -3, -2,
+	-2, -1,
+};
+
 const u16 tbl_iqcal_gainparams[2][9][8] = {
 	{
 		{ 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 },
@@ -3708,6 +3742,39 @@ const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
 	}
 }
 
+const s16 *b43_ntab_get_rf_pwr_offset_table(struct b43_wldev *dev)
+{
+	struct b43_phy *phy = &dev->phy;
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		switch (phy->rev) {
+		case 17:
+			if (phy->radio_rev == 14)
+				return b43_ntab_rf_pwr_offset_2057_rev14_2g;
+			break;
+		case 16:
+			if (phy->radio_rev == 9)
+				return b43_ntab_rf_pwr_offset_2057_rev9_2g;
+			break;
+		}
+
+		b43err(dev->wl,
+		       "No 2GHz RF power table available for this device\n");
+		return NULL;
+	} else {
+		switch (phy->rev) {
+		case 16:
+			if (phy->radio_rev == 9)
+				return b43_ntab_rf_pwr_offset_2057_rev9_5g;
+			break;
+		}
+
+		b43err(dev->wl,
+		       "No 5GHz RF power table available for this device\n");
+		return NULL;
+	}
+}
+
 struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
 	struct b43_wldev *dev, bool ghz5, bool ext_lna)
 {
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 3ce2e6f..b51f386 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -191,6 +191,8 @@ void b43_nphy_tables_init(struct b43_wldev *dev);
 
 const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev);
 
+const s16 *b43_ntab_get_rf_pwr_offset_table(struct b43_wldev *dev);
+
 extern const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[];
 
 extern const u16 tbl_iqcal_gainparams[2][9][8];
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH V2 3.18 6/7] b43: implement PPR (Power Per Rate) management/API
  2014-07-31 19:59 ` Rafał Miłecki
@ 2014-07-31 19:59   ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Broadcom hardware supports auto-adjustment of TX power depending on the
currently used rate. So far all calculations were handled without any
helpers (API) using big arrays and magic offsets.
It seems Broadcom recently decided to clean this up by developing PPR.
Their wlc_ppr.h can be found in open parts of the SDK.
As we plan to implement support for rate-based TX power it makes sense
to also implement our version of PPR as well.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
Notes: I compile it unconditionally, other PHYs should use it as well. I
already started working on HT-PHY.

V2: Drop unneeded __packed
    Added Copyright/GPL header
    Dropped some unneeded pointer (u32 replaced it)
    Replaced BUG_ON with WARN_ON_ONCE
    Fix indexing some array (use 4 + i)
---
 drivers/net/wireless/b43/Makefile |   1 +
 drivers/net/wireless/b43/b43.h    |   7 ++
 drivers/net/wireless/b43/ppr.c    | 199 ++++++++++++++++++++++++++++++++++++++
 drivers/net/wireless/b43/ppr.h    |  45 +++++++++
 4 files changed, 252 insertions(+)
 create mode 100644 drivers/net/wireless/b43/ppr.c
 create mode 100644 drivers/net/wireless/b43/ppr.h

diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 6e00b88..9f7965a 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -18,6 +18,7 @@ b43-y				+= xmit.o
 b43-y				+= dma.o
 b43-y				+= pio.o
 b43-y				+= rfkill.o
+b43-y				+= ppr.o
 b43-$(CONFIG_B43_LEDS)		+= leds.o
 b43-$(CONFIG_B43_PCMCIA)	+= pcmcia.o
 b43-$(CONFIG_B43_SDIO)		+= sdio.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index ff0c666..d55bd86 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -791,6 +791,13 @@ struct b43_firmware {
 	bool pcm_request_failed;
 };
 
+enum b43_band {
+	B43_BAND_2G = 0,
+	B43_BAND_5G_LO = 1,
+	B43_BAND_5G_MI = 2,
+	B43_BAND_5G_HI = 3,
+};
+
 /* Device (802.11 core) initialization status. */
 enum {
 	B43_STAT_UNINIT = 0,	/* Uninitialized. */
diff --git a/drivers/net/wireless/b43/ppr.c b/drivers/net/wireless/b43/ppr.c
new file mode 100644
index 0000000..f609cc5
--- /dev/null
+++ b/drivers/net/wireless/b43/ppr.c
@@ -0,0 +1,199 @@
+/*
+ * Broadcom B43 wireless driver
+ * PPR (Power Per Rate) management
+ *
+ * Copyright (c) 2014 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "ppr.h"
+#include "b43.h"
+
+#define ppr_for_each_entry(ppr, i, entry)				\
+	for (i = 0, entry = &(ppr)->__all_rates[i];			\
+	     i < B43_PPR_RATES_NUM;					\
+	     i++, entry++)
+
+void b43_ppr_clear(struct b43_wldev *dev, struct b43_ppr *ppr)
+{
+	memset(ppr, 0, sizeof(*ppr));
+
+	/* Compile-time PPR check */
+	BUILD_BUG_ON(sizeof(struct b43_ppr) != B43_PPR_RATES_NUM * sizeof(u8));
+}
+
+void b43_ppr_add(struct b43_wldev *dev, struct b43_ppr *ppr, int diff)
+{
+	int i;
+	u8 *rate;
+
+	ppr_for_each_entry(ppr, i, rate) {
+		*rate = clamp_val(*rate + diff, 0, 127);
+	}
+}
+
+void b43_ppr_apply_max(struct b43_wldev *dev, struct b43_ppr *ppr, u8 max)
+{
+	int i;
+	u8 *rate;
+
+	ppr_for_each_entry(ppr, i, rate) {
+		*rate = min(*rate, max);
+	}
+}
+
+void b43_ppr_apply_min(struct b43_wldev *dev, struct b43_ppr *ppr, u8 min)
+{
+	int i;
+	u8 *rate;
+
+	ppr_for_each_entry(ppr, i, rate) {
+		*rate = max(*rate, min);
+	}
+}
+
+u8 b43_ppr_get_max(struct b43_wldev *dev, struct b43_ppr *ppr)
+{
+	u8 res = 0;
+	int i;
+	u8 *rate;
+
+	ppr_for_each_entry(ppr, i, rate) {
+		res = max(*rate, res);
+	}
+
+	return res;
+}
+
+bool b43_ppr_load_max_from_sprom(struct b43_wldev *dev, struct b43_ppr *ppr,
+				 enum b43_band band)
+{
+	struct b43_ppr_rates *rates = &ppr->rates;
+	struct ssb_sprom *sprom = dev->dev->bus_sprom;
+	struct b43_phy *phy = &dev->phy;
+	u8 maxpwr, off;
+	u32 sprom_ofdm_po;
+	u16 *sprom_mcs_po;
+	u8 extra_cdd_po, extra_stbc_po;
+	int i;
+
+	switch (band) {
+	case B43_BAND_2G:
+		maxpwr = min(sprom->core_pwr_info[0].maxpwr_2g,
+			     sprom->core_pwr_info[1].maxpwr_2g);
+		sprom_ofdm_po = sprom->ofdm2gpo;
+		sprom_mcs_po = sprom->mcs2gpo;
+		extra_cdd_po = (sprom->cddpo >> 0) & 0xf;
+		extra_stbc_po = (sprom->stbcpo >> 0) & 0xf;
+		break;
+	case B43_BAND_5G_LO:
+		maxpwr = min(sprom->core_pwr_info[0].maxpwr_5gl,
+			     sprom->core_pwr_info[1].maxpwr_5gl);
+		sprom_ofdm_po = sprom->ofdm5glpo;
+		sprom_mcs_po = sprom->mcs5glpo;
+		extra_cdd_po = (sprom->cddpo >> 8) & 0xf;
+		extra_stbc_po = (sprom->stbcpo >> 8) & 0xf;
+		break;
+	case B43_BAND_5G_MI:
+		maxpwr = min(sprom->core_pwr_info[0].maxpwr_5g,
+			     sprom->core_pwr_info[1].maxpwr_5g);
+		sprom_ofdm_po = sprom->ofdm5gpo;
+		sprom_mcs_po = sprom->mcs5gpo;
+		extra_cdd_po = (sprom->cddpo >> 4) & 0xf;
+		extra_stbc_po = (sprom->stbcpo >> 4) & 0xf;
+		break;
+	case B43_BAND_5G_HI:
+		maxpwr = min(sprom->core_pwr_info[0].maxpwr_5gh,
+			     sprom->core_pwr_info[1].maxpwr_5gh);
+		sprom_ofdm_po = sprom->ofdm5ghpo;
+		sprom_mcs_po = sprom->mcs5ghpo;
+		extra_cdd_po = (sprom->cddpo >> 12) & 0xf;
+		extra_stbc_po = (sprom->stbcpo >> 12) & 0xf;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return false;
+	}
+
+	if (band == B43_BAND_2G) {
+		for (i = 0; i < 4; i++) {
+			off = ((sprom->cck2gpo >> (i * 4)) & 0xf) * 2;
+			rates->cck[i] = maxpwr - off;
+		}
+	}
+
+	/* OFDM */
+	for (i = 0; i < 8; i++) {
+		off = ((sprom_ofdm_po >> (i * 4)) & 0xf) * 2;
+		rates->ofdm[i] = maxpwr - off;
+	}
+
+	/* MCS 20 SISO */
+	rates->mcs_20[0] = rates->ofdm[0];
+	rates->mcs_20[1] = rates->ofdm[2];
+	rates->mcs_20[2] = rates->ofdm[3];
+	rates->mcs_20[3] = rates->ofdm[4];
+	rates->mcs_20[4] = rates->ofdm[5];
+	rates->mcs_20[5] = rates->ofdm[6];
+	rates->mcs_20[6] = rates->ofdm[7];
+	rates->mcs_20[7] = rates->ofdm[7];
+
+	/* MCS 20 CDD */
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_cdd[i] = maxpwr - off;
+		if (phy->type == B43_PHYTYPE_N && phy->rev >= 3)
+			rates->mcs_20_cdd[i] -= extra_cdd_po;
+	}
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_cdd[4 + i] = maxpwr - off;
+		if (phy->type == B43_PHYTYPE_N && phy->rev >= 3)
+			rates->mcs_20_cdd[4 + i] -= extra_cdd_po;
+	}
+
+	/* OFDM 20 CDD */
+	rates->ofdm_20_cdd[0] = rates->mcs_20_cdd[0];
+	rates->ofdm_20_cdd[1] = rates->mcs_20_cdd[0];
+	rates->ofdm_20_cdd[2] = rates->mcs_20_cdd[1];
+	rates->ofdm_20_cdd[3] = rates->mcs_20_cdd[2];
+	rates->ofdm_20_cdd[4] = rates->mcs_20_cdd[3];
+	rates->ofdm_20_cdd[5] = rates->mcs_20_cdd[4];
+	rates->ofdm_20_cdd[6] = rates->mcs_20_cdd[5];
+	rates->ofdm_20_cdd[7] = rates->mcs_20_cdd[6];
+
+	/* MCS 20 STBC */
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_stbc[i] = maxpwr - off;
+		if (phy->type == B43_PHYTYPE_N && phy->rev >= 3)
+			rates->mcs_20_stbc[i] -= extra_stbc_po;
+	}
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_stbc[4 + i] = maxpwr - off;
+		if (phy->type == B43_PHYTYPE_N && phy->rev >= 3)
+			rates->mcs_20_stbc[4 + i] -= extra_stbc_po;
+	}
+
+	/* MCS 20 SDM */
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[2] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_sdm[i] = maxpwr - off;
+	}
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[3] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_sdm[4 + i] = maxpwr - off;
+	}
+
+	return true;
+}
diff --git a/drivers/net/wireless/b43/ppr.h b/drivers/net/wireless/b43/ppr.h
new file mode 100644
index 0000000..24d7447
--- /dev/null
+++ b/drivers/net/wireless/b43/ppr.h
@@ -0,0 +1,45 @@
+#ifndef LINUX_B43_PPR_H_
+#define LINUX_B43_PPR_H_
+
+#include <linux/types.h>
+
+#define B43_PPR_CCK_RATES_NUM		4
+#define B43_PPR_OFDM_RATES_NUM		8
+#define B43_PPR_MCS_RATES_NUM		8
+
+#define B43_PPR_RATES_NUM	(B43_PPR_CCK_RATES_NUM +	\
+				 B43_PPR_OFDM_RATES_NUM * 2 +	\
+				 B43_PPR_MCS_RATES_NUM * 4)
+
+struct b43_ppr_rates {
+	u8 cck[B43_PPR_CCK_RATES_NUM];
+	u8 ofdm[B43_PPR_OFDM_RATES_NUM];
+	u8 ofdm_20_cdd[B43_PPR_OFDM_RATES_NUM];
+	u8 mcs_20[B43_PPR_MCS_RATES_NUM]; /* SISO */
+	u8 mcs_20_cdd[B43_PPR_MCS_RATES_NUM];
+	u8 mcs_20_stbc[B43_PPR_MCS_RATES_NUM];
+	u8 mcs_20_sdm[B43_PPR_MCS_RATES_NUM];
+};
+
+struct b43_ppr {
+	/* All powers are in qdbm (Q5.2) */
+	union {
+		u8 __all_rates[B43_PPR_RATES_NUM];
+		struct b43_ppr_rates rates;
+	};
+};
+
+struct b43_wldev;
+enum b43_band;
+
+void b43_ppr_clear(struct b43_wldev *dev, struct b43_ppr *ppr);
+
+void b43_ppr_add(struct b43_wldev *dev, struct b43_ppr *ppr, int diff);
+void b43_ppr_apply_max(struct b43_wldev *dev, struct b43_ppr *ppr, u8 max);
+void b43_ppr_apply_min(struct b43_wldev *dev, struct b43_ppr *ppr, u8 min);
+u8 b43_ppr_get_max(struct b43_wldev *dev, struct b43_ppr *ppr);
+
+bool b43_ppr_load_max_from_sprom(struct b43_wldev *dev, struct b43_ppr *ppr,
+				 enum b43_band band);
+
+#endif /* LINUX_B43_PPR_H_ */
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH V2 3.18 6/7] b43: implement PPR (Power Per Rate) management/API
@ 2014-07-31 19:59   ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Broadcom hardware supports auto-adjustment of TX power depending on the
currently used rate. So far all calculations were handled without any
helpers (API) using big arrays and magic offsets.
It seems Broadcom recently decided to clean this up by developing PPR.
Their wlc_ppr.h can be found in open parts of the SDK.
As we plan to implement support for rate-based TX power it makes sense
to also implement our version of PPR as well.

Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
---
Notes: I compile it unconditionally, other PHYs should use it as well. I
already started working on HT-PHY.

V2: Drop unneeded __packed
    Added Copyright/GPL header
    Dropped some unneeded pointer (u32 replaced it)
    Replaced BUG_ON with WARN_ON_ONCE
    Fix indexing some array (use 4 + i)
---
 drivers/net/wireless/b43/Makefile |   1 +
 drivers/net/wireless/b43/b43.h    |   7 ++
 drivers/net/wireless/b43/ppr.c    | 199 ++++++++++++++++++++++++++++++++++++++
 drivers/net/wireless/b43/ppr.h    |  45 +++++++++
 4 files changed, 252 insertions(+)
 create mode 100644 drivers/net/wireless/b43/ppr.c
 create mode 100644 drivers/net/wireless/b43/ppr.h

diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 6e00b88..9f7965a 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -18,6 +18,7 @@ b43-y				+= xmit.o
 b43-y				+= dma.o
 b43-y				+= pio.o
 b43-y				+= rfkill.o
+b43-y				+= ppr.o
 b43-$(CONFIG_B43_LEDS)		+= leds.o
 b43-$(CONFIG_B43_PCMCIA)	+= pcmcia.o
 b43-$(CONFIG_B43_SDIO)		+= sdio.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index ff0c666..d55bd86 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -791,6 +791,13 @@ struct b43_firmware {
 	bool pcm_request_failed;
 };
 
+enum b43_band {
+	B43_BAND_2G = 0,
+	B43_BAND_5G_LO = 1,
+	B43_BAND_5G_MI = 2,
+	B43_BAND_5G_HI = 3,
+};
+
 /* Device (802.11 core) initialization status. */
 enum {
 	B43_STAT_UNINIT = 0,	/* Uninitialized. */
diff --git a/drivers/net/wireless/b43/ppr.c b/drivers/net/wireless/b43/ppr.c
new file mode 100644
index 0000000..f609cc5
--- /dev/null
+++ b/drivers/net/wireless/b43/ppr.c
@@ -0,0 +1,199 @@
+/*
+ * Broadcom B43 wireless driver
+ * PPR (Power Per Rate) management
+ *
+ * Copyright (c) 2014 Rafa? Mi?ecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "ppr.h"
+#include "b43.h"
+
+#define ppr_for_each_entry(ppr, i, entry)				\
+	for (i = 0, entry = &(ppr)->__all_rates[i];			\
+	     i < B43_PPR_RATES_NUM;					\
+	     i++, entry++)
+
+void b43_ppr_clear(struct b43_wldev *dev, struct b43_ppr *ppr)
+{
+	memset(ppr, 0, sizeof(*ppr));
+
+	/* Compile-time PPR check */
+	BUILD_BUG_ON(sizeof(struct b43_ppr) != B43_PPR_RATES_NUM * sizeof(u8));
+}
+
+void b43_ppr_add(struct b43_wldev *dev, struct b43_ppr *ppr, int diff)
+{
+	int i;
+	u8 *rate;
+
+	ppr_for_each_entry(ppr, i, rate) {
+		*rate = clamp_val(*rate + diff, 0, 127);
+	}
+}
+
+void b43_ppr_apply_max(struct b43_wldev *dev, struct b43_ppr *ppr, u8 max)
+{
+	int i;
+	u8 *rate;
+
+	ppr_for_each_entry(ppr, i, rate) {
+		*rate = min(*rate, max);
+	}
+}
+
+void b43_ppr_apply_min(struct b43_wldev *dev, struct b43_ppr *ppr, u8 min)
+{
+	int i;
+	u8 *rate;
+
+	ppr_for_each_entry(ppr, i, rate) {
+		*rate = max(*rate, min);
+	}
+}
+
+u8 b43_ppr_get_max(struct b43_wldev *dev, struct b43_ppr *ppr)
+{
+	u8 res = 0;
+	int i;
+	u8 *rate;
+
+	ppr_for_each_entry(ppr, i, rate) {
+		res = max(*rate, res);
+	}
+
+	return res;
+}
+
+bool b43_ppr_load_max_from_sprom(struct b43_wldev *dev, struct b43_ppr *ppr,
+				 enum b43_band band)
+{
+	struct b43_ppr_rates *rates = &ppr->rates;
+	struct ssb_sprom *sprom = dev->dev->bus_sprom;
+	struct b43_phy *phy = &dev->phy;
+	u8 maxpwr, off;
+	u32 sprom_ofdm_po;
+	u16 *sprom_mcs_po;
+	u8 extra_cdd_po, extra_stbc_po;
+	int i;
+
+	switch (band) {
+	case B43_BAND_2G:
+		maxpwr = min(sprom->core_pwr_info[0].maxpwr_2g,
+			     sprom->core_pwr_info[1].maxpwr_2g);
+		sprom_ofdm_po = sprom->ofdm2gpo;
+		sprom_mcs_po = sprom->mcs2gpo;
+		extra_cdd_po = (sprom->cddpo >> 0) & 0xf;
+		extra_stbc_po = (sprom->stbcpo >> 0) & 0xf;
+		break;
+	case B43_BAND_5G_LO:
+		maxpwr = min(sprom->core_pwr_info[0].maxpwr_5gl,
+			     sprom->core_pwr_info[1].maxpwr_5gl);
+		sprom_ofdm_po = sprom->ofdm5glpo;
+		sprom_mcs_po = sprom->mcs5glpo;
+		extra_cdd_po = (sprom->cddpo >> 8) & 0xf;
+		extra_stbc_po = (sprom->stbcpo >> 8) & 0xf;
+		break;
+	case B43_BAND_5G_MI:
+		maxpwr = min(sprom->core_pwr_info[0].maxpwr_5g,
+			     sprom->core_pwr_info[1].maxpwr_5g);
+		sprom_ofdm_po = sprom->ofdm5gpo;
+		sprom_mcs_po = sprom->mcs5gpo;
+		extra_cdd_po = (sprom->cddpo >> 4) & 0xf;
+		extra_stbc_po = (sprom->stbcpo >> 4) & 0xf;
+		break;
+	case B43_BAND_5G_HI:
+		maxpwr = min(sprom->core_pwr_info[0].maxpwr_5gh,
+			     sprom->core_pwr_info[1].maxpwr_5gh);
+		sprom_ofdm_po = sprom->ofdm5ghpo;
+		sprom_mcs_po = sprom->mcs5ghpo;
+		extra_cdd_po = (sprom->cddpo >> 12) & 0xf;
+		extra_stbc_po = (sprom->stbcpo >> 12) & 0xf;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return false;
+	}
+
+	if (band == B43_BAND_2G) {
+		for (i = 0; i < 4; i++) {
+			off = ((sprom->cck2gpo >> (i * 4)) & 0xf) * 2;
+			rates->cck[i] = maxpwr - off;
+		}
+	}
+
+	/* OFDM */
+	for (i = 0; i < 8; i++) {
+		off = ((sprom_ofdm_po >> (i * 4)) & 0xf) * 2;
+		rates->ofdm[i] = maxpwr - off;
+	}
+
+	/* MCS 20 SISO */
+	rates->mcs_20[0] = rates->ofdm[0];
+	rates->mcs_20[1] = rates->ofdm[2];
+	rates->mcs_20[2] = rates->ofdm[3];
+	rates->mcs_20[3] = rates->ofdm[4];
+	rates->mcs_20[4] = rates->ofdm[5];
+	rates->mcs_20[5] = rates->ofdm[6];
+	rates->mcs_20[6] = rates->ofdm[7];
+	rates->mcs_20[7] = rates->ofdm[7];
+
+	/* MCS 20 CDD */
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_cdd[i] = maxpwr - off;
+		if (phy->type == B43_PHYTYPE_N && phy->rev >= 3)
+			rates->mcs_20_cdd[i] -= extra_cdd_po;
+	}
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_cdd[4 + i] = maxpwr - off;
+		if (phy->type == B43_PHYTYPE_N && phy->rev >= 3)
+			rates->mcs_20_cdd[4 + i] -= extra_cdd_po;
+	}
+
+	/* OFDM 20 CDD */
+	rates->ofdm_20_cdd[0] = rates->mcs_20_cdd[0];
+	rates->ofdm_20_cdd[1] = rates->mcs_20_cdd[0];
+	rates->ofdm_20_cdd[2] = rates->mcs_20_cdd[1];
+	rates->ofdm_20_cdd[3] = rates->mcs_20_cdd[2];
+	rates->ofdm_20_cdd[4] = rates->mcs_20_cdd[3];
+	rates->ofdm_20_cdd[5] = rates->mcs_20_cdd[4];
+	rates->ofdm_20_cdd[6] = rates->mcs_20_cdd[5];
+	rates->ofdm_20_cdd[7] = rates->mcs_20_cdd[6];
+
+	/* MCS 20 STBC */
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[0] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_stbc[i] = maxpwr - off;
+		if (phy->type == B43_PHYTYPE_N && phy->rev >= 3)
+			rates->mcs_20_stbc[i] -= extra_stbc_po;
+	}
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[1] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_stbc[4 + i] = maxpwr - off;
+		if (phy->type == B43_PHYTYPE_N && phy->rev >= 3)
+			rates->mcs_20_stbc[4 + i] -= extra_stbc_po;
+	}
+
+	/* MCS 20 SDM */
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[2] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_sdm[i] = maxpwr - off;
+	}
+	for (i = 0; i < 4; i++) {
+		off = ((sprom_mcs_po[3] >> (i * 4)) & 0xf) * 2;
+		rates->mcs_20_sdm[4 + i] = maxpwr - off;
+	}
+
+	return true;
+}
diff --git a/drivers/net/wireless/b43/ppr.h b/drivers/net/wireless/b43/ppr.h
new file mode 100644
index 0000000..24d7447
--- /dev/null
+++ b/drivers/net/wireless/b43/ppr.h
@@ -0,0 +1,45 @@
+#ifndef LINUX_B43_PPR_H_
+#define LINUX_B43_PPR_H_
+
+#include <linux/types.h>
+
+#define B43_PPR_CCK_RATES_NUM		4
+#define B43_PPR_OFDM_RATES_NUM		8
+#define B43_PPR_MCS_RATES_NUM		8
+
+#define B43_PPR_RATES_NUM	(B43_PPR_CCK_RATES_NUM +	\
+				 B43_PPR_OFDM_RATES_NUM * 2 +	\
+				 B43_PPR_MCS_RATES_NUM * 4)
+
+struct b43_ppr_rates {
+	u8 cck[B43_PPR_CCK_RATES_NUM];
+	u8 ofdm[B43_PPR_OFDM_RATES_NUM];
+	u8 ofdm_20_cdd[B43_PPR_OFDM_RATES_NUM];
+	u8 mcs_20[B43_PPR_MCS_RATES_NUM]; /* SISO */
+	u8 mcs_20_cdd[B43_PPR_MCS_RATES_NUM];
+	u8 mcs_20_stbc[B43_PPR_MCS_RATES_NUM];
+	u8 mcs_20_sdm[B43_PPR_MCS_RATES_NUM];
+};
+
+struct b43_ppr {
+	/* All powers are in qdbm (Q5.2) */
+	union {
+		u8 __all_rates[B43_PPR_RATES_NUM];
+		struct b43_ppr_rates rates;
+	};
+};
+
+struct b43_wldev;
+enum b43_band;
+
+void b43_ppr_clear(struct b43_wldev *dev, struct b43_ppr *ppr);
+
+void b43_ppr_add(struct b43_wldev *dev, struct b43_ppr *ppr, int diff);
+void b43_ppr_apply_max(struct b43_wldev *dev, struct b43_ppr *ppr, u8 max);
+void b43_ppr_apply_min(struct b43_wldev *dev, struct b43_ppr *ppr, u8 min);
+u8 b43_ppr_get_max(struct b43_wldev *dev, struct b43_ppr *ppr);
+
+bool b43_ppr_load_max_from_sprom(struct b43_wldev *dev, struct b43_ppr *ppr,
+				 enum b43_band band);
+
+#endif /* LINUX_B43_PPR_H_ */
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH V2 3.18 7/7] b43: N-PHY: support setting custom TX power
  2014-07-31 19:59 ` Rafał Miłecki
@ 2014-07-31 19:59   ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
Notes: I still need to implement helper for B43_MACCTL_PHY_LOCK, but
this may require wider changes, so will be handled in another patch.

V2: Make struct b43_ppr part of struct b43_phy_n
---
 drivers/net/wireless/b43/b43.h   |  1 +
 drivers/net/wireless/b43/phy_n.c | 84 ++++++++++++++++++++++++++++++++++------
 drivers/net/wireless/b43/phy_n.h |  4 ++
 3 files changed, 77 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index d55bd86..c0dda0b 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -457,6 +457,7 @@ enum {
 #define B43_MACCTL_RADIOLOCK		0x00080000	/* Radio lock */
 #define B43_MACCTL_BEACPROMISC		0x00100000	/* Beacon Promiscuous */
 #define B43_MACCTL_KEEP_BADPLCP		0x00200000	/* Keep frames with bad PLCP */
+#define B43_MACCTL_PHY_LOCK		0x00200000
 #define B43_MACCTL_KEEP_CTL		0x00400000	/* Keep control frames */
 #define B43_MACCTL_KEEP_BAD		0x00800000	/* Keep bad frames (FCS) */
 #define B43_MACCTL_PROMISC		0x01000000	/* Promiscuous mode */
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 57a3ab2..cf625d8 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -34,6 +34,7 @@
 #include "radio_2056.h"
 #include "radio_2057.h"
 #include "main.h"
+#include "ppr.h"
 
 struct nphy_txgains {
 	u16 tx_lpf[2];
@@ -3606,16 +3607,6 @@ static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
  * Tx and Rx
  **************************************************/
 
-static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev)
-{//TODO
-}
-
-static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
-							bool ignore_tssi)
-{//TODO
-	return B43_TXPWR_RES_DONE;
-}
-
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
 static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
 {
@@ -4069,6 +4060,7 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
 
 	s16 a1[2], b0[2], b1[2];
 	u8 idle[2];
+	u8 ppr_max;
 	s8 target[2];
 	s32 num, den, pwr;
 	u32 regval[64];
@@ -4147,7 +4139,12 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
 			b1[0] = b1[1] = -1393;
 		}
 	}
-	/* target[0] = target[1] = nphy->tx_power_max; */
+
+	ppr_max = b43_ppr_get_max(dev, &nphy->tx_pwr_max_ppr);
+	if (ppr_max) {
+		target[0] = ppr_max;
+		target[1] = ppr_max;
+	}
 
 	if (dev->phy.rev >= 3) {
 		if (sprom->fem.ghz2.tssipos)
@@ -5889,6 +5886,69 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
 	b43_mac_enable(dev);
 }
 
+static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
+							bool ignore_tssi)
+{
+	struct b43_phy *phy = &dev->phy;
+	struct b43_phy_n *nphy = dev->phy.n;
+	struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
+	struct b43_ppr *ppr = &nphy->tx_pwr_max_ppr;
+	u8 max; /* qdBm */
+	bool tx_pwr_state;
+
+	if (nphy->tx_pwr_last_recalc_freq == channel->center_freq &&
+	    nphy->tx_pwr_last_recalc_limit == phy->desired_txpower)
+		return B43_TXPWR_RES_DONE;
+
+	/* Make sure we have a clean PPR */
+	b43_ppr_clear(dev, ppr);
+
+	/* HW limitations */
+	b43_ppr_load_max_from_sprom(dev, ppr, B43_BAND_2G);
+
+	/* Regulatory & user settings */
+	max = INT_TO_Q52(phy->chandef->chan->max_power);
+	if (phy->desired_txpower)
+		max = min_t(u8, max, INT_TO_Q52(phy->desired_txpower));
+	b43_ppr_apply_max(dev, ppr, max);
+	if (b43_debug(dev, B43_DBG_XMITPOWER))
+		b43dbg(dev->wl, "Calculated TX power: " Q52_FMT "\n",
+		       Q52_ARG(b43_ppr_get_max(dev, ppr)));
+
+	/* TODO: Enable this once we get gains working */
+#if 0
+	/* Some extra gains */
+	hw_gain = 6; /* N-PHY specific */
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+		hw_gain += sprom->antenna_gain.a0;
+	else
+		hw_gain += sprom->antenna_gain.a1;
+	b43_ppr_add(dev, ppr, -hw_gain);
+#endif
+
+	/* Make sure we didn't go too low */
+	b43_ppr_apply_min(dev, ppr, INT_TO_Q52(8));
+
+	/* Apply */
+	tx_pwr_state = nphy->txpwrctrl;
+	b43_mac_suspend(dev);
+	b43_nphy_tx_power_ctl_setup(dev);
+	if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_PHY_LOCK);
+		b43_read32(dev, B43_MMIO_MACCTL);
+		udelay(1);
+	}
+	b43_nphy_tx_power_ctrl(dev, nphy->txpwrctrl);
+	if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PHY_LOCK, 0);
+	b43_mac_enable(dev);
+
+	nphy->tx_pwr_last_recalc_freq = channel->center_freq;
+	nphy->tx_pwr_last_recalc_limit = phy->desired_txpower;
+
+	return B43_TXPWR_RES_DONE;
+}
+
 /**************************************************
  * N-PHY init
  **************************************************/
@@ -6422,6 +6482,7 @@ static int b43_nphy_op_allocate(struct b43_wldev *dev)
 	nphy = kzalloc(sizeof(*nphy), GFP_KERNEL);
 	if (!nphy)
 		return -ENOMEM;
+
 	dev->phy.n = nphy;
 
 	return 0;
@@ -6662,5 +6723,4 @@ const struct b43_phy_operations b43_phyops_n = {
 	.switch_channel		= b43_nphy_op_switch_channel,
 	.get_default_chan	= b43_nphy_op_get_default_chan,
 	.recalc_txpower		= b43_nphy_op_recalc_txpower,
-	.adjust_txpower		= b43_nphy_op_adjust_txpower,
 };
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 30bec81..a6da2c3 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -2,6 +2,7 @@
 #define B43_NPHY_H_
 
 #include "phy_common.h"
+#include "ppr.h"
 
 
 /* N-PHY registers. */
@@ -967,6 +968,9 @@ struct b43_phy_n {
 	struct b43_phy_n_txpwrindex txpwrindex[2];
 	struct b43_phy_n_pwr_ctl_info pwr_ctl_info[2];
 	struct b43_chanspec txiqlocal_chanspec;
+	struct b43_ppr tx_pwr_max_ppr;
+	u16 tx_pwr_last_recalc_freq;
+	int tx_pwr_last_recalc_limit;
 
 	u8 txrx_chain;
 	u16 tx_rx_cal_phy_saveregs[11];
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH V2 3.18 7/7] b43: N-PHY: support setting custom TX power
@ 2014-07-31 19:59   ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 19:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
---
Notes: I still need to implement helper for B43_MACCTL_PHY_LOCK, but
this may require wider changes, so will be handled in another patch.

V2: Make struct b43_ppr part of struct b43_phy_n
---
 drivers/net/wireless/b43/b43.h   |  1 +
 drivers/net/wireless/b43/phy_n.c | 84 ++++++++++++++++++++++++++++++++++------
 drivers/net/wireless/b43/phy_n.h |  4 ++
 3 files changed, 77 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index d55bd86..c0dda0b 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -457,6 +457,7 @@ enum {
 #define B43_MACCTL_RADIOLOCK		0x00080000	/* Radio lock */
 #define B43_MACCTL_BEACPROMISC		0x00100000	/* Beacon Promiscuous */
 #define B43_MACCTL_KEEP_BADPLCP		0x00200000	/* Keep frames with bad PLCP */
+#define B43_MACCTL_PHY_LOCK		0x00200000
 #define B43_MACCTL_KEEP_CTL		0x00400000	/* Keep control frames */
 #define B43_MACCTL_KEEP_BAD		0x00800000	/* Keep bad frames (FCS) */
 #define B43_MACCTL_PROMISC		0x01000000	/* Promiscuous mode */
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 57a3ab2..cf625d8 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -34,6 +34,7 @@
 #include "radio_2056.h"
 #include "radio_2057.h"
 #include "main.h"
+#include "ppr.h"
 
 struct nphy_txgains {
 	u16 tx_lpf[2];
@@ -3606,16 +3607,6 @@ static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
  * Tx and Rx
  **************************************************/
 
-static void b43_nphy_op_adjust_txpower(struct b43_wldev *dev)
-{//TODO
-}
-
-static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
-							bool ignore_tssi)
-{//TODO
-	return B43_TXPWR_RES_DONE;
-}
-
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlEnable */
 static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
 {
@@ -4069,6 +4060,7 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
 
 	s16 a1[2], b0[2], b1[2];
 	u8 idle[2];
+	u8 ppr_max;
 	s8 target[2];
 	s32 num, den, pwr;
 	u32 regval[64];
@@ -4147,7 +4139,12 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
 			b1[0] = b1[1] = -1393;
 		}
 	}
-	/* target[0] = target[1] = nphy->tx_power_max; */
+
+	ppr_max = b43_ppr_get_max(dev, &nphy->tx_pwr_max_ppr);
+	if (ppr_max) {
+		target[0] = ppr_max;
+		target[1] = ppr_max;
+	}
 
 	if (dev->phy.rev >= 3) {
 		if (sprom->fem.ghz2.tssipos)
@@ -5889,6 +5886,69 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
 	b43_mac_enable(dev);
 }
 
+static enum b43_txpwr_result b43_nphy_op_recalc_txpower(struct b43_wldev *dev,
+							bool ignore_tssi)
+{
+	struct b43_phy *phy = &dev->phy;
+	struct b43_phy_n *nphy = dev->phy.n;
+	struct ieee80211_channel *channel = dev->wl->hw->conf.chandef.chan;
+	struct b43_ppr *ppr = &nphy->tx_pwr_max_ppr;
+	u8 max; /* qdBm */
+	bool tx_pwr_state;
+
+	if (nphy->tx_pwr_last_recalc_freq == channel->center_freq &&
+	    nphy->tx_pwr_last_recalc_limit == phy->desired_txpower)
+		return B43_TXPWR_RES_DONE;
+
+	/* Make sure we have a clean PPR */
+	b43_ppr_clear(dev, ppr);
+
+	/* HW limitations */
+	b43_ppr_load_max_from_sprom(dev, ppr, B43_BAND_2G);
+
+	/* Regulatory & user settings */
+	max = INT_TO_Q52(phy->chandef->chan->max_power);
+	if (phy->desired_txpower)
+		max = min_t(u8, max, INT_TO_Q52(phy->desired_txpower));
+	b43_ppr_apply_max(dev, ppr, max);
+	if (b43_debug(dev, B43_DBG_XMITPOWER))
+		b43dbg(dev->wl, "Calculated TX power: " Q52_FMT "\n",
+		       Q52_ARG(b43_ppr_get_max(dev, ppr)));
+
+	/* TODO: Enable this once we get gains working */
+#if 0
+	/* Some extra gains */
+	hw_gain = 6; /* N-PHY specific */
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+		hw_gain += sprom->antenna_gain.a0;
+	else
+		hw_gain += sprom->antenna_gain.a1;
+	b43_ppr_add(dev, ppr, -hw_gain);
+#endif
+
+	/* Make sure we didn't go too low */
+	b43_ppr_apply_min(dev, ppr, INT_TO_Q52(8));
+
+	/* Apply */
+	tx_pwr_state = nphy->txpwrctrl;
+	b43_mac_suspend(dev);
+	b43_nphy_tx_power_ctl_setup(dev);
+	if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) {
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_PHY_LOCK);
+		b43_read32(dev, B43_MMIO_MACCTL);
+		udelay(1);
+	}
+	b43_nphy_tx_power_ctrl(dev, nphy->txpwrctrl);
+	if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12)
+		b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PHY_LOCK, 0);
+	b43_mac_enable(dev);
+
+	nphy->tx_pwr_last_recalc_freq = channel->center_freq;
+	nphy->tx_pwr_last_recalc_limit = phy->desired_txpower;
+
+	return B43_TXPWR_RES_DONE;
+}
+
 /**************************************************
  * N-PHY init
  **************************************************/
@@ -6422,6 +6482,7 @@ static int b43_nphy_op_allocate(struct b43_wldev *dev)
 	nphy = kzalloc(sizeof(*nphy), GFP_KERNEL);
 	if (!nphy)
 		return -ENOMEM;
+
 	dev->phy.n = nphy;
 
 	return 0;
@@ -6662,5 +6723,4 @@ const struct b43_phy_operations b43_phyops_n = {
 	.switch_channel		= b43_nphy_op_switch_channel,
 	.get_default_chan	= b43_nphy_op_get_default_chan,
 	.recalc_txpower		= b43_nphy_op_recalc_txpower,
-	.adjust_txpower		= b43_nphy_op_adjust_txpower,
 };
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 30bec81..a6da2c3 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -2,6 +2,7 @@
 #define B43_NPHY_H_
 
 #include "phy_common.h"
+#include "ppr.h"
 
 
 /* N-PHY registers. */
@@ -967,6 +968,9 @@ struct b43_phy_n {
 	struct b43_phy_n_txpwrindex txpwrindex[2];
 	struct b43_phy_n_pwr_ctl_info pwr_ctl_info[2];
 	struct b43_chanspec txiqlocal_chanspec;
+	struct b43_ppr tx_pwr_max_ppr;
+	u16 tx_pwr_last_recalc_freq;
+	int tx_pwr_last_recalc_limit;
 
 	u8 txrx_chain;
 	u16 tx_rx_cal_phy_saveregs[11];
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
  2014-07-31 19:59   ` Rafał Miłecki
@ 2014-07-31 20:23     ` Hauke Mehrtens
  -1 siblings, 0 replies; 30+ messages in thread
From: Hauke Mehrtens @ 2014-07-31 20:23 UTC (permalink / raw)
  To: Rafał Miłecki, John W. Linville; +Cc: linux-wireless, b43-dev

On 07/31/2014 09:59 PM, Rafał Miłecki wrote:
> Access to PHY and radio registers is indirect on Broadcom hardware and
> it seems that addressing on MIPS SoCs may require flushing. Broadcom
> code does that unconditionally on MIPS, so let's do the same to make
> sure hardware won't miss anything important.
> 
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
> ---
>  drivers/net/wireless/b43/b43.h        |  8 ++++++++
>  drivers/net/wireless/b43/main.c       | 17 ++++++++---------
>  drivers/net/wireless/b43/phy_a.c      |  4 ++--
>  drivers/net/wireless/b43/phy_common.c |  4 ++--
>  drivers/net/wireless/b43/phy_g.c      |  8 ++++----
>  drivers/net/wireless/b43/phy_ht.c     |  6 +++---
>  drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
>  drivers/net/wireless/b43/phy_lp.c     |  6 +++---
>  drivers/net/wireless/b43/phy_n.c      |  6 +++---
>  9 files changed, 36 insertions(+), 29 deletions(-)
> 

A comment in brcmsmac says this is only needed to work around a bug in
the host pcie controller of 4717, 4718 and 4706. I haven't noticed this
problem with BCM4706, so it could be that it is already fixed in the
shipped version of bcm4706.

The comment says the following:
bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
transactions. As a fix, a read after write is performed on certain
places in the code. Older chips and the newer 5357 family don't require
this fix.

This commit did the cleanup:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6a9a25eec0b55ea45e22710a9bcaf9690cb42fe6

Hauke

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
@ 2014-07-31 20:23     ` Hauke Mehrtens
  0 siblings, 0 replies; 30+ messages in thread
From: Hauke Mehrtens @ 2014-07-31 20:23 UTC (permalink / raw)
  To: Rafał Miłecki, John W. Linville; +Cc: linux-wireless, b43-dev

On 07/31/2014 09:59 PM, Rafa? Mi?ecki wrote:
> Access to PHY and radio registers is indirect on Broadcom hardware and
> it seems that addressing on MIPS SoCs may require flushing. Broadcom
> code does that unconditionally on MIPS, so let's do the same to make
> sure hardware won't miss anything important.
> 
> Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
> ---
>  drivers/net/wireless/b43/b43.h        |  8 ++++++++
>  drivers/net/wireless/b43/main.c       | 17 ++++++++---------
>  drivers/net/wireless/b43/phy_a.c      |  4 ++--
>  drivers/net/wireless/b43/phy_common.c |  4 ++--
>  drivers/net/wireless/b43/phy_g.c      |  8 ++++----
>  drivers/net/wireless/b43/phy_ht.c     |  6 +++---
>  drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
>  drivers/net/wireless/b43/phy_lp.c     |  6 +++---
>  drivers/net/wireless/b43/phy_n.c      |  6 +++---
>  9 files changed, 36 insertions(+), 29 deletions(-)
> 

A comment in brcmsmac says this is only needed to work around a bug in
the host pcie controller of 4717, 4718 and 4706. I haven't noticed this
problem with BCM4706, so it could be that it is already fixed in the
shipped version of bcm4706.

The comment says the following:
bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
transactions. As a fix, a read after write is performed on certain
places in the code. Older chips and the newer 5357 family don't require
this fix.

This commit did the cleanup:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6a9a25eec0b55ea45e22710a9bcaf9690cb42fe6

Hauke

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
  2014-07-31 19:59   ` Rafał Miłecki
@ 2014-07-31 20:25     ` Florian Fainelli
  -1 siblings, 0 replies; 30+ messages in thread
From: Florian Fainelli @ 2014-07-31 20:25 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: John W. Linville, open list:ATHEROS ATH5K WIR..., b43-dev

2014-07-31 12:59 GMT-07:00 Rafał Miłecki <zajec5@gmail.com>:
> Access to PHY and radio registers is indirect on Broadcom hardware and
> it seems that addressing on MIPS SoCs may require flushing. Broadcom
> code does that unconditionally on MIPS, so let's do the same to make
> sure hardware won't miss anything important.
>
> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
> ---
>  drivers/net/wireless/b43/b43.h        |  8 ++++++++
>  drivers/net/wireless/b43/main.c       | 17 ++++++++---------
>  drivers/net/wireless/b43/phy_a.c      |  4 ++--
>  drivers/net/wireless/b43/phy_common.c |  4 ++--
>  drivers/net/wireless/b43/phy_g.c      |  8 ++++----
>  drivers/net/wireless/b43/phy_ht.c     |  6 +++---
>  drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
>  drivers/net/wireless/b43/phy_lp.c     |  6 +++---
>  drivers/net/wireless/b43/phy_n.c      |  6 +++---
>  9 files changed, 36 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
> index 4113b69..ff0c666 100644
> --- a/drivers/net/wireless/b43/b43.h
> +++ b/drivers/net/wireless/b43/b43.h
> @@ -1012,6 +1012,14 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
>         dev->dev->write16(dev->dev, offset, value);
>  }
>
> +static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
> +{
> +       b43_write16(dev, offset, value);
> +#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
> +       b43_read16(dev, offset);
> +#endif
> +}

How about you leave the calls to b43_write16() to avoid missing call
sites, but you re-define it for BCM47XX and BCM63XX? Or, you could
introduce a __b43_write16() that defaults to dev->dev->write16 in the
normal case, and gets called by b43_write16() such that we you'd get:


static u16 void __b43_read16(struct b43_wldev *dev, u16 offset)
{
     return dev->dev->readt16(dev->dev, offset);
|

static inline void __b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
{
      dev->dev->write16(dev->dev, offset, value);
#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
      __b43_read16(dev, offset);
#endif
}

static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
{
      __b43_write16(dev, offset, value);
}

> +
>  static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask,
>                                  u16 set)
>  {
> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
> index 2af1ac3..66ff718 100644
> --- a/drivers/net/wireless/b43/main.c
> +++ b/drivers/net/wireless/b43/main.c
> @@ -4466,10 +4466,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
>         if (core_rev == 40 || core_rev == 42) {
>                 radio_manuf = 0x17F;
>
> -               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
> +               b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 0);
>                 radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
>
> -               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
> +               b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 1);
>                 radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
>
>                 radio_ver = 0; /* Is there version somewhere? */
> @@ -4477,7 +4477,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
>                 u16 radio24[3];
>
>                 for (tmp = 0; tmp < 3; tmp++) {
> -                       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
> +                       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, tmp);
>                         radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
>                 }
>
> @@ -4494,13 +4494,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
>                         else
>                                 tmp = 0x5205017F;
>                 } else {
> -                       b43_write16(dev, B43_MMIO_RADIO_CONTROL,
> -                                   B43_RADIOCTL_ID);
> +                       b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
> +                                    B43_RADIOCTL_ID);
>                         tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
> -                       b43_write16(dev, B43_MMIO_RADIO_CONTROL,
> -                                   B43_RADIOCTL_ID);
> -                       tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
> -                               << 16;
> +                       b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
> +                                    B43_RADIOCTL_ID);
> +                       tmp |= b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
>                 }
>                 radio_manuf = (tmp & 0x00000FFF);
>                 radio_id = (tmp & 0x0FFFF000) >> 12;
> diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
> index 25e4043..99c036f 100644
> --- a/drivers/net/wireless/b43/phy_a.c
> +++ b/drivers/net/wireless/b43/phy_a.c
> @@ -444,14 +444,14 @@ static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
>  static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
>  {
>         reg = adjust_phyreg(dev, reg);
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_PHY_DATA);
>  }
>
>  static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
>  {
>         reg = adjust_phyreg(dev, reg);
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
> index 08ca524..1dfc682 100644
> --- a/drivers/net/wireless/b43/phy_common.c
> +++ b/drivers/net/wireless/b43/phy_common.c
> @@ -278,7 +278,7 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
>         if (dev->phy.ops->phy_read)
>                 return dev->phy.ops->phy_read(dev, reg);
>
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_PHY_DATA);
>  }
>
> @@ -294,7 +294,7 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
>         if (dev->phy.ops->phy_write)
>                 return dev->phy.ops->phy_write(dev, reg, value);
>
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
> index 8f5c14b..727ce6e 100644
> --- a/drivers/net/wireless/b43/phy_g.c
> +++ b/drivers/net/wireless/b43/phy_g.c
> @@ -2555,13 +2555,13 @@ static void b43_gphy_op_exit(struct b43_wldev *dev)
>
>  static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_PHY_DATA);
>  }
>
>  static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA, value);
>  }
>
> @@ -2572,7 +2572,7 @@ static u16 b43_gphy_op_radio_read(struct b43_wldev *dev, u16 reg)
>         /* G-PHY needs 0x80 for read access. */
>         reg |= 0x80;
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
>  }
>
> @@ -2581,7 +2581,7 @@ static void b43_gphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
>         /* Register 1 is a 32-bit register. */
>         B43_WARN_ON(reg == 1);
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
> index 8b0b4b6..c4dc8b0 100644
> --- a/drivers/net/wireless/b43/phy_ht.c
> +++ b/drivers/net/wireless/b43/phy_ht.c
> @@ -1074,7 +1074,7 @@ static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
>  static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
>                                  u16 set)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA,
>                     (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
>  }
> @@ -1084,14 +1084,14 @@ static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg)
>         /* HT-PHY needs 0x200 for read access */
>         reg |= 0x200;
>
> -       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO24_DATA);
>  }
>
>  static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
>                                       u16 value)
>  {
> -       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
> index bf29c3e..97461cc 100644
> --- a/drivers/net/wireless/b43/phy_lcn.c
> +++ b/drivers/net/wireless/b43/phy_lcn.c
> @@ -813,7 +813,7 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
>  static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
>                                    u16 set)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA,
>                     (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
>  }
> @@ -823,14 +823,14 @@ static u16 b43_phy_lcn_op_radio_read(struct b43_wldev *dev, u16 reg)
>         /* LCN-PHY needs 0x200 for read access */
>         reg |= 0x200;
>
> -       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO24_DATA);
>  }
>
>  static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg,
>                                        u16 value)
>  {
> -       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
> index 1e9bae6..058a9f2 100644
> --- a/drivers/net/wireless/b43/phy_lp.c
> +++ b/drivers/net/wireless/b43/phy_lp.c
> @@ -1988,7 +1988,7 @@ static void lpphy_calibration(struct b43_wldev *dev)
>  static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
>                                  u16 set)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA,
>                     (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
>  }
> @@ -2004,7 +2004,7 @@ static u16 b43_lpphy_op_radio_read(struct b43_wldev *dev, u16 reg)
>         } else
>                 reg |= 0x200;
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
>  }
>
> @@ -2013,7 +2013,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
>         /* Register 1 is a 32-bit register. */
>         B43_WARN_ON(reg == 1);
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
> index 5565318..df64032 100644
> --- a/drivers/net/wireless/b43/phy_n.c
> +++ b/drivers/net/wireless/b43/phy_n.c
> @@ -6501,7 +6501,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
>                                  u16 set)
>  {
>         check_phyreg(dev, reg);
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
>         dev->phy.writes_counter = 1;
>  }
> @@ -6516,7 +6516,7 @@ static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
>         else
>                 reg |= 0x100;
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
>  }
>
> @@ -6525,7 +6525,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
>         /* Register 1 is a 32-bit register. */
>         B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
>  }
>
> --
> 1.8.4.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Florian

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
@ 2014-07-31 20:25     ` Florian Fainelli
  0 siblings, 0 replies; 30+ messages in thread
From: Florian Fainelli @ 2014-07-31 20:25 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: John W. Linville, open list:ATHEROS ATH5K WIR..., b43-dev

2014-07-31 12:59 GMT-07:00 Rafa? Mi?ecki <zajec5@gmail.com>:
> Access to PHY and radio registers is indirect on Broadcom hardware and
> it seems that addressing on MIPS SoCs may require flushing. Broadcom
> code does that unconditionally on MIPS, so let's do the same to make
> sure hardware won't miss anything important.
>
> Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
> ---
>  drivers/net/wireless/b43/b43.h        |  8 ++++++++
>  drivers/net/wireless/b43/main.c       | 17 ++++++++---------
>  drivers/net/wireless/b43/phy_a.c      |  4 ++--
>  drivers/net/wireless/b43/phy_common.c |  4 ++--
>  drivers/net/wireless/b43/phy_g.c      |  8 ++++----
>  drivers/net/wireless/b43/phy_ht.c     |  6 +++---
>  drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
>  drivers/net/wireless/b43/phy_lp.c     |  6 +++---
>  drivers/net/wireless/b43/phy_n.c      |  6 +++---
>  9 files changed, 36 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
> index 4113b69..ff0c666 100644
> --- a/drivers/net/wireless/b43/b43.h
> +++ b/drivers/net/wireless/b43/b43.h
> @@ -1012,6 +1012,14 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
>         dev->dev->write16(dev->dev, offset, value);
>  }
>
> +static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
> +{
> +       b43_write16(dev, offset, value);
> +#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
> +       b43_read16(dev, offset);
> +#endif
> +}

How about you leave the calls to b43_write16() to avoid missing call
sites, but you re-define it for BCM47XX and BCM63XX? Or, you could
introduce a __b43_write16() that defaults to dev->dev->write16 in the
normal case, and gets called by b43_write16() such that we you'd get:


static u16 void __b43_read16(struct b43_wldev *dev, u16 offset)
{
     return dev->dev->readt16(dev->dev, offset);
|

static inline void __b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
{
      dev->dev->write16(dev->dev, offset, value);
#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
      __b43_read16(dev, offset);
#endif
}

static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
{
      __b43_write16(dev, offset, value);
}

> +
>  static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask,
>                                  u16 set)
>  {
> diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
> index 2af1ac3..66ff718 100644
> --- a/drivers/net/wireless/b43/main.c
> +++ b/drivers/net/wireless/b43/main.c
> @@ -4466,10 +4466,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
>         if (core_rev == 40 || core_rev == 42) {
>                 radio_manuf = 0x17F;
>
> -               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
> +               b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 0);
>                 radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
>
> -               b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
> +               b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 1);
>                 radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
>
>                 radio_ver = 0; /* Is there version somewhere? */
> @@ -4477,7 +4477,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
>                 u16 radio24[3];
>
>                 for (tmp = 0; tmp < 3; tmp++) {
> -                       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
> +                       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, tmp);
>                         radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
>                 }
>
> @@ -4494,13 +4494,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
>                         else
>                                 tmp = 0x5205017F;
>                 } else {
> -                       b43_write16(dev, B43_MMIO_RADIO_CONTROL,
> -                                   B43_RADIOCTL_ID);
> +                       b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
> +                                    B43_RADIOCTL_ID);
>                         tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
> -                       b43_write16(dev, B43_MMIO_RADIO_CONTROL,
> -                                   B43_RADIOCTL_ID);
> -                       tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
> -                               << 16;
> +                       b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
> +                                    B43_RADIOCTL_ID);
> +                       tmp |= b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
>                 }
>                 radio_manuf = (tmp & 0x00000FFF);
>                 radio_id = (tmp & 0x0FFFF000) >> 12;
> diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
> index 25e4043..99c036f 100644
> --- a/drivers/net/wireless/b43/phy_a.c
> +++ b/drivers/net/wireless/b43/phy_a.c
> @@ -444,14 +444,14 @@ static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
>  static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
>  {
>         reg = adjust_phyreg(dev, reg);
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_PHY_DATA);
>  }
>
>  static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
>  {
>         reg = adjust_phyreg(dev, reg);
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
> index 08ca524..1dfc682 100644
> --- a/drivers/net/wireless/b43/phy_common.c
> +++ b/drivers/net/wireless/b43/phy_common.c
> @@ -278,7 +278,7 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
>         if (dev->phy.ops->phy_read)
>                 return dev->phy.ops->phy_read(dev, reg);
>
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_PHY_DATA);
>  }
>
> @@ -294,7 +294,7 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
>         if (dev->phy.ops->phy_write)
>                 return dev->phy.ops->phy_write(dev, reg, value);
>
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
> index 8f5c14b..727ce6e 100644
> --- a/drivers/net/wireless/b43/phy_g.c
> +++ b/drivers/net/wireless/b43/phy_g.c
> @@ -2555,13 +2555,13 @@ static void b43_gphy_op_exit(struct b43_wldev *dev)
>
>  static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_PHY_DATA);
>  }
>
>  static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA, value);
>  }
>
> @@ -2572,7 +2572,7 @@ static u16 b43_gphy_op_radio_read(struct b43_wldev *dev, u16 reg)
>         /* G-PHY needs 0x80 for read access. */
>         reg |= 0x80;
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
>  }
>
> @@ -2581,7 +2581,7 @@ static void b43_gphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
>         /* Register 1 is a 32-bit register. */
>         B43_WARN_ON(reg == 1);
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
> index 8b0b4b6..c4dc8b0 100644
> --- a/drivers/net/wireless/b43/phy_ht.c
> +++ b/drivers/net/wireless/b43/phy_ht.c
> @@ -1074,7 +1074,7 @@ static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
>  static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
>                                  u16 set)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA,
>                     (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
>  }
> @@ -1084,14 +1084,14 @@ static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg)
>         /* HT-PHY needs 0x200 for read access */
>         reg |= 0x200;
>
> -       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO24_DATA);
>  }
>
>  static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
>                                       u16 value)
>  {
> -       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
> index bf29c3e..97461cc 100644
> --- a/drivers/net/wireless/b43/phy_lcn.c
> +++ b/drivers/net/wireless/b43/phy_lcn.c
> @@ -813,7 +813,7 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
>  static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
>                                    u16 set)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA,
>                     (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
>  }
> @@ -823,14 +823,14 @@ static u16 b43_phy_lcn_op_radio_read(struct b43_wldev *dev, u16 reg)
>         /* LCN-PHY needs 0x200 for read access */
>         reg |= 0x200;
>
> -       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO24_DATA);
>  }
>
>  static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg,
>                                        u16 value)
>  {
> -       b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
> index 1e9bae6..058a9f2 100644
> --- a/drivers/net/wireless/b43/phy_lp.c
> +++ b/drivers/net/wireless/b43/phy_lp.c
> @@ -1988,7 +1988,7 @@ static void lpphy_calibration(struct b43_wldev *dev)
>  static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
>                                  u16 set)
>  {
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_PHY_DATA,
>                     (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
>  }
> @@ -2004,7 +2004,7 @@ static u16 b43_lpphy_op_radio_read(struct b43_wldev *dev, u16 reg)
>         } else
>                 reg |= 0x200;
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
>  }
>
> @@ -2013,7 +2013,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
>         /* Register 1 is a 32-bit register. */
>         B43_WARN_ON(reg == 1);
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
>  }
>
> diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
> index 5565318..df64032 100644
> --- a/drivers/net/wireless/b43/phy_n.c
> +++ b/drivers/net/wireless/b43/phy_n.c
> @@ -6501,7 +6501,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
>                                  u16 set)
>  {
>         check_phyreg(dev, reg);
> -       b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
>         b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
>         dev->phy.writes_counter = 1;
>  }
> @@ -6516,7 +6516,7 @@ static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
>         else
>                 reg |= 0x100;
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
>  }
>
> @@ -6525,7 +6525,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
>         /* Register 1 is a 32-bit register. */
>         B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
>
> -       b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
> +       b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
>         b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
>  }
>
> --
> 1.8.4.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Florian

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
  2014-07-31 20:23     ` Hauke Mehrtens
@ 2014-07-31 20:33       ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 20:33 UTC (permalink / raw)
  To: Hauke Mehrtens; +Cc: John W. Linville, linux-wireless, b43-dev

On 31 July 2014 22:23, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> A comment in brcmsmac says this is only needed to work around a bug in
> the host pcie controller of 4717, 4718 and 4706. I haven't noticed this
> problem with BCM4706, so it could be that it is already fixed in the
> shipped version of bcm4706.
>
> The comment says the following:
> bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
> transactions. As a fix, a read after write is performed on certain
> places in the code. Older chips and the newer 5357 family don't require
> this fix.
>
> This commit did the cleanup:
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6a9a25eec0b55ea45e22710a9bcaf9690cb42fe6

Any idea why Broadcom didn't own comments and didn't enable it for
bcm4716 and bcm4706 only?

-- 
Rafał

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
@ 2014-07-31 20:33       ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 20:33 UTC (permalink / raw)
  To: Hauke Mehrtens; +Cc: John W. Linville, linux-wireless, b43-dev

On 31 July 2014 22:23, Hauke Mehrtens <hauke@hauke-m.de> wrote:
> A comment in brcmsmac says this is only needed to work around a bug in
> the host pcie controller of 4717, 4718 and 4706. I haven't noticed this
> problem with BCM4706, so it could be that it is already fixed in the
> shipped version of bcm4706.
>
> The comment says the following:
> bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
> transactions. As a fix, a read after write is performed on certain
> places in the code. Older chips and the newer 5357 family don't require
> this fix.
>
> This commit did the cleanup:
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6a9a25eec0b55ea45e22710a9bcaf9690cb42fe6

Any idea why Broadcom didn't own comments and didn't enable it for
bcm4716 and bcm4706 only?

-- 
Rafa?

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
  2014-07-31 20:23     ` Hauke Mehrtens
@ 2014-07-31 20:34       ` Florian Fainelli
  -1 siblings, 0 replies; 30+ messages in thread
From: Florian Fainelli @ 2014-07-31 20:34 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: Rafał Miłecki, John W. Linville,
	open list:ATHEROS ATH5K WIR...,
	b43-dev

2014-07-31 13:23 GMT-07:00 Hauke Mehrtens <hauke@hauke-m.de>:
> On 07/31/2014 09:59 PM, Rafał Miłecki wrote:
>> Access to PHY and radio registers is indirect on Broadcom hardware and
>> it seems that addressing on MIPS SoCs may require flushing. Broadcom
>> code does that unconditionally on MIPS, so let's do the same to make
>> sure hardware won't miss anything important.
>>
>> Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
>> ---
>>  drivers/net/wireless/b43/b43.h        |  8 ++++++++
>>  drivers/net/wireless/b43/main.c       | 17 ++++++++---------
>>  drivers/net/wireless/b43/phy_a.c      |  4 ++--
>>  drivers/net/wireless/b43/phy_common.c |  4 ++--
>>  drivers/net/wireless/b43/phy_g.c      |  8 ++++----
>>  drivers/net/wireless/b43/phy_ht.c     |  6 +++---
>>  drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
>>  drivers/net/wireless/b43/phy_lp.c     |  6 +++---
>>  drivers/net/wireless/b43/phy_n.c      |  6 +++---
>>  9 files changed, 36 insertions(+), 29 deletions(-)
>>
>
> A comment in brcmsmac says this is only needed to work around a bug in
> the host pcie controller of 4717, 4718 and 4706. I haven't noticed this
> problem with BCM4706, so it could be that it is already fixed in the
> shipped version of bcm4706.

I don't think we have ever needed it on BCM63xx as well.

>
> The comment says the following:
> bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
> transactions. As a fix, a read after write is performed on certain
> places in the code. Older chips and the newer 5357 family don't require
> this fix.

The fix in brcmsmac is covering a lot more chips with a __mips__ that
it needs to. Maybe we should have a helper function that returns the
SoC ID so we can selectively apply this write then read flush
workaround?

>
> This commit did the cleanup:
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6a9a25eec0b55ea45e22710a9bcaf9690cb42fe6
>
-- 
Florian

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
@ 2014-07-31 20:34       ` Florian Fainelli
  0 siblings, 0 replies; 30+ messages in thread
From: Florian Fainelli @ 2014-07-31 20:34 UTC (permalink / raw)
  To: Hauke Mehrtens
  Cc: Rafał Miłecki, John W. Linville,
	open list:ATHEROS ATH5K WIR...,
	b43-dev

2014-07-31 13:23 GMT-07:00 Hauke Mehrtens <hauke@hauke-m.de>:
> On 07/31/2014 09:59 PM, Rafa? Mi?ecki wrote:
>> Access to PHY and radio registers is indirect on Broadcom hardware and
>> it seems that addressing on MIPS SoCs may require flushing. Broadcom
>> code does that unconditionally on MIPS, so let's do the same to make
>> sure hardware won't miss anything important.
>>
>> Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
>> ---
>>  drivers/net/wireless/b43/b43.h        |  8 ++++++++
>>  drivers/net/wireless/b43/main.c       | 17 ++++++++---------
>>  drivers/net/wireless/b43/phy_a.c      |  4 ++--
>>  drivers/net/wireless/b43/phy_common.c |  4 ++--
>>  drivers/net/wireless/b43/phy_g.c      |  8 ++++----
>>  drivers/net/wireless/b43/phy_ht.c     |  6 +++---
>>  drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
>>  drivers/net/wireless/b43/phy_lp.c     |  6 +++---
>>  drivers/net/wireless/b43/phy_n.c      |  6 +++---
>>  9 files changed, 36 insertions(+), 29 deletions(-)
>>
>
> A comment in brcmsmac says this is only needed to work around a bug in
> the host pcie controller of 4717, 4718 and 4706. I haven't noticed this
> problem with BCM4706, so it could be that it is already fixed in the
> shipped version of bcm4706.

I don't think we have ever needed it on BCM63xx as well.

>
> The comment says the following:
> bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
> transactions. As a fix, a read after write is performed on certain
> places in the code. Older chips and the newer 5357 family don't require
> this fix.

The fix in brcmsmac is covering a lot more chips with a __mips__ that
it needs to. Maybe we should have a helper function that returns the
SoC ID so we can selectively apply this write then read flush
workaround?

>
> This commit did the cleanup:
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6a9a25eec0b55ea45e22710a9bcaf9690cb42fe6
>
-- 
Florian

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
  2014-07-31 20:25     ` Florian Fainelli
@ 2014-07-31 20:34       ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 20:34 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: John W. Linville, open list:ATHEROS ATH5K WIR..., b43-dev

On 31 July 2014 22:25, Florian Fainelli <f.fainelli@gmail.com> wrote:
>> +static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
>> +{
>> +       b43_write16(dev, offset, value);
>> +#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
>> +       b43_read16(dev, offset);
>> +#endif
>> +}
>
> How about you leave the calls to b43_write16() to avoid missing call
> sites, but you re-define it for BCM47XX and BCM63XX? Or, you could
> introduce a __b43_write16() that defaults to dev->dev->write16 in the
> normal case, and gets called by b43_write16() such that we you'd get:

I didn't mean (and I didn't) enable flushing for all writes. Only
these touching specific registers. I don't think we need to flush
every single write.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
@ 2014-07-31 20:34       ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-07-31 20:34 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: John W. Linville, open list:ATHEROS ATH5K WIR..., b43-dev

On 31 July 2014 22:25, Florian Fainelli <f.fainelli@gmail.com> wrote:
>> +static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
>> +{
>> +       b43_write16(dev, offset, value);
>> +#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
>> +       b43_read16(dev, offset);
>> +#endif
>> +}
>
> How about you leave the calls to b43_write16() to avoid missing call
> sites, but you re-define it for BCM47XX and BCM63XX? Or, you could
> introduce a __b43_write16() that defaults to dev->dev->write16 in the
> normal case, and gets called by b43_write16() such that we you'd get:

I didn't mean (and I didn't) enable flushing for all writes. Only
these touching specific registers. I don't think we need to flush
every single write.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
  2014-07-31 20:34       ` Rafał Miłecki
@ 2014-08-01  1:55         ` Florian Fainelli
  -1 siblings, 0 replies; 30+ messages in thread
From: Florian Fainelli @ 2014-08-01  1:55 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: John W. Linville, open list:ATHEROS ATH5K WIR..., b43-dev

2014-07-31 13:34 GMT-07:00 Rafał Miłecki <zajec5@gmail.com>:
> On 31 July 2014 22:25, Florian Fainelli <f.fainelli@gmail.com> wrote:
>>> +static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
>>> +{
>>> +       b43_write16(dev, offset, value);
>>> +#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
>>> +       b43_read16(dev, offset);
>>> +#endif
>>> +}
>>
>> How about you leave the calls to b43_write16() to avoid missing call
>> sites, but you re-define it for BCM47XX and BCM63XX? Or, you could
>> introduce a __b43_write16() that defaults to dev->dev->write16 in the
>> normal case, and gets called by b43_write16() such that we you'd get:
>
> I didn't mean (and I didn't) enable flushing for all writes. Only
> these touching specific registers. I don't think we need to flush
> every single write.

Ok, then the current approach looks good to me, thanks!
-- 
Florian

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs
@ 2014-08-01  1:55         ` Florian Fainelli
  0 siblings, 0 replies; 30+ messages in thread
From: Florian Fainelli @ 2014-08-01  1:55 UTC (permalink / raw)
  To: Rafał Miłecki
  Cc: John W. Linville, open list:ATHEROS ATH5K WIR..., b43-dev

2014-07-31 13:34 GMT-07:00 Rafa? Mi?ecki <zajec5@gmail.com>:
> On 31 July 2014 22:25, Florian Fainelli <f.fainelli@gmail.com> wrote:
>>> +static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
>>> +{
>>> +       b43_write16(dev, offset, value);
>>> +#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM63XX)
>>> +       b43_read16(dev, offset);
>>> +#endif
>>> +}
>>
>> How about you leave the calls to b43_write16() to avoid missing call
>> sites, but you re-define it for BCM47XX and BCM63XX? Or, you could
>> introduce a __b43_write16() that defaults to dev->dev->write16 in the
>> normal case, and gets called by b43_write16() such that we you'd get:
>
> I didn't mean (and I didn't) enable flushing for all writes. Only
> these touching specific registers. I don't think we need to flush
> every single write.

Ok, then the current approach looks good to me, thanks!
-- 
Florian

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH V2 3/7] b43: flush some writes on Broadcom MIPS SoCs
  2014-07-31 19:59   ` Rafał Miłecki
@ 2014-08-07  5:45     ` Rafał Miłecki
  -1 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-08-07  5:45 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Access to PHY and radio registers is indirect on Broadcom hardware and
it seems that addressing on some MIPS SoCs may require flushing. So far
this problem was noticed on 0x4716 SoC only (marketing names: BCM4717,
BCM4718).

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
V2: As Hauke noticed, Broadcom comment says this is needed for 0x4716
    and 0x4706 only. Their code does this globally on the whole MIPS
    arch, but it doesn't seem to be needed. Also BCM4706 doesn't seem
    to require this.
    So let's enable this for BCMA_CHIP_ID_BCM4716 SoC only.
    Florian has also confirmed he never needed this on BCM63XX.
---
 drivers/net/wireless/b43/b43.h        | 10 ++++++++++
 drivers/net/wireless/b43/bus.c        | 10 ++++++++++
 drivers/net/wireless/b43/bus.h        |  1 +
 drivers/net/wireless/b43/main.c       | 17 ++++++++---------
 drivers/net/wireless/b43/phy_a.c      |  4 ++--
 drivers/net/wireless/b43/phy_common.c |  4 ++--
 drivers/net/wireless/b43/phy_g.c      |  8 ++++----
 drivers/net/wireless/b43/phy_ht.c     |  6 +++---
 drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
 drivers/net/wireless/b43/phy_lp.c     |  6 +++---
 drivers/net/wireless/b43/phy_n.c      |  6 +++---
 11 files changed, 49 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 4113b69..9b2d0c9 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -1012,6 +1012,16 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
 	dev->dev->write16(dev->dev, offset, value);
 }
 
+/* To optimize this check for flush_writes on BCM47XX_BCMA only. */
+static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
+{
+	b43_write16(dev, offset, value);
+#if defined(CONFIG_BCM47XX_BCMA)
+	if (dev->dev->flush_writes)
+		b43_read16(dev, offset);
+#endif
+}
+
 static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask,
 				 u16 set)
 {
diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c
index 565fdbd..17d16a3 100644
--- a/drivers/net/wireless/b43/bus.c
+++ b/drivers/net/wireless/b43/bus.c
@@ -22,6 +22,10 @@
 
 */
 
+#ifdef CONFIG_BCM47XX_BCMA
+#include <asm/mach-bcm47xx/bcm47xx.h>
+#endif
+
 #include "b43.h"
 #include "bus.h"
 
@@ -102,6 +106,12 @@ struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core)
 	dev->write32 = b43_bus_bcma_write32;
 	dev->block_read = b43_bus_bcma_block_read;
 	dev->block_write = b43_bus_bcma_block_write;
+#ifdef CONFIG_BCM47XX_BCMA
+	if (b43_bus_host_is_pci(dev) &&
+	    bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA &&
+	    bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4716)
+		dev->flush_writes = true;
+#endif
 
 	dev->dev = &core->dev;
 	dev->dma_dev = core->dma_dev;
diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h
index 460d9d9..256c2c1 100644
--- a/drivers/net/wireless/b43/bus.h
+++ b/drivers/net/wireless/b43/bus.h
@@ -33,6 +33,7 @@ struct b43_bus_dev {
 			   size_t count, u16 offset, u8 reg_width);
 	void (*block_write)(struct b43_bus_dev *dev, const void *buffer,
 			    size_t count, u16 offset, u8 reg_width);
+	bool flush_writes;
 
 	struct device *dev;
 	struct device *dma_dev;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 2af1ac3..66ff718 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4466,10 +4466,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 	if (core_rev == 40 || core_rev == 42) {
 		radio_manuf = 0x17F;
 
-		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
+		b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 0);
 		radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 
-		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
+		b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 1);
 		radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 
 		radio_ver = 0; /* Is there version somewhere? */
@@ -4477,7 +4477,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 		u16 radio24[3];
 
 		for (tmp = 0; tmp < 3; tmp++) {
-			b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
+			b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, tmp);
 			radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 		}
 
@@ -4494,13 +4494,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 			else
 				tmp = 0x5205017F;
 		} else {
-			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-				    B43_RADIOCTL_ID);
+			b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+				     B43_RADIOCTL_ID);
 			tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
-			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-				    B43_RADIOCTL_ID);
-			tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
-				<< 16;
+			b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+				     B43_RADIOCTL_ID);
+			tmp |= b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
 		}
 		radio_manuf = (tmp & 0x00000FFF);
 		radio_id = (tmp & 0x0FFFF000) >> 12;
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 25e4043..99c036f 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -444,14 +444,14 @@ static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
 static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
 {
 	reg = adjust_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
 	reg = adjust_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 08ca524..1dfc682 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -278,7 +278,7 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
 	if (dev->phy.ops->phy_read)
 		return dev->phy.ops->phy_read(dev, reg);
 
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
@@ -294,7 +294,7 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 	if (dev->phy.ops->phy_write)
 		return dev->phy.ops->phy_write(dev, reg, value);
 
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index 8f5c14b..727ce6e 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -2555,13 +2555,13 @@ static void b43_gphy_op_exit(struct b43_wldev *dev)
 
 static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
@@ -2572,7 +2572,7 @@ static u16 b43_gphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* G-PHY needs 0x80 for read access. */
 	reg |= 0x80;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -2581,7 +2581,7 @@ static void b43_gphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 8b0b4b6..c4dc8b0 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -1074,7 +1074,7 @@ static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
 static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -1084,14 +1084,14 @@ static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* HT-PHY needs 0x200 for read access */
 	reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
 }
 
 static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
 				      u16 value)
 {
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index bf29c3e..97461cc 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -813,7 +813,7 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
 static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				   u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -823,14 +823,14 @@ static u16 b43_phy_lcn_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* LCN-PHY needs 0x200 for read access */
 	reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
 }
 
 static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg,
 				       u16 value)
 {
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 1e9bae6..058a9f2 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1988,7 +1988,7 @@ static void lpphy_calibration(struct b43_wldev *dev)
 static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -2004,7 +2004,7 @@ static u16 b43_lpphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	} else
 		reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -2013,7 +2013,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 5565318..df64032 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -6501,7 +6501,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
 	check_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
 	dev->phy.writes_counter = 1;
 }
@@ -6516,7 +6516,7 @@ static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	else
 		reg |= 0x100;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -6525,7 +6525,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH V2 3/7] b43: flush some writes on Broadcom MIPS SoCs
@ 2014-08-07  5:45     ` Rafał Miłecki
  0 siblings, 0 replies; 30+ messages in thread
From: Rafał Miłecki @ 2014-08-07  5:45 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, b43-dev, Rafał Miłecki

Access to PHY and radio registers is indirect on Broadcom hardware and
it seems that addressing on some MIPS SoCs may require flushing. So far
this problem was noticed on 0x4716 SoC only (marketing names: BCM4717,
BCM4718).

Signed-off-by: Rafa? Mi?ecki <zajec5@gmail.com>
---
V2: As Hauke noticed, Broadcom comment says this is needed for 0x4716
    and 0x4706 only. Their code does this globally on the whole MIPS
    arch, but it doesn't seem to be needed. Also BCM4706 doesn't seem
    to require this.
    So let's enable this for BCMA_CHIP_ID_BCM4716 SoC only.
    Florian has also confirmed he never needed this on BCM63XX.
---
 drivers/net/wireless/b43/b43.h        | 10 ++++++++++
 drivers/net/wireless/b43/bus.c        | 10 ++++++++++
 drivers/net/wireless/b43/bus.h        |  1 +
 drivers/net/wireless/b43/main.c       | 17 ++++++++---------
 drivers/net/wireless/b43/phy_a.c      |  4 ++--
 drivers/net/wireless/b43/phy_common.c |  4 ++--
 drivers/net/wireless/b43/phy_g.c      |  8 ++++----
 drivers/net/wireless/b43/phy_ht.c     |  6 +++---
 drivers/net/wireless/b43/phy_lcn.c    |  6 +++---
 drivers/net/wireless/b43/phy_lp.c     |  6 +++---
 drivers/net/wireless/b43/phy_n.c      |  6 +++---
 11 files changed, 49 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 4113b69..9b2d0c9 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -1012,6 +1012,16 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
 	dev->dev->write16(dev->dev, offset, value);
 }
 
+/* To optimize this check for flush_writes on BCM47XX_BCMA only. */
+static inline void b43_write16f(struct b43_wldev *dev, u16 offset, u16 value)
+{
+	b43_write16(dev, offset, value);
+#if defined(CONFIG_BCM47XX_BCMA)
+	if (dev->dev->flush_writes)
+		b43_read16(dev, offset);
+#endif
+}
+
 static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask,
 				 u16 set)
 {
diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c
index 565fdbd..17d16a3 100644
--- a/drivers/net/wireless/b43/bus.c
+++ b/drivers/net/wireless/b43/bus.c
@@ -22,6 +22,10 @@
 
 */
 
+#ifdef CONFIG_BCM47XX_BCMA
+#include <asm/mach-bcm47xx/bcm47xx.h>
+#endif
+
 #include "b43.h"
 #include "bus.h"
 
@@ -102,6 +106,12 @@ struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core)
 	dev->write32 = b43_bus_bcma_write32;
 	dev->block_read = b43_bus_bcma_block_read;
 	dev->block_write = b43_bus_bcma_block_write;
+#ifdef CONFIG_BCM47XX_BCMA
+	if (b43_bus_host_is_pci(dev) &&
+	    bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA &&
+	    bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4716)
+		dev->flush_writes = true;
+#endif
 
 	dev->dev = &core->dev;
 	dev->dma_dev = core->dma_dev;
diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h
index 460d9d9..256c2c1 100644
--- a/drivers/net/wireless/b43/bus.h
+++ b/drivers/net/wireless/b43/bus.h
@@ -33,6 +33,7 @@ struct b43_bus_dev {
 			   size_t count, u16 offset, u8 reg_width);
 	void (*block_write)(struct b43_bus_dev *dev, const void *buffer,
 			    size_t count, u16 offset, u8 reg_width);
+	bool flush_writes;
 
 	struct device *dev;
 	struct device *dma_dev;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 2af1ac3..66ff718 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4466,10 +4466,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 	if (core_rev == 40 || core_rev == 42) {
 		radio_manuf = 0x17F;
 
-		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
+		b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 0);
 		radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 
-		b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
+		b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, 1);
 		radio_id = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 
 		radio_ver = 0; /* Is there version somewhere? */
@@ -4477,7 +4477,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 		u16 radio24[3];
 
 		for (tmp = 0; tmp < 3; tmp++) {
-			b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
+			b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, tmp);
 			radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
 		}
 
@@ -4494,13 +4494,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 			else
 				tmp = 0x5205017F;
 		} else {
-			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-				    B43_RADIOCTL_ID);
+			b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+				     B43_RADIOCTL_ID);
 			tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
-			b43_write16(dev, B43_MMIO_RADIO_CONTROL,
-				    B43_RADIOCTL_ID);
-			tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
-				<< 16;
+			b43_write16f(dev, B43_MMIO_RADIO_CONTROL,
+				     B43_RADIOCTL_ID);
+			tmp |= b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
 		}
 		radio_manuf = (tmp & 0x00000FFF);
 		radio_id = (tmp & 0x0FFFF000) >> 12;
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 25e4043..99c036f 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -444,14 +444,14 @@ static inline u16 adjust_phyreg(struct b43_wldev *dev, u16 offset)
 static u16 b43_aphy_op_read(struct b43_wldev *dev, u16 reg)
 {
 	reg = adjust_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 static void b43_aphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
 	reg = adjust_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 08ca524..1dfc682 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -278,7 +278,7 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg)
 	if (dev->phy.ops->phy_read)
 		return dev->phy.ops->phy_read(dev, reg);
 
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
@@ -294,7 +294,7 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 	if (dev->phy.ops->phy_write)
 		return dev->phy.ops->phy_write(dev, reg, value);
 
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index 8f5c14b..727ce6e 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -2555,13 +2555,13 @@ static void b43_gphy_op_exit(struct b43_wldev *dev)
 
 static u16 b43_gphy_op_read(struct b43_wldev *dev, u16 reg)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_PHY_DATA);
 }
 
 static void b43_gphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
@@ -2572,7 +2572,7 @@ static u16 b43_gphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* G-PHY needs 0x80 for read access. */
 	reg |= 0x80;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -2581,7 +2581,7 @@ static void b43_gphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 8b0b4b6..c4dc8b0 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -1074,7 +1074,7 @@ static unsigned int b43_phy_ht_op_get_default_chan(struct b43_wldev *dev)
 static void b43_phy_ht_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -1084,14 +1084,14 @@ static u16 b43_phy_ht_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* HT-PHY needs 0x200 for read access */
 	reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
 }
 
 static void b43_phy_ht_op_radio_write(struct b43_wldev *dev, u16 reg,
 				      u16 value)
 {
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_lcn.c b/drivers/net/wireless/b43/phy_lcn.c
index bf29c3e..97461cc 100644
--- a/drivers/net/wireless/b43/phy_lcn.c
+++ b/drivers/net/wireless/b43/phy_lcn.c
@@ -813,7 +813,7 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
 static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				   u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -823,14 +823,14 @@ static u16 b43_phy_lcn_op_radio_read(struct b43_wldev *dev, u16 reg)
 	/* LCN-PHY needs 0x200 for read access */
 	reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO24_DATA);
 }
 
 static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg,
 				       u16 value)
 {
-	b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 1e9bae6..058a9f2 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1988,7 +1988,7 @@ static void lpphy_calibration(struct b43_wldev *dev)
 static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_PHY_DATA,
 		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
 }
@@ -2004,7 +2004,7 @@ static u16 b43_lpphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	} else
 		reg |= 0x200;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -2013,7 +2013,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 5565318..df64032 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -6501,7 +6501,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
 				 u16 set)
 {
 	check_phyreg(dev, reg);
-	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
 	b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set);
 	dev->phy.writes_counter = 1;
 }
@@ -6516,7 +6516,7 @@ static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 	else
 		reg |= 0x100;
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	return b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
 }
 
@@ -6525,7 +6525,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 	/* Register 1 is a 32-bit register. */
 	B43_WARN_ON(dev->phy.rev < 7 && reg == 1);
 
-	b43_write16(dev, B43_MMIO_RADIO_CONTROL, reg);
+	b43_write16f(dev, B43_MMIO_RADIO_CONTROL, reg);
 	b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, value);
 }
 
-- 
1.8.4.5

^ permalink raw reply related	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2014-08-07  5:45 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-31 19:59 [PATCH 3.18 0/7] b43: first series for 3.18 Rafał Miłecki
2014-07-31 19:59 ` Rafał Miłecki
2014-07-31 19:59 ` [PATCH 3.18 1/7] b43: update flushing many writes performed in a row Rafał Miłecki
2014-07-31 19:59   ` Rafał Miłecki
2014-07-31 19:59 ` [PATCH 3.18 2/7] b43: don't duplicate common PHY read/write ops Rafał Miłecki
2014-07-31 19:59   ` Rafał Miłecki
2014-07-31 19:59 ` [PATCH 3.18 3/7] b43: flush some writes on Broadcom MIPS SoCs Rafał Miłecki
2014-07-31 19:59   ` Rafał Miłecki
2014-07-31 20:23   ` Hauke Mehrtens
2014-07-31 20:23     ` Hauke Mehrtens
2014-07-31 20:33     ` Rafał Miłecki
2014-07-31 20:33       ` Rafał Miłecki
2014-07-31 20:34     ` Florian Fainelli
2014-07-31 20:34       ` Florian Fainelli
2014-07-31 20:25   ` Florian Fainelli
2014-07-31 20:25     ` Florian Fainelli
2014-07-31 20:34     ` Rafał Miłecki
2014-07-31 20:34       ` Rafał Miłecki
2014-08-01  1:55       ` Florian Fainelli
2014-08-01  1:55         ` Florian Fainelli
2014-08-07  5:45   ` [PATCH V2 " Rafał Miłecki
2014-08-07  5:45     ` Rafał Miłecki
2014-07-31 19:59 ` [PATCH 3.18 4/7] b43: N-PHY: update rev3+ gain control workarounds Rafał Miłecki
2014-07-31 19:59   ` Rafał Miłecki
2014-07-31 19:59 ` [PATCH 3.18 5/7] b43: N-PHY: add RF power tables for radio 0x2057 revs 9 & 14 Rafał Miłecki
2014-07-31 19:59   ` Rafał Miłecki
2014-07-31 19:59 ` [PATCH V2 3.18 6/7] b43: implement PPR (Power Per Rate) management/API Rafał Miłecki
2014-07-31 19:59   ` Rafał Miłecki
2014-07-31 19:59 ` [PATCH V2 3.18 7/7] b43: N-PHY: support setting custom TX power Rafał Miłecki
2014-07-31 19:59   ` Rafał Miłecki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.