diff options
Diffstat (limited to 'drivers/net/ethernet/tile')
| -rw-r--r-- | drivers/net/ethernet/tile/Kconfig | 12 | ||||
| -rw-r--r-- | drivers/net/ethernet/tile/tilegx.c | 65 | ||||
| -rw-r--r-- | drivers/net/ethernet/tile/tilepro.c | 13 |
3 files changed, 37 insertions, 53 deletions
diff --git a/drivers/net/ethernet/tile/Kconfig b/drivers/net/ethernet/tile/Kconfig index 4083ba8839e..f59a6c26533 100644 --- a/drivers/net/ethernet/tile/Kconfig +++ b/drivers/net/ethernet/tile/Kconfig @@ -9,20 +9,10 @@ config TILE_NET select CRC32 select TILE_GXIO_MPIPE if TILEGX select HIGH_RES_TIMERS if TILEGX + select PTP_1588_CLOCK if TILEGX ---help--- This is a standard Linux network device driver for the on-chip Tilera Gigabit Ethernet and XAUI interfaces. To compile this driver as a module, choose M here: the module will be called tile_net. - -config PTP_1588_CLOCK_TILEGX - tristate "Tilera TILE-Gx mPIPE as PTP clock" - select PTP_1588_CLOCK - depends on TILE_NET - depends on TILEGX - ---help--- - This driver adds support for using the mPIPE as a PTP - clock. This clock is only useful if your PTP programs are - getting hardware time stamps on the PTP Ethernet packets - using the SO_TIMESTAMPING API. diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 13e6fff8ca2..4c70360967c 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c @@ -187,10 +187,8 @@ struct tile_net_priv { int echannel; /* mPIPE instance, 0 or 1. */ int instance; -#ifdef CONFIG_PTP_1588_CLOCK_TILEGX /* The timestamp config. */ struct hwtstamp_config stamp_cfg; -#endif }; static struct mpipe_data { @@ -229,14 +227,12 @@ static struct mpipe_data { int first_bucket; int num_buckets; -#ifdef CONFIG_PTP_1588_CLOCK_TILEGX /* PTP-specific data. */ struct ptp_clock *ptp_clock; struct ptp_clock_info caps; /* Lock for ptp accessors. */ struct mutex ptp_lock; -#endif } mpipe_data[NR_MPIPE_MAX] = { [0 ... (NR_MPIPE_MAX - 1)] { @@ -451,20 +447,17 @@ static void tile_net_provide_needed_buffers(void) static void tile_rx_timestamp(struct tile_net_priv *priv, struct sk_buff *skb, gxio_mpipe_idesc_t *idesc) { -#ifdef CONFIG_PTP_1588_CLOCK_TILEGX if (unlikely(priv->stamp_cfg.rx_filter != HWTSTAMP_FILTER_NONE)) { struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); memset(shhwtstamps, 0, sizeof(*shhwtstamps)); shhwtstamps->hwtstamp = ktime_set(idesc->time_stamp_sec, idesc->time_stamp_ns); } -#endif } /* Get TX timestamp, and store it in the skb. */ static void tile_tx_timestamp(struct sk_buff *skb, int instance) { -#ifdef CONFIG_PTP_1588_CLOCK_TILEGX struct skb_shared_info *shtx = skb_shinfo(skb); if (unlikely((shtx->tx_flags & SKBTX_HW_TSTAMP) != 0)) { struct mpipe_data *md = &mpipe_data[instance]; @@ -477,14 +470,11 @@ static void tile_tx_timestamp(struct sk_buff *skb, int instance) shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); skb_tstamp_tx(skb, &shhwtstamps); } -#endif } /* Use ioctl() to enable or disable TX or RX timestamping. */ -static int tile_hwtstamp_ioctl(struct net_device *dev, struct ifreq *rq, - int cmd) +static int tile_hwtstamp_set(struct net_device *dev, struct ifreq *rq) { -#ifdef CONFIG_PTP_1588_CLOCK_TILEGX struct hwtstamp_config config; struct tile_net_priv *priv = netdev_priv(dev); @@ -530,9 +520,17 @@ static int tile_hwtstamp_ioctl(struct net_device *dev, struct ifreq *rq, priv->stamp_cfg = config; return 0; -#else - return -EOPNOTSUPP; -#endif +} + +static int tile_hwtstamp_get(struct net_device *dev, struct ifreq *rq) +{ + struct tile_net_priv *priv = netdev_priv(dev); + + if (copy_to_user(rq->ifr_data, &priv->stamp_cfg, + sizeof(priv->stamp_cfg))) + return -EFAULT; + + return 0; } static inline bool filter_packet(struct net_device *dev, void *buf) @@ -661,6 +659,9 @@ static int tile_net_poll(struct napi_struct *napi, int budget) struct info_mpipe *info_mpipe = container_of(napi, struct info_mpipe, napi); + if (budget <= 0) + goto done; + instance = info_mpipe->instance; while ((n = gxio_mpipe_iqueue_try_peek( &info_mpipe->iqueue, @@ -814,8 +815,6 @@ static enum hrtimer_restart tile_net_handle_egress_timer(struct hrtimer *t) return HRTIMER_NORESTART; } -#ifdef CONFIG_PTP_1588_CLOCK_TILEGX - /* PTP clock operations. */ static int ptp_mpipe_adjfreq(struct ptp_clock_info *ptp, s32 ppb) @@ -874,6 +873,7 @@ static struct ptp_clock_info ptp_mpipe_caps = { .name = "mPIPE clock", .max_adj = 999999999, .n_ext_ts = 0, + .n_pins = 0, .pps = 0, .adjfreq = ptp_mpipe_adjfreq, .adjtime = ptp_mpipe_adjtime, @@ -882,12 +882,9 @@ static struct ptp_clock_info ptp_mpipe_caps = { .enable = ptp_mpipe_enable, }; -#endif /* CONFIG_PTP_1588_CLOCK_TILEGX */ - /* Sync mPIPE's timestamp up with Linux system time and register PTP clock. */ static void register_ptp_clock(struct net_device *dev, struct mpipe_data *md) { -#ifdef CONFIG_PTP_1588_CLOCK_TILEGX struct timespec ts; getnstimeofday(&ts); @@ -899,16 +896,13 @@ static void register_ptp_clock(struct net_device *dev, struct mpipe_data *md) if (IS_ERR(md->ptp_clock)) netdev_err(dev, "ptp_clock_register failed %ld\n", PTR_ERR(md->ptp_clock)); -#endif } /* Initialize PTP fields in a new device. */ static void init_ptp_dev(struct tile_net_priv *priv) { -#ifdef CONFIG_PTP_1588_CLOCK_TILEGX priv->stamp_cfg.rx_filter = HWTSTAMP_FILTER_NONE; priv->stamp_cfg.tx_type = HWTSTAMP_TX_OFF; -#endif } /* Helper functions for "tile_net_update()". */ @@ -1214,8 +1208,8 @@ static int tile_net_setup_interrupts(struct net_device *dev) irq = md->ingress_irq; if (irq < 0) { - irq = create_irq(); - if (irq < 0) { + irq = irq_alloc_hwirq(-1); + if (!irq) { netdev_err(dev, "create_irq failed: mpipe[%d] %d\n", instance, irq); @@ -1229,7 +1223,7 @@ static int tile_net_setup_interrupts(struct net_device *dev) if (rc != 0) { netdev_err(dev, "request_irq failed: mpipe[%d] %d\n", instance, rc); - destroy_irq(irq); + irq_free_hwirq(irq); return rc; } md->ingress_irq = irq; @@ -2080,7 +2074,8 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev) } /* Return subqueue id on this core (one per core). */ -static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb) +static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) { return smp_processor_id(); } @@ -2098,7 +2093,9 @@ static void tile_net_tx_timeout(struct net_device *dev) static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { if (cmd == SIOCSHWTSTAMP) - return tile_hwtstamp_ioctl(dev, rq, cmd); + return tile_hwtstamp_set(dev, rq); + if (cmd == SIOCGHWTSTAMP) + return tile_hwtstamp_get(dev, rq); return -EOPNOTSUPP; } @@ -2194,8 +2191,6 @@ static void tile_net_setup(struct net_device *dev) static void tile_net_dev_init(const char *name, const uint8_t *mac) { int ret; - int i; - int nz_addr = 0; struct net_device *dev; struct tile_net_priv *priv; @@ -2215,7 +2210,6 @@ static void tile_net_dev_init(const char *name, const uint8_t *mac) /* Initialize "priv". */ priv = netdev_priv(dev); - memset(priv, 0, sizeof(*priv)); priv->dev = dev; priv->channel = -1; priv->loopify_channel = -1; @@ -2226,15 +2220,10 @@ static void tile_net_dev_init(const char *name, const uint8_t *mac) * be done before the device is opened. If the MAC is all zeroes, * we use a random address, since we're probably on the simulator. */ - for (i = 0; i < 6; i++) - nz_addr |= mac[i]; - - if (nz_addr) { - memcpy(dev->dev_addr, mac, 6); - dev->addr_len = 6; - } else { + if (!is_zero_ether_addr(mac)) + ether_addr_copy(dev->dev_addr, mac); + else eth_hw_addr_random(dev); - } /* Register the network device. */ ret = register_netdev(dev); diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index 106be47716e..e5a5c5d4ce0 100644 --- a/drivers/net/ethernet/tile/tilepro.c +++ b/drivers/net/ethernet/tile/tilepro.c @@ -831,6 +831,9 @@ static int tile_net_poll(struct napi_struct *napi, int budget) unsigned int work = 0; + if (budget <= 0) + goto done; + while (priv->active) { int index = qup->__packet_receive_read; if (index == qsp->__packet_receive_queue.__packet_write) @@ -1008,6 +1011,8 @@ static void tile_net_register(void *dev_ptr) info->egress_timer.data = (long)info; info->egress_timer.function = tile_net_handle_egress_timer; + u64_stats_init(&info->stats.syncp); + priv->cpu[my_cpu] = info; /* @@ -1819,7 +1824,7 @@ busy: /* Handle completions. */ for (i = 0; i < nolds; i++) - kfree_skb(olds[i]); + dev_consume_skb_any(olds[i]); /* Update stats. */ u64_stats_update_begin(&stats->syncp); @@ -2003,7 +2008,7 @@ busy: /* Handle completions. */ for (i = 0; i < nolds; i++) - kfree_skb(olds[i]); + dev_consume_skb_any(olds[i]); /* HACK: Track "expanded" size for short packets (e.g. 42 < 60). */ u64_stats_update_begin(&stats->syncp); @@ -2066,14 +2071,14 @@ static struct rtnl_link_stats64 *tile_net_get_stats64(struct net_device *dev, cpu_stats = &priv->cpu[i]->stats; do { - start = u64_stats_fetch_begin_bh(&cpu_stats->syncp); + start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); trx_packets = cpu_stats->rx_packets; ttx_packets = cpu_stats->tx_packets; trx_bytes = cpu_stats->rx_bytes; ttx_bytes = cpu_stats->tx_bytes; trx_errors = cpu_stats->rx_errors; trx_dropped = cpu_stats->rx_dropped; - } while (u64_stats_fetch_retry_bh(&cpu_stats->syncp, start)); + } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); rx_packets += trx_packets; tx_packets += ttx_packets; |
