diff options
-rw-r--r-- | drivers/net/smc91x.c | 53 | ||||
-rw-r--r-- | drivers/net/smc91x.h | 474 |
2 files changed, 307 insertions, 220 deletions
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 75e9b3b910cc..0e9833adf9fe 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -215,15 +215,12 @@ struct smc_local { | |||
215 | 215 | ||
216 | spinlock_t lock; | 216 | spinlock_t lock; |
217 | 217 | ||
218 | #ifdef SMC_CAN_USE_DATACS | ||
219 | u32 __iomem *datacs; | ||
220 | #endif | ||
221 | |||
222 | #ifdef SMC_USE_PXA_DMA | 218 | #ifdef SMC_USE_PXA_DMA |
223 | /* DMA needs the physical address of the chip */ | 219 | /* DMA needs the physical address of the chip */ |
224 | u_long physaddr; | 220 | u_long physaddr; |
225 | #endif | 221 | #endif |
226 | void __iomem *base; | 222 | void __iomem *base; |
223 | void __iomem *datacs; | ||
227 | }; | 224 | }; |
228 | 225 | ||
229 | #if SMC_DEBUG > 0 | 226 | #if SMC_DEBUG > 0 |
@@ -2104,9 +2101,8 @@ static int smc_enable_device(struct platform_device *pdev) | |||
2104 | * Set the appropriate byte/word mode. | 2101 | * Set the appropriate byte/word mode. |
2105 | */ | 2102 | */ |
2106 | ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; | 2103 | ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8; |
2107 | #ifndef SMC_CAN_USE_16BIT | 2104 | if (!SMC_CAN_USE_16BIT) |
2108 | ecsr |= ECSR_IOIS8; | 2105 | ecsr |= ECSR_IOIS8; |
2109 | #endif | ||
2110 | writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); | 2106 | writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT)); |
2111 | local_irq_restore(flags); | 2107 | local_irq_restore(flags); |
2112 | 2108 | ||
@@ -2143,40 +2139,39 @@ static void smc_release_attrib(struct platform_device *pdev) | |||
2143 | release_mem_region(res->start, ATTRIB_SIZE); | 2139 | release_mem_region(res->start, ATTRIB_SIZE); |
2144 | } | 2140 | } |
2145 | 2141 | ||
2146 | #ifdef SMC_CAN_USE_DATACS | 2142 | static inline void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) |
2147 | static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) | ||
2148 | { | 2143 | { |
2149 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); | 2144 | if (SMC_CAN_USE_DATACS) { |
2150 | struct smc_local *lp = netdev_priv(ndev); | 2145 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); |
2146 | struct smc_local *lp = netdev_priv(ndev); | ||
2151 | 2147 | ||
2152 | if (!res) | 2148 | if (!res) |
2153 | return; | 2149 | return; |
2154 | 2150 | ||
2155 | if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { | 2151 | if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) { |
2156 | printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); | 2152 | printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME); |
2157 | return; | 2153 | return; |
2158 | } | 2154 | } |
2159 | 2155 | ||
2160 | lp->datacs = ioremap(res->start, SMC_DATA_EXTENT); | 2156 | lp->datacs = ioremap(res->start, SMC_DATA_EXTENT); |
2157 | } | ||
2161 | } | 2158 | } |
2162 | 2159 | ||
2163 | static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) | 2160 | static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) |
2164 | { | 2161 | { |
2165 | struct smc_local *lp = netdev_priv(ndev); | 2162 | if (SMC_CAN_USE_DATACS) { |
2166 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); | 2163 | struct smc_local *lp = netdev_priv(ndev); |
2164 | struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32"); | ||
2167 | 2165 | ||
2168 | if (lp->datacs) | 2166 | if (lp->datacs) |
2169 | iounmap(lp->datacs); | 2167 | iounmap(lp->datacs); |
2170 | 2168 | ||
2171 | lp->datacs = NULL; | 2169 | lp->datacs = NULL; |
2172 | 2170 | ||
2173 | if (res) | 2171 | if (res) |
2174 | release_mem_region(res->start, SMC_DATA_EXTENT); | 2172 | release_mem_region(res->start, SMC_DATA_EXTENT); |
2173 | } | ||
2175 | } | 2174 | } |
2176 | #else | ||
2177 | static void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev) {} | ||
2178 | static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev) {} | ||
2179 | #endif | ||
2180 | 2175 | ||
2181 | /* | 2176 | /* |
2182 | * smc_init(void) | 2177 | * smc_init(void) |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index e0efd1964e72..e1be1af51201 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -275,7 +275,10 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) | |||
275 | #define SMC_insw(a,r,p,l) readsw ((void*) ((a) + (r)), p, l) | 275 | #define SMC_insw(a,r,p,l) readsw ((void*) ((a) + (r)), p, l) |
276 | #define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7A40X_IOBARRIER; }) | 276 | #define SMC_outw(v,a,r) ({ writew ((v), (a) + (r)); LPD7A40X_IOBARRIER; }) |
277 | 277 | ||
278 | static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) | 278 | #define SMC_outsw LPD7A40X_SMC_outsw |
279 | |||
280 | static inline void LPD7A40X_SMC_outsw(unsigned long a, int r, | ||
281 | unsigned char* p, int l) | ||
279 | { | 282 | { |
280 | unsigned short* ps = (unsigned short*) p; | 283 | unsigned short* ps = (unsigned short*) p; |
281 | while (l-- > 0) { | 284 | while (l-- > 0) { |
@@ -342,10 +345,6 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) | |||
342 | 345 | ||
343 | #endif | 346 | #endif |
344 | 347 | ||
345 | #ifndef SMC_IRQ_FLAGS | ||
346 | #define SMC_IRQ_FLAGS SA_TRIGGER_RISING | ||
347 | #endif | ||
348 | |||
349 | #ifdef SMC_USE_PXA_DMA | 348 | #ifdef SMC_USE_PXA_DMA |
350 | /* | 349 | /* |
351 | * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is | 350 | * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is |
@@ -441,10 +440,85 @@ smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs) | |||
441 | #endif /* SMC_USE_PXA_DMA */ | 440 | #endif /* SMC_USE_PXA_DMA */ |
442 | 441 | ||
443 | 442 | ||
444 | /* Because of bank switching, the LAN91x uses only 16 I/O ports */ | 443 | /* |
444 | * Everything a particular hardware setup needs should have been defined | ||
445 | * at this point. Add stubs for the undefined cases, mainly to avoid | ||
446 | * compilation warnings since they'll be optimized away, or to prevent buggy | ||
447 | * use of them. | ||
448 | */ | ||
449 | |||
450 | #if ! SMC_CAN_USE_32BIT | ||
451 | #define SMC_inl(ioaddr, reg) ({ BUG(); 0; }) | ||
452 | #define SMC_outl(x, ioaddr, reg) BUG() | ||
453 | #define SMC_insl(a, r, p, l) BUG() | ||
454 | #define SMC_outsl(a, r, p, l) BUG() | ||
455 | #endif | ||
456 | |||
457 | #if !defined(SMC_insl) || !defined(SMC_outsl) | ||
458 | #define SMC_insl(a, r, p, l) BUG() | ||
459 | #define SMC_outsl(a, r, p, l) BUG() | ||
460 | #endif | ||
461 | |||
462 | #if ! SMC_CAN_USE_16BIT | ||
463 | |||
464 | /* | ||
465 | * Any 16-bit access is performed with two 8-bit accesses if the hardware | ||
466 | * can't do it directly. Most registers are 16-bit so those are mandatory. | ||
467 | */ | ||
468 | #define SMC_outw(x, ioaddr, reg) \ | ||
469 | do { \ | ||
470 | unsigned int __val16 = (x); \ | ||
471 | SMC_outb( __val16, ioaddr, reg ); \ | ||
472 | SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ | ||
473 | } while (0) | ||
474 | #define SMC_inw(ioaddr, reg) \ | ||
475 | ({ \ | ||
476 | unsigned int __val16; \ | ||
477 | __val16 = SMC_inb( ioaddr, reg ); \ | ||
478 | __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ | ||
479 | __val16; \ | ||
480 | }) | ||
481 | |||
482 | #define SMC_insw(a, r, p, l) BUG() | ||
483 | #define SMC_outsw(a, r, p, l) BUG() | ||
484 | |||
485 | #endif | ||
486 | |||
487 | #if !defined(SMC_insw) || !defined(SMC_outsw) | ||
488 | #define SMC_insw(a, r, p, l) BUG() | ||
489 | #define SMC_outsw(a, r, p, l) BUG() | ||
490 | #endif | ||
491 | |||
492 | #if ! SMC_CAN_USE_8BIT | ||
493 | #define SMC_inb(ioaddr, reg) ({ BUG(); 0; }) | ||
494 | #define SMC_outb(x, ioaddr, reg) BUG() | ||
495 | #define SMC_insb(a, r, p, l) BUG() | ||
496 | #define SMC_outsb(a, r, p, l) BUG() | ||
497 | #endif | ||
498 | |||
499 | #if !defined(SMC_insb) || !defined(SMC_outsb) | ||
500 | #define SMC_insb(a, r, p, l) BUG() | ||
501 | #define SMC_outsb(a, r, p, l) BUG() | ||
502 | #endif | ||
503 | |||
504 | #ifndef SMC_CAN_USE_DATACS | ||
505 | #define SMC_CAN_USE_DATACS 0 | ||
506 | #endif | ||
507 | |||
445 | #ifndef SMC_IO_SHIFT | 508 | #ifndef SMC_IO_SHIFT |
446 | #define SMC_IO_SHIFT 0 | 509 | #define SMC_IO_SHIFT 0 |
447 | #endif | 510 | #endif |
511 | |||
512 | #ifndef SMC_IRQ_FLAGS | ||
513 | #define SMC_IRQ_FLAGS SA_TRIGGER_RISING | ||
514 | #endif | ||
515 | |||
516 | #ifndef SMC_INTERRUPT_PREAMBLE | ||
517 | #define SMC_INTERRUPT_PREAMBLE | ||
518 | #endif | ||
519 | |||
520 | |||
521 | /* Because of bank switching, the LAN91x uses only 16 I/O ports */ | ||
448 | #define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) | 522 | #define SMC_IO_EXTENT (16 << SMC_IO_SHIFT) |
449 | #define SMC_DATA_EXTENT (4) | 523 | #define SMC_DATA_EXTENT (4) |
450 | 524 | ||
@@ -817,6 +891,11 @@ static const char * chip_ids[ 16 ] = { | |||
817 | * Note: the following macros do *not* select the bank -- this must | 891 | * Note: the following macros do *not* select the bank -- this must |
818 | * be done separately as needed in the main code. The SMC_REG() macro | 892 | * be done separately as needed in the main code. The SMC_REG() macro |
819 | * only uses the bank argument for debugging purposes (when enabled). | 893 | * only uses the bank argument for debugging purposes (when enabled). |
894 | * | ||
895 | * Note: despite inline functions being safer, everything leading to this | ||
896 | * should preferably be macros to let BUG() display the line number in | ||
897 | * the core source code since we're interested in the top call site | ||
898 | * not in any inline function location. | ||
820 | */ | 899 | */ |
821 | 900 | ||
822 | #if SMC_DEBUG > 0 | 901 | #if SMC_DEBUG > 0 |
@@ -834,62 +913,142 @@ static const char * chip_ids[ 16 ] = { | |||
834 | #define SMC_REG(reg, bank) (reg<<SMC_IO_SHIFT) | 913 | #define SMC_REG(reg, bank) (reg<<SMC_IO_SHIFT) |
835 | #endif | 914 | #endif |
836 | 915 | ||
837 | #if SMC_CAN_USE_8BIT | 916 | /* |
838 | #define SMC_GET_PN() SMC_inb( ioaddr, PN_REG ) | 917 | * Hack Alert: Some setups just can't write 8 or 16 bits reliably when not |
839 | #define SMC_SET_PN(x) SMC_outb( x, ioaddr, PN_REG ) | 918 | * aligned to a 32 bit boundary. I tell you that does exist! |
840 | #define SMC_GET_AR() SMC_inb( ioaddr, AR_REG ) | 919 | * Fortunately the affected register accesses can be easily worked around |
841 | #define SMC_GET_TXFIFO() SMC_inb( ioaddr, TXFIFO_REG ) | 920 | * since we can write zeroes to the preceeding 16 bits without adverse |
842 | #define SMC_GET_RXFIFO() SMC_inb( ioaddr, RXFIFO_REG ) | 921 | * effects and use a 32-bit access. |
843 | #define SMC_GET_INT() SMC_inb( ioaddr, INT_REG ) | 922 | * |
844 | #define SMC_ACK_INT(x) SMC_outb( x, ioaddr, INT_REG ) | 923 | * Enforce it on any 32-bit capable setup for now. |
845 | #define SMC_GET_INT_MASK() SMC_inb( ioaddr, IM_REG ) | 924 | */ |
846 | #define SMC_SET_INT_MASK(x) SMC_outb( x, ioaddr, IM_REG ) | 925 | #define SMC_MUST_ALIGN_WRITE SMC_CAN_USE_32BIT |
847 | #else | 926 | |
848 | #define SMC_GET_PN() (SMC_inw( ioaddr, PN_REG ) & 0xFF) | 927 | #define SMC_GET_PN() \ |
849 | #define SMC_SET_PN(x) SMC_outw( x, ioaddr, PN_REG ) | 928 | ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, PN_REG)) \ |
850 | #define SMC_GET_AR() (SMC_inw( ioaddr, PN_REG ) >> 8) | 929 | : (SMC_inw(ioaddr, PN_REG) & 0xFF) ) |
851 | #define SMC_GET_TXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) & 0xFF) | 930 | |
852 | #define SMC_GET_RXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) >> 8) | 931 | #define SMC_SET_PN(x) \ |
853 | #define SMC_GET_INT() (SMC_inw( ioaddr, INT_REG ) & 0xFF) | 932 | do { \ |
933 | if (SMC_MUST_ALIGN_WRITE) \ | ||
934 | SMC_outl((x)<<16, ioaddr, SMC_REG(0, 2)); \ | ||
935 | else if (SMC_CAN_USE_8BIT) \ | ||
936 | SMC_outb(x, ioaddr, PN_REG); \ | ||
937 | else \ | ||
938 | SMC_outw(x, ioaddr, PN_REG); \ | ||
939 | } while (0) | ||
940 | |||
941 | #define SMC_GET_AR() \ | ||
942 | ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, AR_REG)) \ | ||
943 | : (SMC_inw(ioaddr, PN_REG) >> 8) ) | ||
944 | |||
945 | #define SMC_GET_TXFIFO() \ | ||
946 | ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, TXFIFO_REG)) \ | ||
947 | : (SMC_inw(ioaddr, TXFIFO_REG) & 0xFF) ) | ||
948 | |||
949 | #define SMC_GET_RXFIFO() \ | ||
950 | ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, RXFIFO_REG)) \ | ||
951 | : (SMC_inw(ioaddr, TXFIFO_REG) >> 8) ) | ||
952 | |||
953 | #define SMC_GET_INT() \ | ||
954 | ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, INT_REG)) \ | ||
955 | : (SMC_inw(ioaddr, INT_REG) & 0xFF) ) | ||
956 | |||
854 | #define SMC_ACK_INT(x) \ | 957 | #define SMC_ACK_INT(x) \ |
855 | do { \ | 958 | do { \ |
856 | unsigned long __flags; \ | 959 | if (SMC_CAN_USE_8BIT) \ |
857 | int __mask; \ | 960 | SMC_outb(x, ioaddr, INT_REG); \ |
858 | local_irq_save(__flags); \ | 961 | else { \ |
859 | __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \ | 962 | unsigned long __flags; \ |
860 | SMC_outw( __mask | (x), ioaddr, INT_REG ); \ | 963 | int __mask; \ |
861 | local_irq_restore(__flags); \ | 964 | local_irq_save(__flags); \ |
965 | __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \ | ||
966 | SMC_outw( __mask | (x), ioaddr, INT_REG ); \ | ||
967 | local_irq_restore(__flags); \ | ||
968 | } \ | ||
969 | } while (0) | ||
970 | |||
971 | #define SMC_GET_INT_MASK() \ | ||
972 | ( SMC_CAN_USE_8BIT ? (SMC_inb(ioaddr, IM_REG)) \ | ||
973 | : (SMC_inw( ioaddr, INT_REG ) >> 8) ) | ||
974 | |||
975 | #define SMC_SET_INT_MASK(x) \ | ||
976 | do { \ | ||
977 | if (SMC_CAN_USE_8BIT) \ | ||
978 | SMC_outb(x, ioaddr, IM_REG); \ | ||
979 | else \ | ||
980 | SMC_outw((x) << 8, ioaddr, INT_REG); \ | ||
981 | } while (0) | ||
982 | |||
983 | #define SMC_CURRENT_BANK() SMC_inw(ioaddr, BANK_SELECT) | ||
984 | |||
985 | #define SMC_SELECT_BANK(x) \ | ||
986 | do { \ | ||
987 | if (SMC_MUST_ALIGN_WRITE) \ | ||
988 | SMC_outl((x)<<16, ioaddr, 12<<SMC_IO_SHIFT); \ | ||
989 | else \ | ||
990 | SMC_outw(x, ioaddr, BANK_SELECT); \ | ||
991 | } while (0) | ||
992 | |||
993 | #define SMC_GET_BASE() SMC_inw(ioaddr, BASE_REG) | ||
994 | |||
995 | #define SMC_SET_BASE(x) SMC_outw(x, ioaddr, BASE_REG) | ||
996 | |||
997 | #define SMC_GET_CONFIG() SMC_inw(ioaddr, CONFIG_REG) | ||
998 | |||
999 | #define SMC_SET_CONFIG(x) SMC_outw(x, ioaddr, CONFIG_REG) | ||
1000 | |||
1001 | #define SMC_GET_COUNTER() SMC_inw(ioaddr, COUNTER_REG) | ||
1002 | |||
1003 | #define SMC_GET_CTL() SMC_inw(ioaddr, CTL_REG) | ||
1004 | |||
1005 | #define SMC_SET_CTL(x) SMC_outw(x, ioaddr, CTL_REG) | ||
1006 | |||
1007 | #define SMC_GET_MII() SMC_inw(ioaddr, MII_REG) | ||
1008 | |||
1009 | #define SMC_SET_MII(x) SMC_outw(x, ioaddr, MII_REG) | ||
1010 | |||
1011 | #define SMC_GET_MIR() SMC_inw(ioaddr, MIR_REG) | ||
1012 | |||
1013 | #define SMC_SET_MIR(x) SMC_outw(x, ioaddr, MIR_REG) | ||
1014 | |||
1015 | #define SMC_GET_MMU_CMD() SMC_inw(ioaddr, MMU_CMD_REG) | ||
1016 | |||
1017 | #define SMC_SET_MMU_CMD(x) SMC_outw(x, ioaddr, MMU_CMD_REG) | ||
1018 | |||
1019 | #define SMC_GET_FIFO() SMC_inw(ioaddr, FIFO_REG) | ||
1020 | |||
1021 | #define SMC_GET_PTR() SMC_inw(ioaddr, PTR_REG) | ||
1022 | |||
1023 | #define SMC_SET_PTR(x) \ | ||
1024 | do { \ | ||
1025 | if (SMC_MUST_ALIGN_WRITE) \ | ||
1026 | SMC_outl((x)<<16, ioaddr, SMC_REG(4, 2)); \ | ||
1027 | else \ | ||
1028 | SMC_outw(x, ioaddr, PTR_REG); \ | ||
862 | } while (0) | 1029 | } while (0) |
863 | #define SMC_GET_INT_MASK() (SMC_inw( ioaddr, INT_REG ) >> 8) | ||
864 | #define SMC_SET_INT_MASK(x) SMC_outw( (x) << 8, ioaddr, INT_REG ) | ||
865 | #endif | ||
866 | 1030 | ||
867 | #define SMC_CURRENT_BANK() SMC_inw( ioaddr, BANK_SELECT ) | 1031 | #define SMC_GET_EPH_STATUS() SMC_inw(ioaddr, EPH_STATUS_REG) |
868 | #define SMC_SELECT_BANK(x) SMC_outw( x, ioaddr, BANK_SELECT ) | 1032 | |
869 | #define SMC_GET_BASE() SMC_inw( ioaddr, BASE_REG ) | 1033 | #define SMC_GET_RCR() SMC_inw(ioaddr, RCR_REG) |
870 | #define SMC_SET_BASE(x) SMC_outw( x, ioaddr, BASE_REG ) | 1034 | |
871 | #define SMC_GET_CONFIG() SMC_inw( ioaddr, CONFIG_REG ) | 1035 | #define SMC_SET_RCR(x) SMC_outw(x, ioaddr, RCR_REG) |
872 | #define SMC_SET_CONFIG(x) SMC_outw( x, ioaddr, CONFIG_REG ) | 1036 | |
873 | #define SMC_GET_COUNTER() SMC_inw( ioaddr, COUNTER_REG ) | 1037 | #define SMC_GET_REV() SMC_inw(ioaddr, REV_REG) |
874 | #define SMC_GET_CTL() SMC_inw( ioaddr, CTL_REG ) | 1038 | |
875 | #define SMC_SET_CTL(x) SMC_outw( x, ioaddr, CTL_REG ) | 1039 | #define SMC_GET_RPC() SMC_inw(ioaddr, RPC_REG) |
876 | #define SMC_GET_MII() SMC_inw( ioaddr, MII_REG ) | 1040 | |
877 | #define SMC_SET_MII(x) SMC_outw( x, ioaddr, MII_REG ) | 1041 | #define SMC_SET_RPC(x) \ |
878 | #define SMC_GET_MIR() SMC_inw( ioaddr, MIR_REG ) | 1042 | do { \ |
879 | #define SMC_SET_MIR(x) SMC_outw( x, ioaddr, MIR_REG ) | 1043 | if (SMC_MUST_ALIGN_WRITE) \ |
880 | #define SMC_GET_MMU_CMD() SMC_inw( ioaddr, MMU_CMD_REG ) | 1044 | SMC_outl((x)<<16, ioaddr, SMC_REG(8, 0)); \ |
881 | #define SMC_SET_MMU_CMD(x) SMC_outw( x, ioaddr, MMU_CMD_REG ) | 1045 | else \ |
882 | #define SMC_GET_FIFO() SMC_inw( ioaddr, FIFO_REG ) | 1046 | SMC_outw(x, ioaddr, RPC_REG); \ |
883 | #define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG ) | 1047 | } while (0) |
884 | #define SMC_SET_PTR(x) SMC_outw( x, ioaddr, PTR_REG ) | 1048 | |
885 | #define SMC_GET_EPH_STATUS() SMC_inw( ioaddr, EPH_STATUS_REG ) | 1049 | #define SMC_GET_TCR() SMC_inw(ioaddr, TCR_REG) |
886 | #define SMC_GET_RCR() SMC_inw( ioaddr, RCR_REG ) | 1050 | |
887 | #define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG ) | 1051 | #define SMC_SET_TCR(x) SMC_outw(x, ioaddr, TCR_REG) |
888 | #define SMC_GET_REV() SMC_inw( ioaddr, REV_REG ) | ||
889 | #define SMC_GET_RPC() SMC_inw( ioaddr, RPC_REG ) | ||
890 | #define SMC_SET_RPC(x) SMC_outw( x, ioaddr, RPC_REG ) | ||
891 | #define SMC_GET_TCR() SMC_inw( ioaddr, TCR_REG ) | ||
892 | #define SMC_SET_TCR(x) SMC_outw( x, ioaddr, TCR_REG ) | ||
893 | 1052 | ||
894 | #ifndef SMC_GET_MAC_ADDR | 1053 | #ifndef SMC_GET_MAC_ADDR |
895 | #define SMC_GET_MAC_ADDR(addr) \ | 1054 | #define SMC_GET_MAC_ADDR(addr) \ |
@@ -920,151 +1079,84 @@ static const char * chip_ids[ 16 ] = { | |||
920 | SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \ | 1079 | SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \ |
921 | } while (0) | 1080 | } while (0) |
922 | 1081 | ||
923 | #if SMC_CAN_USE_32BIT | ||
924 | /* | ||
925 | * Some setups just can't write 8 or 16 bits reliably when not aligned | ||
926 | * to a 32 bit boundary. I tell you that exists! | ||
927 | * We re-do the ones here that can be easily worked around if they can have | ||
928 | * their low parts written to 0 without adverse effects. | ||
929 | */ | ||
930 | #undef SMC_SELECT_BANK | ||
931 | #define SMC_SELECT_BANK(x) SMC_outl( (x)<<16, ioaddr, 12<<SMC_IO_SHIFT ) | ||
932 | #undef SMC_SET_RPC | ||
933 | #define SMC_SET_RPC(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(8, 0) ) | ||
934 | #undef SMC_SET_PN | ||
935 | #define SMC_SET_PN(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(0, 2) ) | ||
936 | #undef SMC_SET_PTR | ||
937 | #define SMC_SET_PTR(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(4, 2) ) | ||
938 | #endif | ||
939 | |||
940 | #if SMC_CAN_USE_32BIT | ||
941 | #define SMC_PUT_PKT_HDR(status, length) \ | ||
942 | SMC_outl( (status) | (length) << 16, ioaddr, DATA_REG ) | ||
943 | #define SMC_GET_PKT_HDR(status, length) \ | ||
944 | do { \ | ||
945 | unsigned int __val = SMC_inl( ioaddr, DATA_REG ); \ | ||
946 | (status) = __val & 0xffff; \ | ||
947 | (length) = __val >> 16; \ | ||
948 | } while (0) | ||
949 | #else | ||
950 | #define SMC_PUT_PKT_HDR(status, length) \ | 1082 | #define SMC_PUT_PKT_HDR(status, length) \ |
951 | do { \ | 1083 | do { \ |
952 | SMC_outw( status, ioaddr, DATA_REG ); \ | 1084 | if (SMC_CAN_USE_32BIT) \ |
953 | SMC_outw( length, ioaddr, DATA_REG ); \ | 1085 | SMC_outl((status) | (length)<<16, ioaddr, DATA_REG); \ |
954 | } while (0) | 1086 | else { \ |
955 | #define SMC_GET_PKT_HDR(status, length) \ | 1087 | SMC_outw(status, ioaddr, DATA_REG); \ |
956 | do { \ | 1088 | SMC_outw(length, ioaddr, DATA_REG); \ |
957 | (status) = SMC_inw( ioaddr, DATA_REG ); \ | 1089 | } \ |
958 | (length) = SMC_inw( ioaddr, DATA_REG ); \ | ||
959 | } while (0) | 1090 | } while (0) |
960 | #endif | ||
961 | 1091 | ||
962 | #if SMC_CAN_USE_32BIT | 1092 | #define SMC_GET_PKT_HDR(status, length) \ |
963 | #define _SMC_PUSH_DATA(p, l) \ | ||
964 | do { \ | 1093 | do { \ |
965 | char *__ptr = (p); \ | 1094 | if (SMC_CAN_USE_32BIT) { \ |
966 | int __len = (l); \ | 1095 | unsigned int __val = SMC_inl(ioaddr, DATA_REG); \ |
967 | if (__len >= 2 && (unsigned long)__ptr & 2) { \ | 1096 | (status) = __val & 0xffff; \ |
968 | __len -= 2; \ | 1097 | (length) = __val >> 16; \ |
969 | SMC_outw( *(u16 *)__ptr, ioaddr, DATA_REG ); \ | 1098 | } else { \ |
970 | __ptr += 2; \ | 1099 | (status) = SMC_inw(ioaddr, DATA_REG); \ |
971 | } \ | 1100 | (length) = SMC_inw(ioaddr, DATA_REG); \ |
972 | SMC_outsl( ioaddr, DATA_REG, __ptr, __len >> 2); \ | ||
973 | if (__len & 2) { \ | ||
974 | __ptr += (__len & ~3); \ | ||
975 | SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ | ||
976 | } \ | 1101 | } \ |
977 | } while (0) | 1102 | } while (0) |
978 | #define _SMC_PULL_DATA(p, l) \ | ||
979 | do { \ | ||
980 | char *__ptr = (p); \ | ||
981 | int __len = (l); \ | ||
982 | if ((unsigned long)__ptr & 2) { \ | ||
983 | /* \ | ||
984 | * We want 32bit alignment here. \ | ||
985 | * Since some buses perform a full 32bit \ | ||
986 | * fetch even for 16bit data we can't use \ | ||
987 | * SMC_inw() here. Back both source (on chip \ | ||
988 | * and destination) pointers of 2 bytes. \ | ||
989 | */ \ | ||
990 | __ptr -= 2; \ | ||
991 | __len += 2; \ | ||
992 | SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ | ||
993 | } \ | ||
994 | __len += 2; \ | ||
995 | SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \ | ||
996 | } while (0) | ||
997 | #elif SMC_CAN_USE_16BIT | ||
998 | #define _SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 ) | ||
999 | #define _SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 ) | ||
1000 | #elif SMC_CAN_USE_8BIT | ||
1001 | #define _SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l ) | ||
1002 | #define _SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l ) | ||
1003 | #endif | ||
1004 | 1103 | ||
1005 | #if ! SMC_CAN_USE_16BIT | 1104 | #define SMC_PUSH_DATA(p, l) \ |
1006 | #define SMC_outw(x, ioaddr, reg) \ | ||
1007 | do { \ | 1105 | do { \ |
1008 | unsigned int __val16 = (x); \ | 1106 | if (SMC_CAN_USE_32BIT) { \ |
1009 | SMC_outb( __val16, ioaddr, reg ); \ | 1107 | void *__ptr = (p); \ |
1010 | SMC_outb( __val16 >> 8, ioaddr, reg + (1 << SMC_IO_SHIFT));\ | 1108 | int __len = (l); \ |
1109 | void *__ioaddr = ioaddr; \ | ||
1110 | if (__len >= 2 && (unsigned long)__ptr & 2) { \ | ||
1111 | __len -= 2; \ | ||
1112 | SMC_outw(*(u16 *)__ptr, ioaddr, DATA_REG); \ | ||
1113 | __ptr += 2; \ | ||
1114 | } \ | ||
1115 | if (SMC_CAN_USE_DATACS && lp->datacs) \ | ||
1116 | __ioaddr = lp->datacs; \ | ||
1117 | SMC_outsl(__ioaddr, DATA_REG, __ptr, __len>>2); \ | ||
1118 | if (__len & 2) { \ | ||
1119 | __ptr += (__len & ~3); \ | ||
1120 | SMC_outw(*((u16 *)__ptr), ioaddr, DATA_REG); \ | ||
1121 | } \ | ||
1122 | } else if (SMC_CAN_USE_16BIT) \ | ||
1123 | SMC_outsw(ioaddr, DATA_REG, p, (l) >> 1); \ | ||
1124 | else if (SMC_CAN_USE_8BIT) \ | ||
1125 | SMC_outsb(ioaddr, DATA_REG, p, l); \ | ||
1011 | } while (0) | 1126 | } while (0) |
1012 | #define SMC_inw(ioaddr, reg) \ | ||
1013 | ({ \ | ||
1014 | unsigned int __val16; \ | ||
1015 | __val16 = SMC_inb( ioaddr, reg ); \ | ||
1016 | __val16 |= SMC_inb( ioaddr, reg + (1 << SMC_IO_SHIFT)) << 8; \ | ||
1017 | __val16; \ | ||
1018 | }) | ||
1019 | #endif | ||
1020 | |||
1021 | #ifdef SMC_CAN_USE_DATACS | ||
1022 | #define SMC_PUSH_DATA(p, l) \ | ||
1023 | if ( lp->datacs ) { \ | ||
1024 | unsigned char *__ptr = (p); \ | ||
1025 | int __len = (l); \ | ||
1026 | if (__len >= 2 && (unsigned long)__ptr & 2) { \ | ||
1027 | __len -= 2; \ | ||
1028 | SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ | ||
1029 | __ptr += 2; \ | ||
1030 | } \ | ||
1031 | outsl(lp->datacs, __ptr, __len >> 2); \ | ||
1032 | if (__len & 2) { \ | ||
1033 | __ptr += (__len & ~3); \ | ||
1034 | SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \ | ||
1035 | } \ | ||
1036 | } else { \ | ||
1037 | _SMC_PUSH_DATA(p, l); \ | ||
1038 | } | ||
1039 | 1127 | ||
1040 | #define SMC_PULL_DATA(p, l) \ | 1128 | #define SMC_PULL_DATA(p, l) \ |
1041 | if ( lp->datacs ) { \ | 1129 | do { \ |
1042 | unsigned char *__ptr = (p); \ | 1130 | if (SMC_CAN_USE_32BIT) { \ |
1043 | int __len = (l); \ | 1131 | void *__ptr = (p); \ |
1044 | if ((unsigned long)__ptr & 2) { \ | 1132 | int __len = (l); \ |
1045 | /* \ | 1133 | void *__ioaddr = ioaddr; \ |
1046 | * We want 32bit alignment here. \ | 1134 | if ((unsigned long)__ptr & 2) { \ |
1047 | * Since some buses perform a full 32bit \ | 1135 | /* \ |
1048 | * fetch even for 16bit data we can't use \ | 1136 | * We want 32bit alignment here. \ |
1049 | * SMC_inw() here. Back both source (on chip \ | 1137 | * Since some buses perform a full \ |
1050 | * and destination) pointers of 2 bytes. \ | 1138 | * 32bit fetch even for 16bit data \ |
1051 | */ \ | 1139 | * we can't use SMC_inw() here. \ |
1052 | __ptr -= 2; \ | 1140 | * Back both source (on-chip) and \ |
1141 | * destination pointers of 2 bytes. \ | ||
1142 | * This is possible since the call to \ | ||
1143 | * SMC_GET_PKT_HDR() already advanced \ | ||
1144 | * the source pointer of 4 bytes, and \ | ||
1145 | * the skb_reserve(skb, 2) advanced \ | ||
1146 | * the destination pointer of 2 bytes. \ | ||
1147 | */ \ | ||
1148 | __ptr -= 2; \ | ||
1149 | __len += 2; \ | ||
1150 | SMC_SET_PTR(2|PTR_READ|PTR_RCV|PTR_AUTOINC); \ | ||
1151 | } \ | ||
1152 | if (SMC_CAN_USE_DATACS && lp->datacs) \ | ||
1153 | __ioaddr = lp->datacs; \ | ||
1053 | __len += 2; \ | 1154 | __len += 2; \ |
1054 | SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \ | 1155 | SMC_insl(__ioaddr, DATA_REG, __ptr, __len>>2); \ |
1055 | } \ | 1156 | } else if (SMC_CAN_USE_16BIT) \ |
1056 | __len += 2; \ | 1157 | SMC_insw(ioaddr, DATA_REG, p, (l) >> 1); \ |
1057 | insl( lp->datacs, __ptr, __len >> 2); \ | 1158 | else if (SMC_CAN_USE_8BIT) \ |
1058 | } else { \ | 1159 | SMC_insb(ioaddr, DATA_REG, p, l); \ |
1059 | _SMC_PULL_DATA(p, l); \ | 1160 | } while (0) |
1060 | } | ||
1061 | #else | ||
1062 | #define SMC_PUSH_DATA(p, l) _SMC_PUSH_DATA(p, l) | ||
1063 | #define SMC_PULL_DATA(p, l) _SMC_PULL_DATA(p, l) | ||
1064 | #endif | ||
1065 | |||
1066 | #if !defined (SMC_INTERRUPT_PREAMBLE) | ||
1067 | # define SMC_INTERRUPT_PREAMBLE | ||
1068 | #endif | ||
1069 | 1161 | ||
1070 | #endif /* _SMC91X_H_ */ | 1162 | #endif /* _SMC91X_H_ */ |