net: ks8851-ml: Fix IO operations, again

This patch reverts 58292104832f ("net: ks8851-ml: Fix 16-bit IO operation")
and edacb098ea9c ("net: ks8851-ml: Fix 16-bit data access"), because it
turns out these were only necessary due to buggy hardware. This patch adds
a check for such a buggy hardware to prevent any such mistakes again.

While working further on the KS8851 driver, it came to light that the
KS8851-16MLL is capable of switching bus endianness by a hardware strap,
EESK pin. If this strap is incorrect, the IO accesses require such endian
swapping as is being reverted by this patch. Such swapping also impacts
the performance significantly.

Hence, in addition to removing it, detect that the hardware is broken,
report to user, and fail to bind with such hardware.

Fixes: 58292104832f ("net: ks8851-ml: Fix 16-bit IO operation")
Fixes: edacb098ea9c ("net: ks8851-ml: Fix 16-bit data access")
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Lukas Wunner <lukas@wunner.de>
Cc: Petr Stetiar <ynezz@true.cz>
Cc: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Marek Vasut and committed by David S. Miller 8262e6f9 328f5bb9

Changed files
+52 -4
drivers
net
ethernet
micrel
+52 -4
drivers/net/ethernet/micrel/ks8851_mll.c
··· 157 157 */ 158 158 159 159 /** 160 + * ks_check_endian - Check whether endianness of the bus is correct 161 + * @ks : The chip information 162 + * 163 + * The KS8851-16MLL EESK pin allows selecting the endianness of the 16bit 164 + * bus. To maintain optimum performance, the bus endianness should be set 165 + * such that it matches the endianness of the CPU. 166 + */ 167 + 168 + static int ks_check_endian(struct ks_net *ks) 169 + { 170 + u16 cider; 171 + 172 + /* 173 + * Read CIDER register first, however read it the "wrong" way around. 174 + * If the endian strap on the KS8851-16MLL in incorrect and the chip 175 + * is operating in different endianness than the CPU, then the meaning 176 + * of BE[3:0] byte-enable bits is also swapped such that: 177 + * BE[3,2,1,0] becomes BE[1,0,3,2] 178 + * 179 + * Luckily for us, the byte-enable bits are the top four MSbits of 180 + * the address register and the CIDER register is at offset 0xc0. 181 + * Hence, by reading address 0xc0c0, which is not impacted by endian 182 + * swapping, we assert either BE[3:2] or BE[1:0] while reading the 183 + * CIDER register. 184 + * 185 + * If the bus configuration is correct, reading 0xc0c0 asserts 186 + * BE[3:2] and this read returns 0x0000, because to read register 187 + * with bottom two LSbits of address set to 0, BE[1:0] must be 188 + * asserted. 189 + * 190 + * If the bus configuration is NOT correct, reading 0xc0c0 asserts 191 + * BE[1:0] and this read returns non-zero 0x8872 value. 192 + */ 193 + iowrite16(BE3 | BE2 | KS_CIDER, ks->hw_addr_cmd); 194 + cider = ioread16(ks->hw_addr); 195 + if (!cider) 196 + return 0; 197 + 198 + netdev_err(ks->netdev, "incorrect EESK endian strap setting\n"); 199 + 200 + return -EINVAL; 201 + } 202 + 203 + /** 160 204 * ks_rdreg16 - read 16 bit register from device 161 205 * @ks : The chip information 162 206 * @offset: The register address ··· 210 166 211 167 static u16 ks_rdreg16(struct ks_net *ks, int offset) 212 168 { 213 - ks->cmd_reg_cache = (u16)offset | ((BE3 | BE2) >> (offset & 0x02)); 169 + ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02)); 214 170 iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); 215 171 return ioread16(ks->hw_addr); 216 172 } ··· 225 181 226 182 static void ks_wrreg16(struct ks_net *ks, int offset, u16 value) 227 183 { 228 - ks->cmd_reg_cache = (u16)offset | ((BE3 | BE2) >> (offset & 0x02)); 184 + ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02)); 229 185 iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); 230 186 iowrite16(value, ks->hw_addr); 231 187 } ··· 241 197 { 242 198 len >>= 1; 243 199 while (len--) 244 - *wptr++ = be16_to_cpu(ioread16(ks->hw_addr)); 200 + *wptr++ = (u16)ioread16(ks->hw_addr); 245 201 } 246 202 247 203 /** ··· 255 211 { 256 212 len >>= 1; 257 213 while (len--) 258 - iowrite16(cpu_to_be16(*wptr++), ks->hw_addr); 214 + iowrite16(*wptr++, ks->hw_addr); 259 215 } 260 216 261 217 static void ks_disable_int(struct ks_net *ks) ··· 1261 1217 err = PTR_ERR(ks->hw_addr_cmd); 1262 1218 goto err_free; 1263 1219 } 1220 + 1221 + err = ks_check_endian(ks); 1222 + if (err) 1223 + goto err_free; 1264 1224 1265 1225 netdev->irq = platform_get_irq(pdev, 0); 1266 1226