Lines Matching +full:mac +full:- +full:clk +full:- +full:rx
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
19 #include "emac-mac.h"
20 #include "emac-phy.h"
21 #include "emac-sgmii.h"
85 mutex_lock(&adpt->reset_lock); in emac_reinit_locked()
91 mutex_unlock(&adpt->reset_lock); in emac_reinit_locked()
101 struct emac_adapter *adpt = netdev_priv(rx_q->netdev); in emac_napi_rtx()
102 struct emac_irq *irq = rx_q->irq; in emac_napi_rtx()
110 irq->mask |= rx_q->intr; in emac_napi_rtx()
111 writel(irq->mask, adpt->base + EMAC_INT_MASK); in emac_napi_rtx()
123 return emac_mac_tx_buf_send(adpt, &adpt->tx_q, skb); in emac_start_xmit()
131 struct emac_rx_queue *rx_q = &adpt->rx_q; in emac_isr()
135 writel(0, adpt->base + EMAC_INT_MASK); in emac_isr()
137 isr = readl_relaxed(adpt->base + EMAC_INT_STATUS); in emac_isr()
139 status = isr & irq->mask; in emac_isr()
145 adpt->netdev->name, status & ISR_ERROR); in emac_isr()
146 /* reset MAC */ in emac_isr()
147 schedule_work(&adpt->work_thread); in emac_isr()
153 if (status & rx_q->intr) { in emac_isr()
154 if (napi_schedule_prep(&rx_q->napi)) { in emac_isr()
155 irq->mask &= ~rx_q->intr; in emac_isr()
156 __napi_schedule(&rx_q->napi); in emac_isr()
161 emac_mac_tx_process(adpt, &adpt->tx_q); in emac_isr()
164 net_warn_ratelimited("%s: TX/RX overflow interrupt\n", in emac_isr()
165 adpt->netdev->name); in emac_isr()
169 writel(irq->mask, adpt->base + EMAC_INT_MASK); in emac_isr()
178 netdev_features_t changed = features ^ netdev->features; in emac_set_features()
190 /* emac_mac_mode_config() uses netdev->features to configure the EMAC, in emac_set_features()
193 netdev->features = features; in emac_set_features()
209 emac_mac_multicast_addr_set(adpt, ha->addr); in emac_rx_mode_set()
217 netif_dbg(adpt, hw, adpt->netdev, in emac_change_mtu()
218 "changing MTU from %d to %d\n", netdev->mtu, in emac_change_mtu()
220 netdev->mtu = new_mtu; in emac_change_mtu()
232 struct emac_irq *irq = &adpt->irq; in emac_open()
235 ret = request_irq(irq->irq, emac_isr, 0, "emac-core0", irq); in emac_open()
237 netdev_err(adpt->netdev, "could not request emac-core0 irq\n"); in emac_open()
241 /* allocate rx/tx dma buffer & descriptors */ in emac_open()
244 netdev_err(adpt->netdev, "error allocating rx/tx rings\n"); in emac_open()
245 free_irq(irq->irq, irq); in emac_open()
252 free_irq(irq->irq, irq); in emac_open()
259 free_irq(irq->irq, irq); in emac_open()
272 mutex_lock(&adpt->reset_lock); in emac_close()
278 free_irq(adpt->irq.irq, &adpt->irq); in emac_close()
280 mutex_unlock(&adpt->reset_lock); in emac_close()
290 schedule_work(&adpt->work_thread); in emac_tx_timeout()
294 * emac_update_hw_stats - read the EMAC stat registers
297 * Reads the stats registers and write the values to adpt->stats.
299 * adpt->stats.lock must be held while calling this function,
300 * and while reading from adpt->stats.
304 struct emac_stats *stats = &adpt->stats; in emac_update_hw_stats()
305 u64 *stats_itr = &adpt->stats.rx_ok; in emac_update_hw_stats()
306 void __iomem *base = adpt->base; in emac_update_hw_stats()
316 /* additional rx status */ in emac_update_hw_stats()
317 stats->rx_crc_align += readl_relaxed(base + EMAC_RXMAC_STATC_REG23); in emac_update_hw_stats()
318 stats->rx_jabbers += readl_relaxed(base + EMAC_RXMAC_STATC_REG24); in emac_update_hw_stats()
322 stats_itr = &stats->tx_ok; in emac_update_hw_stats()
331 stats->tx_col += readl_relaxed(base + EMAC_TXMAC_STATC_REG25); in emac_update_hw_stats()
339 struct emac_stats *stats = &adpt->stats; in emac_get_stats64()
341 spin_lock(&stats->lock); in emac_get_stats64()
346 net_stats->rx_packets = stats->rx_ok; in emac_get_stats64()
347 net_stats->tx_packets = stats->tx_ok; in emac_get_stats64()
348 net_stats->rx_bytes = stats->rx_byte_cnt; in emac_get_stats64()
349 net_stats->tx_bytes = stats->tx_byte_cnt; in emac_get_stats64()
350 net_stats->multicast = stats->rx_mcast; in emac_get_stats64()
351 net_stats->collisions = stats->tx_1_col + stats->tx_2_col * 2 + in emac_get_stats64()
352 stats->tx_late_col + stats->tx_abort_col; in emac_get_stats64()
354 net_stats->rx_errors = stats->rx_frag + stats->rx_fcs_err + in emac_get_stats64()
355 stats->rx_len_err + stats->rx_sz_ov + in emac_get_stats64()
356 stats->rx_align_err; in emac_get_stats64()
357 net_stats->rx_fifo_errors = stats->rx_rxf_ov; in emac_get_stats64()
358 net_stats->rx_length_errors = stats->rx_len_err; in emac_get_stats64()
359 net_stats->rx_crc_errors = stats->rx_fcs_err; in emac_get_stats64()
360 net_stats->rx_frame_errors = stats->rx_align_err; in emac_get_stats64()
361 net_stats->rx_over_errors = stats->rx_rxf_ov; in emac_get_stats64()
362 net_stats->rx_missed_errors = stats->rx_rxf_ov; in emac_get_stats64()
364 net_stats->tx_errors = stats->tx_late_col + stats->tx_abort_col + in emac_get_stats64()
365 stats->tx_underrun + stats->tx_trunc; in emac_get_stats64()
366 net_stats->tx_fifo_errors = stats->tx_underrun; in emac_get_stats64()
367 net_stats->tx_aborted_errors = stats->tx_abort_col; in emac_get_stats64()
368 net_stats->tx_window_errors = stats->tx_late_col; in emac_get_stats64()
370 spin_unlock(&stats->lock); in emac_get_stats64()
401 adpt->rrd_size = EMAC_RRD_SIZE; in emac_init_adapter()
402 adpt->tpd_size = EMAC_TPD_SIZE; in emac_init_adapter()
403 adpt->rfd_size = EMAC_RFD_SIZE; in emac_init_adapter()
406 adpt->tx_desc_cnt = EMAC_DEF_TX_DESCS; in emac_init_adapter()
407 adpt->rx_desc_cnt = EMAC_DEF_RX_DESCS; in emac_init_adapter()
410 adpt->dma_order = emac_dma_ord_out; in emac_init_adapter()
411 adpt->dmar_block = emac_dma_req_4096; in emac_init_adapter()
412 adpt->dmaw_block = emac_dma_req_128; in emac_init_adapter()
413 adpt->dmar_dly_cnt = DMAR_DLY_CNT_DEF; in emac_init_adapter()
414 adpt->dmaw_dly_cnt = DMAW_DLY_CNT_DEF; in emac_init_adapter()
415 adpt->tpd_burst = TXQ0_NUM_TPD_PREF_DEF; in emac_init_adapter()
416 adpt->rfd_burst = RXQ0_NUM_RFD_PREF_DEF; in emac_init_adapter()
421 adpt->irq_mod = reg; in emac_init_adapter()
424 adpt->preamble = EMAC_PREAMBLE_DEF; in emac_init_adapter()
427 adpt->automatic = true; in emac_init_adapter()
429 /* Disable single-pause-frame mode by default */ in emac_init_adapter()
430 adpt->single_pause_mode = false; in emac_init_adapter()
440 struct clk *clk = devm_clk_get(&pdev->dev, emac_clk_name[i]); in emac_clks_get() local
442 if (IS_ERR(clk)) { in emac_clks_get()
443 dev_err(&pdev->dev, in emac_clks_get()
445 emac_clk_name[i], PTR_ERR(clk)); in emac_clks_get()
447 return PTR_ERR(clk); in emac_clks_get()
450 adpt->clk[i] = clk; in emac_clks_get()
465 if (has_acpi_companion(&pdev->dev)) in emac_clks_phase1_init()
472 ret = clk_prepare_enable(adpt->clk[EMAC_CLK_AXI]); in emac_clks_phase1_init()
476 ret = clk_prepare_enable(adpt->clk[EMAC_CLK_CFG_AHB]); in emac_clks_phase1_init()
480 ret = clk_set_rate(adpt->clk[EMAC_CLK_HIGH_SPEED], 19200000); in emac_clks_phase1_init()
484 ret = clk_prepare_enable(adpt->clk[EMAC_CLK_HIGH_SPEED]); in emac_clks_phase1_init()
491 clk_disable_unprepare(adpt->clk[EMAC_CLK_CFG_AHB]); in emac_clks_phase1_init()
493 clk_disable_unprepare(adpt->clk[EMAC_CLK_AXI]); in emac_clks_phase1_init()
504 if (has_acpi_companion(&pdev->dev)) in emac_clks_phase2_init()
507 ret = clk_set_rate(adpt->clk[EMAC_CLK_TX], 125000000); in emac_clks_phase2_init()
511 ret = clk_prepare_enable(adpt->clk[EMAC_CLK_TX]); in emac_clks_phase2_init()
515 ret = clk_set_rate(adpt->clk[EMAC_CLK_HIGH_SPEED], 125000000); in emac_clks_phase2_init()
519 ret = clk_set_rate(adpt->clk[EMAC_CLK_MDIO], 25000000); in emac_clks_phase2_init()
523 ret = clk_prepare_enable(adpt->clk[EMAC_CLK_MDIO]); in emac_clks_phase2_init()
527 ret = clk_prepare_enable(adpt->clk[EMAC_CLK_RX]); in emac_clks_phase2_init()
531 return clk_prepare_enable(adpt->clk[EMAC_CLK_SYS]); in emac_clks_phase2_init()
540 clk_disable_unprepare(adpt->clk[i]); in emac_clks_teardown()
547 struct net_device *netdev = adpt->netdev; in emac_probe_resources()
550 /* get mac address */ in emac_probe_resources()
551 if (device_get_ethdev_address(&pdev->dev, netdev)) in emac_probe_resources()
558 adpt->irq.irq = ret; in emac_probe_resources()
561 adpt->base = devm_platform_ioremap_resource(pdev, 0); in emac_probe_resources()
562 if (IS_ERR(adpt->base)) in emac_probe_resources()
563 return PTR_ERR(adpt->base); in emac_probe_resources()
566 adpt->csr = devm_platform_ioremap_resource(pdev, 1); in emac_probe_resources()
567 if (IS_ERR(adpt->csr)) in emac_probe_resources()
568 return PTR_ERR(adpt->csr); in emac_probe_resources()
570 netdev->base_addr = (unsigned long)adpt->base; in emac_probe_resources()
577 .compatible = "qcom,fsm9900-emac",
604 * 2. NON-PTP: 46bits. in emac_probe()
606 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(46)); in emac_probe()
608 dev_err(&pdev->dev, "could not set DMA mask\n"); in emac_probe()
614 return -ENOMEM; in emac_probe()
616 dev_set_drvdata(&pdev->dev, netdev); in emac_probe()
617 SET_NETDEV_DEV(netdev, &pdev->dev); in emac_probe()
621 adpt->netdev = netdev; in emac_probe()
622 adpt->msg_enable = EMAC_MSG_DEFAULT; in emac_probe()
624 phy = &adpt->phy; in emac_probe()
625 atomic_set(&phy->decode_error_count, 0); in emac_probe()
627 mutex_init(&adpt->reset_lock); in emac_probe()
628 spin_lock_init(&adpt->stats.lock); in emac_probe()
630 adpt->irq.mask = RX_PKT_INT0 | IMR_NORMAL_MASK; in emac_probe()
639 dev_err(&pdev->dev, "could not initialize clocks\n"); in emac_probe()
643 netdev->watchdog_timeo = EMAC_WATCHDOG_TIME; in emac_probe()
644 netdev->irq = adpt->irq.irq; in emac_probe()
646 netdev->netdev_ops = &emac_netdev_ops; in emac_probe()
663 dev_err(&pdev->dev, "could not initialize clocks\n"); in emac_probe()
668 netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM | in emac_probe()
671 netdev->hw_features = netdev->features; in emac_probe()
673 netdev->vlan_features |= NETIF_F_SG | NETIF_F_HW_CSUM | in emac_probe()
676 /* MTU range: 46 - 9194 */ in emac_probe()
677 netdev->min_mtu = EMAC_MIN_ETH_FRAME_SIZE - in emac_probe()
679 netdev->max_mtu = EMAC_MAX_ETH_FRAME_SIZE - in emac_probe()
682 INIT_WORK(&adpt->work_thread, emac_work_thread); in emac_probe()
687 netif_napi_add(netdev, &adpt->rx_q.napi, emac_napi_rtx); in emac_probe()
691 dev_err(&pdev->dev, "could not register net device\n"); in emac_probe()
695 reg = readl_relaxed(adpt->base + EMAC_DMA_MAS_CTRL); in emac_probe()
698 reg = readl_relaxed(adpt->base + EMAC_CORE_HW_VERSION); in emac_probe()
710 netif_napi_del(&adpt->rx_q.napi); in emac_probe()
712 put_device(&adpt->phydev->mdio.dev); in emac_probe()
713 mdiobus_unregister(adpt->mii_bus); in emac_probe()
724 struct net_device *netdev = dev_get_drvdata(&pdev->dev); in emac_remove()
728 netif_napi_del(&adpt->rx_q.napi); in emac_remove()
732 put_device(&adpt->phydev->mdio.dev); in emac_remove()
733 mdiobus_unregister(adpt->mii_bus); in emac_remove()
735 if (adpt->phy.digital) in emac_remove()
736 iounmap(adpt->phy.digital); in emac_remove()
737 iounmap(adpt->phy.base); in emac_remove()
746 struct net_device *netdev = dev_get_drvdata(&pdev->dev); in emac_shutdown()
749 if (netdev->flags & IFF_UP) { in emac_shutdown()
753 /* Resetting the MAC turns off all DMA and its interrupts */ in emac_shutdown()
762 .name = "qcom-emac",
772 MODULE_ALIAS("platform:qcom-emac");