aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2009-04-27 17:32:16 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-28 04:53:11 -0400
commit833cc67c7722e35863c6aaee9df56b442ef957ae (patch)
treeea7d2f6983fc9a8334065e291678eb418a1d5e44
parent52fbc1007eb071c40a367462476eee695b412578 (diff)
smsc911x: add fifo byteswap support V2
This is V2 of the smsc911x fifo byteswap patch. The smsc911x hardware supports both big and little and endian hardware configurations, and the linux smsc911x driver currently detects word order. For correct operation on big endian platforms lacking swapped byte lanes the following patch is needed. Only fifo data is swapped, register data does not require any swapping. Signed-off-by: Magnus Damm <damm@igel.co.jp> Acked-by: Steve Glendinning <steve.glendinning@smsc.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/smsc911x.c13
-rw-r--r--include/linux/smsc911x.h10
2 files changed, 23 insertions, 0 deletions
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index eb7db032a780..5113b26fc2d9 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -47,6 +47,7 @@
47#include <linux/bitops.h> 47#include <linux/bitops.h>
48#include <linux/irq.h> 48#include <linux/irq.h>
49#include <linux/io.h> 49#include <linux/io.h>
50#include <linux/swab.h>
50#include <linux/phy.h> 51#include <linux/phy.h>
51#include <linux/smsc911x.h> 52#include <linux/smsc911x.h>
52#include "smsc911x.h" 53#include "smsc911x.h"
@@ -175,6 +176,12 @@ static inline void
175smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf, 176smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf,
176 unsigned int wordcount) 177 unsigned int wordcount)
177{ 178{
179 if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
180 while (wordcount--)
181 smsc911x_reg_write(pdata, TX_DATA_FIFO, swab32(*buf++));
182 return;
183 }
184
178 if (pdata->config.flags & SMSC911X_USE_32BIT) { 185 if (pdata->config.flags & SMSC911X_USE_32BIT) {
179 writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount); 186 writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount);
180 return; 187 return;
@@ -194,6 +201,12 @@ static inline void
194smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf, 201smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf,
195 unsigned int wordcount) 202 unsigned int wordcount)
196{ 203{
204 if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
205 while (wordcount--)
206 *buf++ = swab32(smsc911x_reg_read(pdata, RX_DATA_FIFO));
207 return;
208 }
209
197 if (pdata->config.flags & SMSC911X_USE_32BIT) { 210 if (pdata->config.flags & SMSC911X_USE_32BIT) {
198 readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount); 211 readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount);
199 return; 212 return;
diff --git a/include/linux/smsc911x.h b/include/linux/smsc911x.h
index b32725075d71..5241e4fb4eca 100644
--- a/include/linux/smsc911x.h
+++ b/include/linux/smsc911x.h
@@ -47,4 +47,14 @@ struct smsc911x_platform_config {
47#define SMSC911X_FORCE_EXTERNAL_PHY (BIT(3)) 47#define SMSC911X_FORCE_EXTERNAL_PHY (BIT(3))
48#define SMSC911X_SAVE_MAC_ADDRESS (BIT(4)) 48#define SMSC911X_SAVE_MAC_ADDRESS (BIT(4))
49 49
50/*
51 * SMSC911X_SWAP_FIFO:
52 * Enables software byte swap for fifo data. Should only be used as a
53 * "last resort" in the case of big endian mode on boards with incorrectly
54 * routed data bus to older devices such as LAN9118. Newer devices such as
55 * LAN9221 can handle this in hardware, there are registers to control
56 * this swapping but the driver doesn't currently use them.
57 */
58#define SMSC911X_SWAP_FIFO (BIT(5))
59
50#endif /* __LINUX_SMSC911X_H__ */ 60#endif /* __LINUX_SMSC911X_H__ */