update tile network drivers
Subsystems (3)
cover update tile network drivers
This patch series contains changes made to the Tilera on-chip network drivers for both the 64-bit tilegx and 32-bit tilepro architectures. The changes involve a number of bug fixes, support for the multiple mPIPEs on the new Gx72 chip, support for jumbo frames, TSO for IPv6, GRO, PTP support, and statistics improvements.
The series can be pulled from:
git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile.git tile-net-next
Chris Metcalf (13):
tile: handle 64-bit statistics in tilepro network driver
tile: support rx_dropped/rx_errors in tilepro net driver
tile: avoid bug in tilepro net driver built with old hypervisor
tile: remove dead is_dup_ack() function from tilepro net driver
tile: support PTP using the tilegx mPIPE (IEEE 1588)
tile: support jumbo frames in the tilegx network driver
tile: update dev->stats directly in tilegx network driver
tile: fix panic bug in napi support for tilegx network driver
tile: enable GRO in the tilegx network driver
tile: support multiple mPIPE shims in tilegx network driver
tile: support TSO for IPv6 in tilegx network driver
tile: make "tile_net.custom" a proper bool module parameter
tile: remove deprecated NETIF_F_LLTX flag from tile drivers
arch/tile/gxio/iorpc_mpipe.c | 66 +++ arch/tile/gxio/iorpc_mpipe_info.c | 18 + arch/tile/gxio/mpipe.c | 44 +- arch/tile/include/gxio/iorpc_mpipe.h | 8 + arch/tile/include/gxio/iorpc_mpipe_info.h | 4 + arch/tile/include/gxio/mpipe.h | 142 ++++- arch/tile/include/hv/drv_mpipe_intf.h | 3 + drivers/net/ethernet/tile/Makefile | 1 + drivers/net/ethernet/tile/tilegx.c | 954 ++++++++++++++++++------------ drivers/net/ethernet/tile/tilegx_ptp.c | 212 +++++++ drivers/net/ethernet/tile/tilepro.c | 171 ++---- drivers/ptp/Kconfig | 10 + 12 files changed, 1127 insertions(+), 506 deletions(-) create mode 100644 drivers/net/ethernet/tile/tilegx_ptp.c
Signature · 1 line
1.8.3.1
PATCH 1/13 tile: handle 64-bit statistics in tilepro network driver
--- drivers/net/ethernet/tile/tilepro.c | 42 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-)
drivers/net/ethernet/tile/tilepro.c +20 -22
@@ -156,10 +156,14 @@ struct tile_netio_queue {* Statistics counters for a specific cpu and device. */ struct tile_net_stats_t { -u32 rx_packets; -u32 rx_bytes; -u32 tx_packets; -u32 tx_bytes; +u64 rx_packets;/* total packets received */ +u64 tx_packets;/* total packets transmitted */ +u64 rx_bytes;/* total bytes received */ +u64 tx_bytes;/* total bytes transmitted */ +u64 rx_errors;/* packets truncated or marked bad by hw */ +u64 tx_errors;/* (not currently used) */ +u64 rx_dropped;/* packets not for us or intf not up */ +u64 tx_dropped;/* (not currently used) */ };
@@ -218,8 +222,6 @@ struct tile_net_priv {int network_cpus_count;/* Credits per network cpu. */ int network_cpus_credits; -/* Network stats. */ -struct net_device_stats stats;/* For NetIO bringup retries. */ struct delayed_work retry_work;/* Quick access to per cpu data. */
@@ -2127,30 +2129,26 @@ static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)* * Returns the address of the device statistics structure. */ -static struct net_device_stats *tile_net_get_stats (struct net_device *dev) +static struct rtnl_link_stats64 *tile_net_get_stats64 (struct net_device *dev, +struct rtnl_link_stats64 *stats) {struct tile_net_priv *priv =netdev_priv (dev); -u32 rx_packets =0 ; -u32 tx_packets =0 ; -u32 rx_bytes =0 ; -u32 tx_bytes =0 ;int i;for_each_online_cpu (i) {if (priv->cpu[i]) { - rx_packets += priv->cpu[i]->stats.rx_packets; - rx_bytes += priv->cpu[i]->stats.rx_bytes; - tx_packets += priv->cpu[i]->stats.tx_packets; - tx_bytes += priv->cpu[i]->stats.tx_bytes; + stats->rx_packets += priv->cpu[i]->stats.rx_packets; + stats->tx_packets += priv->cpu[i]->stats.tx_packets; + stats->rx_bytes += priv->cpu[i]->stats.rx_bytes; + stats->tx_bytes += priv->cpu[i]->stats.tx_bytes; + stats->rx_errors += priv->cpu[i]->stats.rx_errors; + stats->tx_errors += priv->cpu[i]->stats.tx_errors; + stats->rx_dropped += priv->cpu[i]->stats.rx_dropped; + stats->tx_dropped += priv->cpu[i]->stats.tx_dropped; } } - priv->stats.rx_packets = rx_packets; - priv->stats.rx_bytes = rx_bytes; - priv->stats.tx_packets = tx_packets; - priv->stats.tx_bytes = tx_bytes; - -return &priv->stats; +return stats; }
@@ -2287,7 +2285,7 @@ static const struct net_device_ops tile_net_ops = { .ndo_stop = tile_net_stop, .ndo_start_xmit = tile_net_tx, .ndo_do_ioctl = tile_net_ioctl, - .ndo_get_stats = tile_net_get_stats, + .ndo_get_stats64 = tile_net_get_stats64, .ndo_change_mtu = tile_net_change_mtu, .ndo_tx_timeout = tile_net_tx_timeout, .ndo_set_mac_address = tile_net_set_mac_address,
Signature · 1 line
1.8.3.1
David Miller
maintainerRe: [PATCH 01/13] tile: handle 64-bit statistics in tilepro network driver
From: Chris Metcalf <[email protected]>
Date: Tue, 23 Jul 2013 16:05:48 -0400
Quoted 1 line
Signed-off-by Chris Metcalf <[email protected]>
I'm pretty sure that you need to make use of the primitives in include/linux/u64_stats_sync.h if you want to use 64-bit statistics in this way.
PATCH v2 1/1 tile: handle 64-bit statistics in tilepro network driver
---
v2: use <linux/u64_stats_sync.h> primitives
drivers/net/ethernet/tile/tilepro.c | 77 ++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 23 deletions(-)
drivers/net/ethernet/tile/tilepro.c +54 -23
@@ -31,6 +31,7 @@#include <linux/in6.h> #include <linux/timer.h> #include <linux/io.h> +#include <linux/u64_stats_sync.h> #include <asm/checksum.h> #include <asm/homecache.h>
@@ -156,10 +157,13 @@ struct tile_netio_queue {* Statistics counters for a specific cpu and device. */ struct tile_net_stats_t { -u32 rx_packets; -u32 rx_bytes; -u32 tx_packets; -u32 tx_bytes; +struct u64_stats_sync syncp; +u64 rx_packets;/* total packets received */ +u64 tx_packets;/* total packets transmitted */ +u64 rx_bytes;/* total bytes received */ +u64 tx_bytes;/* total bytes transmitted */ +u64 rx_errors;/* packets truncated or marked bad by hw */ +u64 rx_dropped;/* packets not for us or intf not up */ };
@@ -218,8 +222,6 @@ struct tile_net_priv {int network_cpus_count;/* Credits per network cpu. */ int network_cpus_credits; -/* Network stats. */ -struct net_device_stats stats;/* For NetIO bringup retries. */ struct delayed_work retry_work;/* Quick access to per cpu data. */
@@ -847,6 +849,8 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index) } } +u64_stats_update_begin (&stats->syncp); +if (filter) {/* ISSUE: Update "drop" statistics? */
@@ -881,6 +885,8 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index) stats->rx_bytes += len; } +u64_stats_update_end (&stats->syncp); +/* ISSUE: It would be nice to defer this until the packet has */ /* actually been processed. */ tile_net_return_credit (info);
@@ -1907,8 +1913,10 @@ busy:kfree_skb (olds[i]);/* Update stats. */ +u64_stats_update_begin (&stats->syncp); stats->tx_packets += num_segs; stats->tx_bytes += (num_segs * sh_len) + d_len; +u64_stats_update_end (&stats->syncp);/* Make sure the egress timer is scheduled. */ tile_net_schedule_egress_timer (info);
@@ -2089,8 +2097,10 @@ busy:kfree_skb (olds[i]);/* HACK: Track "expanded" size for short packets (e.g. 42 < 60). */ +u64_stats_update_begin (&stats->syncp); stats->tx_packets++; stats->tx_bytes += ((len >=ETH_ZLEN ) ? len :ETH_ZLEN ); +u64_stats_update_end (&stats->syncp);/* Make sure the egress timer is scheduled. */ tile_net_schedule_egress_timer (info);
@@ -2127,30 +2137,51 @@ static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)* * Returns the address of the device statistics structure. */ -static struct net_device_stats *tile_net_get_stats (struct net_device *dev) +static struct rtnl_link_stats64 *tile_net_get_stats64 (struct net_device *dev, +struct rtnl_link_stats64 *stats) {struct tile_net_priv *priv =netdev_priv (dev); -u32 rx_packets =0 ; -u32 tx_packets =0 ; -u32 rx_bytes =0 ; -u32 tx_bytes =0 ; +u64 rx_packets =0 , tx_packets =0 ; +u64 rx_bytes =0 , tx_bytes =0 ; +u64 rx_errors =0 , rx_dropped =0 ;int i;for_each_online_cpu (i) { -if (priv->cpu[i]) { - rx_packets += priv->cpu[i]->stats.rx_packets; - rx_bytes += priv->cpu[i]->stats.rx_bytes; - tx_packets += priv->cpu[i]->stats.tx_packets; - tx_bytes += priv->cpu[i]->stats.tx_bytes; - } +struct tile_net_stats_t *cpu_stats; +u64 trx_packets, ttx_packets, trx_bytes, ttx_bytes; +u64 trx_errors, trx_dropped; +unsigned int start; + +if (priv->cpu[i] ==NULL ) +continue ; + cpu_stats = &priv->cpu[i]->stats; + +do { + start =u64_stats_fetch_begin_bh (&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)); + + rx_packets += trx_packets; + tx_packets += ttx_packets; + rx_bytes += trx_bytes; + tx_bytes += ttx_bytes; + rx_errors += trx_errors; + rx_dropped += trx_dropped; } - priv->stats.rx_packets = rx_packets; - priv->stats.rx_bytes = rx_bytes; - priv->stats.tx_packets = tx_packets; - priv->stats.tx_bytes = tx_bytes; + stats->rx_packets = rx_packets; + stats->tx_packets = tx_packets; + stats->rx_bytes = rx_bytes; + stats->tx_bytes = tx_bytes; + stats->rx_errors = rx_errors; + stats->rx_dropped = rx_dropped; -return &priv->stats; +return stats; }
@@ -2287,7 +2318,7 @@ static const struct net_device_ops tile_net_ops = { .ndo_stop = tile_net_stop, .ndo_start_xmit = tile_net_tx, .ndo_do_ioctl = tile_net_ioctl, - .ndo_get_stats = tile_net_get_stats, + .ndo_get_stats64 = tile_net_get_stats64, .ndo_change_mtu = tile_net_change_mtu, .ndo_tx_timeout = tile_net_tx_timeout, .ndo_set_mac_address = tile_net_set_mac_address,
Signature · 1 line
1.8.3.1
Re: [PATCH v2] tile: handle 64-bit statistics in tilepro network driver
From: Chris Metcalf <[email protected]>
Date: Thu, 25 Jul 2013 12:41:15 -0400
Quoted 1 line
Signed-off-by Chris Metcalf <[email protected]>
Applied, thanks.
Your PTP patch for the Tile driver doesn't even come close to applying properly to net-next, please respin it and report if you want me to apply it.
Thanks.
Re: [PATCH v2] tile: handle 64-bit statistics in tilepro network driver
Quoted 11 lines · David Miller
From: Chris Metcalf <[email protected]>
Date: Thu, 25 Jul 2013 12:41:15 -0400Quoted 1 line
Signed-off-by Chris Metcalf <[email protected]>Applied, thanks.
Your PTP patch for the Tile driver doesn't even come close to applying properly to net-next, please respin it and report if you want me to apply it.
Thanks.
It might be easiest to pull the whole series from:
git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile.git tile-net-next
Chris Metcalf (13):
tile: handle 64-bit statistics in tilepro network driver
tile: support rx_dropped/rx_errors in tilepro net driver
tile: avoid bug in tilepro net driver built with old hypervisor
tile: remove dead is_dup_ack() function from tilepro net driver
tile: support jumbo frames in the tilegx network driver
tile: update dev->stats directly in tilegx network driver
tile: fix panic bug in napi support for tilegx network driver
tile: enable GRO in the tilegx network driver
tile: support multiple mPIPE shims in tilegx network driver
tile: support TSO for IPv6 in tilegx network driver
tile: make "tile_net.custom" a proper bool module parameter
tile: remove deprecated NETIF_F_LLTX flag from tile drivers
tile: support PTP using the tilegx mPIPE (IEEE 1588)
arch/tile/gxio/iorpc_mpipe.c | 66 ++ arch/tile/gxio/iorpc_mpipe_info.c | 18 + arch/tile/gxio/mpipe.c | 43 +- arch/tile/include/gxio/iorpc_mpipe.h | 14 +- arch/tile/include/gxio/iorpc_mpipe_info.h | 4 + arch/tile/include/gxio/mpipe.h | 143 +++- arch/tile/include/hv/drv_mpipe_intf.h | 3 + drivers/net/ethernet/tile/Kconfig | 11 + drivers/net/ethernet/tile/tilegx.c | 1097 +++++++++++++++++++---------- drivers/net/ethernet/tile/tilepro.c | 206 ++---- 10 files changed, 1100 insertions(+), 505 deletions(-)
Aside from the tilepro 64-bit stats change, and the PTP change, the other changes didn't receive any substantive feedback. (Eric Dumazet pointed out that explicit NETIF_F_GRO was unnecessary, so I removed it.)
Signature · 2 lines
Chris Metcalf, Tilera Corp. http://www.tilera.com
David Miller
maintainerRe: [PATCH v2] tile: handle 64-bit statistics in tilepro network driver
From: Chris Metcalf <[email protected]>
Date: Tue, 30 Jul 2013 20:34:52 -0400
Quoted 7 lines · David Miller
Quoted 6 lines
From: Chris Metcalf <[email protected]>
Date: Thu, 25 Jul 2013 12:41:15 -0400Quoted 1 line
Signed-off-by Chris Metcalf <[email protected]>Applied, thanks.
Quoted 7 lines
Quoted 5 lines
Your PTP patch for the Tile driver doesn't even come close to applying properly to net-next, please respin it and report if you want me to apply it.
Thanks.
It might be easiest to pull the whole series from:
No Chris, you have to freshly post the patches as a series here when you want me to pull something.
That way it actually can get reviewed.
PATCH 2/13 tile: support rx_dropped/rx_errors in tilepro net driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilepro.c | 41 ++++++++++++++----------------------- 1 file changed, 15 insertions(+), 26 deletions(-)
drivers/net/ethernet/tile/tilepro.c +15 -26
@@ -776,6 +776,7 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)netio_pkt_t *pkt = (netio_pkt_t *)((unsigned long ) &qsp[1 ] + index);netio_pkt_metadata_t *metadata =NETIO_PKT_METADATA (pkt); +netio_pkt_status_t pkt_status =NETIO_PKT_STATUS_M (metadata, pkt);/* Extract the packet size. FIXME: Shouldn't the second line */ /* get subtracted? Mostly moot, since it should be "zero". */
@@ -808,40 +809,25 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)#endif /* TILE_NET_DUMP_PACKETS */ #ifdef TILE_NET_VERIFY_INGRESS -if (!NETIO_PKT_L4_CSUM_CORRECT_M (metadata, pkt) && -NETIO_PKT_L4_CSUM_CALCULATED_M (metadata, pkt)) { -/* Bug 6624: Includes UDP packets with a "zero" checksum. */ -pr_warning ("Bad L4 checksum on %d byte packet.\n" , len); - } -if (!NETIO_PKT_L3_CSUM_CORRECT_M (metadata, pkt) && -NETIO_PKT_L3_CSUM_CALCULATED_M (metadata, pkt)) { +if (pkt_status ==NETIO_PKT_STATUS_OVERSIZE && len >=64 ) {dump_packet (buf, len,"rx" ); -panic ("Bad L3 checksum." ); - } -switch (NETIO_PKT_STATUS_M (metadata, pkt)) { -case NETIO_PKT_STATUS_OVERSIZE : -if (len >=64 ) { -dump_packet (buf, len,"rx" ); -panic ("Unexpected OVERSIZE." ); - } -break ; -case NETIO_PKT_STATUS_BAD : -pr_warning ("Unexpected BAD %ld byte packet.\n" , len); +panic ("Unexpected OVERSIZE." ); }#endif filter =0 ; -/* ISSUE: Filter TCP packets with "bad" checksums? */ - -if (!(dev->flags &IFF_UP )) { +if (pkt_status ==NETIO_PKT_STATUS_BAD ) { +/* Handle CRC error and hardware truncation. */ + filter =2 ; + }else if (!(dev->flags &IFF_UP )) {/* Filter packets received before we're up. */ filter =1 ; - }else if (NETIO_PKT_STATUS_M (metadata, pkt) ==NETIO_PKT_STATUS_BAD ) { + }else if (NETIO_PKT_ETHERTYPE_RECOGNIZED_M (metadata, pkt) && + pkt_status ==NETIO_PKT_STATUS_UNDERSIZE ) {/* Filter "truncated" packets. */ - filter =1 ; + filter =2 ; }else if (!(dev->flags &IFF_PROMISC )) { -/* FIXME: Implement HW multicast filter. */ if (!is_multicast_ether_addr (buf)) {/* Filter packets not for our address. */ const u8 *mine = dev->dev_addr;
@@ -849,9 +835,12 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index) } } -if (filter) { +if (filter !=0 ) { -/* ISSUE: Update "drop" statistics? */ +if (filter ==1 ) + stats->rx_dropped++; +else + stats->rx_errors++;tile_net_provide_linux_buffer (info, va, small);
Signature · 1 line
1.8.3.1
PATCH 3/13 tile: avoid bug in tilepro net driver built with old hypervisor
In reply to Chris MetcalfBuilding against headers from an older Tilera hypervisor can cause the frags[] array to be overrun. Don't enable TSO in that case.
--- drivers/net/ethernet/tile/tilepro.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/net/ethernet/tile/tilepro.c +5 -4
@@ -1927,7 +1927,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)unsigned int csum_start =skb_checksum_start_offset (skb); -lepp_frag_t frags[LEPP_MAX_FRAGS ]; +lepp_frag_t frags[1 +MAX_SKB_FRAGS ];unsigned int num_frags;
@@ -1942,7 +1942,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)unsigned int cmd_head, cmd_tail, cmd_next;unsigned int comp_tail; -lepp_cmd_t cmds[LEPP_MAX_FRAGS ]; +lepp_cmd_t cmds[1 +MAX_SKB_FRAGS ];/*
@@ -2309,8 +2309,9 @@ static void tile_net_setup(struct net_device *dev)/* We support scatter/gather. */ dev->features |=NETIF_F_SG ; -/* We support TSO. */ - dev->features |=NETIF_F_TSO ; +/* We support TSO iff the HV supports sufficient frags. */ +if (LEPP_MAX_FRAGS >=1 +MAX_SKB_FRAGS ) + dev->features |=NETIF_F_TSO ;#ifdef TILE_NET_GSO /* We support GSO. */
Signature · 1 line
1.8.3.1
PATCH 4/13 tile: remove dead is_dup_ack() function from tilepro net driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilepro.c | 76 ------------------------------------- 1 file changed, 76 deletions(-)
drivers/net/ethernet/tile/tilepro.c +0 -76
@@ -92,9 +92,6 @@/* ISSUE: This may actually hurt performance of the TCP blaster. */ /* #define TILE_NET_GSO */ -/* Define this to collapse "duplicate" acks. */ -/* #define IGNORE_DUP_ACKS */ -/* HACK: Define this to verify incoming packets. */ /* #define TILE_NET_VERIFY_INGRESS */
@@ -629,79 +626,6 @@ static void tile_net_handle_egress_timer(unsigned long arg) } -#ifdef IGNORE_DUP_ACKS - -/* -* Help detect "duplicate" ACKs. These are sequential packets (for a -* given flow) which are exactly 66 bytes long, sharing everything but -* ID=2@0x12, Hsum=2@0x18, Ack=4@0x2a, WinSize=2@0x30, Csum=2@0x32, -* Tstamps=10@0x38. The ID's are +1, the Hsum's are -1, the Ack's are -* +N, and the Tstamps are usually identical. -* -* NOTE: Apparently truly duplicate acks (with identical "ack" values), -* should not be collapsed, as they are used for some kind of flow control. -*/ -static bool is_dup_ack (char *s1,char *s2,unsigned int len) -{ -int i; - -unsigned long long ignorable =0 ; - -/* Identification. */ - ignorable |= (1ULL <<0x12 ); - ignorable |= (1ULL <<0x13 ); - -/* Header checksum. */ - ignorable |= (1ULL <<0x18 ); - ignorable |= (1ULL <<0x19 ); - -/* ACK. */ - ignorable |= (1ULL <<0x2a ); - ignorable |= (1ULL <<0x2b ); - ignorable |= (1ULL <<0x2c ); - ignorable |= (1ULL <<0x2d ); - -/* WinSize. */ - ignorable |= (1ULL <<0x30 ); - ignorable |= (1ULL <<0x31 ); - -/* Checksum. */ - ignorable |= (1ULL <<0x32 ); - ignorable |= (1ULL <<0x33 ); - -for (i =0 ; i < len; i++, ignorable >>=1 ) { - -if ((ignorable &1 ) || (s1[i] == s2[i])) -continue ; - -#ifdef TILE_NET_DEBUG -/* HACK: Mention non-timestamp diffs. */ -if (i <0x38 && i !=0x2f && -net_ratelimit ()) -pr_info ("Diff at 0x%x\n" , i); -#endif - -return false; - } - -#ifdef TILE_NET_NO_SUPPRESS_DUP_ACKS -/* HACK: Do not suppress truly duplicate ACKs. */ -/* ISSUE: Is this actually necessary or helpful? */ -if (s1[0x2a ] == s2[0x2a ] && - s1[0x2b ] == s2[0x2b ] && - s1[0x2c ] == s2[0x2c ] && - s1[0x2d ] == s2[0x2d ]) { -return false; - } -#endif - -return true; -} - -#endif - - -static void tile_net_discard_aux (struct tile_net_cpu *info,int index) {struct tile_netio_queue *queue = &info->queue;
Signature · 1 line
1.8.3.1
PATCH 5/13 tile: support PTP using the tilegx mPIPE (IEEE 1588)
In reply to Chris Metcalf--- arch/tile/gxio/iorpc_mpipe.c | 19 ++++ arch/tile/include/gxio/iorpc_mpipe.h | 4 + arch/tile/include/gxio/mpipe.h | 13 +++ drivers/net/ethernet/tile/Makefile | 1 + drivers/net/ethernet/tile/tilegx.c | 56 +++++++++ drivers/net/ethernet/tile/tilegx_ptp.c | 202 +++++++++++++++++++++++++++++++++ drivers/ptp/Kconfig | 10 ++ 7 files changed, 305 insertions(+) create mode 100644 drivers/net/ethernet/tile/tilegx_ptp.c
arch/tile/gxio/iorpc_mpipe.c +19 -0
@@ -454,6 +454,25 @@ int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_aux); +struct adjust_timestamp_freq_param { +int32_t ppb; +}; + +int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb) +{ +struct adjust_timestamp_freq_param temp; +struct adjust_timestamp_freq_param *params = &temp; + + params->ppb = ppb; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params), +GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ ); +} + +EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_freq); +struct arm_pollfd_param {union iorpc_pollfd pollfd; };
arch/tile/include/gxio/iorpc_mpipe.h +4 -0
@@ -48,6 +48,7 @@#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121e)#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121f)#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1220) +#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1222)#define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)#define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)#define GXIO_MPIPE_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
@@ -124,6 +125,9 @@ int gxio_mpipe_set_timestamp_aux(gxio_mpipe_context_t * context, uint64_t sec,int gxio_mpipe_adjust_timestamp_aux (gxio_mpipe_context_t * context,int64_t nsec); +int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb); +int gxio_mpipe_arm_pollfd (gxio_mpipe_context_t * context,int pollfd_cookie);int gxio_mpipe_close_pollfd (gxio_mpipe_context_t * context,int pollfd_cookie);
arch/tile/include/gxio/mpipe.h +13 -0
@@ -1733,4 +1733,17 @@ extern int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context,extern int gxio_mpipe_adjust_timestamp (gxio_mpipe_context_t *context,int64_t delta); +/* Adjust the mPIPE timestamp clock frequency. +* +* @param context An initialized mPIPE context. +* @param ppb A 32-bits signed PPB(Parts Per Billion) value to adjust. +* The absolute value of ppb must be less than or equal to 1000000000, +* and should be larger then 30000, otherwise just ignored because of +* the clock precision restriction. +* @return If the call was successful, zero; otherwise, a negative error +* code. +*/ +extern int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t *context, +int32_t ppb); +#endif /* !_GXIO_MPIPE_H_ */
drivers/net/ethernet/tile/Makefile +1 -0
@@ -5,6 +5,7 @@ obj-$(CONFIG_TILE_NET) += tile_net.o ifdef CONFIG_TILEGX tile_net-y := tilegx.o +obj-$(CONFIG_PTP_1588_CLOCK_TILEGX) += tilegx_ptp.o else tile_net-y := tilepro.o endif
drivers/net/ethernet/tile/tilegx.c +56 -0
98 lines not on this page · raw message
drivers/net/ethernet/tile/tilegx_ptp.c new file +202 -0
202 lines not on this page · raw message
drivers/ptp/Kconfig +10 -0
@@ -87,4 +87,14 @@ config PTP_1588_CLOCK_PCH To compile this driver as a module, choose M here: the module will be called ptp_pch. +config PTP_1588_CLOCK_TILEGX + tristate "Tilera TILE-Gx mPIPE as PTP clock" + select PTP_1588_CLOCK + 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. + endmenu
Signature · 1 line
1.8.3.1
Richard Cochran
maintainerRe: [PATCH 05/13] tile: support PTP using the tilegx mPIPE (IEEE 1588)
Chris,
This mail is a duplicate to you. I left off the CCs by mistake.
Quoted 5 lines · Chris Metcalf
arch/tile/include/gxio/mpipe.h +0
-0
arch/tile/include/gxio/mpipe.h extern int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context, · line 1742
Quoted 10 lines
arch/tile/include/gxio/mpipe.h +7
-0@@ -1733,4 +1733,17 @@ extern int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context,extern int gxio_mpipe_adjust_timestamp (gxio_mpipe_context_t *context,int64_t delta); +/* Adjust the mPIPE timestamp clock frequency. +* +* @param context An initialized mPIPE context. +* @param ppb A 32-bits signed PPB(Parts Per Billion) value to adjust. +* The absolute value of ppb must be less than or equal to 1000000000, +* and should be larger then 30000, otherwise just ignored because of +* the clock precision restriction.
30 ppm? That is not too good.
What do you mean by "should be larger"? The caller (from user space) has no way to know about this limitation.
Quoted 7 lines
arch/tile/include/gxio/mpipe.h +6
-0+* @return If the call was successful, zero; otherwise, a negative error +* code. +*/ +extern int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t *context, +int32_t ppb); +#endif /* !_GXIO_MPIPE_H_ */
...
Quoted 4 lines
drivers/net/ethernet/tile/tilegx.c +0
-0
...
drivers/net/ethernet/tile/tilegx.c static int tile_net_stop(struct net_device *dev) · line 1330
Quoted 7 lines
drivers/net/ethernet/tile/tilegx.c +3
-0@@ -1284,6 +1325,12 @@ static int tile_net_stop(struct net_device *dev)return 0 ; } +gxio_mpipe_context_t *get_mpipe_context (int index) +{ +return ingress_irq <0 ?NULL : &context;
So having a PHC depends on this IRQ having been initialized. Why not just register the PHC in the same place?
Quoted 6 lines
drivers/net/ethernet/tile/tilegx.c +3
-0+} +EXPORT_SYMBOL_GPL (get_mpipe_context); +/* Determine the VA for a fragment. */ static inline void *tile_net_frag_buf (skb_frag_t *f) {
...
drivers/net/ethernet/tile/tilegx.c static void tile_net_tx_timeout(struct net_device *dev) · line 1783
Quoted 8 lines
drivers/net/ethernet/tile/tilegx.c +4
-0@@ -1727,6 +1777,12 @@ static void tile_net_tx_timeout(struct net_device *dev)/* Ioctl commands. */ static int tile_net_ioctl (struct net_device *dev,struct ifreq *rq,int cmd) { +#ifdef CONFIG_PTP_1588_CLOCK_TILEGX +if (cmd ==SIOCSHWTSTAMP ) { +/* Hardware timestamping was enabled by default. */ +return 0 ;
This won't do. You need to update tx_type and rx_filter to reflect the actual settings.
Quoted 18 lines
drivers/net/ethernet/tile/tilegx.c +2
-0+ } +#endif return -EOPNOTSUPP ; }drivers/net/ethernet/tile/tilegx_ptp.c new file +6
-0@@ -0,0 +1,202 @@ +/* +* PTP 1588 clock using the TILE-Gx. +* +* Copyright 2013 Tilera Corporation. All Rights Reserved. +* +* This program is free software; you can redistribute it and/or
drivers/net/ethernet/tile/tilegx_ptp.c line 16
Quoted 10 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +10
-0+* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation, version 2. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or +* NON INFRINGEMENT. See the GNU General Public License for +* more details. +* +* This source code is derived from ptp_ixp46x.c wrote by Richard Cochran.
^^^^^^^^
"written by"
Quoted 15 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +15
-0+*/ + +#include <linux/device.h> +#include <linux/err.h> +#include <linux/gpio.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/ptp_clock_kernel.h> + +#include <gxio/mpipe.h> +#include <gxio/iorpc_mpipe.h>
drivers/net/ethernet/tile/tilegx_ptp.c line 41
Quoted 10 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +10
-0+ +#define GBE_LINK_NR 4 + +/* nanoseconds will be incremented each clock cycle. */ +#define GBE_TIMER_INCREMENT 8 + + +MODULE_AUTHOR ("Tilera Corporation" ); +MODULE_DESCRIPTION ("PTP clock using the TILE-Gx" ); +MODULE_LICENSE ("GPL" );
No need to make this a module at all. Just make the code conditionally compiled, and register the clock along with your ingress_irq.
Quoted 6 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +6
-0+ + +struct mpipe_clock { +struct ptp_clock *ptp_clock; +gxio_mpipe_context_t *context; +struct ptp_clock_info caps;
drivers/net/ethernet/tile/tilegx_ptp.c line 57
Quoted 10 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +10
-0+struct mutex lock; +}; + +static struct mpipe_clock mpipe_clock; + +extern gxio_mpipe_context_t *get_mpipe_context (int index); + +/* +* Check if the context of mpipe device is valid. +*/
This goes away with proper PHC registration as mentioned before.
Quoted 18 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +18
-0+static inline int mpipe_context_check (struct mpipe_clock *clock) +{ +if (!clock->context) { + clock->context =get_mpipe_context (0 ); +if (!clock->context) { +pr_debug ("Invalid mPIPE context.\n" ); +return -EIO ; + } + } + +return 0 ; +} + + +/* +* PTP clock operations. +*/ +
drivers/net/ethernet/tile/tilegx_ptp.c line 85
Quoted 10 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +10
-0+static int ptp_mpipe_adjfreq (struct ptp_clock_info *ptp,s32 ppb) +{ +int ret =0 ; + struct mpipe_clock *clock = container_of(ptp, struct mpipe_clock, caps); + +mutex_lock (&clock->lock); +if (mpipe_context_check (clock)) { +mutex_unlock (&clock->lock); +return -EIO ; + }
This icky code block also goes away (in each method).
Quoted 7 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +7
-0+ +if (gxio_mpipe_adjust_timestamp_freq (clock->context, ppb)) + ret = -EINVAL ; + +mutex_unlock (&clock->lock); +return ret; +}
...
drivers/net/ethernet/tile/tilegx_ptp.c line 167
Quoted 4 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +4
-0+static struct ptp_clock_info ptp_mpipe_caps = { + .owner =THIS_MODULE , + .name ="mPIPE ptp timer" , + .max_adj =512000 ,
But before, you said 10^9 ppb?
drivers/net/ethernet/tile/tilegx_ptp.c line 174
Quoted 7 lines
drivers/net/ethernet/tile/tilegx_ptp.c new file +7
-0+ .n_ext_ts = 0, + .pps = 0, + .adjfreq = ptp_mpipe_adjfreq, + .adjtime = ptp_mpipe_adjtime, + .gettime = ptp_mpipe_gettime, + .settime = ptp_mpipe_settime, +};
Thanks,
Richard
PATCH v2 1/1 tile: support PTP using the tilegx mPIPE (IEEE 1588)
---
v2:
- Moved Kconfig stanza to drivers/ethernet/tile/Kconfig
- Clarify minimum and maximum frequency adjustments
- Merge PTP support into tilegx.c driver source code directly
- Support SIOCSHWTSTAMP ioctl appopriately
- Rebased to be the last patch in the series to simplify development
arch/tile/gxio/iorpc_mpipe.c | 19 +++ arch/tile/include/gxio/iorpc_mpipe.h | 10 +- arch/tile/include/gxio/mpipe.h | 14 +++ drivers/net/ethernet/tile/Kconfig | 11 ++ drivers/net/ethernet/tile/tilegx.c | 216 ++++++++++++++++++++++++++++++++++- 5 files changed, 266 insertions(+), 4 deletions(-)
arch/tile/gxio/iorpc_mpipe.c +19 -0
@@ -475,6 +475,25 @@ int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_aux); +struct adjust_timestamp_freq_param { +int32_t ppb; +}; + +int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb) +{ +struct adjust_timestamp_freq_param temp; +struct adjust_timestamp_freq_param *params = &temp; + + params->ppb = ppb; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params), +GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ ); +} + +EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_freq); +struct config_edma_ring_blks_param {unsigned int ering;unsigned int max_blks;
arch/tile/include/gxio/iorpc_mpipe.h +7 -3
@@ -46,10 +46,11 @@#define GXIO_MPIPE_OP_LINK_CLOSE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1212)#define GXIO_MPIPE_OP_LINK_SET_ATTR_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1213) -#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121e) -#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121f) -#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1220) +#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x121e) +#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x121f) +#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1220)#define GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1221) +#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1222)#define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)#define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)#define GXIO_MPIPE_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
@@ -128,6 +129,9 @@ int gxio_mpipe_set_timestamp_aux(gxio_mpipe_context_t * context, uint64_t sec,int gxio_mpipe_adjust_timestamp_aux (gxio_mpipe_context_t * context,int64_t nsec); +int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb); +int gxio_mpipe_arm_pollfd (gxio_mpipe_context_t * context,int pollfd_cookie);int gxio_mpipe_close_pollfd (gxio_mpipe_context_t * context,int pollfd_cookie);
arch/tile/include/gxio/mpipe.h +14 -0
@@ -1854,4 +1854,18 @@ extern int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context,extern int gxio_mpipe_adjust_timestamp (gxio_mpipe_context_t *context,int64_t delta); +/** Adjust the mPIPE timestamp clock frequency. +* +* @param context An initialized mPIPE context. +* @param ppb A 32-bit signed PPB (Parts Per Billion) value to adjust. +* The absolute value of ppb must be less than or equal to 1000000000. +* Values less than about 30000 will generally cause a GXIO_ERR_INVAL +* return due to the granularity of the hardware that converts reference +* clock cycles into seconds and nanoseconds. +* @return If the call was successful, zero; otherwise, a negative error +* code. +*/ +extern int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb); +#endif /* !_GXIO_MPIPE_H_ */
drivers/net/ethernet/tile/Kconfig +11 -0
@@ -15,3 +15,14 @@ config TILE_NET 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.
drivers/net/ethernet/tile/tilegx.c +215 -1
282 lines not on this page · raw message
Signature · 1 line
1.8.3.1
Re: [PATCH v2] tile: support PTP using the tilegx mPIPE (IEEE 1588)
Quoted 5 lines · Chris Metcalf
Signed-off-by Chris Metcalf <[email protected]>---
v2:
- MovedKconfigstanza todrivers/ethernet/tile/Kconfig
- Clarify minimum and maximum frequency adjustments
So if the requested frequency adjustment lies within the +/-30 ppm interval, then you return EINVAL? Maybe ERANGE would be better. Perhaps the driver should just round to the closest value it can support? Unfortunately, we don't have a way to communicate this kind of limitation to user space.
Quoted 3 lines
- Merge PTP support into
tilegx.cdriver source code directly
- Support SIOCSHWTSTAMP ioctl appopriately
- Rebased to be the last patch in the series to simplify development
Anyhow, this looks much better to me now.
Richard Cochran
maintainerRe: [PATCH 05/13] tile: support PTP using the tilegx mPIPE (IEEE 1588)
In reply to Chris MetcalfQuoted 8 lines · Chris Metcalf
drivers/ptp/Kconfig +0
-0@@ -87,4 +87,14 @@ config PTP_1588_CLOCK_PCH To compile this driver as a module, choose M here: the module will be called ptp_pch.
drivers/ptp/Kconfig config PTP_1588_CLOCK_PCH · line 99
Quoted 10 lines
drivers/ptp/Kconfig +10
-0+config PTP_1588_CLOCK_TILEGX + tristate "Tilera TILE-Gx mPIPE as PTP clock" + select PTP_1588_CLOCK + 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. +
Is this feature available on every TILEGX hardware variant? If not, then there needs to be some provision for that.
Also, this option should probably appear under the main MAC option.
Thanks,
Richard
Re: [PATCH 05/13] tile: support PTP using the tilegx mPIPE (IEEE 1588)
Quoted 10 lines · Richard Cochran
Quoted 8 lines · Chris Metcalf
drivers/ptp/Kconfig +0
-0@@ -87,4 +87,14 @@ config PTP_1588_CLOCK_PCH To compile this driver as a module, choose M here: the module will be called ptp_pch.
Quoted 12 lines
drivers/ptp/Kconfig config PTP_1588_CLOCK_PCH · line 99
Quoted 10 lines
drivers/ptp/Kconfig +10
-0+config PTP_1588_CLOCK_TILEGX + tristate "Tilera TILE-Gx mPIPE as PTP clock" + select PTP_1588_CLOCK + 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. +Is this feature available on every TILEGX hardware variant? If not, then there needs to be some provision for that.
It is.
Quoted 1 line
Also, this option should probably appear under the main MAC option.
By that I assume you mean in drivers/net/ethernet/tile/Kconfig? I will do that.
Thanks!
Signature · 2 lines
Chris Metcalf, Tilera Corp. http://www.tilera.com
PATCH 6/13 tile: support jumbo frames in the tilegx network driver
In reply to Chris Metcalf--- arch/tile/gxio/iorpc_mpipe.c | 47 +++++ arch/tile/gxio/mpipe.c | 18 +- arch/tile/include/gxio/iorpc_mpipe.h | 4 + arch/tile/include/gxio/mpipe.h | 101 +++++++++- drivers/net/ethernet/tile/tilegx.c | 349 +++++++++++++++++++---------------- 5 files changed, 352 insertions(+), 167 deletions(-)
arch/tile/gxio/iorpc_mpipe.c +47 -0
@@ -387,6 +387,27 @@ int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac)EXPORT_SYMBOL (gxio_mpipe_link_close_aux); +struct link_set_attr_aux_param { +int mac; +uint32_t attr; +int64_t val; +}; + +int gxio_mpipe_link_set_attr_aux (gxio_mpipe_context_t * context,int mac, +uint32_t attr,int64_t val) +{ +struct link_set_attr_aux_param temp; +struct link_set_attr_aux_param *params = &temp; + + params->mac = mac; + params->attr = attr; + params->val = val; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params),GXIO_MPIPE_OP_LINK_SET_ATTR_AUX ); +} + +EXPORT_SYMBOL (gxio_mpipe_link_set_attr_aux);struct get_timestamp_aux_param {uint64_t sec;
@@ -454,6 +475,32 @@ int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_aux); +struct config_edma_ring_blks_param { +unsigned int ering; +unsigned int max_blks; +unsigned int min_snf_blks; +unsigned int db; +}; + +int gxio_mpipe_config_edma_ring_blks (gxio_mpipe_context_t * context, +unsigned int ering,unsigned int max_blks, +unsigned int min_snf_blks,unsigned int db) +{ +struct config_edma_ring_blks_param temp; +struct config_edma_ring_blks_param *params = &temp; + + params->ering = ering; + params->max_blks = max_blks; + params->min_snf_blks = min_snf_blks; + params->db = db; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params), +GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS ); +} + +EXPORT_SYMBOL (gxio_mpipe_config_edma_ring_blks); +struct adjust_timestamp_freq_param {int32_t ppb; };
arch/tile/gxio/mpipe.c +15 -3
@@ -383,7 +383,7 @@ EXPORT_SYMBOL_GPL(gxio_mpipe_iqueue_init);int gxio_mpipe_equeue_init (gxio_mpipe_equeue_t *equeue,gxio_mpipe_context_t *context, -unsigned int edma_ring_id, +unsigned int ering,unsigned int channel,void *mem,unsigned int mem_size,unsigned int mem_flags)
@@ -394,7 +394,7 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue,/* Offset used to read number of completed commands. */ MPIPE_EDMA_POST_REGION_ADDR_t offset; -int result =gxio_mpipe_init_edma_ring (context, edma_ring_id, channel, +int result =gxio_mpipe_init_edma_ring (context, ering, channel, mem, mem_size, mem_flags);if (result <0 )return result;
@@ -405,7 +405,7 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, offset.region =MPIPE_MMIO_ADDR__REGION_VAL_EDMA -MPIPE_MMIO_ADDR__REGION_VAL_IDMA ; - offset.ring = edma_ring_id; + offset.ring = ering; __gxio_dma_queue_init(&equeue->dma_queue, context->mmio_fast_base + offset.word,
@@ -413,6 +413,9 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, equeue->edescs = mem; equeue->mask_num_entries = num_entries -1 ; equeue->log2_num_entries =__builtin_ctz (num_entries); + equeue->context = context; + equeue->ering = ering; + equeue->channel = channel;return 0 ; }
@@ -543,3 +546,12 @@ int gxio_mpipe_link_close(gxio_mpipe_link_t *link) }EXPORT_SYMBOL_GPL (gxio_mpipe_link_close); + +int gxio_mpipe_link_set_attr (gxio_mpipe_link_t *link,uint32_t attr, +int64_t val) +{ +return gxio_mpipe_link_set_attr_aux (link->context, link->mac, attr, + val); +} + +EXPORT_SYMBOL_GPL (gxio_mpipe_link_set_attr);
arch/tile/include/gxio/iorpc_mpipe.h +4 -0
@@ -44,10 +44,12 @@#define GXIO_MPIPE_OP_REGISTER_CLIENT_MEMORY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1210)#define GXIO_MPIPE_OP_LINK_OPEN_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1211)#define GXIO_MPIPE_OP_LINK_CLOSE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1212) +#define GXIO_MPIPE_OP_LINK_SET_ATTR_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1213)#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121e)#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121f)#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1220) +#define GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1221)#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1222)#define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)#define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)
@@ -115,6 +117,8 @@ int gxio_mpipe_link_open_aux(gxio_mpipe_context_t * context,int gxio_mpipe_link_close_aux (gxio_mpipe_context_t * context,int mac); +int gxio_mpipe_link_set_attr_aux (gxio_mpipe_context_t * context,int mac, +uint32_t attr,int64_t val);int gxio_mpipe_get_timestamp_aux (gxio_mpipe_context_t * context,uint64_t * sec,uint64_t * nsec,uint64_t * cycles);
arch/tile/include/gxio/mpipe.h +97 -4
141 lines not on this page · raw message
drivers/net/ethernet/tile/tilegx.c +189 -160
553 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH 7/13 tile: update dev->stats directly in tilegx network driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-)
drivers/net/ethernet/tile/tilegx.c +8 -21
@@ -178,8 +178,6 @@ struct tile_net_priv {int loopify_channel;/* The egress channel (channel or loopify_channel). */ int echannel; -/* Total stats. */ -struct net_device_stats stats; };/* Egress info, indexed by "priv->echannel" (lazily created as needed). */
@@ -447,7 +445,6 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb, gxio_mpipe_idesc_t *idesc, unsigned long len) {struct tile_net_info *info = &__get_cpu_var (per_cpu_info); -struct tile_net_priv *priv =netdev_priv (dev);/* Encode the actual packet length. */ skb_put (skb, len);
@@ -464,8 +461,8 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb,netif_receive_skb (skb);/* Update stats. */ -tile_net_stats_add (1 , &priv->stats.rx_packets); -tile_net_stats_add (len, &priv->stats.rx_bytes); +tile_net_stats_add (1 , &dev->stats.rx_packets); +tile_net_stats_add (len, &dev->stats.rx_bytes);/* Need a new buffer. */ if (idesc->size == buffer_size_enums[0 ])
@@ -481,7 +478,6 @@ static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc) {struct tile_net_info *info = &__get_cpu_var (per_cpu_info);struct net_device *dev = tile_net_devs_for_channel[idesc->channel]; -struct tile_net_priv *priv =netdev_priv (dev);uint8_t l2_offset;void *va;void *buf;
@@ -495,7 +491,7 @@ static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc)*/ if (idesc->be || idesc->me || idesc->tr || idesc->ce) {if (dev) -tile_net_stats_add (1 , &priv->stats.rx_errors); +tile_net_stats_add (1 , &dev->stats.rx_errors); goto drop; }
@@ -515,7 +511,7 @@ static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc) filter =filter_packet (dev, buf);if (filter) {if (dev) -tile_net_stats_add (1 , &priv->stats.rx_dropped); +tile_net_stats_add (1 , &dev->stats.rx_dropped); drop:gxio_mpipe_iqueue_drop (&info->mpipe[instance].iqueue, idesc); }else {
@@ -1549,7 +1545,6 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,static void tso_egress (struct net_device *dev,gxio_mpipe_equeue_t *equeue,struct sk_buff *skb,unsigned char *headers,s64 slot) { -struct tile_net_priv *priv =netdev_priv (dev);struct skb_shared_info *sh =skb_shinfo (skb);unsigned int sh_len =skb_transport_offset (skb) +tcp_hdrlen (skb);unsigned int data_len = skb->len - sh_len;
@@ -1627,8 +1622,8 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, }/* Update stats. */ -tile_net_stats_add (tx_packets, &priv->stats.tx_packets); -tile_net_stats_add (tx_bytes, &priv->stats.tx_bytes); +tile_net_stats_add (tx_packets, &dev->stats.tx_packets); +tile_net_stats_add (tx_bytes, &dev->stats.tx_bytes); }/* Do "TSO" handling for egress.
@@ -1774,9 +1769,9 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)add_comp (equeue, comps, slot -1 , skb);/* NOTE: Use ETH_ZLEN for short packets (e.g. 42 < 60). */ -tile_net_stats_add (1 , &priv->stats.tx_packets); +tile_net_stats_add (1 , &dev->stats.tx_packets); tile_net_stats_add(max_t(unsigned int, len, ETH_ZLEN), - &priv->stats.tx_bytes); + &dev->stats.tx_bytes);local_irq_restore (irqflags);
@@ -1813,13 +1808,6 @@ static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)return -EOPNOTSUPP ; } -/* Get system network statistics for device. */ -static struct net_device_stats *tile_net_get_stats (struct net_device *dev) -{ -struct tile_net_priv *priv =netdev_priv (dev); -return &priv->stats; -} -/* Change the MTU. */ static int tile_net_change_mtu (struct net_device *dev,int new_mtu) {
@@ -1869,7 +1857,6 @@ static const struct net_device_ops tile_net_ops = { .ndo_start_xmit = tile_net_tx, .ndo_select_queue = tile_net_select_queue, .ndo_do_ioctl = tile_net_ioctl, - .ndo_get_stats = tile_net_get_stats, .ndo_change_mtu = tile_net_change_mtu, .ndo_tx_timeout = tile_net_tx_timeout, .ndo_set_mac_address = tile_net_set_mac_address,
Signature · 1 line
1.8.3.1
PATCH 8/13 tile: fix panic bug in napi support for tilegx network driver
In reply to Chris MetcalfThe code used to call napi_disable() in an interrupt handler (from smp_call_function), which in turn could call msleep(). Unfortunately you can't sleep in an interrupt context.
Luckily it turns out all the NAPI support functions are just operating on data structures and not on any deeply per-cpu data, so we can arrange to set up and tear down all the NAPI state on the core driving the process, and just do the IRQ enable/disable as a smp_call_function thing.
--- drivers/net/ethernet/tile/tilegx.c | 65 +++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 32 deletions(-)
drivers/net/ethernet/tile/tilegx.c +33 -32
@@ -686,37 +686,13 @@ static enum hrtimer_restart tile_net_handle_egress_timer(struct hrtimer *t)return HRTIMER_NORESTART ; } -/* Helper function for "tile_net_update()". -* "dev" (i.e. arg) is the device being brought up or down, -* or NULL if all devices are now down. -*/ -static void tile_net_update_cpu (void *arg) +/* Helper function for "tile_net_update()". */ +static void manage_ingress_irq (void *enable) { -struct tile_net_info *info = &__get_cpu_var (per_cpu_info); -struct net_device *dev = arg; - -if (!info->has_iqueue) -return ; - -if (dev !=NULL ) { -if (!info->napi_added) { -netif_napi_add (dev, &info->napi, - tile_net_poll,TILE_NET_WEIGHT ); - info->napi_added = true; - } -if (!info->napi_enabled) { -napi_enable (&info->napi); - info->napi_enabled = true; - } +if (enable)enable_percpu_irq (ingress_irq,0 ); - }else { +else disable_percpu_irq (ingress_irq); -if (info->napi_enabled) { -napi_disable (&info->napi); - info->napi_enabled = false; - } -/* FIXME: Drain the iqueue. */ - } }/* Helper function for tile_net_open() and tile_net_stop().
@@ -753,10 +729,35 @@ static int tile_net_update(struct net_device *dev)return -EIO ; } -/* Update all cpus, sequentially (to protect "netif_napi_add()"). */ -for_each_online_cpu (cpu) -smp_call_function_single (cpu, tile_net_update_cpu, - (saw_channel ? dev :NULL ),1 ); +/* Update all cpus, sequentially (to protect "netif_napi_add()"). +* We use on_each_cpu to handle the IPI mask or unmask. +*/ +if (!saw_channel) +on_each_cpu (manage_ingress_irq, (void *)0 ,1 ); +for_each_online_cpu (cpu) { +struct tile_net_info *info = &per_cpu (per_cpu_info, cpu); +if (!info->has_iqueue) +continue ; +if (saw_channel) { +if (!info->napi_added) { +netif_napi_add (dev, &info->napi, + tile_net_poll,TILE_NET_WEIGHT ); + info->napi_added = true; + } +if (!info->napi_enabled) { +napi_enable (&info->napi); + info->napi_enabled = true; + } + }else { +if (info->napi_enabled) { +napi_disable (&info->napi); + info->napi_enabled = false; + } +/* FIXME: Drain the iqueue. */ + } + } +if (saw_channel) +on_each_cpu (manage_ingress_irq, (void *)1 ,1 );/* HACK: Allow packets to flow in the simulator. */ if (saw_channel)
Signature · 1 line
1.8.3.1
PATCH 9/13 tile: enable GRO in the tilegx network driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/tile/tilegx.c +2 -1
@@ -458,7 +458,7 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb,/* Get RX timestamp from idesc. */ tile_rx_timestamp (skb, idesc); -netif_receive_skb (skb); +napi_gro_receive (&info->napi, skb);/* Update stats. */ tile_net_stats_add (1 , &dev->stats.rx_packets);
@@ -1880,6 +1880,7 @@ static void tile_net_setup(struct net_device *dev) dev->features |=NETIF_F_HW_CSUM ; dev->features |=NETIF_F_SG ; dev->features |=NETIF_F_TSO ; + dev->features |=NETIF_F_GRO ; dev->mtu =1500 ; }
Signature · 1 line
1.8.3.1
Re: [PATCH 09/13] tile: enable GRO in the tilegx network driver
Quoted 19 lines · Chris Metcalf
Signed-off-by Chris Metcalf <[email protected]>--- drivers/net/ethernet/tile/tilegx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/net/ethernet/tile/tilegx.c +1
-1@@ -458,7 +458,7 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb,/* Get RX timestamp from idesc. */ tile_rx_timestamp (skb, idesc); -netif_receive_skb (skb); +napi_gro_receive (&info->napi, skb);/* Update stats. */ tile_net_stats_add (1 , &dev->stats.rx_packets);
drivers/net/ethernet/tile/tilegx.c static void tile_net_setup(struct net_device *dev) · line 1883
Quoted 4 lines
drivers/net/ethernet/tile/tilegx.c +1
-0@@ -1880,6 +1880,7 @@ static void tile_net_setup(struct net_device *dev) dev->features |=NETIF_F_HW_CSUM ; dev->features |=NETIF_F_SG ; dev->features |=NETIF_F_TSO ; + dev->features |=NETIF_F_GRO ;
This line should not be needed
register_netdevice() does it for all devices :
dev->hw_features |= NETIF_F_SOFT_FEATURES;dev->features |= NETIF_F_SOFT_FEATURES;
Re: [PATCH 09/13] tile: enable GRO in the tilegx network driver
Quoted 26 lines · Eric Dumazet
Quoted 19 lines · Chris Metcalf
Signed-off-by Chris Metcalf <[email protected]>--- drivers/net/ethernet/tile/tilegx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/net/ethernet/tile/tilegx.c +1
-1@@ -458,7 +458,7 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb,/* Get RX timestamp from idesc. */ tile_rx_timestamp (skb, idesc); -netif_receive_skb (skb); +napi_gro_receive (&info->napi, skb);/* Update stats. */ tile_net_stats_add (1 , &dev->stats.rx_packets);drivers/net/ethernet/tile/tilegx.c static void tile_net_setup(struct net_device *dev) · line 1883
Quoted 4 lines
drivers/net/ethernet/tile/tilegx.c +1
-0@@ -1880,6 +1880,7 @@ static void tile_net_setup(struct net_device *dev) dev->features |=NETIF_F_HW_CSUM ; dev->features |=NETIF_F_SG ; dev->features |=NETIF_F_TSO ; + dev->features |=NETIF_F_GRO ;This line should not be needed
Quoted 4 lines
register_netdevice()does it for all devices :
dev->hw_features|=NETIF_F_SOFT_FEATURES;dev->features|=NETIF_F_SOFT_FEATURES;
Thanks; I removed the line from my tile-net-next tree so it will get pulled without it.
Signature · 2 lines
Chris Metcalf, Tilera Corp. http://www.tilera.com
PATCH 10/13 tile: support multiple mPIPE shims in tilegx network driver
In reply to Chris MetcalfThe initial driver support was for a single mPIPE shim on the chip (as is the case for the Gx36 hardware). The Gx72 chip has two mPIPE shims, so we extend the driver to handle that case.
--- arch/tile/gxio/iorpc_mpipe_info.c | 18 + arch/tile/gxio/mpipe.c | 26 +- arch/tile/include/gxio/iorpc_mpipe_info.h | 4 + arch/tile/include/gxio/mpipe.h | 28 ++ arch/tile/include/hv/drv_mpipe_intf.h | 3 + drivers/net/ethernet/tile/tilegx.c | 561 ++++++++++++++++++------------ drivers/net/ethernet/tile/tilegx_ptp.c | 36 +- 7 files changed, 448 insertions(+), 228 deletions(-)
arch/tile/gxio/iorpc_mpipe_info.c +18 -0
@@ -16,6 +16,24 @@#include "gxio/iorpc_mpipe_info.h" +struct instance_aux_param { +_gxio_mpipe_link_name_t name; +}; + +int gxio_mpipe_info_instance_aux (gxio_mpipe_info_context_t * context, +_gxio_mpipe_link_name_t name) +{ +struct instance_aux_param temp; +struct instance_aux_param *params = &temp; + + params->name = name; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params),GXIO_MPIPE_INFO_OP_INSTANCE_AUX ); +} + +EXPORT_SYMBOL (gxio_mpipe_info_instance_aux); +struct enumerate_aux_param {_gxio_mpipe_link_name_t name;_gxio_mpipe_link_mac_t mac;
arch/tile/gxio/mpipe.c +24 -2
@@ -36,8 +36,15 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)int fd;int i; +if (mpipe_index >=GXIO_MPIPE_INSTANCE_MAX ) { +return -EINVAL ; + } +snprintf (file,sizeof (file),"mpipe/%d/iorpc" , mpipe_index); fd =hv_dev_open ((HV_VirtAddr ) file,0 ); + + context->fd = fd; +if (fd <0 ) {if (fd >=GXIO_ERR_MIN && fd <=GXIO_ERR_MAX )return fd;
@@ -45,8 +52,6 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)return -ENODEV ; } - context->fd = fd; -/* Map in the MMIO space. */ context->mmio_cfg_base = (void __force *) iorpc_ioremap(fd, HV_MPIPE_CONFIG_MMIO_OFFSET,
@@ -64,12 +69,15 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)for (i =0 ; i <8 ; i++) context->__stacks.stacks[i] =255 ; + context->instance = mpipe_index; +return 0 ; fast_failed:iounmap ((void __force __iomem *)(context->mmio_cfg_base)); cfg_failed:hv_dev_close (context->fd); + context->fd =-1 ;return -ENODEV ; }
@@ -496,6 +504,20 @@ static gxio_mpipe_context_t *_gxio_get_link_context(void)return contextp; } +int gxio_mpipe_link_instance (const char *link_name) +{ +_gxio_mpipe_link_name_t name; +gxio_mpipe_context_t *context =_gxio_get_link_context (); + +if (!context) +return GXIO_ERR_NO_DEVICE ; + +strncpy (name.name, link_name,sizeof (name.name)); + name.name[GXIO_MPIPE_LINK_NAME_LEN -1 ] ='\0' ; + +return gxio_mpipe_info_instance_aux (context, name); +} +int gxio_mpipe_link_enumerate_mac (int idx,char *link_name,uint8_t *link_mac) {int rv;
arch/tile/include/gxio/iorpc_mpipe_info.h +4 -0
@@ -27,11 +27,15 @@#include <asm/pgtable.h> +#define GXIO_MPIPE_INFO_OP_INSTANCE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1250)#define GXIO_MPIPE_INFO_OP_ENUMERATE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1251)#define GXIO_MPIPE_INFO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)#define GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001) +int gxio_mpipe_info_instance_aux (gxio_mpipe_info_context_t * context, +_gxio_mpipe_link_name_t name); + int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context, unsigned int idx, _gxio_mpipe_link_name_t * name,
arch/tile/include/gxio/mpipe.h +28 -0
@@ -220,6 +220,13 @@ typedef MPIPE_PDESC_t gxio_mpipe_idesc_t;*/ typedef MPIPE_EDMA_DESC_t gxio_mpipe_edesc_t ; +/* +* Max # of mpipe instances. 2 currently. +*/ +#define GXIO_MPIPE_INSTANCE_MAX HV_MPIPE_INSTANCE_MAX + +#define NR_MPIPE_MAX GXIO_MPIPE_INSTANCE_MAX +/* Get the "va" field from an "idesc". * * This is the address at which the ingress hardware copied the first
@@ -311,6 +318,9 @@ typedef struct {/* File descriptor for calling up to Linux (and thus the HV). */ int fd; +/* Corresponding mpipe instance #. */ +int instance; +/* The VA at which configuration registers are mapped. */ char *mmio_cfg_base;
@@ -1716,6 +1726,24 @@ typedef struct {uint8_t mac; } gxio_mpipe_link_t; +/* Translate a link name to the instance number of the mPIPE shim which is +* connected to that link. This call does not verify whether the link is +* currently available, and does not reserve any link resources; +* gxio_mpipe_link_open() must be called to perform those functions. +* +* Typically applications will call this function to translate a link name +* to an mPIPE instance number; call gxio_mpipe_init(), passing it that +* instance number, to initialize the mPIPE shim; and then call +* gxio_mpipe_link_open(), passing it the same link name plus the mPIPE +* context, to configure the link. +* +* @param link_name Name of the link; see @ref gxio_mpipe_link_names. +* @return The mPIPE instance number which is associated with the named +* link, or a negative error code (::GXIO_ERR_NO_DEVICE) if the link does +* not exist. +*/ +extern int gxio_mpipe_link_instance (const char *link_name); +/* Retrieve one of this system's legal link names, and its MAC address. * * @param index Link name index. If a system supports N legal link names,
arch/tile/include/hv/drv_mpipe_intf.h +3 -0
@@ -23,6 +23,9 @@#include <arch/mpipe_constants.h> +/** Number of mPIPE instances supported */ +#define HV_MPIPE_INSTANCE_MAX (2) +/** Number of buffer stacks (32). */ #define HV_MPIPE_NUM_BUFFER_STACKS \ (MPIPE_MMIO_INIT_DAT_GX36_1__BUFFER_STACK_MASK_WIDTH)
drivers/net/ethernet/tile/tilegx.c +348 -213
1,067 lines not on this page · raw message
drivers/net/ethernet/tile/tilegx_ptp.c +23 -13
@@ -42,13 +42,14 @@ MODULE_LICENSE("GPL");struct mpipe_clock { +int index;struct ptp_clock *ptp_clock;gxio_mpipe_context_t *context;struct ptp_clock_info caps;struct mutex lock; }; -static struct mpipe_clock mpipe_clock; +static struct mpipe_clock mpipe_clock[NR_MPIPE_MAX ];extern gxio_mpipe_context_t *get_mpipe_context (int index);
@@ -58,7 +59,7 @@ extern gxio_mpipe_context_t *get_mpipe_context(int index);static inline int mpipe_context_check (struct mpipe_clock *clock) {if (!clock->context) { - clock->context =get_mpipe_context (0 ); + clock->context =get_mpipe_context (clock->index);if (!clock->context) {pr_debug ("Invalid mPIPE context.\n" );return -EIO ;
@@ -176,23 +177,32 @@ static struct ptp_clock_info ptp_mpipe_caps = { static void __exit ptp_tilegx_exit(void) { -ptp_clock_unregister (mpipe_clock.ptp_clock); -mutex_destroy (&mpipe_clock.lock); +int i; + +for (i =0 ; i <NR_MPIPE_MAX ; i++) { +ptp_clock_unregister (mpipe_clock[i].ptp_clock); +mutex_destroy (&mpipe_clock[i].lock); + } }static int __init ptp_tilegx_init (void ) {int err =0 ; - - mpipe_clock.context =NULL ; - mpipe_clock.caps = ptp_mpipe_caps; -mutex_init (&mpipe_clock.lock); - - mpipe_clock.ptp_clock =ptp_clock_register (&mpipe_clock.caps,NULL ); -if (IS_ERR (mpipe_clock.ptp_clock)) { - err =PTR_ERR (mpipe_clock.ptp_clock); -pr_debug ("Register ptp clock fail: %d\n" , err); +int i; + +for (i =0 ; i <NR_MPIPE_MAX ; i++) { + mpipe_clock[i].index = i; + mpipe_clock[i].context =NULL ; + mpipe_clock[i].caps = ptp_mpipe_caps; +mutex_init (&mpipe_clock[i].lock); + + mpipe_clock[i].ptp_clock = +ptp_clock_register (&mpipe_clock[i].caps,NULL ); +if (IS_ERR (mpipe_clock[i].ptp_clock)) { + err =PTR_ERR (mpipe_clock[i].ptp_clock); +pr_debug ("Register ptp clock %d fail: %d\n" , i, err); + } }return err;
Signature · 1 line
1.8.3.1
PATCH 11/13 tile: support TSO for IPv6 in tilegx network driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 44 +++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 15 deletions(-)
drivers/net/ethernet/tile/tilegx.c +29 -15
@@ -36,6 +36,7 @@#include <linux/io.h> #include <linux/ctype.h> #include <linux/ip.h> +#include <linux/ipv6.h> #include <linux/tcp.h> #include <asm/checksum.h>
@@ -1563,20 +1564,20 @@ static int tso_count_edescs(struct sk_buff *skb)return num_edescs; } -/* Prepare modified copies of the skbuff headers. -* FIXME: add support for IPv6. -*/ +/* Prepare modified copies of the skbuff headers. */ static void tso_headers_prepare (struct sk_buff *skb,unsigned char *headers,s64 slot) {struct skb_shared_info *sh =skb_shinfo (skb);struct iphdr *ih; +struct ipv6hdr *ih6;struct tcphdr *th;unsigned int sh_len =skb_transport_offset (skb) +tcp_hdrlen (skb);unsigned int data_len = skb->len - sh_len;unsigned char *data = skb->data;unsigned int ih_off, th_off, p_len;unsigned int isum_seed, tsum_seed, id, seq; +int is_ipv6;long f_id =-1 ;/* id of the current fragment */ long f_size =skb_headlen (skb) - sh_len;/* current fragment size */ long f_used =0 ;/* bytes used from the current fragment */
@@ -1584,18 +1585,24 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,int segment;/* Locate original headers and compute various lengths. */ - ih =ip_hdr (skb); + is_ipv6 =skb_is_gso_v6 (skb); +if (is_ipv6) { + ih6 =ipv6_hdr (skb); + ih_off =skb_network_offset (skb); + }else { + ih =ip_hdr (skb); + ih_off =skb_network_offset (skb); + isum_seed = ((0xFFFF - ih->check) + + (0xFFFF - ih->tot_len) + + (0xFFFF - ih->id)); + id =ntohs (ih->id); + } + th =tcp_hdr (skb); - ih_off =skb_network_offset (skb); th_off =skb_transport_offset (skb); p_len = sh->gso_size; -/* Set up seed values for IP and TCP csum and initialize id and seq. */ - isum_seed = ((0xFFFF - ih->check) + - (0xFFFF - ih->tot_len) + - (0xFFFF - ih->id)); tsum_seed = th->check + (0xFFFF ^htons (skb->len)); - id =ntohs (ih->id); seq =ntohl (th->seq);/* Prepare all the headers. */
@@ -1609,11 +1616,17 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,memcpy (buf, data, sh_len);/* Update copied ip header. */ - ih = (struct iphdr *)(buf + ih_off); - ih->tot_len =htons (sh_len + p_len - ih_off); - ih->id =htons (id); - ih->check =csum_long (isum_seed + ih->tot_len + - ih->id) ^0xffff ; +if (is_ipv6) { + ih6 = (struct ipv6hdr *)(buf + ih_off); + ih6->payload_len =htons (sh_len + p_len - ih_off - +sizeof (*ih6)); + }else { + ih = (struct iphdr *)(buf + ih_off); + ih->tot_len =htons (sh_len + p_len - ih_off); + ih->id =htons (id); + ih->check =csum_long (isum_seed + ih->tot_len + + ih->id) ^0xffff ; + }/* Update copied tcp header. */ th = (struct tcphdr *)(buf + th_off);
@@ -2010,6 +2023,7 @@ static void tile_net_setup(struct net_device *dev) dev->features |=NETIF_F_HW_CSUM ; dev->features |=NETIF_F_SG ; dev->features |=NETIF_F_TSO ; + dev->features |=NETIF_F_TSO6 ; dev->features |=NETIF_F_GRO ; dev->mtu =1500 ; }
Signature · 1 line
1.8.3.1
PATCH 12/13 tile: make "tile_net.custom" a proper bool module parameter
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/ethernet/tile/tilegx.c +5 -5
@@ -256,11 +256,11 @@ static char *network_cpus_string;/* The actual cpus in "network_cpus". */ static struct cpumask network_cpus_map; -/* If "loopify=LINK" was specified, this is "LINK". */ +/* If "tile_net.loopify=LINK" was specified, this is "LINK". */ static char *loopify_link_name; -/* If "tile_net.custom" was specified, this is non-NULL. */ -static char *custom_str; +/* If "tile_net.custom" was specified, this is true. */ +static bool custom_flag;/* If "tile_net.jumbo=NUM" was specified, this is "NUM". */ static uint jumbo_num;
@@ -323,7 +323,7 @@ MODULE_PARM_DESC(loopify, "name the device to use loop0/1 for ingress/egress");/* The "tile_net.custom" argument causes us to ignore the "conventional" * classifier metadata, in particular, the "l2_offset". */ -module_param_named (custom, custom_str, charp,0444 ); +module_param_named (custom, custom_flag, bool,0444 );MODULE_PARM_DESC (custom,"indicates a (heavily) customized classifier" );/* The "tile_net.jumbo" argument causes us to support "jumbo" packets,
@@ -540,7 +540,7 @@ static bool tile_net_handle_packet(int instance, gxio_mpipe_idesc_t *idesc) }/* Get the "l2_offset", if allowed. */ - l2_offset = custom_str ?0 :gxio_mpipe_idesc_get_l2_offset (idesc); + l2_offset = custom_flag ?0 :gxio_mpipe_idesc_get_l2_offset (idesc);/* Get the VA (including NET_IP_ALIGN bytes of "headroom"). */ va =tile_io_addr_to_va ((unsigned long )(long )idesc->va);
Signature · 1 line
1.8.3.1
PATCH 13/13 tile: remove deprecated NETIF_F_LLTX flag from tile drivers
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 1 - drivers/net/ethernet/tile/tilepro.c | 3 --- 2 files changed, 4 deletions(-)
drivers/net/ethernet/tile/tilegx.c +0 -1
@@ -2019,7 +2019,6 @@ static void tile_net_setup(struct net_device *dev)ether_setup (dev); dev->netdev_ops = &tile_net_ops; dev->watchdog_timeo =TILE_NET_TIMEOUT ; - dev->features |=NETIF_F_LLTX ; dev->features |=NETIF_F_HW_CSUM ; dev->features |=NETIF_F_SG ; dev->features |=NETIF_F_TSO ;
drivers/net/ethernet/tile/tilepro.c +0 -3
@@ -2224,9 +2224,6 @@ static void tile_net_setup(struct net_device *dev) dev->watchdog_timeo =TILE_NET_TIMEOUT ; -/* We want lockless xmit. */ - dev->features |=NETIF_F_LLTX ; -/* We support hardware tx checksums. */ dev->features |=NETIF_F_HW_CSUM ;
Signature · 1 line
1.8.3.1
v2 cover update tile network drivers
In reply to Chris MetcalfThis is v2 of the patch series to update the Tilera network drivers.
Quoted 1 line
From the v1 00/13 cover letter: "This patch series contains changes made
to the Tilera on-chip network drivers for both the 64-bit tilegx and 32-bit tilepro architectures. The changes involve a number of bug fixes, support for the multiple mPIPEs on the new Gx72 chip, support for jumbo frames, TSO for IPv6, GRO, PTP support, and statistics improvements."
David has already applied the v2 patch for what was patch 01/13 in the first series ("handle 64-bit statistics in tilepro network driver") so it is not included in this v2 series.
Changes from the v1 series include:
- Nearly complete rewrite of PTP changes based on feedback from Richard Cochran
- Removal of NETIF_F_GRO as unnecessary (from Eric Dumazet)
- A few minor whitespace and code style changes
The revised PTP change (12/12 in this series) was already posted separately, but this version includes one whitespace tweak (leading tabs instead of spaces on one line) that I missed in the initial PTP v2, as well as the Acked-by from Richard Cochran.
Chris Metcalf (12):
tile: support rx_dropped/rx_errors in tilepro net driver
tile: avoid bug in tilepro net driver built with old hypervisor
tile: remove dead is_dup_ack() function from tilepro net driver
tile: support jumbo frames in the tilegx network driver
tile: update dev->stats directly in tilegx network driver
tile: fix panic bug in napi support for tilegx network driver
tile: enable GRO in the tilegx network driver
tile: support multiple mPIPE shims in tilegx network driver
tile: support TSO for IPv6 in tilegx network driver
tile: make "tile_net.custom" a proper bool module parameter
tile: remove deprecated NETIF_F_LLTX flag from tile drivers
tile: support PTP using the tilegx mPIPE (IEEE 1588)
arch/tile/gxio/iorpc_mpipe.c | 66 ++ arch/tile/gxio/iorpc_mpipe_info.c | 18 + arch/tile/gxio/mpipe.c | 43 +- arch/tile/include/gxio/iorpc_mpipe.h | 14 +- arch/tile/include/gxio/iorpc_mpipe_info.h | 4 + arch/tile/include/gxio/mpipe.h | 143 +++- arch/tile/include/hv/drv_mpipe_intf.h | 3 + drivers/net/ethernet/tile/Kconfig | 11 + drivers/net/ethernet/tile/tilegx.c | 1097 +++++++++++++++++++---------- drivers/net/ethernet/tile/tilepro.c | 129 +--- 10 files changed, 1046 insertions(+), 482 deletions(-)
Signature · 1 line
1.8.3.1
PATCH v2 1/12 tile: support rx_dropped/rx_errors in tilepro net driver
--- drivers/net/ethernet/tile/tilepro.c | 41 ++++++++++++++----------------------- 1 file changed, 15 insertions(+), 26 deletions(-)
drivers/net/ethernet/tile/tilepro.c +15 -26
@@ -776,6 +776,7 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)netio_pkt_t *pkt = (netio_pkt_t *)((unsigned long ) &qsp[1 ] + index);netio_pkt_metadata_t *metadata =NETIO_PKT_METADATA (pkt); +netio_pkt_status_t pkt_status =NETIO_PKT_STATUS_M (metadata, pkt);/* Extract the packet size. FIXME: Shouldn't the second line */ /* get subtracted? Mostly moot, since it should be "zero". */
@@ -808,40 +809,25 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)#endif /* TILE_NET_DUMP_PACKETS */ #ifdef TILE_NET_VERIFY_INGRESS -if (!NETIO_PKT_L4_CSUM_CORRECT_M (metadata, pkt) && -NETIO_PKT_L4_CSUM_CALCULATED_M (metadata, pkt)) { -/* Bug 6624: Includes UDP packets with a "zero" checksum. */ -pr_warning ("Bad L4 checksum on %d byte packet.\n" , len); - } -if (!NETIO_PKT_L3_CSUM_CORRECT_M (metadata, pkt) && -NETIO_PKT_L3_CSUM_CALCULATED_M (metadata, pkt)) { +if (pkt_status ==NETIO_PKT_STATUS_OVERSIZE && len >=64 ) {dump_packet (buf, len,"rx" ); -panic ("Bad L3 checksum." ); - } -switch (NETIO_PKT_STATUS_M (metadata, pkt)) { -case NETIO_PKT_STATUS_OVERSIZE : -if (len >=64 ) { -dump_packet (buf, len,"rx" ); -panic ("Unexpected OVERSIZE." ); - } -break ; -case NETIO_PKT_STATUS_BAD : -pr_warning ("Unexpected BAD %ld byte packet.\n" , len); +panic ("Unexpected OVERSIZE." ); }#endif filter =0 ; -/* ISSUE: Filter TCP packets with "bad" checksums? */ - -if (!(dev->flags &IFF_UP )) { +if (pkt_status ==NETIO_PKT_STATUS_BAD ) { +/* Handle CRC error and hardware truncation. */ + filter =2 ; + }else if (!(dev->flags &IFF_UP )) {/* Filter packets received before we're up. */ filter =1 ; - }else if (NETIO_PKT_STATUS_M (metadata, pkt) ==NETIO_PKT_STATUS_BAD ) { + }else if (NETIO_PKT_ETHERTYPE_RECOGNIZED_M (metadata, pkt) && + pkt_status ==NETIO_PKT_STATUS_UNDERSIZE ) {/* Filter "truncated" packets. */ - filter =1 ; + filter =2 ; }else if (!(dev->flags &IFF_PROMISC )) { -/* FIXME: Implement HW multicast filter. */ if (!is_multicast_ether_addr (buf)) {/* Filter packets not for our address. */ const u8 *mine = dev->dev_addr;
@@ -851,9 +837,12 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)u64_stats_update_begin (&stats->syncp); -if (filter) { +if (filter !=0 ) { -/* ISSUE: Update "drop" statistics? */ +if (filter ==1 ) + stats->rx_dropped++; +else + stats->rx_errors++;tile_net_provide_linux_buffer (info, va, small);
Signature · 1 line
1.8.3.1
PATCH v2 2/12 tile: avoid bug in tilepro net driver built with old hypervisor
In reply to Chris MetcalfBuilding against headers from an older Tilera hypervisor can cause the frags[] array to be overrun. Don't enable TSO in that case.
--- drivers/net/ethernet/tile/tilepro.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/net/ethernet/tile/tilepro.c +5 -4
@@ -1933,7 +1933,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)unsigned int csum_start =skb_checksum_start_offset (skb); -lepp_frag_t frags[LEPP_MAX_FRAGS ]; +lepp_frag_t frags[1 +MAX_SKB_FRAGS ];unsigned int num_frags;
@@ -1948,7 +1948,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)unsigned int cmd_head, cmd_tail, cmd_next;unsigned int comp_tail; -lepp_cmd_t cmds[LEPP_MAX_FRAGS ]; +lepp_cmd_t cmds[1 +MAX_SKB_FRAGS ];/*
@@ -2342,8 +2342,9 @@ static void tile_net_setup(struct net_device *dev)/* We support scatter/gather. */ dev->features |=NETIF_F_SG ; -/* We support TSO. */ - dev->features |=NETIF_F_TSO ; +/* We support TSO iff the HV supports sufficient frags. */ +if (LEPP_MAX_FRAGS >=1 +MAX_SKB_FRAGS ) + dev->features |=NETIF_F_TSO ;#ifdef TILE_NET_GSO /* We support GSO. */
Signature · 1 line
1.8.3.1
PATCH v2 3/12 tile: remove dead is_dup_ack() function from tilepro net driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilepro.c | 76 ------------------------------------- 1 file changed, 76 deletions(-)
drivers/net/ethernet/tile/tilepro.c +0 -76
@@ -93,9 +93,6 @@/* ISSUE: This may actually hurt performance of the TCP blaster. */ /* #define TILE_NET_GSO */ -/* Define this to collapse "duplicate" acks. */ -/* #define IGNORE_DUP_ACKS */ -/* HACK: Define this to verify incoming packets. */ /* #define TILE_NET_VERIFY_INGRESS */
@@ -629,79 +626,6 @@ static void tile_net_handle_egress_timer(unsigned long arg) } -#ifdef IGNORE_DUP_ACKS - -/* -* Help detect "duplicate" ACKs. These are sequential packets (for a -* given flow) which are exactly 66 bytes long, sharing everything but -* ID=2@0x12, Hsum=2@0x18, Ack=4@0x2a, WinSize=2@0x30, Csum=2@0x32, -* Tstamps=10@0x38. The ID's are +1, the Hsum's are -1, the Ack's are -* +N, and the Tstamps are usually identical. -* -* NOTE: Apparently truly duplicate acks (with identical "ack" values), -* should not be collapsed, as they are used for some kind of flow control. -*/ -static bool is_dup_ack (char *s1,char *s2,unsigned int len) -{ -int i; - -unsigned long long ignorable =0 ; - -/* Identification. */ - ignorable |= (1ULL <<0x12 ); - ignorable |= (1ULL <<0x13 ); - -/* Header checksum. */ - ignorable |= (1ULL <<0x18 ); - ignorable |= (1ULL <<0x19 ); - -/* ACK. */ - ignorable |= (1ULL <<0x2a ); - ignorable |= (1ULL <<0x2b ); - ignorable |= (1ULL <<0x2c ); - ignorable |= (1ULL <<0x2d ); - -/* WinSize. */ - ignorable |= (1ULL <<0x30 ); - ignorable |= (1ULL <<0x31 ); - -/* Checksum. */ - ignorable |= (1ULL <<0x32 ); - ignorable |= (1ULL <<0x33 ); - -for (i =0 ; i < len; i++, ignorable >>=1 ) { - -if ((ignorable &1 ) || (s1[i] == s2[i])) -continue ; - -#ifdef TILE_NET_DEBUG -/* HACK: Mention non-timestamp diffs. */ -if (i <0x38 && i !=0x2f && -net_ratelimit ()) -pr_info ("Diff at 0x%x\n" , i); -#endif - -return false; - } - -#ifdef TILE_NET_NO_SUPPRESS_DUP_ACKS -/* HACK: Do not suppress truly duplicate ACKs. */ -/* ISSUE: Is this actually necessary or helpful? */ -if (s1[0x2a ] == s2[0x2a ] && - s1[0x2b ] == s2[0x2b ] && - s1[0x2c ] == s2[0x2c ] && - s1[0x2d ] == s2[0x2d ]) { -return false; - } -#endif - -return true; -} - -#endif - - -static void tile_net_discard_aux (struct tile_net_cpu *info,int index) {struct tile_netio_queue *queue = &info->queue;
Signature · 1 line
1.8.3.1
PATCH v2 4/12 tile: support jumbo frames in the tilegx network driver
In reply to Chris Metcalf--- arch/tile/gxio/iorpc_mpipe.c | 47 +++++ arch/tile/gxio/mpipe.c | 18 +- arch/tile/include/gxio/iorpc_mpipe.h | 4 + arch/tile/include/gxio/mpipe.h | 101 +++++++++- drivers/net/ethernet/tile/tilegx.c | 345 +++++++++++++++++++---------------- 5 files changed, 350 insertions(+), 165 deletions(-)
arch/tile/gxio/iorpc_mpipe.c +47 -0
@@ -387,6 +387,27 @@ int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac)EXPORT_SYMBOL (gxio_mpipe_link_close_aux); +struct link_set_attr_aux_param { +int mac; +uint32_t attr; +int64_t val; +}; + +int gxio_mpipe_link_set_attr_aux (gxio_mpipe_context_t * context,int mac, +uint32_t attr,int64_t val) +{ +struct link_set_attr_aux_param temp; +struct link_set_attr_aux_param *params = &temp; + + params->mac = mac; + params->attr = attr; + params->val = val; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params),GXIO_MPIPE_OP_LINK_SET_ATTR_AUX ); +} + +EXPORT_SYMBOL (gxio_mpipe_link_set_attr_aux);struct get_timestamp_aux_param {uint64_t sec;
@@ -454,6 +475,32 @@ int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_aux); +struct config_edma_ring_blks_param { +unsigned int ering; +unsigned int max_blks; +unsigned int min_snf_blks; +unsigned int db; +}; + +int gxio_mpipe_config_edma_ring_blks (gxio_mpipe_context_t * context, +unsigned int ering,unsigned int max_blks, +unsigned int min_snf_blks,unsigned int db) +{ +struct config_edma_ring_blks_param temp; +struct config_edma_ring_blks_param *params = &temp; + + params->ering = ering; + params->max_blks = max_blks; + params->min_snf_blks = min_snf_blks; + params->db = db; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params), +GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS ); +} + +EXPORT_SYMBOL (gxio_mpipe_config_edma_ring_blks); +struct arm_pollfd_param {union iorpc_pollfd pollfd; };
arch/tile/gxio/mpipe.c +15 -3
@@ -383,7 +383,7 @@ EXPORT_SYMBOL_GPL(gxio_mpipe_iqueue_init);int gxio_mpipe_equeue_init (gxio_mpipe_equeue_t *equeue,gxio_mpipe_context_t *context, -unsigned int edma_ring_id, +unsigned int ering,unsigned int channel,void *mem,unsigned int mem_size,unsigned int mem_flags)
@@ -394,7 +394,7 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue,/* Offset used to read number of completed commands. */ MPIPE_EDMA_POST_REGION_ADDR_t offset; -int result =gxio_mpipe_init_edma_ring (context, edma_ring_id, channel, +int result =gxio_mpipe_init_edma_ring (context, ering, channel, mem, mem_size, mem_flags);if (result <0 )return result;
@@ -405,7 +405,7 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, offset.region =MPIPE_MMIO_ADDR__REGION_VAL_EDMA -MPIPE_MMIO_ADDR__REGION_VAL_IDMA ; - offset.ring = edma_ring_id; + offset.ring = ering; __gxio_dma_queue_init(&equeue->dma_queue, context->mmio_fast_base + offset.word,
@@ -413,6 +413,9 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, equeue->edescs = mem; equeue->mask_num_entries = num_entries -1 ; equeue->log2_num_entries =__builtin_ctz (num_entries); + equeue->context = context; + equeue->ering = ering; + equeue->channel = channel;return 0 ; }
@@ -543,3 +546,12 @@ int gxio_mpipe_link_close(gxio_mpipe_link_t *link) }EXPORT_SYMBOL_GPL (gxio_mpipe_link_close); + +int gxio_mpipe_link_set_attr (gxio_mpipe_link_t *link,uint32_t attr, +int64_t val) +{ +return gxio_mpipe_link_set_attr_aux (link->context, link->mac, attr, + val); +} + +EXPORT_SYMBOL_GPL (gxio_mpipe_link_set_attr);
arch/tile/include/gxio/iorpc_mpipe.h +4 -0
@@ -44,10 +44,12 @@#define GXIO_MPIPE_OP_REGISTER_CLIENT_MEMORY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1210)#define GXIO_MPIPE_OP_LINK_OPEN_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1211)#define GXIO_MPIPE_OP_LINK_CLOSE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1212) +#define GXIO_MPIPE_OP_LINK_SET_ATTR_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1213)#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121e)#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121f)#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1220) +#define GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1221)#define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)#define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)#define GXIO_MPIPE_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
@@ -114,6 +116,8 @@ int gxio_mpipe_link_open_aux(gxio_mpipe_context_t * context,int gxio_mpipe_link_close_aux (gxio_mpipe_context_t * context,int mac); +int gxio_mpipe_link_set_attr_aux (gxio_mpipe_context_t * context,int mac, +uint32_t attr,int64_t val);int gxio_mpipe_get_timestamp_aux (gxio_mpipe_context_t * context,uint64_t * sec,uint64_t * nsec,uint64_t * cycles);
arch/tile/include/gxio/mpipe.h +97 -4
141 lines not on this page · raw message
drivers/net/ethernet/tile/tilegx.c +187 -158
543 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v2 5/12 tile: update dev->stats directly in tilegx network driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-)
drivers/net/ethernet/tile/tilegx.c +8 -21
@@ -178,8 +178,6 @@ struct tile_net_priv {int loopify_channel;/* The egress channel (channel or loopify_channel). */ int echannel; -/* Total stats. */ -struct net_device_stats stats; };/* Egress info, indexed by "priv->echannel" (lazily created as needed). */
@@ -414,7 +412,6 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb, gxio_mpipe_idesc_t *idesc, unsigned long len) {struct tile_net_info *info = &__get_cpu_var (per_cpu_info); -struct tile_net_priv *priv =netdev_priv (dev);/* Encode the actual packet length. */ skb_put (skb, len);
@@ -428,8 +425,8 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb,netif_receive_skb (skb);/* Update stats. */ -tile_net_stats_add (1 , &priv->stats.rx_packets); -tile_net_stats_add (len, &priv->stats.rx_bytes); +tile_net_stats_add (1 , &dev->stats.rx_packets); +tile_net_stats_add (len, &dev->stats.rx_bytes);/* Need a new buffer. */ if (idesc->size == buffer_size_enums[0 ])
@@ -445,7 +442,6 @@ static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc) {struct tile_net_info *info = &__get_cpu_var (per_cpu_info);struct net_device *dev = tile_net_devs_for_channel[idesc->channel]; -struct tile_net_priv *priv =netdev_priv (dev);uint8_t l2_offset;void *va;void *buf;
@@ -459,7 +455,7 @@ static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc)*/ if (idesc->be || idesc->me || idesc->tr || idesc->ce) {if (dev) -tile_net_stats_add (1 , &priv->stats.rx_errors); +tile_net_stats_add (1 , &dev->stats.rx_errors); goto drop; }
@@ -479,7 +475,7 @@ static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc) filter =filter_packet (dev, buf);if (filter) {if (dev) -tile_net_stats_add (1 , &priv->stats.rx_dropped); +tile_net_stats_add (1 , &dev->stats.rx_dropped); drop:gxio_mpipe_iqueue_drop (&info->iqueue, idesc); }else {
@@ -1502,7 +1498,6 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,static void tso_egress (struct net_device *dev,gxio_mpipe_equeue_t *equeue,struct sk_buff *skb,unsigned char *headers,s64 slot) { -struct tile_net_priv *priv =netdev_priv (dev);struct skb_shared_info *sh =skb_shinfo (skb);unsigned int sh_len =skb_transport_offset (skb) +tcp_hdrlen (skb);unsigned int data_len = skb->len - sh_len;
@@ -1580,8 +1575,8 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, }/* Update stats. */ -tile_net_stats_add (tx_packets, &priv->stats.tx_packets); -tile_net_stats_add (tx_bytes, &priv->stats.tx_bytes); +tile_net_stats_add (tx_packets, &dev->stats.tx_packets); +tile_net_stats_add (tx_bytes, &dev->stats.tx_bytes); }/* Do "TSO" handling for egress.
@@ -1724,9 +1719,9 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)add_comp (equeue, comps, slot -1 , skb);/* NOTE: Use ETH_ZLEN for short packets (e.g. 42 < 60). */ -tile_net_stats_add (1 , &priv->stats.tx_packets); +tile_net_stats_add (1 , &dev->stats.tx_packets); tile_net_stats_add(max_t(unsigned int, len, ETH_ZLEN), - &priv->stats.tx_bytes); + &dev->stats.tx_bytes);local_irq_restore (irqflags);
@@ -1757,13 +1752,6 @@ static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)return -EOPNOTSUPP ; } -/* Get system network statistics for device. */ -static struct net_device_stats *tile_net_get_stats (struct net_device *dev) -{ -struct tile_net_priv *priv =netdev_priv (dev); -return &priv->stats; -} -/* Change the MTU. */ static int tile_net_change_mtu (struct net_device *dev,int new_mtu) {
@@ -1813,7 +1801,6 @@ static const struct net_device_ops tile_net_ops = { .ndo_start_xmit = tile_net_tx, .ndo_select_queue = tile_net_select_queue, .ndo_do_ioctl = tile_net_ioctl, - .ndo_get_stats = tile_net_get_stats, .ndo_change_mtu = tile_net_change_mtu, .ndo_tx_timeout = tile_net_tx_timeout, .ndo_set_mac_address = tile_net_set_mac_address,
Signature · 1 line
1.8.3.1
PATCH v2 6/12 tile: fix panic bug in napi support for tilegx network driver
In reply to Chris MetcalfThe code used to call napi_disable() in an interrupt handler (from smp_call_function), which in turn could call msleep(). Unfortunately you can't sleep in an interrupt context.
Luckily it turns out all the NAPI support functions are just operating on data structures and not on any deeply per-cpu data, so we can arrange to set up and tear down all the NAPI state on the core driving the process, and just do the IRQ enable/disable as a smp_call_function thing.
--- drivers/net/ethernet/tile/tilegx.c | 65 +++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 32 deletions(-)
drivers/net/ethernet/tile/tilegx.c +33 -32
@@ -650,37 +650,13 @@ static enum hrtimer_restart tile_net_handle_egress_timer(struct hrtimer *t)return HRTIMER_NORESTART ; } -/* Helper function for "tile_net_update()". -* "dev" (i.e. arg) is the device being brought up or down, -* or NULL if all devices are now down. -*/ -static void tile_net_update_cpu (void *arg) +/* Helper function for "tile_net_update()". */ +static void manage_ingress_irq (void *enable) { -struct tile_net_info *info = &__get_cpu_var (per_cpu_info); -struct net_device *dev = arg; - -if (!info->has_iqueue) -return ; - -if (dev !=NULL ) { -if (!info->napi_added) { -netif_napi_add (dev, &info->napi, - tile_net_poll,TILE_NET_WEIGHT ); - info->napi_added = true; - } -if (!info->napi_enabled) { -napi_enable (&info->napi); - info->napi_enabled = true; - } +if (enable)enable_percpu_irq (ingress_irq,0 ); - }else { +else disable_percpu_irq (ingress_irq); -if (info->napi_enabled) { -napi_disable (&info->napi); - info->napi_enabled = false; - } -/* FIXME: Drain the iqueue. */ - } }/* Helper function for tile_net_open() and tile_net_stop().
@@ -717,10 +693,35 @@ static int tile_net_update(struct net_device *dev)return -EIO ; } -/* Update all cpus, sequentially (to protect "netif_napi_add()"). */ -for_each_online_cpu (cpu) -smp_call_function_single (cpu, tile_net_update_cpu, - (saw_channel ? dev :NULL ),1 ); +/* Update all cpus, sequentially (to protect "netif_napi_add()"). +* We use on_each_cpu to handle the IPI mask or unmask. +*/ +if (!saw_channel) +on_each_cpu (manage_ingress_irq, (void *)0 ,1 ); +for_each_online_cpu (cpu) { +struct tile_net_info *info = &per_cpu (per_cpu_info, cpu); +if (!info->has_iqueue) +continue ; +if (saw_channel) { +if (!info->napi_added) { +netif_napi_add (dev, &info->napi, + tile_net_poll,TILE_NET_WEIGHT ); + info->napi_added = true; + } +if (!info->napi_enabled) { +napi_enable (&info->napi); + info->napi_enabled = true; + } + }else { +if (info->napi_enabled) { +napi_disable (&info->napi); + info->napi_enabled = false; + } +/* FIXME: Drain the iqueue. */ + } + } +if (saw_channel) +on_each_cpu (manage_ingress_irq, (void *)1 ,1 );/* HACK: Allow packets to flow in the simulator. */ if (saw_channel)
Signature · 1 line
1.8.3.1
PATCH v2 7/12 tile: enable GRO in the tilegx network driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/tile/tilegx.c +1 -1
@@ -422,7 +422,7 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb,if (idesc->cs && idesc->csum_seed_val ==0xFFFF ) skb->ip_summed =CHECKSUM_UNNECESSARY ; -netif_receive_skb (skb); +napi_gro_receive (&info->napi, skb);/* Update stats. */ tile_net_stats_add (1 , &dev->stats.rx_packets);
Signature · 1 line
1.8.3.1
PATCH v2 8/12 tile: support multiple mPIPE shims in tilegx network driver
In reply to Chris MetcalfThe initial driver support was for a single mPIPE shim on the chip (as is the case for the Gx36 hardware). The Gx72 chip has two mPIPE shims, so we extend the driver to handle that case.
--- arch/tile/gxio/iorpc_mpipe_info.c | 18 + arch/tile/gxio/mpipe.c | 25 +- arch/tile/include/gxio/iorpc_mpipe_info.h | 4 + arch/tile/include/gxio/mpipe.h | 28 ++ arch/tile/include/hv/drv_mpipe_intf.h | 3 + drivers/net/ethernet/tile/tilegx.c | 551 ++++++++++++++++++------------ 6 files changed, 417 insertions(+), 212 deletions(-)
arch/tile/gxio/iorpc_mpipe_info.c +18 -0
@@ -16,6 +16,24 @@#include "gxio/iorpc_mpipe_info.h" +struct instance_aux_param { +_gxio_mpipe_link_name_t name; +}; + +int gxio_mpipe_info_instance_aux (gxio_mpipe_info_context_t * context, +_gxio_mpipe_link_name_t name) +{ +struct instance_aux_param temp; +struct instance_aux_param *params = &temp; + + params->name = name; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params),GXIO_MPIPE_INFO_OP_INSTANCE_AUX ); +} + +EXPORT_SYMBOL (gxio_mpipe_info_instance_aux); +struct enumerate_aux_param {_gxio_mpipe_link_name_t name;_gxio_mpipe_link_mac_t mac;
arch/tile/gxio/mpipe.c +23 -2
@@ -36,8 +36,14 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)int fd;int i; +if (mpipe_index >=GXIO_MPIPE_INSTANCE_MAX ) +return -EINVAL ; +snprintf (file,sizeof (file),"mpipe/%d/iorpc" , mpipe_index); fd =hv_dev_open ((HV_VirtAddr ) file,0 ); + + context->fd = fd; +if (fd <0 ) {if (fd >=GXIO_ERR_MIN && fd <=GXIO_ERR_MAX )return fd;
@@ -45,8 +51,6 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)return -ENODEV ; } - context->fd = fd; -/* Map in the MMIO space. */ context->mmio_cfg_base = (void __force *) iorpc_ioremap(fd, HV_MPIPE_CONFIG_MMIO_OFFSET,
@@ -64,12 +68,15 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)for (i =0 ; i <8 ; i++) context->__stacks.stacks[i] =255 ; + context->instance = mpipe_index; +return 0 ; fast_failed:iounmap ((void __force __iomem *)(context->mmio_cfg_base)); cfg_failed:hv_dev_close (context->fd); + context->fd =-1 ;return -ENODEV ; }
@@ -496,6 +503,20 @@ static gxio_mpipe_context_t *_gxio_get_link_context(void)return contextp; } +int gxio_mpipe_link_instance (const char *link_name) +{ +_gxio_mpipe_link_name_t name; +gxio_mpipe_context_t *context =_gxio_get_link_context (); + +if (!context) +return GXIO_ERR_NO_DEVICE ; + +strncpy (name.name, link_name,sizeof (name.name)); + name.name[GXIO_MPIPE_LINK_NAME_LEN -1 ] ='\0' ; + +return gxio_mpipe_info_instance_aux (context, name); +} +int gxio_mpipe_link_enumerate_mac (int idx,char *link_name,uint8_t *link_mac) {int rv;
arch/tile/include/gxio/iorpc_mpipe_info.h +4 -0
@@ -27,11 +27,15 @@#include <asm/pgtable.h> +#define GXIO_MPIPE_INFO_OP_INSTANCE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1250)#define GXIO_MPIPE_INFO_OP_ENUMERATE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1251)#define GXIO_MPIPE_INFO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)#define GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001) +int gxio_mpipe_info_instance_aux (gxio_mpipe_info_context_t * context, +_gxio_mpipe_link_name_t name); + int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context, unsigned int idx, _gxio_mpipe_link_name_t * name,
arch/tile/include/gxio/mpipe.h +28 -0
@@ -220,6 +220,13 @@ typedef MPIPE_PDESC_t gxio_mpipe_idesc_t;*/ typedef MPIPE_EDMA_DESC_t gxio_mpipe_edesc_t ; +/* +* Max # of mpipe instances. 2 currently. +*/ +#define GXIO_MPIPE_INSTANCE_MAX HV_MPIPE_INSTANCE_MAX + +#define NR_MPIPE_MAX GXIO_MPIPE_INSTANCE_MAX +/* Get the "va" field from an "idesc". * * This is the address at which the ingress hardware copied the first
@@ -311,6 +318,9 @@ typedef struct {/* File descriptor for calling up to Linux (and thus the HV). */ int fd; +/* Corresponding mpipe instance #. */ +int instance; +/* The VA at which configuration registers are mapped. */ char *mmio_cfg_base;
@@ -1716,6 +1726,24 @@ typedef struct {uint8_t mac; } gxio_mpipe_link_t; +/* Translate a link name to the instance number of the mPIPE shim which is +* connected to that link. This call does not verify whether the link is +* currently available, and does not reserve any link resources; +* gxio_mpipe_link_open() must be called to perform those functions. +* +* Typically applications will call this function to translate a link name +* to an mPIPE instance number; call gxio_mpipe_init(), passing it that +* instance number, to initialize the mPIPE shim; and then call +* gxio_mpipe_link_open(), passing it the same link name plus the mPIPE +* context, to configure the link. +* +* @param link_name Name of the link; see @ref gxio_mpipe_link_names. +* @return The mPIPE instance number which is associated with the named +* link, or a negative error code (::GXIO_ERR_NO_DEVICE) if the link does +* not exist. +*/ +extern int gxio_mpipe_link_instance (const char *link_name); +/* Retrieve one of this system's legal link names, and its MAC address. * * @param index Link name index. If a system supports N legal link names,
arch/tile/include/hv/drv_mpipe_intf.h +3 -0
@@ -23,6 +23,9 @@#include <arch/mpipe_constants.h> +/** Number of mPIPE instances supported */ +#define HV_MPIPE_INSTANCE_MAX (2) +/** Number of buffer stacks (32). */ #define HV_MPIPE_NUM_BUFFER_STACKS \ (MPIPE_MMIO_INIT_DAT_GX36_1__BUFFER_STACK_MASK_WIDTH)
drivers/net/ethernet/tile/tilegx.c +341 -210
1,035 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v2 9/12 tile: support TSO for IPv6 in tilegx network driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 44 +++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 15 deletions(-)
drivers/net/ethernet/tile/tilegx.c +29 -15
@@ -36,6 +36,7 @@#include <linux/io.h> #include <linux/ctype.h> #include <linux/ip.h> +#include <linux/ipv6.h> #include <linux/tcp.h> #include <asm/checksum.h>
@@ -1512,20 +1513,20 @@ static int tso_count_edescs(struct sk_buff *skb)return num_edescs; } -/* Prepare modified copies of the skbuff headers. -* FIXME: add support for IPv6. -*/ +/* Prepare modified copies of the skbuff headers. */ static void tso_headers_prepare (struct sk_buff *skb,unsigned char *headers,s64 slot) {struct skb_shared_info *sh =skb_shinfo (skb);struct iphdr *ih; +struct ipv6hdr *ih6;struct tcphdr *th;unsigned int sh_len =skb_transport_offset (skb) +tcp_hdrlen (skb);unsigned int data_len = skb->len - sh_len;unsigned char *data = skb->data;unsigned int ih_off, th_off, p_len;unsigned int isum_seed, tsum_seed, id, seq; +int is_ipv6;long f_id =-1 ;/* id of the current fragment */ long f_size =skb_headlen (skb) - sh_len;/* current fragment size */ long f_used =0 ;/* bytes used from the current fragment */
@@ -1533,18 +1534,24 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,int segment;/* Locate original headers and compute various lengths. */ - ih =ip_hdr (skb); + is_ipv6 =skb_is_gso_v6 (skb); +if (is_ipv6) { + ih6 =ipv6_hdr (skb); + ih_off =skb_network_offset (skb); + }else { + ih =ip_hdr (skb); + ih_off =skb_network_offset (skb); + isum_seed = ((0xFFFF - ih->check) + + (0xFFFF - ih->tot_len) + + (0xFFFF - ih->id)); + id =ntohs (ih->id); + } + th =tcp_hdr (skb); - ih_off =skb_network_offset (skb); th_off =skb_transport_offset (skb); p_len = sh->gso_size; -/* Set up seed values for IP and TCP csum and initialize id and seq. */ - isum_seed = ((0xFFFF - ih->check) + - (0xFFFF - ih->tot_len) + - (0xFFFF - ih->id)); tsum_seed = th->check + (0xFFFF ^htons (skb->len)); - id =ntohs (ih->id); seq =ntohl (th->seq);/* Prepare all the headers. */
@@ -1558,11 +1565,17 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,memcpy (buf, data, sh_len);/* Update copied ip header. */ - ih = (struct iphdr *)(buf + ih_off); - ih->tot_len =htons (sh_len + p_len - ih_off); - ih->id =htons (id); - ih->check =csum_long (isum_seed + ih->tot_len + - ih->id) ^0xffff ; +if (is_ipv6) { + ih6 = (struct ipv6hdr *)(buf + ih_off); + ih6->payload_len =htons (sh_len + p_len - ih_off - +sizeof (*ih6)); + }else { + ih = (struct iphdr *)(buf + ih_off); + ih->tot_len =htons (sh_len + p_len - ih_off); + ih->id =htons (id); + ih->check =csum_long (isum_seed + ih->tot_len + + ih->id) ^0xffff ; + }/* Update copied tcp header. */ th = (struct tcphdr *)(buf + th_off);
@@ -1950,6 +1963,7 @@ static void tile_net_setup(struct net_device *dev) dev->features |=NETIF_F_HW_CSUM ; dev->features |=NETIF_F_SG ; dev->features |=NETIF_F_TSO ; + dev->features |=NETIF_F_TSO6 ; dev->mtu =1500 ; }
Signature · 1 line
1.8.3.1
Re: [PATCH 09/12] tile: support TSO for IPv6 in tilegx network driver
From: Chris Metcalf <[email protected]>
Date: Wed, 31 Jul 2013 11:05:04 -0400
drivers/net/ethernet/tile/tilegx.c static void tile_net_setup(struct net_device *dev) · line 1967
Quoted 6 lines
drivers/net/ethernet/tile/tilegx.c +1
-0@@ -1950,6 +1963,7 @@ static void tile_net_setup(struct net_device *dev) dev->features |=NETIF_F_HW_CSUM ; dev->features |=NETIF_F_SG ; dev->features |=NETIF_F_TSO ; + dev->features |=NETIF_F_TSO6 ; dev->mtu =1500 ;
This driver is severely out of date wrt. how to properly advertise device features, and you really need to fix this _before_ adding support for new capabilities.
dev->hw_features specifies what the device is capable of, whereas dev->features specifies what features are currently enabled.
Using these two values we determine what feature bits the user can configure on and off using generic code which checks dev->hw_features when the user makes a request.
You'll also want to have a look at netdev_ops->ndo_fix_features and netdev_ops->ndo_set_features which allow a driver to handle attempts to install illegal combinations of features.
You can look at other well maintained drivers to see how this works.
Thanks.
[PATCH v2 13/12] tile: set hw_features and vlan_features in setup
This change allows the user to configure various features of the tile networking drivers on and off. There is no change to the default initialization state of either the tilegx or tilepro drivers.
Neither driver needs the ndo_fix_features or ndo_set_features callbacks, since the generic code already handles the dependencies for fix_features, and there is no hardware state to tweak in set_features.
---
David, I've fixed the drivers to use hw_features as a follow-on "13 of 12" patch in the v2 series, rather than rebasing the previous patches, since they weren't actually buggy as-is, and this was simpler. However, I am happy to provide a v3 of the patch series with the hw_features change rebased to the front if that feels better to you.
drivers/net/ethernet/tile/tilegx.c | 15 ++++++++++---- drivers/net/ethernet/tile/tilepro.c | 39 +++++++++++++++---------------------- 2 files changed, 27 insertions(+), 27 deletions(-)
drivers/net/ethernet/tile/tilegx.c +11 -4
@@ -2169,14 +2169,21 @@ static const struct net_device_ops tile_net_ops = {*/ static void tile_net_setup (struct net_device *dev) { +netdev_features_t features =0 ; +ether_setup (dev); dev->netdev_ops = &tile_net_ops; dev->watchdog_timeo =TILE_NET_TIMEOUT ; - dev->features |=NETIF_F_HW_CSUM ; - dev->features |=NETIF_F_SG ; - dev->features |=NETIF_F_TSO ; - dev->features |=NETIF_F_TSO6 ; dev->mtu =1500 ; + + features |=NETIF_F_HW_CSUM ; + features |=NETIF_F_SG ; + features |=NETIF_F_TSO ; + features |=NETIF_F_TSO6 ; + + dev->hw_features |= features; + dev->vlan_features |= features; + dev->features |= features; }/* Allocate the device structure, register the device, and obtain the
drivers/net/ethernet/tile/tilepro.c +16 -23
@@ -89,9 +89,9 @@/* ISSUE: This has not been thoroughly tested (except at 1500). */ #define TILE_NET_MTU 1500 -/* HACK: Define to support GSO. */ -/* ISSUE: This may actually hurt performance of the TCP blaster. */ -/* #define TILE_NET_GSO */ +/* Define as 0 to enable all features by default. */ +/* ISSUE: GSO appears to actually hurt performance of the TCP blaster. */ +#define TILE_NETIF_F_DEFAULT_DISABLE NETIF_F_GSO/* HACK: Define this to verify incoming packets. */ /* #define TILE_NET_VERIFY_INGRESS */
@@ -2249,37 +2249,30 @@ static const struct net_device_ops tile_net_ops = {*/ static void tile_net_setup (struct net_device *dev) { -PDEBUG ("tile_net_setup()\n" ); +netdev_features_t features =0 ;ether_setup (dev); - dev->netdev_ops = &tile_net_ops; - dev->watchdog_timeo =TILE_NET_TIMEOUT ; + dev->tx_queue_len =TILE_NET_TX_QUEUE_LEN ; + dev->mtu =TILE_NET_MTU ; -/* We support hardware tx checksums. */ - dev->features |=NETIF_F_HW_CSUM ; - -/* We support scatter/gather. */ - dev->features |=NETIF_F_SG ; + features |=NETIF_F_HW_CSUM ; + features |=NETIF_F_SG ;/* We support TSO iff the HV supports sufficient frags. */ if (LEPP_MAX_FRAGS >=1 +MAX_SKB_FRAGS ) - dev->features |=NETIF_F_TSO ; - -#ifdef TILE_NET_GSO -/* We support GSO. */ - dev->features |=NETIF_F_GSO ; -#endif + features |=NETIF_F_TSO ; +/* We can't support HIGHDMA without hash_default, since we need +* to be able to finv() with a VA if we don't have hash_default. +*/ if (hash_default) - dev->features |=NETIF_F_HIGHDMA ; - -/* ISSUE: We should support NETIF_F_UFO. */ + features |=NETIF_F_HIGHDMA ; - dev->tx_queue_len =TILE_NET_TX_QUEUE_LEN ; - - dev->mtu =TILE_NET_MTU ; + dev->hw_features |= features; + dev->vlan_features |= features; + dev->features |= features & ~TILE_NETIF_F_DEFAULT_DISABLE ; }
Signature · 1 line
1.8.3.1
David Miller
maintainerRe: [PATCH v2 13/12] tile: set hw_features and vlan_features in setup
From: Chris Metcalf <[email protected]>
Date: Thu, 1 Aug 2013 11:36:42 -0400
Quoted 8 lines
This change allows the user to configure various features of the tile networking drivers on and off. There is no change to the default initialization state of either the tilegx or tilepro drivers.
Neither driver needs the
ndo_fix_featuresorndo_set_featurescallbacks, since the generic code already handles the dependencies forfix_features, and there is no hardware state to tweak inset_features.
Quoted 7 lines
Signed-off-by Chris Metcalf <[email protected]>---
David, I've fixed the drivers to usehw_featuresas a follow-on "13 of 12" patch in the v2 series, rather than rebasing the previous patches, since they weren't actually buggy as-is, and this was simpler. However, I am happy to provide a v3 of the patch series with thehw_featureschange rebased to the front if that feels better to you.
Please redo your patch series properly rather than appending fixes on top, thank you.
v3 cover update tile network drivers
This is v3 of the patch series to update the Tilera network drivers.
Quoted 1 line
From the v1 00/13 cover letter: "This patch series contains changes made
to the Tilera on-chip network drivers for both the 64-bit tilegx and 32-bit tilepro architectures. The changes involve a number of bug fixes, support for the multiple mPIPEs on the new Gx72 chip, support for jumbo frames, TSO for IPv6, GRO, PTP support, and statistics improvements."
David has already applied the v2 patch for what was patch 01/13 in the first series ("handle 64-bit statistics in tilepro network driver") so it is not included in this v3 series.
Changes from the v1 series include:
- Nearly complete rewrite of PTP changes based on feedback from Richard Cochran
- Removal of NETIF_F_GRO as unnecessary (from Eric Dumazet)
- A few minor whitespace and code style changes
Changes from the v2 series:
- use of dev->hw_features instead of just dev->features
Chris Metcalf (13):
tile: set hw_features and vlan_features in setup
tile: support rx_dropped/rx_errors in tilepro net driver
tile: avoid bug in tilepro net driver built with old hypervisor
tile: remove dead is_dup_ack() function from tilepro net driver
tile: support jumbo frames in the tilegx network driver
tile: update dev->stats directly in tilegx network driver
tile: fix panic bug in napi support for tilegx network driver
tile: enable GRO in the tilegx network driver
tile: support multiple mPIPE shims in tilegx network driver
tile: support TSO for IPv6 in tilegx network driver
tile: make "tile_net.custom" a proper bool module parameter
tile: remove deprecated NETIF_F_LLTX flag from tile drivers
tile: support PTP using the tilegx mPIPE (IEEE 1588)
arch/tile/gxio/iorpc_mpipe.c | 66 ++ arch/tile/gxio/iorpc_mpipe_info.c | 18 + arch/tile/gxio/mpipe.c | 43 +- arch/tile/include/gxio/iorpc_mpipe.h | 14 +- arch/tile/include/gxio/iorpc_mpipe_info.h | 4 + arch/tile/include/gxio/mpipe.h | 143 +++- arch/tile/include/hv/drv_mpipe_intf.h | 3 + drivers/net/ethernet/tile/Kconfig | 11 + drivers/net/ethernet/tile/tilegx.c | 1112 +++++++++++++++++++---------- drivers/net/ethernet/tile/tilepro.c | 164 +---- 10 files changed, 1069 insertions(+), 509 deletions(-)
Signature · 1 line
1.8.3.1
PATCH v3 1/13 tile: set hw_features and vlan_features in setup
This change allows the user to configure various features of the tile networking drivers on and off. There is no change to the default initialization state of either the tilegx or tilepro drivers.
Neither driver needs the ndo_fix_features or ndo_set_features callbacks, since the generic code already handles the dependencies for fix_features, and there is no hardware state to tweak in set_features.
--- drivers/net/ethernet/tile/tilegx.c | 15 +++++++++---- drivers/net/ethernet/tile/tilepro.c | 43 ++++++++++++------------------------- 2 files changed, 25 insertions(+), 33 deletions(-)
drivers/net/ethernet/tile/tilegx.c +11 -4
@@ -1800,14 +1800,21 @@ static const struct net_device_ops tile_net_ops = {*/ static void tile_net_setup (struct net_device *dev) { +netdev_features_t features =0 ; +ether_setup (dev); dev->netdev_ops = &tile_net_ops; dev->watchdog_timeo =TILE_NET_TIMEOUT ; - dev->features |=NETIF_F_LLTX ; - dev->features |=NETIF_F_HW_CSUM ; - dev->features |=NETIF_F_SG ; - dev->features |=NETIF_F_TSO ; dev->mtu =1500 ; + + features |=NETIF_F_LLTX ; + features |=NETIF_F_HW_CSUM ; + features |=NETIF_F_SG ; + features |=NETIF_F_TSO ; + + dev->hw_features |= features; + dev->vlan_features |= features; + dev->features |= features; }/* Allocate the device structure, register the device, and obtain the
drivers/net/ethernet/tile/tilepro.c +14 -29
63 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v3 2/13 tile: support rx_dropped/rx_errors in tilepro net driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilepro.c | 41 ++++++++++++++----------------------- 1 file changed, 15 insertions(+), 26 deletions(-)
drivers/net/ethernet/tile/tilepro.c +15 -26
@@ -772,6 +772,7 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)netio_pkt_t *pkt = (netio_pkt_t *)((unsigned long ) &qsp[1 ] + index);netio_pkt_metadata_t *metadata =NETIO_PKT_METADATA (pkt); +netio_pkt_status_t pkt_status =NETIO_PKT_STATUS_M (metadata, pkt);/* Extract the packet size. FIXME: Shouldn't the second line */ /* get subtracted? Mostly moot, since it should be "zero". */
@@ -804,40 +805,25 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)#endif /* TILE_NET_DUMP_PACKETS */ #ifdef TILE_NET_VERIFY_INGRESS -if (!NETIO_PKT_L4_CSUM_CORRECT_M (metadata, pkt) && -NETIO_PKT_L4_CSUM_CALCULATED_M (metadata, pkt)) { -/* Bug 6624: Includes UDP packets with a "zero" checksum. */ -pr_warning ("Bad L4 checksum on %d byte packet.\n" , len); - } -if (!NETIO_PKT_L3_CSUM_CORRECT_M (metadata, pkt) && -NETIO_PKT_L3_CSUM_CALCULATED_M (metadata, pkt)) { +if (pkt_status ==NETIO_PKT_STATUS_OVERSIZE && len >=64 ) {dump_packet (buf, len,"rx" ); -panic ("Bad L3 checksum." ); - } -switch (NETIO_PKT_STATUS_M (metadata, pkt)) { -case NETIO_PKT_STATUS_OVERSIZE : -if (len >=64 ) { -dump_packet (buf, len,"rx" ); -panic ("Unexpected OVERSIZE." ); - } -break ; -case NETIO_PKT_STATUS_BAD : -pr_warning ("Unexpected BAD %ld byte packet.\n" , len); +panic ("Unexpected OVERSIZE." ); }#endif filter =0 ; -/* ISSUE: Filter TCP packets with "bad" checksums? */ - -if (!(dev->flags &IFF_UP )) { +if (pkt_status ==NETIO_PKT_STATUS_BAD ) { +/* Handle CRC error and hardware truncation. */ + filter =2 ; + }else if (!(dev->flags &IFF_UP )) {/* Filter packets received before we're up. */ filter =1 ; - }else if (NETIO_PKT_STATUS_M (metadata, pkt) ==NETIO_PKT_STATUS_BAD ) { + }else if (NETIO_PKT_ETHERTYPE_RECOGNIZED_M (metadata, pkt) && + pkt_status ==NETIO_PKT_STATUS_UNDERSIZE ) {/* Filter "truncated" packets. */ - filter =1 ; + filter =2 ; }else if (!(dev->flags &IFF_PROMISC )) { -/* FIXME: Implement HW multicast filter. */ if (!is_multicast_ether_addr (buf)) {/* Filter packets not for our address. */ const u8 *mine = dev->dev_addr;
@@ -847,9 +833,12 @@ static bool tile_net_poll_aux(struct tile_net_cpu *info, int index)u64_stats_update_begin (&stats->syncp); -if (filter) { +if (filter !=0 ) { -/* ISSUE: Update "drop" statistics? */ +if (filter ==1 ) + stats->rx_dropped++; +else + stats->rx_errors++;tile_net_provide_linux_buffer (info, va, small);
Signature · 1 line
1.8.3.1
PATCH v3 3/13 tile: avoid bug in tilepro net driver built with old hypervisor
In reply to Chris MetcalfBuilding against headers from an older Tilera hypervisor can cause the frags[] array to be overrun. Don't enable TSO in that case.
--- drivers/net/ethernet/tile/tilepro.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/net/ethernet/tile/tilepro.c +6 -3
@@ -1929,7 +1929,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)unsigned int csum_start =skb_checksum_start_offset (skb); -lepp_frag_t frags[LEPP_MAX_FRAGS ]; +lepp_frag_t frags[1 +MAX_SKB_FRAGS ];unsigned int num_frags;
@@ -1944,7 +1944,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)unsigned int cmd_head, cmd_tail, cmd_next;unsigned int comp_tail; -lepp_cmd_t cmds[LEPP_MAX_FRAGS ]; +lepp_cmd_t cmds[1 +MAX_SKB_FRAGS ];/*
@@ -2332,7 +2332,10 @@ static void tile_net_setup(struct net_device *dev) features |=NETIF_F_LLTX ; features |=NETIF_F_HW_CSUM ; features |=NETIF_F_SG ; - features |=NETIF_F_TSO ; + +/* We support TSO iff the HV supports sufficient frags. */ +if (LEPP_MAX_FRAGS >=1 +MAX_SKB_FRAGS ) + features |=NETIF_F_TSO ;/* We can't support HIGHDMA without hash_default, since we need * to be able to finv() with a VA if we don't have hash_default.
Signature · 1 line
1.8.3.1
PATCH v3 4/13 tile: remove dead is_dup_ack() function from tilepro net driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilepro.c | 76 ------------------------------------- 1 file changed, 76 deletions(-)
drivers/net/ethernet/tile/tilepro.c +0 -76
@@ -89,9 +89,6 @@/* ISSUE: This has not been thoroughly tested (except at 1500). */ #define TILE_NET_MTU 1500 -/* Define this to collapse "duplicate" acks. */ -/* #define IGNORE_DUP_ACKS */ -/* HACK: Define this to verify incoming packets. */ /* #define TILE_NET_VERIFY_INGRESS */
@@ -625,79 +622,6 @@ static void tile_net_handle_egress_timer(unsigned long arg) } -#ifdef IGNORE_DUP_ACKS - -/* -* Help detect "duplicate" ACKs. These are sequential packets (for a -* given flow) which are exactly 66 bytes long, sharing everything but -* ID=2@0x12, Hsum=2@0x18, Ack=4@0x2a, WinSize=2@0x30, Csum=2@0x32, -* Tstamps=10@0x38. The ID's are +1, the Hsum's are -1, the Ack's are -* +N, and the Tstamps are usually identical. -* -* NOTE: Apparently truly duplicate acks (with identical "ack" values), -* should not be collapsed, as they are used for some kind of flow control. -*/ -static bool is_dup_ack (char *s1,char *s2,unsigned int len) -{ -int i; - -unsigned long long ignorable =0 ; - -/* Identification. */ - ignorable |= (1ULL <<0x12 ); - ignorable |= (1ULL <<0x13 ); - -/* Header checksum. */ - ignorable |= (1ULL <<0x18 ); - ignorable |= (1ULL <<0x19 ); - -/* ACK. */ - ignorable |= (1ULL <<0x2a ); - ignorable |= (1ULL <<0x2b ); - ignorable |= (1ULL <<0x2c ); - ignorable |= (1ULL <<0x2d ); - -/* WinSize. */ - ignorable |= (1ULL <<0x30 ); - ignorable |= (1ULL <<0x31 ); - -/* Checksum. */ - ignorable |= (1ULL <<0x32 ); - ignorable |= (1ULL <<0x33 ); - -for (i =0 ; i < len; i++, ignorable >>=1 ) { - -if ((ignorable &1 ) || (s1[i] == s2[i])) -continue ; - -#ifdef TILE_NET_DEBUG -/* HACK: Mention non-timestamp diffs. */ -if (i <0x38 && i !=0x2f && -net_ratelimit ()) -pr_info ("Diff at 0x%x\n" , i); -#endif - -return false; - } - -#ifdef TILE_NET_NO_SUPPRESS_DUP_ACKS -/* HACK: Do not suppress truly duplicate ACKs. */ -/* ISSUE: Is this actually necessary or helpful? */ -if (s1[0x2a ] == s2[0x2a ] && - s1[0x2b ] == s2[0x2b ] && - s1[0x2c ] == s2[0x2c ] && - s1[0x2d ] == s2[0x2d ]) { -return false; - } -#endif - -return true; -} - -#endif - - -static void tile_net_discard_aux (struct tile_net_cpu *info,int index) {struct tile_netio_queue *queue = &info->queue;
Signature · 1 line
1.8.3.1
PATCH v3 5/13 tile: support jumbo frames in the tilegx network driver
In reply to Chris Metcalf--- arch/tile/gxio/iorpc_mpipe.c | 47 +++++ arch/tile/gxio/mpipe.c | 18 +- arch/tile/include/gxio/iorpc_mpipe.h | 4 + arch/tile/include/gxio/mpipe.h | 101 +++++++++- drivers/net/ethernet/tile/tilegx.c | 347 +++++++++++++++++++---------------- 5 files changed, 351 insertions(+), 166 deletions(-)
arch/tile/gxio/iorpc_mpipe.c +47 -0
@@ -387,6 +387,27 @@ int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac)EXPORT_SYMBOL (gxio_mpipe_link_close_aux); +struct link_set_attr_aux_param { +int mac; +uint32_t attr; +int64_t val; +}; + +int gxio_mpipe_link_set_attr_aux (gxio_mpipe_context_t * context,int mac, +uint32_t attr,int64_t val) +{ +struct link_set_attr_aux_param temp; +struct link_set_attr_aux_param *params = &temp; + + params->mac = mac; + params->attr = attr; + params->val = val; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params),GXIO_MPIPE_OP_LINK_SET_ATTR_AUX ); +} + +EXPORT_SYMBOL (gxio_mpipe_link_set_attr_aux);struct get_timestamp_aux_param {uint64_t sec;
@@ -454,6 +475,32 @@ int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_aux); +struct config_edma_ring_blks_param { +unsigned int ering; +unsigned int max_blks; +unsigned int min_snf_blks; +unsigned int db; +}; + +int gxio_mpipe_config_edma_ring_blks (gxio_mpipe_context_t * context, +unsigned int ering,unsigned int max_blks, +unsigned int min_snf_blks,unsigned int db) +{ +struct config_edma_ring_blks_param temp; +struct config_edma_ring_blks_param *params = &temp; + + params->ering = ering; + params->max_blks = max_blks; + params->min_snf_blks = min_snf_blks; + params->db = db; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params), +GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS ); +} + +EXPORT_SYMBOL (gxio_mpipe_config_edma_ring_blks); +struct arm_pollfd_param {union iorpc_pollfd pollfd; };
arch/tile/gxio/mpipe.c +15 -3
@@ -383,7 +383,7 @@ EXPORT_SYMBOL_GPL(gxio_mpipe_iqueue_init);int gxio_mpipe_equeue_init (gxio_mpipe_equeue_t *equeue,gxio_mpipe_context_t *context, -unsigned int edma_ring_id, +unsigned int ering,unsigned int channel,void *mem,unsigned int mem_size,unsigned int mem_flags)
@@ -394,7 +394,7 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue,/* Offset used to read number of completed commands. */ MPIPE_EDMA_POST_REGION_ADDR_t offset; -int result =gxio_mpipe_init_edma_ring (context, edma_ring_id, channel, +int result =gxio_mpipe_init_edma_ring (context, ering, channel, mem, mem_size, mem_flags);if (result <0 )return result;
@@ -405,7 +405,7 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, offset.region =MPIPE_MMIO_ADDR__REGION_VAL_EDMA -MPIPE_MMIO_ADDR__REGION_VAL_IDMA ; - offset.ring = edma_ring_id; + offset.ring = ering; __gxio_dma_queue_init(&equeue->dma_queue, context->mmio_fast_base + offset.word,
@@ -413,6 +413,9 @@ int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue, equeue->edescs = mem; equeue->mask_num_entries = num_entries -1 ; equeue->log2_num_entries =__builtin_ctz (num_entries); + equeue->context = context; + equeue->ering = ering; + equeue->channel = channel;return 0 ; }
@@ -543,3 +546,12 @@ int gxio_mpipe_link_close(gxio_mpipe_link_t *link) }EXPORT_SYMBOL_GPL (gxio_mpipe_link_close); + +int gxio_mpipe_link_set_attr (gxio_mpipe_link_t *link,uint32_t attr, +int64_t val) +{ +return gxio_mpipe_link_set_attr_aux (link->context, link->mac, attr, + val); +} + +EXPORT_SYMBOL_GPL (gxio_mpipe_link_set_attr);
arch/tile/include/gxio/iorpc_mpipe.h +4 -0
@@ -44,10 +44,12 @@#define GXIO_MPIPE_OP_REGISTER_CLIENT_MEMORY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1210)#define GXIO_MPIPE_OP_LINK_OPEN_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1211)#define GXIO_MPIPE_OP_LINK_CLOSE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1212) +#define GXIO_MPIPE_OP_LINK_SET_ATTR_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1213)#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121e)#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121f)#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1220) +#define GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1221)#define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)#define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)#define GXIO_MPIPE_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
@@ -114,6 +116,8 @@ int gxio_mpipe_link_open_aux(gxio_mpipe_context_t * context,int gxio_mpipe_link_close_aux (gxio_mpipe_context_t * context,int mac); +int gxio_mpipe_link_set_attr_aux (gxio_mpipe_context_t * context,int mac, +uint32_t attr,int64_t val);int gxio_mpipe_get_timestamp_aux (gxio_mpipe_context_t * context,uint64_t * sec,uint64_t * nsec,uint64_t * cycles);
arch/tile/include/gxio/mpipe.h +97 -4
141 lines not on this page · raw message
drivers/net/ethernet/tile/tilegx.c +188 -159
545 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v3 6/13 tile: update dev->stats directly in tilegx network driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-)
drivers/net/ethernet/tile/tilegx.c +8 -21
@@ -178,8 +178,6 @@ struct tile_net_priv {int loopify_channel;/* The egress channel (channel or loopify_channel). */ int echannel; -/* Total stats. */ -struct net_device_stats stats; };/* Egress info, indexed by "priv->echannel" (lazily created as needed). */
@@ -414,7 +412,6 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb, gxio_mpipe_idesc_t *idesc, unsigned long len) {struct tile_net_info *info = &__get_cpu_var (per_cpu_info); -struct tile_net_priv *priv =netdev_priv (dev);/* Encode the actual packet length. */ skb_put (skb, len);
@@ -428,8 +425,8 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb,netif_receive_skb (skb);/* Update stats. */ -tile_net_stats_add (1 , &priv->stats.rx_packets); -tile_net_stats_add (len, &priv->stats.rx_bytes); +tile_net_stats_add (1 , &dev->stats.rx_packets); +tile_net_stats_add (len, &dev->stats.rx_bytes);/* Need a new buffer. */ if (idesc->size == buffer_size_enums[0 ])
@@ -445,7 +442,6 @@ static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc) {struct tile_net_info *info = &__get_cpu_var (per_cpu_info);struct net_device *dev = tile_net_devs_for_channel[idesc->channel]; -struct tile_net_priv *priv =netdev_priv (dev);uint8_t l2_offset;void *va;void *buf;
@@ -459,7 +455,7 @@ static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc)*/ if (idesc->be || idesc->me || idesc->tr || idesc->ce) {if (dev) -tile_net_stats_add (1 , &priv->stats.rx_errors); +tile_net_stats_add (1 , &dev->stats.rx_errors); goto drop; }
@@ -479,7 +475,7 @@ static bool tile_net_handle_packet(gxio_mpipe_idesc_t *idesc) filter =filter_packet (dev, buf);if (filter) {if (dev) -tile_net_stats_add (1 , &priv->stats.rx_dropped); +tile_net_stats_add (1 , &dev->stats.rx_dropped); drop:gxio_mpipe_iqueue_drop (&info->iqueue, idesc); }else {
@@ -1502,7 +1498,6 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,static void tso_egress (struct net_device *dev,gxio_mpipe_equeue_t *equeue,struct sk_buff *skb,unsigned char *headers,s64 slot) { -struct tile_net_priv *priv =netdev_priv (dev);struct skb_shared_info *sh =skb_shinfo (skb);unsigned int sh_len =skb_transport_offset (skb) +tcp_hdrlen (skb);unsigned int data_len = skb->len - sh_len;
@@ -1580,8 +1575,8 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, }/* Update stats. */ -tile_net_stats_add (tx_packets, &priv->stats.tx_packets); -tile_net_stats_add (tx_bytes, &priv->stats.tx_bytes); +tile_net_stats_add (tx_packets, &dev->stats.tx_packets); +tile_net_stats_add (tx_bytes, &dev->stats.tx_bytes); }/* Do "TSO" handling for egress.
@@ -1724,9 +1719,9 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev)add_comp (equeue, comps, slot -1 , skb);/* NOTE: Use ETH_ZLEN for short packets (e.g. 42 < 60). */ -tile_net_stats_add (1 , &priv->stats.tx_packets); +tile_net_stats_add (1 , &dev->stats.tx_packets); tile_net_stats_add(max_t(unsigned int, len, ETH_ZLEN), - &priv->stats.tx_bytes); + &dev->stats.tx_bytes);local_irq_restore (irqflags);
@@ -1757,13 +1752,6 @@ static int tile_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)return -EOPNOTSUPP ; } -/* Get system network statistics for device. */ -static struct net_device_stats *tile_net_get_stats (struct net_device *dev) -{ -struct tile_net_priv *priv =netdev_priv (dev); -return &priv->stats; -} -/* Change the MTU. */ static int tile_net_change_mtu (struct net_device *dev,int new_mtu) {
@@ -1813,7 +1801,6 @@ static const struct net_device_ops tile_net_ops = { .ndo_start_xmit = tile_net_tx, .ndo_select_queue = tile_net_select_queue, .ndo_do_ioctl = tile_net_ioctl, - .ndo_get_stats = tile_net_get_stats, .ndo_change_mtu = tile_net_change_mtu, .ndo_tx_timeout = tile_net_tx_timeout, .ndo_set_mac_address = tile_net_set_mac_address,
Signature · 1 line
1.8.3.1
PATCH v3 7/13 tile: fix panic bug in napi support for tilegx network driver
In reply to Chris MetcalfThe code used to call napi_disable() in an interrupt handler (from smp_call_function), which in turn could call msleep(). Unfortunately you can't sleep in an interrupt context.
Luckily it turns out all the NAPI support functions are just operating on data structures and not on any deeply per-cpu data, so we can arrange to set up and tear down all the NAPI state on the core driving the process, and just do the IRQ enable/disable as a smp_call_function thing.
--- drivers/net/ethernet/tile/tilegx.c | 65 +++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 32 deletions(-)
drivers/net/ethernet/tile/tilegx.c +33 -32
@@ -650,37 +650,13 @@ static enum hrtimer_restart tile_net_handle_egress_timer(struct hrtimer *t)return HRTIMER_NORESTART ; } -/* Helper function for "tile_net_update()". -* "dev" (i.e. arg) is the device being brought up or down, -* or NULL if all devices are now down. -*/ -static void tile_net_update_cpu (void *arg) +/* Helper function for "tile_net_update()". */ +static void manage_ingress_irq (void *enable) { -struct tile_net_info *info = &__get_cpu_var (per_cpu_info); -struct net_device *dev = arg; - -if (!info->has_iqueue) -return ; - -if (dev !=NULL ) { -if (!info->napi_added) { -netif_napi_add (dev, &info->napi, - tile_net_poll,TILE_NET_WEIGHT ); - info->napi_added = true; - } -if (!info->napi_enabled) { -napi_enable (&info->napi); - info->napi_enabled = true; - } +if (enable)enable_percpu_irq (ingress_irq,0 ); - }else { +else disable_percpu_irq (ingress_irq); -if (info->napi_enabled) { -napi_disable (&info->napi); - info->napi_enabled = false; - } -/* FIXME: Drain the iqueue. */ - } }/* Helper function for tile_net_open() and tile_net_stop().
@@ -717,10 +693,35 @@ static int tile_net_update(struct net_device *dev)return -EIO ; } -/* Update all cpus, sequentially (to protect "netif_napi_add()"). */ -for_each_online_cpu (cpu) -smp_call_function_single (cpu, tile_net_update_cpu, - (saw_channel ? dev :NULL ),1 ); +/* Update all cpus, sequentially (to protect "netif_napi_add()"). +* We use on_each_cpu to handle the IPI mask or unmask. +*/ +if (!saw_channel) +on_each_cpu (manage_ingress_irq, (void *)0 ,1 ); +for_each_online_cpu (cpu) { +struct tile_net_info *info = &per_cpu (per_cpu_info, cpu); +if (!info->has_iqueue) +continue ; +if (saw_channel) { +if (!info->napi_added) { +netif_napi_add (dev, &info->napi, + tile_net_poll,TILE_NET_WEIGHT ); + info->napi_added = true; + } +if (!info->napi_enabled) { +napi_enable (&info->napi); + info->napi_enabled = true; + } + }else { +if (info->napi_enabled) { +napi_disable (&info->napi); + info->napi_enabled = false; + } +/* FIXME: Drain the iqueue. */ + } + } +if (saw_channel) +on_each_cpu (manage_ingress_irq, (void *)1 ,1 );/* HACK: Allow packets to flow in the simulator. */ if (saw_channel)
Signature · 1 line
1.8.3.1
PATCH v3 8/13 tile: enable GRO in the tilegx network driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/tile/tilegx.c +1 -1
@@ -422,7 +422,7 @@ static void tile_net_receive_skb(struct net_device *dev, struct sk_buff *skb,if (idesc->cs && idesc->csum_seed_val ==0xFFFF ) skb->ip_summed =CHECKSUM_UNNECESSARY ; -netif_receive_skb (skb); +napi_gro_receive (&info->napi, skb);/* Update stats. */ tile_net_stats_add (1 , &dev->stats.rx_packets);
Signature · 1 line
1.8.3.1
PATCH v3 9/13 tile: support multiple mPIPE shims in tilegx network driver
In reply to Chris MetcalfThe initial driver support was for a single mPIPE shim on the chip (as is the case for the Gx36 hardware). The Gx72 chip has two mPIPE shims, so we extend the driver to handle that case.
--- arch/tile/gxio/iorpc_mpipe_info.c | 18 + arch/tile/gxio/mpipe.c | 25 +- arch/tile/include/gxio/iorpc_mpipe_info.h | 4 + arch/tile/include/gxio/mpipe.h | 28 ++ arch/tile/include/hv/drv_mpipe_intf.h | 3 + drivers/net/ethernet/tile/tilegx.c | 551 ++++++++++++++++++------------ 6 files changed, 417 insertions(+), 212 deletions(-)
arch/tile/gxio/iorpc_mpipe_info.c +18 -0
@@ -16,6 +16,24 @@#include "gxio/iorpc_mpipe_info.h" +struct instance_aux_param { +_gxio_mpipe_link_name_t name; +}; + +int gxio_mpipe_info_instance_aux (gxio_mpipe_info_context_t * context, +_gxio_mpipe_link_name_t name) +{ +struct instance_aux_param temp; +struct instance_aux_param *params = &temp; + + params->name = name; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params),GXIO_MPIPE_INFO_OP_INSTANCE_AUX ); +} + +EXPORT_SYMBOL (gxio_mpipe_info_instance_aux); +struct enumerate_aux_param {_gxio_mpipe_link_name_t name;_gxio_mpipe_link_mac_t mac;
arch/tile/gxio/mpipe.c +23 -2
@@ -36,8 +36,14 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)int fd;int i; +if (mpipe_index >=GXIO_MPIPE_INSTANCE_MAX ) +return -EINVAL ; +snprintf (file,sizeof (file),"mpipe/%d/iorpc" , mpipe_index); fd =hv_dev_open ((HV_VirtAddr ) file,0 ); + + context->fd = fd; +if (fd <0 ) {if (fd >=GXIO_ERR_MIN && fd <=GXIO_ERR_MAX )return fd;
@@ -45,8 +51,6 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)return -ENODEV ; } - context->fd = fd; -/* Map in the MMIO space. */ context->mmio_cfg_base = (void __force *) iorpc_ioremap(fd, HV_MPIPE_CONFIG_MMIO_OFFSET,
@@ -64,12 +68,15 @@ int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)for (i =0 ; i <8 ; i++) context->__stacks.stacks[i] =255 ; + context->instance = mpipe_index; +return 0 ; fast_failed:iounmap ((void __force __iomem *)(context->mmio_cfg_base)); cfg_failed:hv_dev_close (context->fd); + context->fd =-1 ;return -ENODEV ; }
@@ -496,6 +503,20 @@ static gxio_mpipe_context_t *_gxio_get_link_context(void)return contextp; } +int gxio_mpipe_link_instance (const char *link_name) +{ +_gxio_mpipe_link_name_t name; +gxio_mpipe_context_t *context =_gxio_get_link_context (); + +if (!context) +return GXIO_ERR_NO_DEVICE ; + +strncpy (name.name, link_name,sizeof (name.name)); + name.name[GXIO_MPIPE_LINK_NAME_LEN -1 ] ='\0' ; + +return gxio_mpipe_info_instance_aux (context, name); +} +int gxio_mpipe_link_enumerate_mac (int idx,char *link_name,uint8_t *link_mac) {int rv;
arch/tile/include/gxio/iorpc_mpipe_info.h +4 -0
@@ -27,11 +27,15 @@#include <asm/pgtable.h> +#define GXIO_MPIPE_INFO_OP_INSTANCE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1250)#define GXIO_MPIPE_INFO_OP_ENUMERATE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1251)#define GXIO_MPIPE_INFO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)#define GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001) +int gxio_mpipe_info_instance_aux (gxio_mpipe_info_context_t * context, +_gxio_mpipe_link_name_t name); + int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context, unsigned int idx, _gxio_mpipe_link_name_t * name,
arch/tile/include/gxio/mpipe.h +28 -0
@@ -220,6 +220,13 @@ typedef MPIPE_PDESC_t gxio_mpipe_idesc_t;*/ typedef MPIPE_EDMA_DESC_t gxio_mpipe_edesc_t ; +/* +* Max # of mpipe instances. 2 currently. +*/ +#define GXIO_MPIPE_INSTANCE_MAX HV_MPIPE_INSTANCE_MAX + +#define NR_MPIPE_MAX GXIO_MPIPE_INSTANCE_MAX +/* Get the "va" field from an "idesc". * * This is the address at which the ingress hardware copied the first
@@ -311,6 +318,9 @@ typedef struct {/* File descriptor for calling up to Linux (and thus the HV). */ int fd; +/* Corresponding mpipe instance #. */ +int instance; +/* The VA at which configuration registers are mapped. */ char *mmio_cfg_base;
@@ -1716,6 +1726,24 @@ typedef struct {uint8_t mac; } gxio_mpipe_link_t; +/* Translate a link name to the instance number of the mPIPE shim which is +* connected to that link. This call does not verify whether the link is +* currently available, and does not reserve any link resources; +* gxio_mpipe_link_open() must be called to perform those functions. +* +* Typically applications will call this function to translate a link name +* to an mPIPE instance number; call gxio_mpipe_init(), passing it that +* instance number, to initialize the mPIPE shim; and then call +* gxio_mpipe_link_open(), passing it the same link name plus the mPIPE +* context, to configure the link. +* +* @param link_name Name of the link; see @ref gxio_mpipe_link_names. +* @return The mPIPE instance number which is associated with the named +* link, or a negative error code (::GXIO_ERR_NO_DEVICE) if the link does +* not exist. +*/ +extern int gxio_mpipe_link_instance (const char *link_name); +/* Retrieve one of this system's legal link names, and its MAC address. * * @param index Link name index. If a system supports N legal link names,
arch/tile/include/hv/drv_mpipe_intf.h +3 -0
@@ -23,6 +23,9 @@#include <arch/mpipe_constants.h> +/** Number of mPIPE instances supported */ +#define HV_MPIPE_INSTANCE_MAX (2) +/** Number of buffer stacks (32). */ #define HV_MPIPE_NUM_BUFFER_STACKS \ (MPIPE_MMIO_INIT_DAT_GX36_1__BUFFER_STACK_MASK_WIDTH)
drivers/net/ethernet/tile/tilegx.c +341 -210
1,035 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v3 10/13 tile: support TSO for IPv6 in tilegx network driver
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 44 +++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 15 deletions(-)
drivers/net/ethernet/tile/tilegx.c +29 -15
@@ -36,6 +36,7 @@#include <linux/io.h> #include <linux/ctype.h> #include <linux/ip.h> +#include <linux/ipv6.h> #include <linux/tcp.h> #include <asm/checksum.h>
@@ -1512,20 +1513,20 @@ static int tso_count_edescs(struct sk_buff *skb)return num_edescs; } -/* Prepare modified copies of the skbuff headers. -* FIXME: add support for IPv6. -*/ +/* Prepare modified copies of the skbuff headers. */ static void tso_headers_prepare (struct sk_buff *skb,unsigned char *headers,s64 slot) {struct skb_shared_info *sh =skb_shinfo (skb);struct iphdr *ih; +struct ipv6hdr *ih6;struct tcphdr *th;unsigned int sh_len =skb_transport_offset (skb) +tcp_hdrlen (skb);unsigned int data_len = skb->len - sh_len;unsigned char *data = skb->data;unsigned int ih_off, th_off, p_len;unsigned int isum_seed, tsum_seed, id, seq; +int is_ipv6;long f_id =-1 ;/* id of the current fragment */ long f_size =skb_headlen (skb) - sh_len;/* current fragment size */ long f_used =0 ;/* bytes used from the current fragment */
@@ -1533,18 +1534,24 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,int segment;/* Locate original headers and compute various lengths. */ - ih =ip_hdr (skb); + is_ipv6 =skb_is_gso_v6 (skb); +if (is_ipv6) { + ih6 =ipv6_hdr (skb); + ih_off =skb_network_offset (skb); + }else { + ih =ip_hdr (skb); + ih_off =skb_network_offset (skb); + isum_seed = ((0xFFFF - ih->check) + + (0xFFFF - ih->tot_len) + + (0xFFFF - ih->id)); + id =ntohs (ih->id); + } + th =tcp_hdr (skb); - ih_off =skb_network_offset (skb); th_off =skb_transport_offset (skb); p_len = sh->gso_size; -/* Set up seed values for IP and TCP csum and initialize id and seq. */ - isum_seed = ((0xFFFF - ih->check) + - (0xFFFF - ih->tot_len) + - (0xFFFF - ih->id)); tsum_seed = th->check + (0xFFFF ^htons (skb->len)); - id =ntohs (ih->id); seq =ntohl (th->seq);/* Prepare all the headers. */
@@ -1558,11 +1565,17 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers,memcpy (buf, data, sh_len);/* Update copied ip header. */ - ih = (struct iphdr *)(buf + ih_off); - ih->tot_len =htons (sh_len + p_len - ih_off); - ih->id =htons (id); - ih->check =csum_long (isum_seed + ih->tot_len + - ih->id) ^0xffff ; +if (is_ipv6) { + ih6 = (struct ipv6hdr *)(buf + ih_off); + ih6->payload_len =htons (sh_len + p_len - ih_off - +sizeof (*ih6)); + }else { + ih = (struct iphdr *)(buf + ih_off); + ih->tot_len =htons (sh_len + p_len - ih_off); + ih->id =htons (id); + ih->check =csum_long (isum_seed + ih->tot_len + + ih->id) ^0xffff ; + }/* Update copied tcp header. */ th = (struct tcphdr *)(buf + th_off);
@@ -1954,6 +1967,7 @@ static void tile_net_setup(struct net_device *dev) features |=NETIF_F_HW_CSUM ; features |=NETIF_F_SG ; features |=NETIF_F_TSO ; + features |=NETIF_F_TSO6 ; dev->hw_features |= features; dev->vlan_features |= features;
Signature · 1 line
1.8.3.1
PATCH v3 11/13 tile: make "tile_net.custom" a proper bool module parameter
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/ethernet/tile/tilegx.c +5 -5
@@ -256,11 +256,11 @@ static char *network_cpus_string;/* The actual cpus in "network_cpus". */ static struct cpumask network_cpus_map; -/* If "loopify=LINK" was specified, this is "LINK". */ +/* If "tile_net.loopify=LINK" was specified, this is "LINK". */ static char *loopify_link_name; -/* If "tile_net.custom" was specified, this is non-NULL. */ -static char *custom_str; +/* If "tile_net.custom" was specified, this is true. */ +static bool custom_flag;/* If "tile_net.jumbo=NUM" was specified, this is "NUM". */ static uint jumbo_num;
@@ -323,7 +323,7 @@ MODULE_PARM_DESC(loopify, "name the device to use loop0/1 for ingress/egress");/* The "tile_net.custom" argument causes us to ignore the "conventional" * classifier metadata, in particular, the "l2_offset". */ -module_param_named (custom, custom_str, charp,0444 ); +module_param_named (custom, custom_flag, bool,0444 );MODULE_PARM_DESC (custom,"indicates a (heavily) customized classifier" );/* The "tile_net.jumbo" argument causes us to support "jumbo" packets,
@@ -501,7 +501,7 @@ static bool tile_net_handle_packet(int instance, gxio_mpipe_idesc_t *idesc) }/* Get the "l2_offset", if allowed. */ - l2_offset = custom_str ?0 :gxio_mpipe_idesc_get_l2_offset (idesc); + l2_offset = custom_flag ?0 :gxio_mpipe_idesc_get_l2_offset (idesc);/* Get the VA (including NET_IP_ALIGN bytes of "headroom"). */ va =tile_io_addr_to_va ((unsigned long )idesc->va);
Signature · 1 line
1.8.3.1
PATCH v3 12/13 tile: remove deprecated NETIF_F_LLTX flag from tile drivers
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 1 - drivers/net/ethernet/tile/tilepro.c | 1 - 2 files changed, 2 deletions(-)
drivers/net/ethernet/tile/tilegx.c +0 -1
@@ -1963,7 +1963,6 @@ static void tile_net_setup(struct net_device *dev) dev->watchdog_timeo =TILE_NET_TIMEOUT ; dev->mtu =1500 ; - features |=NETIF_F_LLTX ; features |=NETIF_F_HW_CSUM ; features |=NETIF_F_SG ; features |=NETIF_F_TSO ;
drivers/net/ethernet/tile/tilepro.c +0 -1
@@ -2253,7 +2253,6 @@ static void tile_net_setup(struct net_device *dev) dev->tx_queue_len =TILE_NET_TX_QUEUE_LEN ; dev->mtu =TILE_NET_MTU ; - features |=NETIF_F_LLTX ; features |=NETIF_F_HW_CSUM ; features |=NETIF_F_SG ;
Signature · 1 line
1.8.3.1
PATCH v3 13/13 tile: support PTP using the tilegx mPIPE (IEEE 1588)
In reply to Chris Metcalf--- arch/tile/gxio/iorpc_mpipe.c | 19 +++ arch/tile/include/gxio/iorpc_mpipe.h | 10 +- arch/tile/include/gxio/mpipe.h | 14 +++ drivers/net/ethernet/tile/Kconfig | 11 ++ drivers/net/ethernet/tile/tilegx.c | 216 ++++++++++++++++++++++++++++++++++- 5 files changed, 266 insertions(+), 4 deletions(-)
arch/tile/gxio/iorpc_mpipe.c +19 -0
@@ -475,6 +475,25 @@ int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_aux); +struct adjust_timestamp_freq_param { +int32_t ppb; +}; + +int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb) +{ +struct adjust_timestamp_freq_param temp; +struct adjust_timestamp_freq_param *params = &temp; + + params->ppb = ppb; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params), +GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ ); +} + +EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_freq); +struct config_edma_ring_blks_param {unsigned int ering;unsigned int max_blks;
arch/tile/include/gxio/iorpc_mpipe.h +7 -3
@@ -46,10 +46,11 @@#define GXIO_MPIPE_OP_LINK_CLOSE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1212)#define GXIO_MPIPE_OP_LINK_SET_ATTR_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1213) -#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121e) -#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121f) -#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1220) +#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x121e) +#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x121f) +#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1220)#define GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1221) +#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1222)#define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)#define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)#define GXIO_MPIPE_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
@@ -128,6 +129,9 @@ int gxio_mpipe_set_timestamp_aux(gxio_mpipe_context_t * context, uint64_t sec,int gxio_mpipe_adjust_timestamp_aux (gxio_mpipe_context_t * context,int64_t nsec); +int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb); +int gxio_mpipe_arm_pollfd (gxio_mpipe_context_t * context,int pollfd_cookie);int gxio_mpipe_close_pollfd (gxio_mpipe_context_t * context,int pollfd_cookie);
arch/tile/include/gxio/mpipe.h +14 -0
@@ -1854,4 +1854,18 @@ extern int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context,extern int gxio_mpipe_adjust_timestamp (gxio_mpipe_context_t *context,int64_t delta); +/** Adjust the mPIPE timestamp clock frequency. +* +* @param context An initialized mPIPE context. +* @param ppb A 32-bit signed PPB (Parts Per Billion) value to adjust. +* The absolute value of ppb must be less than or equal to 1000000000. +* Values less than about 30000 will generally cause a GXIO_ERR_INVAL +* return due to the granularity of the hardware that converts reference +* clock cycles into seconds and nanoseconds. +* @return If the call was successful, zero; otherwise, a negative error +* code. +*/ +extern int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb); +#endif /* !_GXIO_MPIPE_H_ */
drivers/net/ethernet/tile/Kconfig +11 -0
@@ -15,3 +15,14 @@ config TILE_NET 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.
drivers/net/ethernet/tile/tilegx.c +215 -1
282 lines not on this page · raw message
Signature · 1 line
1.8.3.1
David Miller
maintainerFrom: Chris Metcalf <[email protected]>
Date: Thu, 1 Aug 2013 15:25:19 -0400
Quoted 11 lines
This is v3 of the patch series to update the Tilera network drivers.
From the v1 00/13 cover letter: "This patch series contains changes made to the Tilera on-chip network drivers for both the 64-bit tilegx and 32-bit tilepro architectures. The changes involve a number of bug fixes, support for the multiple mPIPEs on the new Gx72 chip, support for jumbo frames, TSO for IPv6, GRO, PTP support, and statistics improvements."
David has already applied the v2 patch for what was patch 01/13 in the first series ("handle 64-bit statistics in tilepro network driver") so it is not included in this v3 series.
Series applied to net-next, thanks.
PATCH v2 10/12 tile: make "tile_net.custom" a proper bool module parameter
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/ethernet/tile/tilegx.c +5 -5
@@ -256,11 +256,11 @@ static char *network_cpus_string;/* The actual cpus in "network_cpus". */ static struct cpumask network_cpus_map; -/* If "loopify=LINK" was specified, this is "LINK". */ +/* If "tile_net.loopify=LINK" was specified, this is "LINK". */ static char *loopify_link_name; -/* If "tile_net.custom" was specified, this is non-NULL. */ -static char *custom_str; +/* If "tile_net.custom" was specified, this is true. */ +static bool custom_flag;/* If "tile_net.jumbo=NUM" was specified, this is "NUM". */ static uint jumbo_num;
@@ -323,7 +323,7 @@ MODULE_PARM_DESC(loopify, "name the device to use loop0/1 for ingress/egress");/* The "tile_net.custom" argument causes us to ignore the "conventional" * classifier metadata, in particular, the "l2_offset". */ -module_param_named (custom, custom_str, charp,0444 ); +module_param_named (custom, custom_flag, bool,0444 );MODULE_PARM_DESC (custom,"indicates a (heavily) customized classifier" );/* The "tile_net.jumbo" argument causes us to support "jumbo" packets,
@@ -501,7 +501,7 @@ static bool tile_net_handle_packet(int instance, gxio_mpipe_idesc_t *idesc) }/* Get the "l2_offset", if allowed. */ - l2_offset = custom_str ?0 :gxio_mpipe_idesc_get_l2_offset (idesc); + l2_offset = custom_flag ?0 :gxio_mpipe_idesc_get_l2_offset (idesc);/* Get the VA (including NET_IP_ALIGN bytes of "headroom"). */ va =tile_io_addr_to_va ((unsigned long )(long )idesc->va);
Signature · 1 line
1.8.3.1
PATCH v2 11/12 tile: remove deprecated NETIF_F_LLTX flag from tile drivers
In reply to Chris Metcalf--- drivers/net/ethernet/tile/tilegx.c | 1 - drivers/net/ethernet/tile/tilepro.c | 3 --- 2 files changed, 4 deletions(-)
drivers/net/ethernet/tile/tilegx.c +0 -1
@@ -1959,7 +1959,6 @@ static void tile_net_setup(struct net_device *dev)ether_setup (dev); dev->netdev_ops = &tile_net_ops; dev->watchdog_timeo =TILE_NET_TIMEOUT ; - dev->features |=NETIF_F_LLTX ; dev->features |=NETIF_F_HW_CSUM ; dev->features |=NETIF_F_SG ; dev->features |=NETIF_F_TSO ;
drivers/net/ethernet/tile/tilepro.c +0 -3
@@ -2257,9 +2257,6 @@ static void tile_net_setup(struct net_device *dev) dev->watchdog_timeo =TILE_NET_TIMEOUT ; -/* We want lockless xmit. */ - dev->features |=NETIF_F_LLTX ; -/* We support hardware tx checksums. */ dev->features |=NETIF_F_HW_CSUM ;
Signature · 1 line
1.8.3.1
PATCH v2 12/12 tile: support PTP using the tilegx mPIPE (IEEE 1588)
In reply to Chris Metcalf--- arch/tile/gxio/iorpc_mpipe.c | 19 +++ arch/tile/include/gxio/iorpc_mpipe.h | 10 +- arch/tile/include/gxio/mpipe.h | 14 +++ drivers/net/ethernet/tile/Kconfig | 11 ++ drivers/net/ethernet/tile/tilegx.c | 216 ++++++++++++++++++++++++++++++++++- 5 files changed, 266 insertions(+), 4 deletions(-)
arch/tile/gxio/iorpc_mpipe.c +19 -0
@@ -475,6 +475,25 @@ int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_aux); +struct adjust_timestamp_freq_param { +int32_t ppb; +}; + +int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb) +{ +struct adjust_timestamp_freq_param temp; +struct adjust_timestamp_freq_param *params = &temp; + + params->ppb = ppb; + +return hv_dev_pwrite (context->fd,0 , (HV_VirtAddr ) params, +sizeof (*params), +GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ ); +} + +EXPORT_SYMBOL (gxio_mpipe_adjust_timestamp_freq); +struct config_edma_ring_blks_param {unsigned int ering;unsigned int max_blks;
arch/tile/include/gxio/iorpc_mpipe.h +7 -3
@@ -46,10 +46,11 @@#define GXIO_MPIPE_OP_LINK_CLOSE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1212)#define GXIO_MPIPE_OP_LINK_SET_ATTR_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1213) -#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121e) -#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x121f) -#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1220) +#define GXIO_MPIPE_OP_GET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x121e) +#define GXIO_MPIPE_OP_SET_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x121f) +#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1220)#define GXIO_MPIPE_OP_CONFIG_EDMA_RING_BLKS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1221) +#define GXIO_MPIPE_OP_ADJUST_TIMESTAMP_FREQ IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1222)#define GXIO_MPIPE_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)#define GXIO_MPIPE_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)#define GXIO_MPIPE_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
@@ -128,6 +129,9 @@ int gxio_mpipe_set_timestamp_aux(gxio_mpipe_context_t * context, uint64_t sec,int gxio_mpipe_adjust_timestamp_aux (gxio_mpipe_context_t * context,int64_t nsec); +int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb); +int gxio_mpipe_arm_pollfd (gxio_mpipe_context_t * context,int pollfd_cookie);int gxio_mpipe_close_pollfd (gxio_mpipe_context_t * context,int pollfd_cookie);
arch/tile/include/gxio/mpipe.h +14 -0
@@ -1854,4 +1854,18 @@ extern int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context,extern int gxio_mpipe_adjust_timestamp (gxio_mpipe_context_t *context,int64_t delta); +/** Adjust the mPIPE timestamp clock frequency. +* +* @param context An initialized mPIPE context. +* @param ppb A 32-bit signed PPB (Parts Per Billion) value to adjust. +* The absolute value of ppb must be less than or equal to 1000000000. +* Values less than about 30000 will generally cause a GXIO_ERR_INVAL +* return due to the granularity of the hardware that converts reference +* clock cycles into seconds and nanoseconds. +* @return If the call was successful, zero; otherwise, a negative error +* code. +*/ +extern int gxio_mpipe_adjust_timestamp_freq (gxio_mpipe_context_t * context, +int32_t ppb); +#endif /* !_GXIO_MPIPE_H_ */
drivers/net/ethernet/tile/Kconfig +11 -0
@@ -15,3 +15,14 @@ config TILE_NET 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.
drivers/net/ethernet/tile/tilegx.c +215 -1
282 lines not on this page · raw message
Signature · 1 line
1.8.3.1