3 * eInfochips Ltd. <www.einfochips.com>
4 * Written-by: Ajay Bhargav <contact@8051projects.net>
7 * Marvell Semiconductor <www.marvell.com>
8 * Contributor: Mahavir Jain <mjain@marvell.com>
10 * SPDX-License-Identifier: GPL-2.0+
18 #include <asm/types.h>
19 #include <asm/byteorder.h>
20 #include <linux/err.h>
21 #include <linux/mii.h>
23 #include <asm/arch/armada100.h>
24 #include "armada100_fec.h"
26 #define PHY_ADR_REQ 0xFF /* Magic number to read/write PHY address */
29 static int eth_dump_regs(struct eth_device
*dev
)
31 struct armdfec_device
*darmdfec
= to_darmdfec(dev
);
32 struct armdfec_reg
*regs
= darmdfec
->regs
;
35 printf("\noffset: phy_adr, value: 0x%x\n", readl(®s
->phyadr
));
36 printf("offset: smi, value: 0x%x\n", readl(®s
->smi
));
37 for (i
= 0x400; i
<= 0x4e4; i
+= 4)
38 printf("offset: 0x%x, value: 0x%x\n",
39 i
, readl(ARMD1_FEC_BASE
+ i
));
44 static int armdfec_phy_timeout(u32
*reg
, u32 flag
, int cond
)
46 u32 timeout
= PHY_WAIT_ITERATIONS
;
51 if (cond
&& (reg_val
& flag
))
53 else if (!cond
&& !(reg_val
& flag
))
55 udelay(PHY_WAIT_MICRO_SECONDS
);
60 static int smi_reg_read(struct mii_dev
*bus
, int phy_addr
, int devad
,
64 struct eth_device
*dev
= eth_get_dev_by_name(bus
->name
);
65 struct armdfec_device
*darmdfec
= to_darmdfec(dev
);
66 struct armdfec_reg
*regs
= darmdfec
->regs
;
69 if (phy_addr
== PHY_ADR_REQ
&& phy_reg
== PHY_ADR_REQ
) {
70 val
= readl(®s
->phyadr
);
75 /* check parameters */
76 if (phy_addr
> PHY_MASK
) {
77 printf("ARMD100 FEC: (%s) Invalid phy address: 0x%X\n",
81 if (phy_reg
> PHY_MASK
) {
82 printf("ARMD100 FEC: (%s) Invalid register offset: 0x%X\n",
87 /* wait for the SMI register to become available */
88 if (armdfec_phy_timeout(®s
->smi
, SMI_BUSY
, false)) {
89 printf("ARMD100 FEC: (%s) PHY busy timeout\n", __func__
);
93 writel((phy_addr
<< 16) | (phy_reg
<< 21) | SMI_OP_R
, ®s
->smi
);
95 /* now wait for the data to be valid */
96 if (armdfec_phy_timeout(®s
->smi
, SMI_R_VALID
, true)) {
97 val
= readl(®s
->smi
);
98 printf("ARMD100 FEC: (%s) PHY Read timeout, val=0x%x\n",
102 val
= readl(®s
->smi
);
103 value
= val
& 0xffff;
108 static int smi_reg_write(struct mii_dev
*bus
, int phy_addr
, int devad
,
109 int phy_reg
, u16 value
)
111 struct eth_device
*dev
= eth_get_dev_by_name(bus
->name
);
112 struct armdfec_device
*darmdfec
= to_darmdfec(dev
);
113 struct armdfec_reg
*regs
= darmdfec
->regs
;
115 if (phy_addr
== PHY_ADR_REQ
&& phy_reg
== PHY_ADR_REQ
) {
116 clrsetbits_le32(®s
->phyadr
, 0x1f, value
& 0x1f);
120 /* check parameters */
121 if (phy_addr
> PHY_MASK
) {
122 printf("ARMD100 FEC: (%s) Invalid phy address\n", __func__
);
125 if (phy_reg
> PHY_MASK
) {
126 printf("ARMD100 FEC: (%s) Invalid register offset\n", __func__
);
130 /* wait for the SMI register to become available */
131 if (armdfec_phy_timeout(®s
->smi
, SMI_BUSY
, false)) {
132 printf("ARMD100 FEC: (%s) PHY busy timeout\n", __func__
);
136 writel((phy_addr
<< 16) | (phy_reg
<< 21) | SMI_OP_W
| (value
& 0xffff),
142 * Abort any transmit and receive operations and put DMA
143 * in idle state. AT and AR bits are cleared upon entering
144 * in IDLE state. So poll those bits to verify operation.
146 static void abortdma(struct eth_device
*dev
)
148 struct armdfec_device
*darmdfec
= to_darmdfec(dev
);
149 struct armdfec_reg
*regs
= darmdfec
->regs
;
154 while (--maxretries
) {
155 writel(SDMA_CMD_AR
| SDMA_CMD_AT
, ®s
->sdma_cmd
);
160 tmp
= readl(®s
->sdma_cmd
);
161 if (!(tmp
& (SDMA_CMD_AR
| SDMA_CMD_AT
)))
170 printf("ARMD100 FEC: (%s) DMA Stuck\n", __func__
);
173 static inline u32
nibble_swapping_32_bit(u32 x
)
175 return ((x
& 0xf0f0f0f0) >> 4) | ((x
& 0x0f0f0f0f) << 4);
178 static inline u32
nibble_swapping_16_bit(u32 x
)
180 return ((x
& 0x0000f0f0) >> 4) | ((x
& 0x00000f0f) << 4);
183 static inline u32
flip_4_bits(u32 x
)
185 return ((x
& 0x01) << 3) | ((x
& 0x002) << 1)
186 | ((x
& 0x04) >> 1) | ((x
& 0x008) >> 3);
190 * This function will calculate the hash function of the address.
191 * depends on the hash mode and hash size.
193 * mach - the 2 most significant bytes of the MAC address.
194 * macl - the 4 least significant bytes of the MAC address.
196 * return the calculated entry.
198 static u32
hash_function(u32 mach
, u32 macl
)
210 addrh
= nibble_swapping_16_bit(mach
);
211 addrl
= nibble_swapping_32_bit(macl
);
213 addrhswapped
= flip_4_bits(addrh
& 0xf)
214 + ((flip_4_bits((addrh
>> 4) & 0xf)) << 4)
215 + ((flip_4_bits((addrh
>> 8) & 0xf)) << 8)
216 + ((flip_4_bits((addrh
>> 12) & 0xf)) << 12);
218 addrlswapped
= flip_4_bits(addrl
& 0xf)
219 + ((flip_4_bits((addrl
>> 4) & 0xf)) << 4)
220 + ((flip_4_bits((addrl
>> 8) & 0xf)) << 8)
221 + ((flip_4_bits((addrl
>> 12) & 0xf)) << 12)
222 + ((flip_4_bits((addrl
>> 16) & 0xf)) << 16)
223 + ((flip_4_bits((addrl
>> 20) & 0xf)) << 20)
224 + ((flip_4_bits((addrl
>> 24) & 0xf)) << 24)
225 + ((flip_4_bits((addrl
>> 28) & 0xf)) << 28);
227 addrh
= addrhswapped
;
228 addrl
= addrlswapped
;
230 addr0
= (addrl
>> 2) & 0x03f;
231 addr1
= (addrl
& 0x003) | (((addrl
>> 8) & 0x7f) << 2);
232 addr2
= (addrl
>> 15) & 0x1ff;
233 addr3
= ((addrl
>> 24) & 0x0ff) | ((addrh
& 1) << 8);
235 hashresult
= (addr0
<< 9) | (addr1
^ addr2
^ addr3
);
236 hashresult
= hashresult
& 0x07ff;
241 * This function will add an entry to the address table.
242 * depends on the hash mode and hash size that was initialized.
244 * mach - the 2 most significant bytes of the MAC address.
245 * macl - the 4 least significant bytes of the MAC address.
246 * skip - if 1, skip this address.
247 * rd - the RD field in the address table.
249 * address table entry is added.
251 * -ENOSPC if table full
253 static int add_del_hash_entry(struct armdfec_device
*darmdfec
, u32 mach
,
254 u32 macl
, u32 rd
, u32 skip
, int del
)
256 struct addr_table_entry_t
*entry
, *start
;
261 newlo
= (((mach
>> 4) & 0xf) << 15)
262 | (((mach
>> 0) & 0xf) << 11)
263 | (((mach
>> 12) & 0xf) << 7)
264 | (((mach
>> 8) & 0xf) << 3)
265 | (((macl
>> 20) & 0x1) << 31)
266 | (((macl
>> 16) & 0xf) << 27)
267 | (((macl
>> 28) & 0xf) << 23)
268 | (((macl
>> 24) & 0xf) << 19)
269 | (skip
<< HTESKIP
) | (rd
<< HTERDBIT
)
272 newhi
= (((macl
>> 4) & 0xf) << 15)
273 | (((macl
>> 0) & 0xf) << 11)
274 | (((macl
>> 12) & 0xf) << 7)
275 | (((macl
>> 8) & 0xf) << 3)
276 | (((macl
>> 21) & 0x7) << 0);
279 * Pick the appropriate table, start scanning for free/reusable
280 * entries at the index obtained by hashing the specified MAC address
282 start
= (struct addr_table_entry_t
*)(darmdfec
->htpr
);
283 entry
= start
+ hash_function(mach
, macl
);
284 for (i
= 0; i
< HOP_NUMBER
; i
++) {
285 if (!(entry
->lo
& HTEVALID
)) {
288 /* if same address put in same position */
289 if (((entry
->lo
& 0xfffffff8) == (newlo
& 0xfffffff8))
290 && (entry
->hi
== newhi
))
293 if (entry
== start
+ 0x7ff)
299 if (((entry
->lo
& 0xfffffff8) != (newlo
& 0xfffffff8)) &&
300 (entry
->hi
!= newhi
) && del
)
303 if (i
== HOP_NUMBER
) {
305 printf("ARMD100 FEC: (%s) table section is full\n",
314 * Update the selected entry
328 * Create an addressTable entry from MAC address info
329 * found in the specifed net_device struct
331 * Input : pointer to ethernet interface network device structure
334 static void update_hash_table_mac_address(struct armdfec_device
*darmdfec
,
340 /* Delete old entry */
342 mach
= (oaddr
[0] << 8) | oaddr
[1];
343 macl
= (oaddr
[2] << 24) | (oaddr
[3] << 16) |
344 (oaddr
[4] << 8) | oaddr
[5];
345 add_del_hash_entry(darmdfec
, mach
, macl
, 1, 0, HASH_DELETE
);
349 mach
= (addr
[0] << 8) | addr
[1];
350 macl
= (addr
[2] << 24) | (addr
[3] << 16) | (addr
[4] << 8) | addr
[5];
351 add_del_hash_entry(darmdfec
, mach
, macl
, 1, 0, HASH_ADD
);
354 /* Address Table Initialization */
355 static void init_hashtable(struct eth_device
*dev
)
357 struct armdfec_device
*darmdfec
= to_darmdfec(dev
);
358 struct armdfec_reg
*regs
= darmdfec
->regs
;
359 memset(darmdfec
->htpr
, 0, HASH_ADDR_TABLE_SIZE
);
360 writel((u32
)darmdfec
->htpr
, ®s
->htpr
);
364 * This detects PHY chip from address 0-31 by reading PHY status
365 * registers. PHY chip can be connected at any of this address.
367 static int ethernet_phy_detect(struct eth_device
*dev
)
373 for (addr
= 0; addr
< 32; addr
++) {
374 if (miiphy_read(dev
->name
, addr
, MII_BMSR
, &mii_status
) != 0)
378 /* invalid MII status. More validation required here... */
379 if (mii_status
== 0 || mii_status
== 0xffff)
383 if (miiphy_read(dev
->name
, addr
, MII_PHYSID1
, &tmp
) != 0)
388 if (miiphy_read(dev
->name
, addr
, MII_PHYSID2
, &tmp
) != 0)
394 if ((val
& 0xfffffff0) != 0)
400 static void armdfec_init_rx_desc_ring(struct armdfec_device
*darmdfec
)
402 struct rx_desc
*p_rx_desc
;
405 /* initialize the Rx descriptors ring */
406 p_rx_desc
= darmdfec
->p_rxdesc
;
407 for (i
= 0; i
< RINGSZ
; i
++) {
408 p_rx_desc
->cmd_sts
= BUF_OWNED_BY_DMA
| RX_EN_INT
;
409 p_rx_desc
->buf_size
= PKTSIZE_ALIGN
;
410 p_rx_desc
->byte_cnt
= 0;
411 p_rx_desc
->buf_ptr
= darmdfec
->p_rxbuf
+ i
* PKTSIZE_ALIGN
;
412 if (i
== (RINGSZ
- 1)) {
413 p_rx_desc
->nxtdesc_p
= darmdfec
->p_rxdesc
;
415 p_rx_desc
->nxtdesc_p
= (struct rx_desc
*)
416 ((u32
)p_rx_desc
+ ARMDFEC_RXQ_DESC_ALIGNED_SIZE
);
417 p_rx_desc
= p_rx_desc
->nxtdesc_p
;
420 darmdfec
->p_rxdesc_curr
= darmdfec
->p_rxdesc
;
423 static int armdfec_init(struct eth_device
*dev
, bd_t
*bd
)
425 struct armdfec_device
*darmdfec
= to_darmdfec(dev
);
426 struct armdfec_reg
*regs
= darmdfec
->regs
;
430 armdfec_init_rx_desc_ring(darmdfec
);
432 /* Disable interrupts */
433 writel(0, ®s
->im
);
434 writel(0, ®s
->ic
);
435 /* Write to ICR to clear interrupts. */
436 writel(0, ®s
->iwc
);
439 * Abort any transmit and receive operations and put DMA
444 /* Initialize address hash table */
447 /* SDMA configuration */
448 writel(SDCR_BSZ8
| /* Burst size = 32 bytes */
449 SDCR_RIFB
| /* Rx interrupt on frame */
450 SDCR_BLMT
| /* Little endian transmit */
451 SDCR_BLMR
| /* Little endian receive */
452 SDCR_RC_MAX_RETRANS
, /* Max retransmit count */
454 /* Port Configuration */
455 writel(PCR_HS
, ®s
->pconf
); /* Hash size is 1/2kb */
457 /* Set extended port configuration */
458 writel(PCXR_2BSM
| /* Two byte suffix aligns IP hdr */
459 PCXR_DSCP_EN
| /* Enable DSCP in IP */
460 PCXR_MFL_1536
| /* Set MTU = 1536 */
461 PCXR_FLP
| /* do not force link pass */
462 PCXR_TX_HIGH_PRI
, /* Transmit - high priority queue */
465 update_hash_table_mac_address(darmdfec
, NULL
, dev
->enetaddr
);
467 /* Update TX and RX queue descriptor register */
468 temp
= (u32
)®s
->txcdp
[TXQ
];
469 writel((u32
)darmdfec
->p_txdesc
, temp
);
470 temp
= (u32
)®s
->rxfdp
[RXQ
];
471 writel((u32
)darmdfec
->p_rxdesc
, temp
);
472 temp
= (u32
)®s
->rxcdp
[RXQ
];
473 writel((u32
)darmdfec
->p_rxdesc_curr
, temp
);
475 /* Enable Interrupts */
476 writel(ALL_INTS
, ®s
->im
);
478 /* Enable Ethernet Port */
479 setbits_le32(®s
->pconf
, PCR_EN
);
481 /* Enable RX DMA engine */
482 setbits_le32(®s
->sdma_cmd
, SDMA_CMD_ERD
);
488 #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
490 #if defined(CONFIG_PHY_BASE_ADR)
491 miiphy_write(dev
->name
, PHY_ADR_REQ
, PHY_ADR_REQ
, CONFIG_PHY_BASE_ADR
);
493 /* Search phy address from range 0-31 */
494 phy_adr
= ethernet_phy_detect(dev
);
496 printf("ARMD100 FEC: PHY not detected at address range 0-31\n");
499 debug("ARMD100 FEC: PHY detected at addr %d\n", phy_adr
);
500 miiphy_write(dev
->name
, PHY_ADR_REQ
, PHY_ADR_REQ
, phy_adr
);
504 #if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
505 /* Wait up to 5s for the link status */
506 for (i
= 0; i
< 5; i
++) {
509 miiphy_read(dev
->name
, 0xFF, 0xFF, &phy_adr
);
510 /* Return if we get link up */
511 if (miiphy_link(dev
->name
, phy_adr
))
516 printf("ARMD100 FEC: No link on %s\n", dev
->name
);
523 static void armdfec_halt(struct eth_device
*dev
)
525 struct armdfec_device
*darmdfec
= to_darmdfec(dev
);
526 struct armdfec_reg
*regs
= darmdfec
->regs
;
529 clrbits_le32(®s
->sdma_cmd
, SDMA_CMD_ERD
);
532 * Abort any transmit and receive operations and put DMA
537 /* Disable interrupts */
538 writel(0, ®s
->im
);
539 writel(0, ®s
->ic
);
540 writel(0, ®s
->iwc
);
543 clrbits_le32(®s
->pconf
, PCR_EN
);
546 static int armdfec_send(struct eth_device
*dev
, void *dataptr
, int datasize
)
548 struct armdfec_device
*darmdfec
= to_darmdfec(dev
);
549 struct armdfec_reg
*regs
= darmdfec
->regs
;
550 struct tx_desc
*p_txdesc
= darmdfec
->p_txdesc
;
551 void *p
= (void *)dataptr
;
552 int retry
= PHY_WAIT_ITERATIONS
* PHY_WAIT_MICRO_SECONDS
;
555 /* Copy buffer if it's misaligned */
556 if ((u32
)dataptr
& 0x07) {
557 if (datasize
> PKTSIZE_ALIGN
) {
558 printf("ARMD100 FEC: Non-aligned data too large (%d)\n",
562 memcpy(darmdfec
->p_aligned_txbuf
, p
, datasize
);
563 p
= darmdfec
->p_aligned_txbuf
;
566 p_txdesc
->cmd_sts
= TX_ZERO_PADDING
| TX_GEN_CRC
;
567 p_txdesc
->cmd_sts
|= TX_FIRST_DESC
| TX_LAST_DESC
;
568 p_txdesc
->cmd_sts
|= BUF_OWNED_BY_DMA
;
569 p_txdesc
->cmd_sts
|= TX_EN_INT
;
570 p_txdesc
->buf_ptr
= p
;
571 p_txdesc
->byte_cnt
= datasize
;
573 /* Apply send command using high priority TX queue */
574 temp
= (u32
)®s
->txcdp
[TXQ
];
575 writel((u32
)p_txdesc
, temp
);
576 writel(SDMA_CMD_TXDL
| SDMA_CMD_TXDH
| SDMA_CMD_ERD
, ®s
->sdma_cmd
);
579 * wait for packet xmit completion
581 cmd_sts
= readl(&p_txdesc
->cmd_sts
);
582 while (cmd_sts
& BUF_OWNED_BY_DMA
) {
583 /* return fail if error is detected */
584 if ((cmd_sts
& (TX_ERROR
| TX_LAST_DESC
)) ==
585 (TX_ERROR
| TX_LAST_DESC
)) {
586 printf("ARMD100 FEC: (%s) in xmit packet\n", __func__
);
589 cmd_sts
= readl(&p_txdesc
->cmd_sts
);
591 printf("ARMD100 FEC: (%s) xmit packet timeout!\n",
600 static int armdfec_recv(struct eth_device
*dev
)
602 struct armdfec_device
*darmdfec
= to_darmdfec(dev
);
603 struct rx_desc
*p_rxdesc_curr
= darmdfec
->p_rxdesc_curr
;
608 /* wait untill rx packet available or timeout */
610 if (timeout
< PHY_WAIT_ITERATIONS
* PHY_WAIT_MICRO_SECONDS
) {
613 debug("ARMD100 FEC: %s time out...\n", __func__
);
616 } while (readl(&p_rxdesc_curr
->cmd_sts
) & BUF_OWNED_BY_DMA
);
618 if (p_rxdesc_curr
->byte_cnt
!= 0) {
619 debug("ARMD100 FEC: %s: Received %d byte Packet @ 0x%x"
620 "(cmd_sts= %08x)\n", __func__
,
621 (u32
)p_rxdesc_curr
->byte_cnt
,
622 (u32
)p_rxdesc_curr
->buf_ptr
,
623 (u32
)p_rxdesc_curr
->cmd_sts
);
627 * In case received a packet without first/last bits on
628 * OR the error summary bit is on,
629 * the packets needs to be dropeed.
631 cmd_sts
= readl(&p_rxdesc_curr
->cmd_sts
);
633 if ((cmd_sts
& (RX_FIRST_DESC
| RX_LAST_DESC
)) !=
634 (RX_FIRST_DESC
| RX_LAST_DESC
)) {
635 printf("ARMD100 FEC: (%s) Dropping packet spread on"
636 " multiple descriptors\n", __func__
);
637 } else if (cmd_sts
& RX_ERROR
) {
638 printf("ARMD100 FEC: (%s) Dropping packet with errors\n",
641 /* !!! call higher layer processing */
642 debug("ARMD100 FEC: (%s) Sending Received packet to"
643 " upper layer (net_process_received_packet)\n", __func__
);
646 * let the upper layer handle the packet, subtract offset
647 * as two dummy bytes are added in received buffer see
648 * PORT_CONFIG_EXT register bit TWO_Byte_Stuff_Mode bit.
650 net_process_received_packet(
651 p_rxdesc_curr
->buf_ptr
+ RX_BUF_OFFSET
,
652 (int)(p_rxdesc_curr
->byte_cnt
- RX_BUF_OFFSET
));
655 * free these descriptors and point next in the ring
657 p_rxdesc_curr
->cmd_sts
= BUF_OWNED_BY_DMA
| RX_EN_INT
;
658 p_rxdesc_curr
->buf_size
= PKTSIZE_ALIGN
;
659 p_rxdesc_curr
->byte_cnt
= 0;
661 temp
= (u32
)&darmdfec
->p_rxdesc_curr
;
662 writel((u32
)p_rxdesc_curr
->nxtdesc_p
, temp
);
667 int armada100_fec_register(unsigned long base_addr
)
669 struct armdfec_device
*darmdfec
;
670 struct eth_device
*dev
;
672 darmdfec
= malloc(sizeof(struct armdfec_device
));
676 memset(darmdfec
, 0, sizeof(struct armdfec_device
));
678 darmdfec
->htpr
= memalign(8, HASH_ADDR_TABLE_SIZE
);
682 darmdfec
->p_rxdesc
= memalign(PKTALIGN
,
683 ARMDFEC_RXQ_DESC_ALIGNED_SIZE
* RINGSZ
+ 1);
685 if (!darmdfec
->p_rxdesc
)
688 darmdfec
->p_rxbuf
= memalign(PKTALIGN
, RINGSZ
* PKTSIZE_ALIGN
+ 1);
689 if (!darmdfec
->p_rxbuf
)
692 darmdfec
->p_aligned_txbuf
= memalign(8, PKTSIZE_ALIGN
);
693 if (!darmdfec
->p_aligned_txbuf
)
696 darmdfec
->p_txdesc
= memalign(PKTALIGN
, sizeof(struct tx_desc
) + 1);
697 if (!darmdfec
->p_txdesc
)
700 dev
= &darmdfec
->dev
;
701 /* Assign ARMADA100 Fast Ethernet Controller Base Address */
702 darmdfec
->regs
= (void *)base_addr
;
704 /* must be less than sizeof(dev->name) */
705 strcpy(dev
->name
, "armd-fec0");
707 dev
->init
= armdfec_init
;
708 dev
->halt
= armdfec_halt
;
709 dev
->send
= armdfec_send
;
710 dev
->recv
= armdfec_recv
;
714 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
716 struct mii_dev
*mdiodev
= mdio_alloc();
719 strncpy(mdiodev
->name
, dev
->name
, MDIO_NAME_LEN
);
720 mdiodev
->read
= smi_reg_read
;
721 mdiodev
->write
= smi_reg_write
;
723 retval
= mdio_register(mdiodev
);
730 free(darmdfec
->p_aligned_txbuf
);
731 free(darmdfec
->p_rxbuf
);
732 free(darmdfec
->p_rxdesc
);
733 free(darmdfec
->htpr
);
736 printf("AMD100 FEC: (%s) Failed to allocate memory\n", __func__
);