Lines Matching +full:eth +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * meth.c -- O2 Builtin 10/100 Ethernet driver
5 * Copyright (C) 2001-2003 Ilya Volynets
8 #include <linux/dma-mapping.h>
57 * Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
69 /* in-memory copy of MAC Control register */
72 /* in-memory copy of DMA Control register */
74 /* address of PHY, used by mdio_* functions, initialized in mdio_probe */
96 /* global, initialized in ip32-setup.c */
104 DPRINTK("Loading MAC Address: %pM\n", dev->dev_addr); in load_eaddr()
107 macaddr |= (u64)dev->dev_addr[i] << ((5 - i) * 8); in load_eaddr()
109 mace->eth.mac_addr = macaddr; in load_eaddr()
116 while ((___rval = mace->eth.phy_data) & MDIO_BUSY) { \
119 /*read phy register, return value read */
124 mace->eth.phy_regs = (priv->phy_addr << 5) | (phyreg & 0x1f); in mdio_read()
126 mace->eth.phy_trans_go = 1; in mdio_read()
136 /* check if phy is detected already */ in mdio_probe()
137 if(priv->phy_addr>=0&&priv->phy_addr<32) in mdio_probe()
139 spin_lock_irqsave(&priv->meth_lock, flags); in mdio_probe()
141 priv->phy_addr=i; in mdio_probe()
147 DPRINTK("PHY is QS6612X\n"); in mdio_probe()
150 DPRINTK("PHY is ICS1889\n"); in mdio_probe()
153 DPRINTK("PHY is ICS1890\n"); in mdio_probe()
156 DPRINTK("PHY is DP83840\n"); in mdio_probe()
161 DPRINTK("PHY code: %x\n",(p2<<12)|(p3>>4)); in mdio_probe()
165 spin_unlock_irqrestore(&priv->meth_lock, flags); in mdio_probe()
166 if(priv->phy_addr<32) { in mdio_probe()
169 DPRINTK("Oopsie! PHY is not known!\n"); in mdio_probe()
170 priv->phy_addr=-1; in mdio_probe()
171 return -ENODEV; in mdio_probe()
189 if ((priv->mac_ctrl & METH_PHY_FDX) ^ duplex) { in meth_check_link()
190 DPRINTK("Setting %s-duplex\n", duplex ? "full" : "half"); in meth_check_link()
192 priv->mac_ctrl |= METH_PHY_FDX; in meth_check_link()
194 priv->mac_ctrl &= ~METH_PHY_FDX; in meth_check_link()
195 mace->eth.mac_ctrl = priv->mac_ctrl; in meth_check_link()
198 if ((priv->mac_ctrl & METH_100MBIT) ^ speed) { in meth_check_link()
201 priv->mac_ctrl |= METH_100MBIT; in meth_check_link()
203 priv->mac_ctrl &= ~METH_100MBIT; in meth_check_link()
204 mace->eth.mac_ctrl = priv->mac_ctrl; in meth_check_link()
212 priv->tx_ring = dma_alloc_coherent(&priv->pdev->dev, in meth_init_tx_ring()
213 TX_RING_BUFFER_SIZE, &priv->tx_ring_dma, GFP_ATOMIC); in meth_init_tx_ring()
214 if (!priv->tx_ring) in meth_init_tx_ring()
215 return -ENOMEM; in meth_init_tx_ring()
217 priv->tx_count = priv->tx_read = priv->tx_write = 0; in meth_init_tx_ring()
218 mace->eth.tx_ring_base = priv->tx_ring_dma; in meth_init_tx_ring()
220 memset(priv->tx_skbs, 0, sizeof(priv->tx_skbs)); in meth_init_tx_ring()
221 memset(priv->tx_skb_dmas, 0, sizeof(priv->tx_skb_dmas)); in meth_init_tx_ring()
230 priv->rx_skbs[i] = alloc_skb(METH_RX_BUFF_SIZE, 0); in meth_init_rx_ring()
233 skb_reserve(priv->rx_skbs[i],METH_RX_HEAD); in meth_init_rx_ring()
234 priv->rx_ring[i]=(rx_packet*)(priv->rx_skbs[i]->head); in meth_init_rx_ring()
235 /* I'll need to re-sync it after each RX */ in meth_init_rx_ring()
236 priv->rx_ring_dmas[i] = in meth_init_rx_ring()
237 dma_map_single(&priv->pdev->dev, priv->rx_ring[i], in meth_init_rx_ring()
239 mace->eth.rx_fifo = priv->rx_ring_dmas[i]; in meth_init_rx_ring()
241 priv->rx_write = 0; in meth_init_rx_ring()
250 dev_kfree_skb(priv->tx_skbs[i]); in meth_free_tx_ring()
251 priv->tx_skbs[i] = NULL; in meth_free_tx_ring()
253 dma_free_coherent(&priv->pdev->dev, TX_RING_BUFFER_SIZE, priv->tx_ring, in meth_free_tx_ring()
254 priv->tx_ring_dma); in meth_free_tx_ring()
263 dma_unmap_single(&priv->pdev->dev, priv->rx_ring_dmas[i], in meth_free_rx_ring()
265 priv->rx_ring[i] = 0; in meth_free_rx_ring()
266 priv->rx_ring_dmas[i] = 0; in meth_free_rx_ring()
267 kfree_skb(priv->rx_skbs[i]); in meth_free_rx_ring()
276 mace->eth.mac_ctrl = SGI_MAC_RESET; in meth_reset()
278 mace->eth.mac_ctrl = 0; in meth_reset()
287 DPRINTK("Unable to find PHY\n"); in meth_reset()
288 return -ENODEV; in meth_reset()
291 /* Initial mode: 10 | Half-duplex | Accept normal packets */ in meth_reset()
292 priv->mac_ctrl = METH_ACCEPT_MCAST | METH_DEFAULT_IPG; in meth_reset()
293 if (dev->flags & IFF_PROMISC) in meth_reset()
294 priv->mac_ctrl |= METH_PROMISC; in meth_reset()
295 mace->eth.mac_ctrl = priv->mac_ctrl; in meth_reset()
301 priv->dma_ctrl = (4 << METH_RX_OFFSET_SHIFT) | in meth_reset()
303 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_reset()
318 priv->phy_addr = -1; /* No PHY is known yet... */ in meth_open()
333 ret = request_irq(dev->irq, meth_interrupt, 0, meth_str, dev); in meth_open()
335 printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq); in meth_open()
340 priv->dma_ctrl |= METH_DMA_TX_EN | /*METH_DMA_TX_INT_EN |*/ in meth_open()
342 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_open()
364 priv->dma_ctrl &= ~(METH_DMA_TX_EN | METH_DMA_TX_INT_EN | in meth_release()
366 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_release()
367 free_irq(dev->irq, dev); in meth_release()
384 spin_lock_irqsave(&priv->meth_lock, flags); in meth_rx()
385 priv->dma_ctrl &= ~METH_DMA_RX_INT_EN; in meth_rx()
386 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_rx()
387 spin_unlock_irqrestore(&priv->meth_lock, flags); in meth_rx()
390 fifo_rptr = (fifo_rptr - 1) & 0x0f; in meth_rx()
392 while (priv->rx_write != fifo_rptr) { in meth_rx()
393 dma_unmap_single(&priv->pdev->dev, in meth_rx()
394 priv->rx_ring_dmas[priv->rx_write], in meth_rx()
396 status = priv->rx_ring[priv->rx_write]->status.raw; in meth_rx()
403 int len = (status & 0xffff) - 4; /* omit CRC */ in meth_rx()
407 dev->name, priv->rx_write, in meth_rx()
408 priv->rx_ring[priv->rx_write]->status.raw); in meth_rx()
409 dev->stats.rx_errors++; in meth_rx()
410 dev->stats.rx_length_errors++; in meth_rx()
411 skb = priv->rx_skbs[priv->rx_write]; in meth_rx()
417 dev->stats.rx_dropped++; in meth_rx()
418 skb = priv->rx_skbs[priv->rx_write]; in meth_rx()
420 struct sk_buff *skb_c = priv->rx_skbs[priv->rx_write]; in meth_rx()
426 priv->rx_skbs[priv->rx_write] = skb; in meth_rx()
427 skb_c->protocol = eth_type_trans(skb_c, dev); in meth_rx()
428 dev->stats.rx_packets++; in meth_rx()
429 dev->stats.rx_bytes += len; in meth_rx()
434 dev->stats.rx_errors++; in meth_rx()
435 skb=priv->rx_skbs[priv->rx_write]; in meth_rx()
452 priv->rx_ring[priv->rx_write] = (rx_packet*)skb->head; in meth_rx()
453 priv->rx_ring[priv->rx_write]->status.raw = 0; in meth_rx()
454 priv->rx_ring_dmas[priv->rx_write] = in meth_rx()
455 dma_map_single(&priv->pdev->dev, in meth_rx()
456 priv->rx_ring[priv->rx_write], in meth_rx()
458 mace->eth.rx_fifo = priv->rx_ring_dmas[priv->rx_write]; in meth_rx()
459 ADVANCE_RX_PTR(priv->rx_write); in meth_rx()
461 spin_lock_irqsave(&priv->meth_lock, flags); in meth_rx()
463 priv->dma_ctrl |= METH_DMA_RX_INT_EN | METH_DMA_RX_EN; in meth_rx()
464 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_rx()
465 mace->eth.int_stat = METH_INT_RX_THRESHOLD; in meth_rx()
466 spin_unlock_irqrestore(&priv->meth_lock, flags); in meth_rx()
473 return priv->tx_count >= TX_RING_ENTRIES - 1; in meth_tx_full()
483 spin_lock_irqsave(&priv->meth_lock, flags); in meth_tx_cleanup()
486 priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN); in meth_tx_cleanup()
487 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_tx_cleanup()
489 while (priv->tx_read != rptr) { in meth_tx_cleanup()
490 skb = priv->tx_skbs[priv->tx_read]; in meth_tx_cleanup()
491 status = priv->tx_ring[priv->tx_read].header.raw; in meth_tx_cleanup()
493 if (priv->tx_read == priv->tx_write) in meth_tx_cleanup()
494 DPRINTK("Auchi! tx_read=%d,tx_write=%d,rptr=%d?\n", priv->tx_read, priv->tx_write,rptr); in meth_tx_cleanup()
498 dev->stats.tx_packets++; in meth_tx_cleanup()
499 dev->stats.tx_bytes += skb->len; in meth_tx_cleanup()
501 dev->stats.tx_errors++; in meth_tx_cleanup()
524 priv->tx_skbs[priv->tx_read] = NULL; in meth_tx_cleanup()
525 priv->tx_ring[priv->tx_read].header.raw = 0; in meth_tx_cleanup()
526 priv->tx_read = (priv->tx_read+1)&(TX_RING_ENTRIES-1); in meth_tx_cleanup()
527 priv->tx_count--; in meth_tx_cleanup()
535 mace->eth.int_stat = METH_INT_TX_EMPTY | METH_INT_TX_PKT; in meth_tx_cleanup()
536 spin_unlock_irqrestore(&priv->meth_lock, flags); in meth_tx_cleanup()
557 spin_lock_irqsave(&priv->meth_lock, flags); in meth_error()
558 mace->eth.int_stat = METH_INT_RX_UNDERFLOW; in meth_error()
562 priv->dma_ctrl &= ~METH_DMA_RX_EN; in meth_error()
563 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_error()
565 spin_unlock_irqrestore(&priv->meth_lock, flags); in meth_error()
567 mace->eth.int_stat = METH_INT_ERROR; in meth_error()
579 status = mace->eth.int_stat; in meth_interrupt()
581 /* First handle errors - if we get Rx underflow, in meth_interrupt()
593 if (!(priv->dma_ctrl & METH_DMA_RX_INT_EN)) in meth_interrupt()
598 status = mace->eth.int_stat; in meth_interrupt()
610 tx_packet *desc = &priv->tx_ring[priv->tx_write]; in meth_tx_short_prepare()
611 int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; in meth_tx_short_prepare()
613 desc->header.raw = METH_TX_CMD_INT_EN | (len-1) | ((128-len) << 16); in meth_tx_short_prepare()
615 skb_copy_from_linear_data(skb, desc->data.dt + (120 - len), skb->len); in meth_tx_short_prepare()
616 if (skb->len < len) in meth_tx_short_prepare()
617 memset(desc->data.dt + 120 - len + skb->len, 0, len-skb->len); in meth_tx_short_prepare()
623 tx_packet *desc = &priv->tx_ring[priv->tx_write]; in meth_tx_1page_prepare()
624 void *buffer_data = (void *)(((unsigned long)skb->data + 7) & ~7); in meth_tx_1page_prepare()
625 int unaligned_len = (int)((unsigned long)buffer_data - (unsigned long)skb->data); in meth_tx_1page_prepare()
626 int buffer_len = skb->len - unaligned_len; in meth_tx_1page_prepare()
629 desc->header.raw = METH_TX_CMD_INT_EN | TX_CATBUF1 | (skb->len - 1); in meth_tx_1page_prepare()
633 skb_copy_from_linear_data(skb, desc->data.dt + (120 - unaligned_len), in meth_tx_1page_prepare()
635 desc->header.raw |= (128 - unaligned_len) << 16; in meth_tx_1page_prepare()
639 catbuf = dma_map_single(&priv->pdev->dev, buffer_data, buffer_len, in meth_tx_1page_prepare()
641 desc->data.cat_buf[0].form.start_addr = catbuf >> 3; in meth_tx_1page_prepare()
642 desc->data.cat_buf[0].form.len = buffer_len - 1; in meth_tx_1page_prepare()
648 tx_packet *desc = &priv->tx_ring[priv->tx_write]; in meth_tx_2page_prepare()
649 void *buffer1_data = (void *)(((unsigned long)skb->data + 7) & ~7); in meth_tx_2page_prepare()
650 void *buffer2_data = (void *)PAGE_ALIGN((unsigned long)skb->data); in meth_tx_2page_prepare()
651 int unaligned_len = (int)((unsigned long)buffer1_data - (unsigned long)skb->data); in meth_tx_2page_prepare()
652 int buffer1_len = (int)((unsigned long)buffer2_data - (unsigned long)buffer1_data); in meth_tx_2page_prepare()
653 int buffer2_len = skb->len - buffer1_len - unaligned_len; in meth_tx_2page_prepare()
656 desc->header.raw = METH_TX_CMD_INT_EN | TX_CATBUF1 | TX_CATBUF2| (skb->len - 1); in meth_tx_2page_prepare()
659 skb_copy_from_linear_data(skb, desc->data.dt + (120 - unaligned_len), in meth_tx_2page_prepare()
661 desc->header.raw |= (128 - unaligned_len) << 16; in meth_tx_2page_prepare()
665 catbuf1 = dma_map_single(&priv->pdev->dev, buffer1_data, buffer1_len, in meth_tx_2page_prepare()
667 desc->data.cat_buf[0].form.start_addr = catbuf1 >> 3; in meth_tx_2page_prepare()
668 desc->data.cat_buf[0].form.len = buffer1_len - 1; in meth_tx_2page_prepare()
670 catbuf2 = dma_map_single(&priv->pdev->dev, buffer2_data, buffer2_len, in meth_tx_2page_prepare()
672 desc->data.cat_buf[1].form.start_addr = catbuf2 >> 3; in meth_tx_2page_prepare()
673 desc->data.cat_buf[1].form.len = buffer2_len - 1; in meth_tx_2page_prepare()
679 priv->tx_skbs[priv->tx_write] = skb; in meth_add_to_tx_ring()
680 if (skb->len <= 120) { in meth_add_to_tx_ring()
683 } else if (PAGE_ALIGN((unsigned long)skb->data) != in meth_add_to_tx_ring()
684 PAGE_ALIGN((unsigned long)skb->data + skb->len - 1)) { in meth_add_to_tx_ring()
691 priv->tx_write = (priv->tx_write + 1) & (TX_RING_ENTRIES - 1); in meth_add_to_tx_ring()
692 mace->eth.tx_info = priv->tx_write; in meth_add_to_tx_ring()
693 priv->tx_count++; in meth_add_to_tx_ring()
704 spin_lock_irqsave(&priv->meth_lock, flags); in meth_tx()
706 priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN); in meth_tx()
707 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_tx()
719 priv->dma_ctrl |= METH_DMA_TX_INT_EN; in meth_tx()
720 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_tx()
722 spin_unlock_irqrestore(&priv->meth_lock, flags); in meth_tx()
735 printk(KERN_WARNING "%s: transmit timed out\n", dev->name); in meth_tx_timeout()
738 spin_lock_irqsave(&priv->meth_lock,flags); in meth_tx_timeout()
743 dev->stats.tx_errors++; in meth_tx_timeout()
752 priv->dma_ctrl |= METH_DMA_TX_EN | METH_DMA_RX_EN | METH_DMA_RX_INT_EN; in meth_tx_timeout()
753 mace->eth.dma_ctrl = priv->dma_ctrl; in meth_tx_timeout()
756 spin_unlock_irqrestore(&priv->meth_lock, flags); in meth_tx_timeout()
773 return -EOPNOTSUPP; in meth_ioctl()
783 spin_lock_irqsave(&priv->meth_lock, flags); in meth_set_rx_mode()
784 priv->mac_ctrl &= ~METH_PROMISC; in meth_set_rx_mode()
786 if (dev->flags & IFF_PROMISC) { in meth_set_rx_mode()
787 priv->mac_ctrl |= METH_PROMISC; in meth_set_rx_mode()
788 priv->mcast_filter = 0xffffffffffffffffUL; in meth_set_rx_mode()
790 (dev->flags & IFF_ALLMULTI)) { in meth_set_rx_mode()
791 priv->mac_ctrl |= METH_ACCEPT_AMCAST; in meth_set_rx_mode()
792 priv->mcast_filter = 0xffffffffffffffffUL; in meth_set_rx_mode()
795 priv->mac_ctrl |= METH_ACCEPT_MCAST; in meth_set_rx_mode()
798 set_bit((ether_crc(ETH_ALEN, ha->addr) >> 26), in meth_set_rx_mode()
799 (volatile unsigned long *)&priv->mcast_filter); in meth_set_rx_mode()
803 mace->eth.mac_ctrl = priv->mac_ctrl; in meth_set_rx_mode()
804 mace->eth.mcast_filter = priv->mcast_filter; in meth_set_rx_mode()
807 spin_unlock_irqrestore(&priv->meth_lock, flags); in meth_set_rx_mode()
833 return -ENOMEM; in meth_probe()
835 dev->netdev_ops = &meth_netdev_ops; in meth_probe()
836 dev->watchdog_timeo = timeout; in meth_probe()
837 dev->irq = MACE_ETHERNET_IRQ; in meth_probe()
838 dev->base_addr = (unsigned long)&mace->eth; in meth_probe()
842 priv->pdev = pdev; in meth_probe()
843 spin_lock_init(&priv->meth_lock); in meth_probe()
844 SET_NETDEV_DEV(dev, &pdev->dev); in meth_probe()
853 dev->name, (unsigned int)(mace->eth.mac_ctrl >> 29)); in meth_probe()