cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ethernet-tx.c (20455B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * This file is based on code from OCTEON SDK by Cavium Networks.
      4 *
      5 * Copyright (c) 2003-2010 Cavium Networks
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/kernel.h>
     10#include <linux/netdevice.h>
     11#include <linux/etherdevice.h>
     12#include <linux/ip.h>
     13#include <linux/ratelimit.h>
     14#include <linux/string.h>
     15#include <linux/interrupt.h>
     16#include <net/dst.h>
     17#ifdef CONFIG_XFRM
     18#include <linux/xfrm.h>
     19#include <net/xfrm.h>
     20#endif /* CONFIG_XFRM */
     21
     22#include <linux/atomic.h>
     23#include <net/sch_generic.h>
     24
     25#include "octeon-ethernet.h"
     26#include "ethernet-defines.h"
     27#include "ethernet-tx.h"
     28#include "ethernet-util.h"
     29
     30#define CVM_OCT_SKB_CB(skb)	((u64 *)((skb)->cb))
     31
     32/*
     33 * You can define GET_SKBUFF_QOS() to override how the skbuff output
     34 * function determines which output queue is used. The default
     35 * implementation always uses the base queue for the port. If, for
     36 * example, you wanted to use the skb->priority field, define
     37 * GET_SKBUFF_QOS as: #define GET_SKBUFF_QOS(skb) ((skb)->priority)
     38 */
     39#ifndef GET_SKBUFF_QOS
     40#define GET_SKBUFF_QOS(skb) 0
     41#endif
     42
     43static void cvm_oct_tx_do_cleanup(unsigned long arg);
     44static DECLARE_TASKLET_OLD(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup);
     45
     46/* Maximum number of SKBs to try to free per xmit packet. */
     47#define MAX_SKB_TO_FREE (MAX_OUT_QUEUE_DEPTH * 2)
     48
     49static inline int cvm_oct_adjust_skb_to_free(int skb_to_free, int fau)
     50{
     51	int undo;
     52
     53	undo = skb_to_free > 0 ? MAX_SKB_TO_FREE : skb_to_free +
     54						   MAX_SKB_TO_FREE;
     55	if (undo > 0)
     56		cvmx_fau_atomic_add32(fau, -undo);
     57	skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ? MAX_SKB_TO_FREE :
     58						       -skb_to_free;
     59	return skb_to_free;
     60}
     61
     62static void cvm_oct_kick_tx_poll_watchdog(void)
     63{
     64	union cvmx_ciu_timx ciu_timx;
     65
     66	ciu_timx.u64 = 0;
     67	ciu_timx.s.one_shot = 1;
     68	ciu_timx.s.len = cvm_oct_tx_poll_interval;
     69	cvmx_write_csr(CVMX_CIU_TIMX(1), ciu_timx.u64);
     70}
     71
     72static void cvm_oct_free_tx_skbs(struct net_device *dev)
     73{
     74	int skb_to_free;
     75	int qos, queues_per_port;
     76	int total_freed = 0;
     77	int total_remaining = 0;
     78	unsigned long flags;
     79	struct octeon_ethernet *priv = netdev_priv(dev);
     80
     81	queues_per_port = cvmx_pko_get_num_queues(priv->port);
     82	/* Drain any pending packets in the free list */
     83	for (qos = 0; qos < queues_per_port; qos++) {
     84		if (skb_queue_len(&priv->tx_free_list[qos]) == 0)
     85			continue;
     86		skb_to_free = cvmx_fau_fetch_and_add32(priv->fau + qos * 4,
     87						       MAX_SKB_TO_FREE);
     88		skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free,
     89							 priv->fau + qos * 4);
     90		total_freed += skb_to_free;
     91		if (skb_to_free > 0) {
     92			struct sk_buff *to_free_list = NULL;
     93
     94			spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
     95			while (skb_to_free > 0) {
     96				struct sk_buff *t;
     97
     98				t = __skb_dequeue(&priv->tx_free_list[qos]);
     99				t->next = to_free_list;
    100				to_free_list = t;
    101				skb_to_free--;
    102			}
    103			spin_unlock_irqrestore(&priv->tx_free_list[qos].lock,
    104					       flags);
    105			/* Do the actual freeing outside of the lock. */
    106			while (to_free_list) {
    107				struct sk_buff *t = to_free_list;
    108
    109				to_free_list = to_free_list->next;
    110				dev_kfree_skb_any(t);
    111			}
    112		}
    113		total_remaining += skb_queue_len(&priv->tx_free_list[qos]);
    114	}
    115	if (total_remaining < MAX_OUT_QUEUE_DEPTH && netif_queue_stopped(dev))
    116		netif_wake_queue(dev);
    117	if (total_remaining)
    118		cvm_oct_kick_tx_poll_watchdog();
    119}
    120
    121/**
    122 * cvm_oct_xmit - transmit a packet
    123 * @skb:    Packet to send
    124 * @dev:    Device info structure
    125 *
    126 * Returns Always returns NETDEV_TX_OK
    127 */
    128int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
    129{
    130	union cvmx_pko_command_word0 pko_command;
    131	union cvmx_buf_ptr hw_buffer;
    132	u64 old_scratch;
    133	u64 old_scratch2;
    134	int qos;
    135	int i;
    136	enum {QUEUE_CORE, QUEUE_HW, QUEUE_DROP} queue_type;
    137	struct octeon_ethernet *priv = netdev_priv(dev);
    138	struct sk_buff *to_free_list;
    139	int skb_to_free;
    140	int buffers_to_free;
    141	u32 total_to_clean;
    142	unsigned long flags;
    143#if REUSE_SKBUFFS_WITHOUT_FREE
    144	unsigned char *fpa_head;
    145#endif
    146
    147	/*
    148	 * Prefetch the private data structure.  It is larger than the
    149	 * one cache line.
    150	 */
    151	prefetch(priv);
    152
    153	/*
    154	 * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to
    155	 * completely remove "qos" in the event neither interface
    156	 * supports multiple queues per port.
    157	 */
    158	if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
    159	    (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
    160		qos = GET_SKBUFF_QOS(skb);
    161		if (qos <= 0)
    162			qos = 0;
    163		else if (qos >= cvmx_pko_get_num_queues(priv->port))
    164			qos = 0;
    165	} else {
    166		qos = 0;
    167	}
    168
    169	if (USE_ASYNC_IOBDMA) {
    170		/* Save scratch in case userspace is using it */
    171		CVMX_SYNCIOBDMA;
    172		old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
    173		old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
    174
    175		/*
    176		 * Fetch and increment the number of packets to be
    177		 * freed.
    178		 */
    179		cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8,
    180					       FAU_NUM_PACKET_BUFFERS_TO_FREE,
    181					       0);
    182		cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH,
    183					       priv->fau + qos * 4,
    184					       MAX_SKB_TO_FREE);
    185	}
    186
    187	/*
    188	 * We have space for 6 segment pointers, If there will be more
    189	 * than that, we must linearize.
    190	 */
    191	if (unlikely(skb_shinfo(skb)->nr_frags > 5)) {
    192		if (unlikely(__skb_linearize(skb))) {
    193			queue_type = QUEUE_DROP;
    194			if (USE_ASYNC_IOBDMA) {
    195				/*
    196				 * Get the number of skbuffs in use
    197				 * by the hardware
    198				 */
    199				CVMX_SYNCIOBDMA;
    200				skb_to_free =
    201					cvmx_scratch_read64(CVMX_SCR_SCRATCH);
    202			} else {
    203				/*
    204				 * Get the number of skbuffs in use
    205				 * by the hardware
    206				 */
    207				skb_to_free =
    208				     cvmx_fau_fetch_and_add32(priv->fau +
    209							      qos * 4,
    210							      MAX_SKB_TO_FREE);
    211			}
    212			skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free,
    213								 priv->fau +
    214								 qos * 4);
    215			spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
    216			goto skip_xmit;
    217		}
    218	}
    219
    220	/*
    221	 * The CN3XXX series of parts has an errata (GMX-401) which
    222	 * causes the GMX block to hang if a collision occurs towards
    223	 * the end of a <68 byte packet. As a workaround for this, we
    224	 * pad packets to be 68 bytes whenever we are in half duplex
    225	 * mode. We don't handle the case of having a small packet but
    226	 * no room to add the padding.  The kernel should always give
    227	 * us at least a cache line
    228	 */
    229	if ((skb->len < 64) && OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
    230		union cvmx_gmxx_prtx_cfg gmx_prt_cfg;
    231		int interface = INTERFACE(priv->port);
    232		int index = INDEX(priv->port);
    233
    234		if (interface < 2) {
    235			/* We only need to pad packet in half duplex mode */
    236			gmx_prt_cfg.u64 =
    237			    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
    238			if (gmx_prt_cfg.s.duplex == 0) {
    239				int add_bytes = 64 - skb->len;
    240
    241				if ((skb_tail_pointer(skb) + add_bytes) <=
    242				    skb_end_pointer(skb))
    243					__skb_put_zero(skb, add_bytes);
    244			}
    245		}
    246	}
    247
    248	/* Build the PKO command */
    249	pko_command.u64 = 0;
    250#ifdef __LITTLE_ENDIAN
    251	pko_command.s.le = 1;
    252#endif
    253	pko_command.s.n2 = 1;	/* Don't pollute L2 with the outgoing packet */
    254	pko_command.s.segs = 1;
    255	pko_command.s.total_bytes = skb->len;
    256	pko_command.s.size0 = CVMX_FAU_OP_SIZE_32;
    257	pko_command.s.subone0 = 1;
    258
    259	pko_command.s.dontfree = 1;
    260
    261	/* Build the PKO buffer pointer */
    262	hw_buffer.u64 = 0;
    263	if (skb_shinfo(skb)->nr_frags == 0) {
    264		hw_buffer.s.addr = XKPHYS_TO_PHYS((uintptr_t)skb->data);
    265		hw_buffer.s.pool = 0;
    266		hw_buffer.s.size = skb->len;
    267	} else {
    268		hw_buffer.s.addr = XKPHYS_TO_PHYS((uintptr_t)skb->data);
    269		hw_buffer.s.pool = 0;
    270		hw_buffer.s.size = skb_headlen(skb);
    271		CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64;
    272		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
    273			skb_frag_t *fs = skb_shinfo(skb)->frags + i;
    274
    275			hw_buffer.s.addr =
    276				XKPHYS_TO_PHYS((uintptr_t)skb_frag_address(fs));
    277			hw_buffer.s.size = skb_frag_size(fs);
    278			CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64;
    279		}
    280		hw_buffer.s.addr =
    281			XKPHYS_TO_PHYS((uintptr_t)CVM_OCT_SKB_CB(skb));
    282		hw_buffer.s.size = skb_shinfo(skb)->nr_frags + 1;
    283		pko_command.s.segs = skb_shinfo(skb)->nr_frags + 1;
    284		pko_command.s.gather = 1;
    285		goto dont_put_skbuff_in_hw;
    286	}
    287
    288	/*
    289	 * See if we can put this skb in the FPA pool. Any strange
    290	 * behavior from the Linux networking stack will most likely
    291	 * be caused by a bug in the following code. If some field is
    292	 * in use by the network stack and gets carried over when a
    293	 * buffer is reused, bad things may happen.  If in doubt and
    294	 * you dont need the absolute best performance, disable the
    295	 * define REUSE_SKBUFFS_WITHOUT_FREE. The reuse of buffers has
    296	 * shown a 25% increase in performance under some loads.
    297	 */
    298#if REUSE_SKBUFFS_WITHOUT_FREE
    299	fpa_head = skb->head + 256 - ((unsigned long)skb->head & 0x7f);
    300	if (unlikely(skb->data < fpa_head)) {
    301		/* TX buffer beginning can't meet FPA alignment constraints */
    302		goto dont_put_skbuff_in_hw;
    303	}
    304	if (unlikely
    305	    ((skb_end_pointer(skb) - fpa_head) < CVMX_FPA_PACKET_POOL_SIZE)) {
    306		/* TX buffer isn't large enough for the FPA */
    307		goto dont_put_skbuff_in_hw;
    308	}
    309	if (unlikely(skb_shared(skb))) {
    310		/* TX buffer sharing data with someone else */
    311		goto dont_put_skbuff_in_hw;
    312	}
    313	if (unlikely(skb_cloned(skb))) {
    314		/* TX buffer has been cloned */
    315		goto dont_put_skbuff_in_hw;
    316	}
    317	if (unlikely(skb_header_cloned(skb))) {
    318		/* TX buffer header has been cloned */
    319		goto dont_put_skbuff_in_hw;
    320	}
    321	if (unlikely(skb->destructor)) {
    322		/* TX buffer has a destructor */
    323		goto dont_put_skbuff_in_hw;
    324	}
    325	if (unlikely(skb_shinfo(skb)->nr_frags)) {
    326		/* TX buffer has fragments */
    327		goto dont_put_skbuff_in_hw;
    328	}
    329	if (unlikely
    330	    (skb->truesize !=
    331	     sizeof(*skb) + skb_end_offset(skb))) {
    332		/* TX buffer truesize has been changed */
    333		goto dont_put_skbuff_in_hw;
    334	}
    335
    336	/*
    337	 * We can use this buffer in the FPA.  We don't need the FAU
    338	 * update anymore
    339	 */
    340	pko_command.s.dontfree = 0;
    341
    342	hw_buffer.s.back = ((unsigned long)skb->data >> 7) -
    343			   ((unsigned long)fpa_head >> 7);
    344
    345	*(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
    346
    347	/*
    348	 * The skbuff will be reused without ever being freed. We must
    349	 * cleanup a bunch of core things.
    350	 */
    351	dst_release(skb_dst(skb));
    352	skb_dst_set(skb, NULL);
    353	skb_ext_reset(skb);
    354	nf_reset_ct(skb);
    355	skb_reset_redirect(skb);
    356
    357#ifdef CONFIG_NET_SCHED
    358	skb->tc_index = 0;
    359#endif /* CONFIG_NET_SCHED */
    360#endif /* REUSE_SKBUFFS_WITHOUT_FREE */
    361
    362dont_put_skbuff_in_hw:
    363
    364	/* Check if we can use the hardware checksumming */
    365	if ((skb->protocol == htons(ETH_P_IP)) &&
    366	    (ip_hdr(skb)->version == 4) &&
    367	    (ip_hdr(skb)->ihl == 5) &&
    368	    ((ip_hdr(skb)->frag_off == 0) ||
    369	     (ip_hdr(skb)->frag_off == htons(1 << 14))) &&
    370	    ((ip_hdr(skb)->protocol == IPPROTO_TCP) ||
    371	     (ip_hdr(skb)->protocol == IPPROTO_UDP))) {
    372		/* Use hardware checksum calc */
    373		pko_command.s.ipoffp1 = skb_network_offset(skb) + 1;
    374	}
    375
    376	if (USE_ASYNC_IOBDMA) {
    377		/* Get the number of skbuffs in use by the hardware */
    378		CVMX_SYNCIOBDMA;
    379		skb_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
    380		buffers_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
    381	} else {
    382		/* Get the number of skbuffs in use by the hardware */
    383		skb_to_free = cvmx_fau_fetch_and_add32(priv->fau + qos * 4,
    384						       MAX_SKB_TO_FREE);
    385		buffers_to_free =
    386		    cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
    387	}
    388
    389	skb_to_free = cvm_oct_adjust_skb_to_free(skb_to_free,
    390						 priv->fau + qos * 4);
    391
    392	/*
    393	 * If we're sending faster than the receive can free them then
    394	 * don't do the HW free.
    395	 */
    396	if ((buffers_to_free < -100) && !pko_command.s.dontfree)
    397		pko_command.s.dontfree = 1;
    398
    399	if (pko_command.s.dontfree) {
    400		queue_type = QUEUE_CORE;
    401		pko_command.s.reg0 = priv->fau + qos * 4;
    402	} else {
    403		queue_type = QUEUE_HW;
    404	}
    405	if (USE_ASYNC_IOBDMA)
    406		cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH,
    407					       FAU_TOTAL_TX_TO_CLEAN, 1);
    408
    409	spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
    410
    411	/* Drop this packet if we have too many already queued to the HW */
    412	if (unlikely(skb_queue_len(&priv->tx_free_list[qos]) >=
    413		     MAX_OUT_QUEUE_DEPTH)) {
    414		if (dev->tx_queue_len != 0) {
    415			/* Drop the lock when notifying the core.  */
    416			spin_unlock_irqrestore(&priv->tx_free_list[qos].lock,
    417					       flags);
    418			netif_stop_queue(dev);
    419			spin_lock_irqsave(&priv->tx_free_list[qos].lock,
    420					  flags);
    421		} else {
    422			/* If not using normal queueing.  */
    423			queue_type = QUEUE_DROP;
    424			goto skip_xmit;
    425		}
    426	}
    427
    428	cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
    429				     CVMX_PKO_LOCK_NONE);
    430
    431	/* Send the packet to the output queue */
    432	if (unlikely(cvmx_pko_send_packet_finish(priv->port,
    433						 priv->queue + qos,
    434						 pko_command, hw_buffer,
    435						 CVMX_PKO_LOCK_NONE))) {
    436		printk_ratelimited("%s: Failed to send the packet\n",
    437				   dev->name);
    438		queue_type = QUEUE_DROP;
    439	}
    440skip_xmit:
    441	to_free_list = NULL;
    442
    443	switch (queue_type) {
    444	case QUEUE_DROP:
    445		skb->next = to_free_list;
    446		to_free_list = skb;
    447		dev->stats.tx_dropped++;
    448		break;
    449	case QUEUE_HW:
    450		cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, -1);
    451		break;
    452	case QUEUE_CORE:
    453		__skb_queue_tail(&priv->tx_free_list[qos], skb);
    454		break;
    455	default:
    456		BUG();
    457	}
    458
    459	while (skb_to_free > 0) {
    460		struct sk_buff *t = __skb_dequeue(&priv->tx_free_list[qos]);
    461
    462		t->next = to_free_list;
    463		to_free_list = t;
    464		skb_to_free--;
    465	}
    466
    467	spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
    468
    469	/* Do the actual freeing outside of the lock. */
    470	while (to_free_list) {
    471		struct sk_buff *t = to_free_list;
    472
    473		to_free_list = to_free_list->next;
    474		dev_kfree_skb_any(t);
    475	}
    476
    477	if (USE_ASYNC_IOBDMA) {
    478		CVMX_SYNCIOBDMA;
    479		total_to_clean = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
    480		/* Restore the scratch area */
    481		cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
    482		cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2);
    483	} else {
    484		total_to_clean =
    485			cvmx_fau_fetch_and_add32(FAU_TOTAL_TX_TO_CLEAN, 1);
    486	}
    487
    488	if (total_to_clean & 0x3ff) {
    489		/*
    490		 * Schedule the cleanup tasklet every 1024 packets for
    491		 * the pathological case of high traffic on one port
    492		 * delaying clean up of packets on a different port
    493		 * that is blocked waiting for the cleanup.
    494		 */
    495		tasklet_schedule(&cvm_oct_tx_cleanup_tasklet);
    496	}
    497
    498	cvm_oct_kick_tx_poll_watchdog();
    499
    500	return NETDEV_TX_OK;
    501}
    502
    503/**
    504 * cvm_oct_xmit_pow - transmit a packet to the POW
    505 * @skb:    Packet to send
    506 * @dev:    Device info structure
    507 * Returns Always returns zero
    508 */
    509int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
    510{
    511	struct octeon_ethernet *priv = netdev_priv(dev);
    512	void *packet_buffer;
    513	void *copy_location;
    514
    515	/* Get a work queue entry */
    516	struct cvmx_wqe *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL);
    517
    518	if (unlikely(!work)) {
    519		printk_ratelimited("%s: Failed to allocate a work queue entry\n",
    520				   dev->name);
    521		dev->stats.tx_dropped++;
    522		dev_kfree_skb_any(skb);
    523		return 0;
    524	}
    525
    526	/* Get a packet buffer */
    527	packet_buffer = cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL);
    528	if (unlikely(!packet_buffer)) {
    529		printk_ratelimited("%s: Failed to allocate a packet buffer\n",
    530				   dev->name);
    531		cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, 1);
    532		dev->stats.tx_dropped++;
    533		dev_kfree_skb_any(skb);
    534		return 0;
    535	}
    536
    537	/*
    538	 * Calculate where we need to copy the data to. We need to
    539	 * leave 8 bytes for a next pointer (unused). We also need to
    540	 * include any configure skip. Then we need to align the IP
    541	 * packet src and dest into the same 64bit word. The below
    542	 * calculation may add a little extra, but that doesn't
    543	 * hurt.
    544	 */
    545	copy_location = packet_buffer + sizeof(u64);
    546	copy_location += ((CVMX_HELPER_FIRST_MBUFF_SKIP + 7) & 0xfff8) + 6;
    547
    548	/*
    549	 * We have to copy the packet since whoever processes this
    550	 * packet will free it to a hardware pool. We can't use the
    551	 * trick of counting outstanding packets like in
    552	 * cvm_oct_xmit.
    553	 */
    554	memcpy(copy_location, skb->data, skb->len);
    555
    556	/*
    557	 * Fill in some of the work queue fields. We may need to add
    558	 * more if the software at the other end needs them.
    559	 */
    560	if (!OCTEON_IS_MODEL(OCTEON_CN68XX))
    561		work->word0.pip.cn38xx.hw_chksum = skb->csum;
    562	work->word1.len = skb->len;
    563	cvmx_wqe_set_port(work, priv->port);
    564	cvmx_wqe_set_qos(work, priv->port & 0x7);
    565	cvmx_wqe_set_grp(work, pow_send_group);
    566	work->word1.tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
    567	work->word1.tag = pow_send_group;	/* FIXME */
    568	/* Default to zero. Sets of zero later are commented out */
    569	work->word2.u64 = 0;
    570	work->word2.s.bufs = 1;
    571	work->packet_ptr.u64 = 0;
    572	work->packet_ptr.s.addr = cvmx_ptr_to_phys(copy_location);
    573	work->packet_ptr.s.pool = CVMX_FPA_PACKET_POOL;
    574	work->packet_ptr.s.size = CVMX_FPA_PACKET_POOL_SIZE;
    575	work->packet_ptr.s.back = (copy_location - packet_buffer) >> 7;
    576
    577	if (skb->protocol == htons(ETH_P_IP)) {
    578		work->word2.s.ip_offset = 14;
    579#if 0
    580		work->word2.s.vlan_valid = 0;	/* FIXME */
    581		work->word2.s.vlan_cfi = 0;	/* FIXME */
    582		work->word2.s.vlan_id = 0;	/* FIXME */
    583		work->word2.s.dec_ipcomp = 0;	/* FIXME */
    584#endif
    585		work->word2.s.tcp_or_udp =
    586		    (ip_hdr(skb)->protocol == IPPROTO_TCP) ||
    587		    (ip_hdr(skb)->protocol == IPPROTO_UDP);
    588#if 0
    589		/* FIXME */
    590		work->word2.s.dec_ipsec = 0;
    591		/* We only support IPv4 right now */
    592		work->word2.s.is_v6 = 0;
    593		/* Hardware would set to zero */
    594		work->word2.s.software = 0;
    595		/* No error, packet is internal */
    596		work->word2.s.L4_error = 0;
    597#endif
    598		work->word2.s.is_frag = !((ip_hdr(skb)->frag_off == 0) ||
    599					  (ip_hdr(skb)->frag_off ==
    600					      cpu_to_be16(1 << 14)));
    601#if 0
    602		/* Assume Linux is sending a good packet */
    603		work->word2.s.IP_exc = 0;
    604#endif
    605		work->word2.s.is_bcast = (skb->pkt_type == PACKET_BROADCAST);
    606		work->word2.s.is_mcast = (skb->pkt_type == PACKET_MULTICAST);
    607#if 0
    608		/* This is an IP packet */
    609		work->word2.s.not_IP = 0;
    610		/* No error, packet is internal */
    611		work->word2.s.rcv_error = 0;
    612		/* No error, packet is internal */
    613		work->word2.s.err_code = 0;
    614#endif
    615
    616		/*
    617		 * When copying the data, include 4 bytes of the
    618		 * ethernet header to align the same way hardware
    619		 * does.
    620		 */
    621		memcpy(work->packet_data, skb->data + 10,
    622		       sizeof(work->packet_data));
    623	} else {
    624#if 0
    625		work->word2.snoip.vlan_valid = 0;	/* FIXME */
    626		work->word2.snoip.vlan_cfi = 0;	/* FIXME */
    627		work->word2.snoip.vlan_id = 0;	/* FIXME */
    628		work->word2.snoip.software = 0;	/* Hardware would set to zero */
    629#endif
    630		work->word2.snoip.is_rarp = skb->protocol == htons(ETH_P_RARP);
    631		work->word2.snoip.is_arp = skb->protocol == htons(ETH_P_ARP);
    632		work->word2.snoip.is_bcast =
    633		    (skb->pkt_type == PACKET_BROADCAST);
    634		work->word2.snoip.is_mcast =
    635		    (skb->pkt_type == PACKET_MULTICAST);
    636		work->word2.snoip.not_IP = 1;	/* IP was done up above */
    637#if 0
    638		/* No error, packet is internal */
    639		work->word2.snoip.rcv_error = 0;
    640		/* No error, packet is internal */
    641		work->word2.snoip.err_code = 0;
    642#endif
    643		memcpy(work->packet_data, skb->data, sizeof(work->packet_data));
    644	}
    645
    646	/* Submit the packet to the POW */
    647	cvmx_pow_work_submit(work, work->word1.tag, work->word1.tag_type,
    648			     cvmx_wqe_get_qos(work), cvmx_wqe_get_grp(work));
    649	dev->stats.tx_packets++;
    650	dev->stats.tx_bytes += skb->len;
    651	dev_consume_skb_any(skb);
    652	return 0;
    653}
    654
    655/**
    656 * cvm_oct_tx_shutdown_dev - free all skb that are currently queued for TX.
    657 * @dev:    Device being shutdown
    658 *
    659 */
    660void cvm_oct_tx_shutdown_dev(struct net_device *dev)
    661{
    662	struct octeon_ethernet *priv = netdev_priv(dev);
    663	unsigned long flags;
    664	int qos;
    665
    666	for (qos = 0; qos < 16; qos++) {
    667		spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
    668		while (skb_queue_len(&priv->tx_free_list[qos]))
    669			dev_kfree_skb_any(__skb_dequeue
    670					  (&priv->tx_free_list[qos]));
    671		spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
    672	}
    673}
    674
    675static void cvm_oct_tx_do_cleanup(unsigned long arg)
    676{
    677	int port;
    678
    679	for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
    680		if (cvm_oct_device[port]) {
    681			struct net_device *dev = cvm_oct_device[port];
    682
    683			cvm_oct_free_tx_skbs(dev);
    684		}
    685	}
    686}
    687
    688static irqreturn_t cvm_oct_tx_cleanup_watchdog(int cpl, void *dev_id)
    689{
    690	/* Disable the interrupt.  */
    691	cvmx_write_csr(CVMX_CIU_TIMX(1), 0);
    692	/* Do the work in the tasklet.  */
    693	tasklet_schedule(&cvm_oct_tx_cleanup_tasklet);
    694	return IRQ_HANDLED;
    695}
    696
    697void cvm_oct_tx_initialize(void)
    698{
    699	int i;
    700
    701	/* Disable the interrupt.  */
    702	cvmx_write_csr(CVMX_CIU_TIMX(1), 0);
    703	/* Register an IRQ handler to receive CIU_TIMX(1) interrupts */
    704	i = request_irq(OCTEON_IRQ_TIMER1,
    705			cvm_oct_tx_cleanup_watchdog, 0,
    706			"Ethernet", cvm_oct_device);
    707
    708	if (i)
    709		panic("Could not acquire Ethernet IRQ %d\n", OCTEON_IRQ_TIMER1);
    710}
    711
    712void cvm_oct_tx_shutdown(void)
    713{
    714	/* Free the interrupt handler */
    715	free_irq(OCTEON_IRQ_TIMER1, cvm_oct_device);
    716}