diff options
Diffstat (limited to 'drivers/net/ethernet/micrel/ks8851_common.c')
| -rw-r--r-- | drivers/net/ethernet/micrel/ks8851_common.c | 132 |
1 files changed, 48 insertions, 84 deletions
diff --git a/drivers/net/ethernet/micrel/ks8851_common.c b/drivers/net/ethernet/micrel/ks8851_common.c index 691206f19ea7..bb5138806c3f 100644 --- a/drivers/net/ethernet/micrel/ks8851_common.c +++ b/drivers/net/ethernet/micrel/ks8851_common.c @@ -17,10 +17,9 @@ #include <linux/cache.h> #include <linux/crc32.h> #include <linux/mii.h> +#include <linux/gpio/consumer.h> #include <linux/regulator/consumer.h> -#include <linux/gpio.h> -#include <linux/of_gpio.h> #include <linux/of_mdio.h> #include <linux/of_net.h> @@ -217,40 +216,15 @@ static void ks8851_init_mac(struct ks8851_net *ks, struct device_node *np) } /** - * ks8851_dbg_dumpkkt - dump initial packet contents to debug - * @ks: The device state - * @rxpkt: The data for the received packet - * - * Dump the initial data from the packet to dev_dbg(). - */ -static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt) -{ - netdev_dbg(ks->netdev, - "pkt %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n", - rxpkt[4], rxpkt[5], rxpkt[6], rxpkt[7], - rxpkt[8], rxpkt[9], rxpkt[10], rxpkt[11], - rxpkt[12], rxpkt[13], rxpkt[14], rxpkt[15]); -} - -/** - * ks8851_rx_skb - receive skbuff - * @ks: The device state. - * @skb: The skbuff - */ -static void ks8851_rx_skb(struct ks8851_net *ks, struct sk_buff *skb) -{ - ks->rx_skb(ks, skb); -} - -/** * ks8851_rx_pkts - receive packets from the host * @ks: The device information. + * @rxq: Queue of packets received in this function. * * This is called from the IRQ work queue when the system detects that there * are packets in the receive queue. Find out how many packets there are and * read them from the FIFO. */ -static void ks8851_rx_pkts(struct ks8851_net *ks) +static void ks8851_rx_pkts(struct ks8851_net *ks, struct sk_buff_head *rxq) { struct sk_buff *skb; unsigned rxfc; @@ -306,11 +280,11 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) ks->rdfifo(ks, rxpkt, rxalign + 8); - if (netif_msg_pktdata(ks)) - ks8851_dbg_dumpkkt(ks, rxpkt); + netif_dbg(ks, pktdata, ks->netdev, + "pkt %12ph\n", &rxpkt[4]); skb->protocol = eth_type_trans(skb, ks->netdev); - ks8851_rx_skb(ks, skb); + __skb_queue_tail(rxq, skb); ks->netdev->stats.rx_packets++; ks->netdev->stats.rx_bytes += rxlen; @@ -337,61 +311,50 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) static irqreturn_t ks8851_irq(int irq, void *_ks) { struct ks8851_net *ks = _ks; - unsigned handled = 0; + struct sk_buff_head rxq; unsigned long flags; unsigned int status; + struct sk_buff *skb; ks8851_lock(ks, &flags); status = ks8851_rdreg16(ks, KS_ISR); + ks8851_wrreg16(ks, KS_ISR, status); netif_dbg(ks, intr, ks->netdev, "%s: status 0x%04x\n", __func__, status); - if (status & IRQ_LCI) - handled |= IRQ_LCI; - if (status & IRQ_LDI) { u16 pmecr = ks8851_rdreg16(ks, KS_PMECR); pmecr &= ~PMECR_WKEVT_MASK; ks8851_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK); - - handled |= IRQ_LDI; } - if (status & IRQ_RXPSI) - handled |= IRQ_RXPSI; - if (status & IRQ_TXI) { - handled |= IRQ_TXI; - - /* no lock here, tx queue should have been stopped */ - - /* update our idea of how much tx space is available to the - * system */ - ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR); + unsigned short tx_space = ks8851_rdreg16(ks, KS_TXMIR); netif_dbg(ks, intr, ks->netdev, - "%s: txspace %d\n", __func__, ks->tx_space); - } + "%s: txspace %d\n", __func__, tx_space); - if (status & IRQ_RXI) - handled |= IRQ_RXI; + spin_lock_bh(&ks->statelock); + ks->tx_space = tx_space; + if (netif_queue_stopped(ks->netdev)) + netif_wake_queue(ks->netdev); + spin_unlock_bh(&ks->statelock); + } if (status & IRQ_SPIBEI) { netdev_err(ks->netdev, "%s: spi bus error\n", __func__); - handled |= IRQ_SPIBEI; } - ks8851_wrreg16(ks, KS_ISR, handled); - if (status & IRQ_RXI) { /* the datasheet says to disable the rx interrupt during * packet read-out, however we're masking the interrupt * from the device so do not bother masking just the RX * from the device. */ - ks8851_rx_pkts(ks); + __skb_queue_head_init(&rxq); + ks8851_rx_pkts(ks, &rxq); } /* if something stopped the rx process, probably due to wanting @@ -415,8 +378,9 @@ static irqreturn_t ks8851_irq(int irq, void *_ks) if (status & IRQ_LCI) mii_check_link(&ks->mii); - if (status & IRQ_TXI) - netif_wake_queue(ks->netdev); + if (status & IRQ_RXI) + while ((skb = __skb_dequeue(&rxq))) + netif_rx(skb); return IRQ_HANDLED; } @@ -501,6 +465,8 @@ static int ks8851_net_open(struct net_device *dev) ks8851_wrreg16(ks, KS_ISR, ks->rc_ier); ks8851_wrreg16(ks, KS_IER, ks->rc_ier); + ks->queued_len = 0; + ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR); netif_start_queue(ks->netdev); netif_dbg(ks, ifup, ks->netdev, "network device up\n"); @@ -654,14 +620,14 @@ static void ks8851_set_rx_mode(struct net_device *dev) /* schedule work to do the actual set of the data if needed */ - spin_lock(&ks->statelock); + spin_lock_bh(&ks->statelock); if (memcmp(&rxctrl, &ks->rxctrl, sizeof(rxctrl)) != 0) { memcpy(&ks->rxctrl, &rxctrl, sizeof(ks->rxctrl)); schedule_work(&ks->rxctrl_work); } - spin_unlock(&ks->statelock); + spin_unlock_bh(&ks->statelock); } static int ks8851_set_mac_address(struct net_device *dev, void *addr) @@ -703,9 +669,9 @@ static const struct net_device_ops ks8851_netdev_ops = { static void ks8851_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *di) { - strlcpy(di->driver, "KS8851", sizeof(di->driver)); - strlcpy(di->version, "1.00", sizeof(di->version)); - strlcpy(di->bus_info, dev_name(dev->dev.parent), sizeof(di->bus_info)); + strscpy(di->driver, "KS8851", sizeof(di->driver)); + strscpy(di->version, "1.00", sizeof(di->version)); + strscpy(di->bus_info, dev_name(dev->dev.parent), sizeof(di->bus_info)); } static u32 ks8851_get_msglevel(struct net_device *dev) @@ -1117,24 +1083,22 @@ int ks8851_probe_common(struct net_device *netdev, struct device *dev, { struct ks8851_net *ks = netdev_priv(netdev); unsigned cider; - int gpio; int ret; ks->netdev = netdev; - ks->tx_space = 6144; - - gpio = of_get_named_gpio_flags(dev->of_node, "reset-gpios", 0, NULL); - if (gpio == -EPROBE_DEFER) - return gpio; - - ks->gpio = gpio; - if (gpio_is_valid(gpio)) { - ret = devm_gpio_request_one(dev, gpio, - GPIOF_OUT_INIT_LOW, "ks8851_rst_n"); - if (ret) { - dev_err(dev, "reset gpio request failed\n"); - return ret; - } + + ks->gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + ret = PTR_ERR_OR_ZERO(ks->gpio); + if (ret) { + if (ret != -EPROBE_DEFER) + dev_err(dev, "reset gpio request failed: %d\n", ret); + return ret; + } + + ret = gpiod_set_consumer_name(ks->gpio, "ks8851_rst_n"); + if (ret) { + dev_err(dev, "failed to set reset gpio name: %d\n", ret); + return ret; } ks->vdd_io = devm_regulator_get(dev, "vdd-io"); @@ -1161,9 +1125,9 @@ int ks8851_probe_common(struct net_device *netdev, struct device *dev, goto err_reg; } - if (gpio_is_valid(gpio)) { + if (ks->gpio) { usleep_range(10000, 11000); - gpio_set_value(gpio, 1); + gpiod_set_value_cansleep(ks->gpio, 0); } spin_lock_init(&ks->statelock); @@ -1239,8 +1203,8 @@ int ks8851_probe_common(struct net_device *netdev, struct device *dev, err_id: ks8851_unregister_mdiobus(ks); err_mdio: - if (gpio_is_valid(gpio)) - gpio_set_value(gpio, 0); + if (ks->gpio) + gpiod_set_value_cansleep(ks->gpio, 1); regulator_disable(ks->vdd_reg); err_reg: regulator_disable(ks->vdd_io); @@ -1259,8 +1223,8 @@ void ks8851_remove_common(struct device *dev) dev_info(dev, "remove\n"); unregister_netdev(priv->netdev); - if (gpio_is_valid(priv->gpio)) - gpio_set_value(priv->gpio, 0); + if (priv->gpio) + gpiod_set_value_cansleep(priv->gpio, 1); regulator_disable(priv->vdd_reg); regulator_disable(priv->vdd_io); } |
