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