| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* drivers/net/ethernet/micrel/ks8851.h |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright 2009 Simtec Electronics |
|---|
| 4 | 5 | * Ben Dooks <ben@simtec.co.uk> |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * KS8851 register definitions |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 9 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 10 | | - * published by the Free Software Foundation. |
|---|
| 11 | 8 | */ |
|---|
| 12 | 9 | |
|---|
| 10 | +#ifndef __KS8851_H__ |
|---|
| 11 | +#define __KS8851_H__ |
|---|
| 12 | + |
|---|
| 13 | +#include <linux/eeprom_93cx6.h> |
|---|
| 14 | + |
|---|
| 13 | 15 | #define KS_CCR 0x08 |
|---|
| 16 | +#define CCR_LE (1 << 10) /* KSZ8851-16MLL */ |
|---|
| 14 | 17 | #define CCR_EEPROM (1 << 9) |
|---|
| 15 | | -#define CCR_SPI (1 << 8) |
|---|
| 16 | | -#define CCR_32PIN (1 << 0) |
|---|
| 18 | +#define CCR_SPI (1 << 8) /* KSZ8851SNL */ |
|---|
| 19 | +#define CCR_8BIT (1 << 7) /* KSZ8851-16MLL */ |
|---|
| 20 | +#define CCR_16BIT (1 << 6) /* KSZ8851-16MLL */ |
|---|
| 21 | +#define CCR_32BIT (1 << 5) /* KSZ8851-16MLL */ |
|---|
| 22 | +#define CCR_SHARED (1 << 4) /* KSZ8851-16MLL */ |
|---|
| 23 | +#define CCR_48PIN (1 << 1) /* KSZ8851-16MLL */ |
|---|
| 24 | +#define CCR_32PIN (1 << 0) /* KSZ8851SNL */ |
|---|
| 17 | 25 | |
|---|
| 18 | 26 | /* MAC address registers */ |
|---|
| 19 | | -#define KS_MAR(_m) (0x15 - (_m)) |
|---|
| 27 | +#define KS_MAR(_m) (0x14 - (_m)) |
|---|
| 20 | 28 | #define KS_MARL 0x10 |
|---|
| 21 | 29 | #define KS_MARM 0x12 |
|---|
| 22 | 30 | #define KS_MARH 0x14 |
|---|
| .. | .. |
|---|
| 112 | 120 | #define RXCR1_RXE (1 << 0) |
|---|
| 113 | 121 | |
|---|
| 114 | 122 | #define KS_RXCR2 0x76 |
|---|
| 115 | | -#define RXCR2_SRDBL_MASK (0x7 << 5) |
|---|
| 116 | | -#define RXCR2_SRDBL_SHIFT (5) |
|---|
| 117 | | -#define RXCR2_SRDBL_4B (0x0 << 5) |
|---|
| 118 | | -#define RXCR2_SRDBL_8B (0x1 << 5) |
|---|
| 119 | | -#define RXCR2_SRDBL_16B (0x2 << 5) |
|---|
| 120 | | -#define RXCR2_SRDBL_32B (0x3 << 5) |
|---|
| 121 | | -#define RXCR2_SRDBL_FRAME (0x4 << 5) |
|---|
| 123 | +#define RXCR2_SRDBL_MASK (0x7 << 5) /* KSZ8851SNL */ |
|---|
| 124 | +#define RXCR2_SRDBL_SHIFT (5) /* KSZ8851SNL */ |
|---|
| 125 | +#define RXCR2_SRDBL_4B (0x0 << 5) /* KSZ8851SNL */ |
|---|
| 126 | +#define RXCR2_SRDBL_8B (0x1 << 5) /* KSZ8851SNL */ |
|---|
| 127 | +#define RXCR2_SRDBL_16B (0x2 << 5) /* KSZ8851SNL */ |
|---|
| 128 | +#define RXCR2_SRDBL_32B (0x3 << 5) /* KSZ8851SNL */ |
|---|
| 129 | +#define RXCR2_SRDBL_FRAME (0x4 << 5) /* KSZ8851SNL */ |
|---|
| 122 | 130 | #define RXCR2_IUFFP (1 << 4) |
|---|
| 123 | 131 | #define RXCR2_RXIUFCEZ (1 << 3) |
|---|
| 124 | 132 | #define RXCR2_UDPLFE (1 << 2) |
|---|
| .. | .. |
|---|
| 143 | 151 | #define RXFSHR_RXCE (1 << 0) |
|---|
| 144 | 152 | |
|---|
| 145 | 153 | #define KS_RXFHBCR 0x7E |
|---|
| 154 | +#define RXFHBCR_CNT_MASK (0xfff << 0) |
|---|
| 155 | + |
|---|
| 146 | 156 | #define KS_TXQCR 0x80 |
|---|
| 147 | | -#define TXQCR_AETFE (1 << 2) |
|---|
| 157 | +#define TXQCR_AETFE (1 << 2) /* KSZ8851SNL */ |
|---|
| 148 | 158 | #define TXQCR_TXQMAM (1 << 1) |
|---|
| 149 | 159 | #define TXQCR_METFE (1 << 0) |
|---|
| 150 | 160 | |
|---|
| .. | .. |
|---|
| 167 | 177 | |
|---|
| 168 | 178 | #define KS_RXFDPR 0x86 |
|---|
| 169 | 179 | #define RXFDPR_RXFPAI (1 << 14) |
|---|
| 180 | +#define RXFDPR_WST (1 << 12) /* KSZ8851-16MLL */ |
|---|
| 181 | +#define RXFDPR_EMS (1 << 11) /* KSZ8851-16MLL */ |
|---|
| 182 | +#define RXFDPR_RXFP_MASK (0x7ff << 0) |
|---|
| 183 | +#define RXFDPR_RXFP_SHIFT (0) |
|---|
| 170 | 184 | |
|---|
| 171 | 185 | #define KS_RXDTTR 0x8C |
|---|
| 172 | 186 | #define KS_RXDBCTR 0x8E |
|---|
| .. | .. |
|---|
| 184 | 198 | #define IRQ_RXMPDI (1 << 4) |
|---|
| 185 | 199 | #define IRQ_LDI (1 << 3) |
|---|
| 186 | 200 | #define IRQ_EDI (1 << 2) |
|---|
| 187 | | -#define IRQ_SPIBEI (1 << 1) |
|---|
| 201 | +#define IRQ_SPIBEI (1 << 1) /* KSZ8851SNL */ |
|---|
| 188 | 202 | #define IRQ_DEDI (1 << 0) |
|---|
| 189 | 203 | |
|---|
| 190 | 204 | #define KS_RXFCTR 0x9C |
|---|
| .. | .. |
|---|
| 257 | 271 | #define KS_P1ANLPR 0xEE |
|---|
| 258 | 272 | |
|---|
| 259 | 273 | #define KS_P1SCLMD 0xF4 |
|---|
| 260 | | -#define P1SCLMD_LEDOFF (1 << 15) |
|---|
| 261 | | -#define P1SCLMD_TXIDS (1 << 14) |
|---|
| 262 | | -#define P1SCLMD_RESTARTAN (1 << 13) |
|---|
| 263 | | -#define P1SCLMD_DISAUTOMDIX (1 << 10) |
|---|
| 264 | | -#define P1SCLMD_FORCEMDIX (1 << 9) |
|---|
| 265 | | -#define P1SCLMD_AUTONEGEN (1 << 7) |
|---|
| 266 | | -#define P1SCLMD_FORCE100 (1 << 6) |
|---|
| 267 | | -#define P1SCLMD_FORCEFDX (1 << 5) |
|---|
| 268 | | -#define P1SCLMD_ADV_FLOW (1 << 4) |
|---|
| 269 | | -#define P1SCLMD_ADV_100BT_FDX (1 << 3) |
|---|
| 270 | | -#define P1SCLMD_ADV_100BT_HDX (1 << 2) |
|---|
| 271 | | -#define P1SCLMD_ADV_10BT_FDX (1 << 1) |
|---|
| 272 | | -#define P1SCLMD_ADV_10BT_HDX (1 << 0) |
|---|
| 273 | 274 | |
|---|
| 274 | 275 | #define KS_P1CR 0xF6 |
|---|
| 275 | | -#define P1CR_HP_MDIX (1 << 15) |
|---|
| 276 | | -#define P1CR_REV_POL (1 << 13) |
|---|
| 277 | | -#define P1CR_OP_100M (1 << 10) |
|---|
| 278 | | -#define P1CR_OP_FDX (1 << 9) |
|---|
| 279 | | -#define P1CR_OP_MDI (1 << 7) |
|---|
| 280 | | -#define P1CR_AN_DONE (1 << 6) |
|---|
| 281 | | -#define P1CR_LINK_GOOD (1 << 5) |
|---|
| 282 | | -#define P1CR_PNTR_FLOW (1 << 4) |
|---|
| 283 | | -#define P1CR_PNTR_100BT_FDX (1 << 3) |
|---|
| 284 | | -#define P1CR_PNTR_100BT_HDX (1 << 2) |
|---|
| 285 | | -#define P1CR_PNTR_10BT_FDX (1 << 1) |
|---|
| 286 | | -#define P1CR_PNTR_10BT_HDX (1 << 0) |
|---|
| 276 | +#define P1CR_LEDOFF (1 << 15) |
|---|
| 277 | +#define P1CR_TXIDS (1 << 14) |
|---|
| 278 | +#define P1CR_RESTARTAN (1 << 13) |
|---|
| 279 | +#define P1CR_DISAUTOMDIX (1 << 10) |
|---|
| 280 | +#define P1CR_FORCEMDIX (1 << 9) |
|---|
| 281 | +#define P1CR_AUTONEGEN (1 << 7) |
|---|
| 282 | +#define P1CR_FORCE100 (1 << 6) |
|---|
| 283 | +#define P1CR_FORCEFDX (1 << 5) |
|---|
| 284 | +#define P1CR_ADV_FLOW (1 << 4) |
|---|
| 285 | +#define P1CR_ADV_100BT_FDX (1 << 3) |
|---|
| 286 | +#define P1CR_ADV_100BT_HDX (1 << 2) |
|---|
| 287 | +#define P1CR_ADV_10BT_FDX (1 << 1) |
|---|
| 288 | +#define P1CR_ADV_10BT_HDX (1 << 0) |
|---|
| 289 | + |
|---|
| 290 | +#define KS_P1SR 0xF8 |
|---|
| 291 | +#define P1SR_HP_MDIX (1 << 15) |
|---|
| 292 | +#define P1SR_REV_POL (1 << 13) |
|---|
| 293 | +#define P1SR_OP_100M (1 << 10) |
|---|
| 294 | +#define P1SR_OP_FDX (1 << 9) |
|---|
| 295 | +#define P1SR_OP_MDI (1 << 7) |
|---|
| 296 | +#define P1SR_AN_DONE (1 << 6) |
|---|
| 297 | +#define P1SR_LINK_GOOD (1 << 5) |
|---|
| 298 | +#define P1SR_PNTR_FLOW (1 << 4) |
|---|
| 299 | +#define P1SR_PNTR_100BT_FDX (1 << 3) |
|---|
| 300 | +#define P1SR_PNTR_100BT_HDX (1 << 2) |
|---|
| 301 | +#define P1SR_PNTR_10BT_FDX (1 << 1) |
|---|
| 302 | +#define P1SR_PNTR_10BT_HDX (1 << 0) |
|---|
| 287 | 303 | |
|---|
| 288 | 304 | /* TX Frame control */ |
|---|
| 289 | | - |
|---|
| 290 | 305 | #define TXFR_TXIC (1 << 15) |
|---|
| 291 | 306 | #define TXFR_TXFID_MASK (0x3f << 0) |
|---|
| 292 | 307 | #define TXFR_TXFID_SHIFT (0) |
|---|
| 293 | 308 | |
|---|
| 294 | | -/* SPI frame opcodes */ |
|---|
| 295 | | -#define KS_SPIOP_RD (0x00) |
|---|
| 296 | | -#define KS_SPIOP_WR (0x40) |
|---|
| 297 | | -#define KS_SPIOP_RXFIFO (0x80) |
|---|
| 298 | | -#define KS_SPIOP_TXFIFO (0xC0) |
|---|
| 309 | +/** |
|---|
| 310 | + * struct ks8851_rxctrl - KS8851 driver rx control |
|---|
| 311 | + * @mchash: Multicast hash-table data. |
|---|
| 312 | + * @rxcr1: KS_RXCR1 register setting |
|---|
| 313 | + * @rxcr2: KS_RXCR2 register setting |
|---|
| 314 | + * |
|---|
| 315 | + * Representation of the settings needs to control the receive filtering |
|---|
| 316 | + * such as the multicast hash-filter and the receive register settings. This |
|---|
| 317 | + * is used to make the job of working out if the receive settings change and |
|---|
| 318 | + * then issuing the new settings to the worker that will send the necessary |
|---|
| 319 | + * commands. |
|---|
| 320 | + */ |
|---|
| 321 | +struct ks8851_rxctrl { |
|---|
| 322 | + u16 mchash[4]; |
|---|
| 323 | + u16 rxcr1; |
|---|
| 324 | + u16 rxcr2; |
|---|
| 325 | +}; |
|---|
| 326 | + |
|---|
| 327 | +/** |
|---|
| 328 | + * union ks8851_tx_hdr - tx header data |
|---|
| 329 | + * @txb: The header as bytes |
|---|
| 330 | + * @txw: The header as 16bit, little-endian words |
|---|
| 331 | + * |
|---|
| 332 | + * A dual representation of the tx header data to allow |
|---|
| 333 | + * access to individual bytes, and to allow 16bit accesses |
|---|
| 334 | + * with 16bit alignment. |
|---|
| 335 | + */ |
|---|
| 336 | +union ks8851_tx_hdr { |
|---|
| 337 | + u8 txb[6]; |
|---|
| 338 | + __le16 txw[3]; |
|---|
| 339 | +}; |
|---|
| 340 | + |
|---|
| 341 | +/** |
|---|
| 342 | + * struct ks8851_net - KS8851 driver private data |
|---|
| 343 | + * @netdev: The network device we're bound to |
|---|
| 344 | + * @statelock: Lock on this structure for tx list. |
|---|
| 345 | + * @mii: The MII state information for the mii calls. |
|---|
| 346 | + * @rxctrl: RX settings for @rxctrl_work. |
|---|
| 347 | + * @rxctrl_work: Work queue for updating RX mode and multicast lists |
|---|
| 348 | + * @txq: Queue of packets for transmission. |
|---|
| 349 | + * @txh: Space for generating packet TX header in DMA-able data |
|---|
| 350 | + * @rxd: Space for receiving SPI data, in DMA-able space. |
|---|
| 351 | + * @txd: Space for transmitting SPI data, in DMA-able space. |
|---|
| 352 | + * @msg_enable: The message flags controlling driver output (see ethtool). |
|---|
| 353 | + * @fid: Incrementing frame id tag. |
|---|
| 354 | + * @rc_ier: Cached copy of KS_IER. |
|---|
| 355 | + * @rc_ccr: Cached copy of KS_CCR. |
|---|
| 356 | + * @rc_rxqcr: Cached copy of KS_RXQCR. |
|---|
| 357 | + * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM. |
|---|
| 358 | + * @vdd_reg: Optional regulator supplying the chip |
|---|
| 359 | + * @vdd_io: Optional digital power supply for IO |
|---|
| 360 | + * @gpio: Optional reset_n gpio |
|---|
| 361 | + * @lock: Bus access lock callback |
|---|
| 362 | + * @unlock: Bus access unlock callback |
|---|
| 363 | + * @rdreg16: 16bit register read callback |
|---|
| 364 | + * @wrreg16: 16bit register write callback |
|---|
| 365 | + * @rdfifo: FIFO read callback |
|---|
| 366 | + * @wrfifo: FIFO write callback |
|---|
| 367 | + * @start_xmit: start_xmit() implementation callback |
|---|
| 368 | + * @rx_skb: rx_skb() implementation callback |
|---|
| 369 | + * @flush_tx_work: flush_tx_work() implementation callback |
|---|
| 370 | + * |
|---|
| 371 | + * The @statelock is used to protect information in the structure which may |
|---|
| 372 | + * need to be accessed via several sources, such as the network driver layer |
|---|
| 373 | + * or one of the work queues. |
|---|
| 374 | + * |
|---|
| 375 | + * We align the buffers we may use for rx/tx to ensure that if the SPI driver |
|---|
| 376 | + * wants to DMA map them, it will not have any problems with data the driver |
|---|
| 377 | + * modifies. |
|---|
| 378 | + */ |
|---|
| 379 | +struct ks8851_net { |
|---|
| 380 | + struct net_device *netdev; |
|---|
| 381 | + spinlock_t statelock; |
|---|
| 382 | + |
|---|
| 383 | + union ks8851_tx_hdr txh ____cacheline_aligned; |
|---|
| 384 | + u8 rxd[8]; |
|---|
| 385 | + u8 txd[8]; |
|---|
| 386 | + |
|---|
| 387 | + u32 msg_enable ____cacheline_aligned; |
|---|
| 388 | + u16 tx_space; |
|---|
| 389 | + u8 fid; |
|---|
| 390 | + |
|---|
| 391 | + u16 rc_ier; |
|---|
| 392 | + u16 rc_rxqcr; |
|---|
| 393 | + u16 rc_ccr; |
|---|
| 394 | + |
|---|
| 395 | + struct mii_if_info mii; |
|---|
| 396 | + struct ks8851_rxctrl rxctrl; |
|---|
| 397 | + |
|---|
| 398 | + struct work_struct rxctrl_work; |
|---|
| 399 | + |
|---|
| 400 | + struct sk_buff_head txq; |
|---|
| 401 | + |
|---|
| 402 | + struct eeprom_93cx6 eeprom; |
|---|
| 403 | + struct regulator *vdd_reg; |
|---|
| 404 | + struct regulator *vdd_io; |
|---|
| 405 | + int gpio; |
|---|
| 406 | + |
|---|
| 407 | + void (*lock)(struct ks8851_net *ks, |
|---|
| 408 | + unsigned long *flags); |
|---|
| 409 | + void (*unlock)(struct ks8851_net *ks, |
|---|
| 410 | + unsigned long *flags); |
|---|
| 411 | + unsigned int (*rdreg16)(struct ks8851_net *ks, |
|---|
| 412 | + unsigned int reg); |
|---|
| 413 | + void (*wrreg16)(struct ks8851_net *ks, |
|---|
| 414 | + unsigned int reg, unsigned int val); |
|---|
| 415 | + void (*rdfifo)(struct ks8851_net *ks, u8 *buff, |
|---|
| 416 | + unsigned int len); |
|---|
| 417 | + void (*wrfifo)(struct ks8851_net *ks, |
|---|
| 418 | + struct sk_buff *txp, bool irq); |
|---|
| 419 | + netdev_tx_t (*start_xmit)(struct sk_buff *skb, |
|---|
| 420 | + struct net_device *dev); |
|---|
| 421 | + void (*rx_skb)(struct ks8851_net *ks, |
|---|
| 422 | + struct sk_buff *skb); |
|---|
| 423 | + void (*flush_tx_work)(struct ks8851_net *ks); |
|---|
| 424 | +}; |
|---|
| 425 | + |
|---|
| 426 | +int ks8851_probe_common(struct net_device *netdev, struct device *dev, |
|---|
| 427 | + int msg_en); |
|---|
| 428 | +int ks8851_remove_common(struct device *dev); |
|---|
| 429 | +int ks8851_suspend(struct device *dev); |
|---|
| 430 | +int ks8851_resume(struct device *dev); |
|---|
| 431 | + |
|---|
| 432 | +static __maybe_unused SIMPLE_DEV_PM_OPS(ks8851_pm_ops, |
|---|
| 433 | + ks8851_suspend, ks8851_resume); |
|---|
| 434 | + |
|---|
| 435 | +/** |
|---|
| 436 | + * ks8851_done_tx - update and then free skbuff after transmitting |
|---|
| 437 | + * @ks: The device state |
|---|
| 438 | + * @txb: The buffer transmitted |
|---|
| 439 | + */ |
|---|
| 440 | +static void __maybe_unused ks8851_done_tx(struct ks8851_net *ks, |
|---|
| 441 | + struct sk_buff *txb) |
|---|
| 442 | +{ |
|---|
| 443 | + struct net_device *dev = ks->netdev; |
|---|
| 444 | + |
|---|
| 445 | + dev->stats.tx_bytes += txb->len; |
|---|
| 446 | + dev->stats.tx_packets++; |
|---|
| 447 | + |
|---|
| 448 | + dev_kfree_skb(txb); |
|---|
| 449 | +} |
|---|
| 450 | + |
|---|
| 451 | +#endif /* __KS8851_H__ */ |
|---|