![Russell King](/assets/img/avatar_default.png)
Commitb70661c708
("net: smc91x: use run-time configuration on all ARM machines") broke some ARM platforms through several mistakes. Firstly, the access size must correspond to the following rule: (a) at least one of 16-bit or 8-bit access size must be supported (b) 32-bit accesses are optional, and may be enabled in addition to the above. Secondly, it provides no emulation of 16-bit accesses, instead blindly making 16-bit accesses even when the platform specifies that only 8-bit is supported. Reorganise smc91x.h so we can make use of the existing 16-bit access emulation already provided - if 16-bit accesses are supported, use 16-bit accesses directly, otherwise if 8-bit accesses are supported, use the provided 16-bit access emulation. If neither, BUG(). This exactly reflects the driver behaviour prior to the commit being fixed. Since the conversion incorrectly cut down the available access sizes on several platforms, we also need to go through every platform and fix up the overly-restrictive access size: Arnd assumed that if a platform can perform 32-bit, 16-bit and 8-bit accesses, then only a 32-bit access size needed to be specified - not so, all available access sizes must be specified. This likely fixes some performance regressions in doing this: if a platform does not support 8-bit accesses, 8-bit accesses have been emulated by performing a 16-bit read-modify-write access. Tested on the Intel Assabet/Neponset platform, which supports only 8-bit accesses, which was broken by the original commit. Fixes:b70661c708
("net: smc91x: use run-time configuration on all ARM machines") Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Tested-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: David S. Miller <davem@davemloft.net>
45 lines
1.5 KiB
C
45 lines
1.5 KiB
C
#ifndef __SMC91X_H__
|
|
#define __SMC91X_H__
|
|
|
|
/*
|
|
* These bits define which access sizes a platform can support, rather
|
|
* than the maximal access size. So, if your platform can do 16-bit
|
|
* and 32-bit accesses to the SMC91x device, but not 8-bit, set both
|
|
* SMC91X_USE_16BIT and SMC91X_USE_32BIT.
|
|
*
|
|
* The SMC91x driver requires at least one of SMC91X_USE_8BIT or
|
|
* SMC91X_USE_16BIT to be supported - just setting SMC91X_USE_32BIT is
|
|
* an invalid configuration.
|
|
*/
|
|
#define SMC91X_USE_8BIT (1 << 0)
|
|
#define SMC91X_USE_16BIT (1 << 1)
|
|
#define SMC91X_USE_32BIT (1 << 2)
|
|
|
|
#define SMC91X_NOWAIT (1 << 3)
|
|
|
|
/* two bits for IO_SHIFT, let's hope later designs will keep this sane */
|
|
#define SMC91X_IO_SHIFT_0 (0 << 4)
|
|
#define SMC91X_IO_SHIFT_1 (1 << 4)
|
|
#define SMC91X_IO_SHIFT_2 (2 << 4)
|
|
#define SMC91X_IO_SHIFT_3 (3 << 4)
|
|
#define SMC91X_IO_SHIFT(x) (((x) >> 4) & 0x3)
|
|
|
|
#define SMC91X_USE_DMA (1 << 6)
|
|
|
|
#define RPC_LED_100_10 (0x00) /* LED = 100Mbps OR's with 10Mbps link detect */
|
|
#define RPC_LED_RES (0x01) /* LED = Reserved */
|
|
#define RPC_LED_10 (0x02) /* LED = 10Mbps link detect */
|
|
#define RPC_LED_FD (0x03) /* LED = Full Duplex Mode */
|
|
#define RPC_LED_TX_RX (0x04) /* LED = TX or RX packet occurred */
|
|
#define RPC_LED_100 (0x05) /* LED = 100Mbps link detect */
|
|
#define RPC_LED_TX (0x06) /* LED = TX packet occurred */
|
|
#define RPC_LED_RX (0x07) /* LED = RX packet occurred */
|
|
|
|
struct smc91x_platdata {
|
|
unsigned long flags;
|
|
unsigned char leda;
|
|
unsigned char ledb;
|
|
};
|
|
|
|
#endif /* __SMC91X_H__ */
|