diff options
Diffstat (limited to 'drivers/net/ethernet/microchip')
-rw-r--r-- | drivers/net/ethernet/microchip/enc28j60.c | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/microchip/encx24j600-regmap.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/microchip/encx24j600.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/microchip/encx24j600_hw.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/microchip/lan743x_main.c | 39 | ||||
-rw-r--r-- | drivers/net/ethernet/microchip/lan743x_main.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/microchip/lan743x_ptp.c | 91 | ||||
-rw-r--r-- | drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c | 7 |
10 files changed, 142 insertions, 41 deletions
diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c index 09cdc2f2e7ff..634ac7649c43 100644 --- a/drivers/net/ethernet/microchip/enc28j60.c +++ b/drivers/net/ethernet/microchip/enc28j60.c @@ -517,7 +517,7 @@ static int enc28j60_set_mac_address(struct net_device *dev, void *addr) if (!is_valid_ether_addr(address->sa_data)) return -EADDRNOTAVAIL; - ether_addr_copy(dev->dev_addr, address->sa_data); + eth_hw_addr_set(dev, address->sa_data); return enc28j60_set_hw_macaddr(dev); } @@ -1539,7 +1539,6 @@ static const struct net_device_ops enc28j60_netdev_ops = { static int enc28j60_probe(struct spi_device *spi) { - unsigned char macaddr[ETH_ALEN]; struct net_device *dev; struct enc28j60_net *priv; int ret = 0; @@ -1572,9 +1571,7 @@ static int enc28j60_probe(struct spi_device *spi) goto error_irq; } - if (device_get_mac_address(&spi->dev, macaddr, sizeof(macaddr))) - ether_addr_copy(dev->dev_addr, macaddr); - else + if (device_get_ethdev_address(&spi->dev, dev)) eth_hw_addr_random(dev); enc28j60_set_hw_macaddr(dev); diff --git a/drivers/net/ethernet/microchip/encx24j600-regmap.c b/drivers/net/ethernet/microchip/encx24j600-regmap.c index 796e46a53926..81a8ccca7e5e 100644 --- a/drivers/net/ethernet/microchip/encx24j600-regmap.c +++ b/drivers/net/ethernet/microchip/encx24j600-regmap.c @@ -497,13 +497,19 @@ static struct regmap_bus phymap_encx24j600 = { .reg_read = regmap_encx24j600_phy_reg_read, }; -void devm_regmap_init_encx24j600(struct device *dev, - struct encx24j600_context *ctx) +int devm_regmap_init_encx24j600(struct device *dev, + struct encx24j600_context *ctx) { mutex_init(&ctx->mutex); regcfg.lock_arg = ctx; ctx->regmap = devm_regmap_init(dev, ®map_encx24j600, ctx, ®cfg); + if (IS_ERR(ctx->regmap)) + return PTR_ERR(ctx->regmap); ctx->phymap = devm_regmap_init(dev, &phymap_encx24j600, ctx, &phycfg); + if (IS_ERR(ctx->phymap)) + return PTR_ERR(ctx->phymap); + + return 0; } EXPORT_SYMBOL_GPL(devm_regmap_init_encx24j600); diff --git a/drivers/net/ethernet/microchip/encx24j600.c b/drivers/net/ethernet/microchip/encx24j600.c index ee921a99e439..b90efc80fb59 100644 --- a/drivers/net/ethernet/microchip/encx24j600.c +++ b/drivers/net/ethernet/microchip/encx24j600.c @@ -761,7 +761,7 @@ static int encx24j600_set_mac_address(struct net_device *dev, void *addr) if (!is_valid_ether_addr(address->sa_data)) return -EADDRNOTAVAIL; - memcpy(dev->dev_addr, address->sa_data, dev->addr_len); + eth_hw_addr_set(dev, address->sa_data); return encx24j600_set_hw_macaddr(dev); } @@ -1001,6 +1001,7 @@ static int encx24j600_spi_probe(struct spi_device *spi) struct net_device *ndev; struct encx24j600_priv *priv; u16 eidled; + u8 addr[ETH_ALEN]; ndev = alloc_etherdev(sizeof(struct encx24j600_priv)); @@ -1023,10 +1024,13 @@ static int encx24j600_spi_probe(struct spi_device *spi) priv->speed = SPEED_100; priv->ctx.spi = spi; - devm_regmap_init_encx24j600(&spi->dev, &priv->ctx); ndev->irq = spi->irq; ndev->netdev_ops = &encx24j600_netdev_ops; + ret = devm_regmap_init_encx24j600(&spi->dev, &priv->ctx); + if (ret) + goto out_free; + mutex_init(&priv->lock); /* Reset device and check if it is connected */ @@ -1053,7 +1057,8 @@ static int encx24j600_spi_probe(struct spi_device *spi) } /* Get the MAC address from the chip */ - encx24j600_hw_get_macaddr(priv, ndev->dev_addr); + encx24j600_hw_get_macaddr(priv, addr); + eth_hw_addr_set(ndev, addr); ndev->ethtool_ops = &encx24j600_ethtool_ops; @@ -1122,4 +1127,3 @@ module_spi_driver(encx24j600_spi_net_driver); MODULE_DESCRIPTION(DRV_NAME " ethernet driver"); MODULE_AUTHOR("Jon Ringle <jringle@gridpoint.com>"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/net/ethernet/microchip/encx24j600_hw.h b/drivers/net/ethernet/microchip/encx24j600_hw.h index fac61a8fbd02..34c5a289898c 100644 --- a/drivers/net/ethernet/microchip/encx24j600_hw.h +++ b/drivers/net/ethernet/microchip/encx24j600_hw.h @@ -15,8 +15,8 @@ struct encx24j600_context { int bank; }; -void devm_regmap_init_encx24j600(struct device *dev, - struct encx24j600_context *ctx); +int devm_regmap_init_encx24j600(struct device *dev, + struct encx24j600_context *ctx); /* Single-byte instructions */ #define BANK_SELECT(bank) (0xC0 | ((bank & (BANK_MASK >> BANK_SHIFT)) << 1)) diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c index 9e8561cdc32a..4fc97823bc84 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c @@ -816,7 +816,7 @@ static int lan743x_mac_init(struct lan743x_adapter *adapter) eth_random_addr(adapter->mac_address); } lan743x_mac_set_address(adapter, adapter->mac_address); - ether_addr_copy(netdev->dev_addr, adapter->mac_address); + eth_hw_addr_set(netdev, adapter->mac_address); return 0; } @@ -1743,6 +1743,16 @@ static int lan743x_tx_ring_init(struct lan743x_tx *tx) ret = -EINVAL; goto cleanup; } + if (dma_set_mask_and_coherent(&tx->adapter->pdev->dev, + DMA_BIT_MASK(64))) { + if (dma_set_mask_and_coherent(&tx->adapter->pdev->dev, + DMA_BIT_MASK(32))) { + dev_warn(&tx->adapter->pdev->dev, + "lan743x_: No suitable DMA available\n"); + ret = -ENOMEM; + goto cleanup; + } + } ring_allocation_size = ALIGN(tx->ring_size * sizeof(struct lan743x_tx_descriptor), PAGE_SIZE); @@ -1934,7 +1944,8 @@ static void lan743x_rx_update_tail(struct lan743x_rx *rx, int index) index); } -static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index) +static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index, + gfp_t gfp) { struct net_device *netdev = rx->adapter->netdev; struct device *dev = &rx->adapter->pdev->dev; @@ -1948,7 +1959,7 @@ static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index) descriptor = &rx->ring_cpu_ptr[index]; buffer_info = &rx->buffer_info[index]; - skb = __netdev_alloc_skb(netdev, buffer_length, GFP_ATOMIC | GFP_DMA); + skb = __netdev_alloc_skb(netdev, buffer_length, gfp); if (!skb) return -ENOMEM; dma_ptr = dma_map_single(dev, skb->data, buffer_length, DMA_FROM_DEVICE); @@ -2110,7 +2121,8 @@ static int lan743x_rx_process_buffer(struct lan743x_rx *rx) /* save existing skb, allocate new skb and map to dma */ skb = buffer_info->skb; - if (lan743x_rx_init_ring_element(rx, rx->last_head)) { + if (lan743x_rx_init_ring_element(rx, rx->last_head, + GFP_ATOMIC | GFP_DMA)) { /* failed to allocate next skb. * Memory is very low. * Drop this packet and reuse buffer. @@ -2276,6 +2288,16 @@ static int lan743x_rx_ring_init(struct lan743x_rx *rx) ret = -EINVAL; goto cleanup; } + if (dma_set_mask_and_coherent(&rx->adapter->pdev->dev, + DMA_BIT_MASK(64))) { + if (dma_set_mask_and_coherent(&rx->adapter->pdev->dev, + DMA_BIT_MASK(32))) { + dev_warn(&rx->adapter->pdev->dev, + "lan743x_: No suitable DMA available\n"); + ret = -ENOMEM; + goto cleanup; + } + } ring_allocation_size = ALIGN(rx->ring_size * sizeof(struct lan743x_rx_descriptor), PAGE_SIZE); @@ -2315,13 +2337,16 @@ static int lan743x_rx_ring_init(struct lan743x_rx *rx) rx->last_head = 0; for (index = 0; index < rx->ring_size; index++) { - ret = lan743x_rx_init_ring_element(rx, index); + ret = lan743x_rx_init_ring_element(rx, index, GFP_KERNEL); if (ret) goto cleanup; } return 0; cleanup: + netif_warn(rx->adapter, ifup, rx->adapter->netdev, + "Error allocating memory for LAN743x\n"); + lan743x_rx_ring_cleanup(rx); return ret; } @@ -2645,7 +2670,7 @@ static int lan743x_netdev_set_mac_address(struct net_device *netdev, ret = eth_prepare_mac_addr_change(netdev, sock_addr); if (ret) return ret; - ether_addr_copy(netdev->dev_addr, sock_addr->sa_data); + eth_hw_addr_set(netdev, sock_addr->sa_data); lan743x_mac_set_address(adapter, sock_addr->sa_data); lan743x_rfe_update_mac_address(adapter); return 0; @@ -3019,6 +3044,8 @@ static int lan743x_pm_resume(struct device *dev) if (ret) { netif_err(adapter, probe, adapter->netdev, "lan743x_hardware_init returned %d\n", ret); + lan743x_pci_cleanup(adapter); + return ret; } /* open netdev when netdev is at running state while resume. diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h index 6080028c1df2..aaf7aaeaba0c 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.h +++ b/drivers/net/ethernet/microchip/lan743x_main.h @@ -279,6 +279,7 @@ #define PTP_GENERAL_CONFIG_CLOCK_EVENT_1MS_ (3) #define PTP_GENERAL_CONFIG_CLOCK_EVENT_10MS_ (4) #define PTP_GENERAL_CONFIG_CLOCK_EVENT_200MS_ (5) +#define PTP_GENERAL_CONFIG_CLOCK_EVENT_TOGGLE_ (6) #define PTP_GENERAL_CONFIG_CLOCK_EVENT_X_SET_(channel, value) \ (((value) & 0x7) << (1 + ((channel) << 2))) #define PTP_GENERAL_CONFIG_RELOAD_ADD_X_(channel) (BIT((channel) << 2)) @@ -830,7 +831,7 @@ struct lan743x_rx_buffer_info { unsigned int buffer_length; }; -#define LAN743X_RX_RING_SIZE (65) +#define LAN743X_RX_RING_SIZE (128) #define RX_PROCESS_RESULT_NOTHING_TO_DO (0) #define RX_PROCESS_RESULT_BUFFER_RECEIVED (1) diff --git a/drivers/net/ethernet/microchip/lan743x_ptp.c b/drivers/net/ethernet/microchip/lan743x_ptp.c index ab6d719d40f0..9380e396f648 100644 --- a/drivers/net/ethernet/microchip/lan743x_ptp.c +++ b/drivers/net/ethernet/microchip/lan743x_ptp.c @@ -491,9 +491,10 @@ static int lan743x_ptp_perout(struct lan743x_adapter *adapter, int on, int perout_pin = 0; unsigned int index = perout_request->index; struct lan743x_ptp_perout *perout = &ptp->perout[index]; + int ret = 0; /* Reject requests with unsupported flags */ - if (perout_request->flags) + if (perout_request->flags & ~PTP_PEROUT_DUTY_CYCLE) return -EOPNOTSUPP; if (on) { @@ -518,6 +519,7 @@ static int lan743x_ptp_perout(struct lan743x_adapter *adapter, int on, netif_warn(adapter, drv, adapter->netdev, "Failed to reserve event channel %d for PEROUT\n", index); + ret = -EBUSY; goto failed; } @@ -529,6 +531,7 @@ static int lan743x_ptp_perout(struct lan743x_adapter *adapter, int on, netif_warn(adapter, drv, adapter->netdev, "Failed to reserve gpio %d for PEROUT\n", perout_pin); + ret = -EBUSY; goto failed; } @@ -540,27 +543,93 @@ static int lan743x_ptp_perout(struct lan743x_adapter *adapter, int on, period_sec += perout_request->period.nsec / 1000000000; period_nsec = perout_request->period.nsec % 1000000000; - if (period_sec == 0) { - if (period_nsec >= 400000000) { + if (perout_request->flags & PTP_PEROUT_DUTY_CYCLE) { + struct timespec64 ts_on, ts_period; + s64 wf_high, period64, half; + s32 reminder; + + ts_on.tv_sec = perout_request->on.sec; + ts_on.tv_nsec = perout_request->on.nsec; + wf_high = timespec64_to_ns(&ts_on); + ts_period.tv_sec = perout_request->period.sec; + ts_period.tv_nsec = perout_request->period.nsec; + period64 = timespec64_to_ns(&ts_period); + + if (period64 < 200) { + netif_warn(adapter, drv, adapter->netdev, + "perout period too small, minimum is 200nS\n"); + ret = -EOPNOTSUPP; + goto failed; + } + if (wf_high >= period64) { + netif_warn(adapter, drv, adapter->netdev, + "pulse width must be smaller than period\n"); + ret = -EINVAL; + goto failed; + } + + /* Check if we can do 50% toggle on an even value of period. + * If the period number is odd, then check if the requested + * pulse width is the same as one of pre-defined width values. + * Otherwise, return failure. + */ + half = div_s64_rem(period64, 2, &reminder); + if (!reminder) { + if (half == wf_high) { + /* It's 50% match. Use the toggle option */ + pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_TOGGLE_; + /* In this case, devide period value by 2 */ + ts_period = ns_to_timespec64(div_s64(period64, 2)); + period_sec = ts_period.tv_sec; + period_nsec = ts_period.tv_nsec; + + goto program; + } + } + /* if we can't do toggle, then the width option needs to be the exact match */ + if (wf_high == 200000000) { pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_200MS_; - } else if (period_nsec >= 20000000) { + } else if (wf_high == 10000000) { pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_10MS_; - } else if (period_nsec >= 2000000) { + } else if (wf_high == 1000000) { pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_1MS_; - } else if (period_nsec >= 200000) { + } else if (wf_high == 100000) { pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_100US_; - } else if (period_nsec >= 20000) { + } else if (wf_high == 10000) { pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_10US_; - } else if (period_nsec >= 200) { + } else if (wf_high == 100) { pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_100NS_; } else { netif_warn(adapter, drv, adapter->netdev, - "perout period too small, minimum is 200nS\n"); + "duty cycle specified is not supported\n"); + ret = -EOPNOTSUPP; goto failed; } } else { - pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_200MS_; + if (period_sec == 0) { + if (period_nsec >= 400000000) { + pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_200MS_; + } else if (period_nsec >= 20000000) { + pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_10MS_; + } else if (period_nsec >= 2000000) { + pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_1MS_; + } else if (period_nsec >= 200000) { + pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_100US_; + } else if (period_nsec >= 20000) { + pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_10US_; + } else if (period_nsec >= 200) { + pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_100NS_; + } else { + netif_warn(adapter, drv, adapter->netdev, + "perout period too small, minimum is 200nS\n"); + ret = -EOPNOTSUPP; + goto failed; + } + } else { + pulse_width = PTP_GENERAL_CONFIG_CLOCK_EVENT_200MS_; + } } +program: /* turn off by setting target far in future */ lan743x_csr_write(adapter, @@ -599,7 +668,7 @@ static int lan743x_ptp_perout(struct lan743x_adapter *adapter, int on, failed: lan743x_ptp_perout_off(adapter, index); - return -ENODEV; + return ret; } static int lan743x_ptpci_enable(struct ptp_clock_info *ptpci, diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c index cbece6e9bff2..4625d4fb4cde 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c @@ -234,8 +234,7 @@ static int sparx5_create_targets(struct sparx5 *sparx5) } iomem[idx] = devm_ioremap(sparx5->dev, iores[idx]->start, - iores[idx]->end - iores[idx]->start - + 1); + resource_size(iores[idx])); if (!iomem[idx]) { dev_err(sparx5->dev, "Unable to get switch registers: %s\n", iores[idx]->name); @@ -758,6 +757,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev) err = dev_err_probe(sparx5->dev, PTR_ERR(serdes), "port %u: missing serdes\n", portno); + of_node_put(portnp); goto cleanup_config; } config->portno = portno; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c index cb68eaaac881..e042f117dc7a 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c @@ -162,7 +162,7 @@ static int sparx5_set_mac_address(struct net_device *dev, void *p) sparx5_mact_learn(sparx5, PGID_CPU, addr->sa_data, port->pvid); /* Record the address */ - ether_addr_copy(dev->dev_addr, addr->sa_data); + eth_hw_addr_set(dev, addr->sa_data); return 0; } @@ -200,7 +200,6 @@ struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno) { struct sparx5_port *spx5_port; struct net_device *ndev; - u64 val; ndev = devm_alloc_etherdev(sparx5->dev, sizeof(struct sparx5_port)); if (!ndev) @@ -216,8 +215,7 @@ struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno) ndev->netdev_ops = &sparx5_port_netdev_ops; ndev->ethtool_ops = &sparx5_ethtool_ops; - val = ether_addr_to_u64(sparx5->base_mac) + portno + 1; - u64_to_ether_addr(val, ndev->dev_addr); + eth_hw_addr_gen(ndev, sparx5->base_mac, portno + 1); return ndev; } diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c index af70e2795125..fb74752de0ca 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c @@ -92,12 +92,11 @@ static void sparx5_phylink_validate(struct phylink_config *config, } break; default: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } - bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static void sparx5_phylink_mac_config(struct phylink_config *config, |