Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Jun 2009 03:57:03 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r194151 - projects/mips/sys/dev/le
Message-ID:  <200906140357.n5E3v3aI034425@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Sun Jun 14 03:57:03 2009
New Revision: 194151
URL: http://svn.freebsd.org/changeset/base/194151

Log:
  Import sgmii driver for Octeon from Cavium FreeBSD tree.

Added:
  projects/mips/sys/dev/le/octeon_fau.c   (contents, props changed)
  projects/mips/sys/dev/le/octeon_fau.h   (contents, props changed)
  projects/mips/sys/dev/le/octeon_fpa.c   (contents, props changed)
  projects/mips/sys/dev/le/octeon_fpa.h   (contents, props changed)
  projects/mips/sys/dev/le/octeon_ipd.c   (contents, props changed)
  projects/mips/sys/dev/le/octeon_ipd.h   (contents, props changed)
  projects/mips/sys/dev/le/octeon_pip.h   (contents, props changed)
  projects/mips/sys/dev/le/octeon_pko.c   (contents, props changed)
  projects/mips/sys/dev/le/octeon_pko.h   (contents, props changed)
  projects/mips/sys/dev/le/octeon_rgmx.c   (contents, props changed)
  projects/mips/sys/dev/le/octeon_rgmx.h   (contents, props changed)

Added: projects/mips/sys/dev/le/octeon_fau.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/dev/le/octeon_fau.c	Sun Jun 14 03:57:03 2009	(r194151)
@@ -0,0 +1,44 @@
+/*------------------------------------------------------------------
+ * octeon_fau.c        Fetch & Add Block
+ *
+ *------------------------------------------------------------------
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include "octeon_fau.h"
+
+/*
+ * oct_fau_init
+ *
+ * How do we initialize FAU unit. I don't even think we can reset it.
+ */
+void octeon_fau_init (void)
+{
+}
+
+
+/*
+ * oct_fau_enable
+ *
+ * Let the Fetch/Add unit roll
+ */
+void octeon_fau_enable (void)
+{
+}
+
+
+/*
+ * oct_fau_disable
+ *
+ * disable fau
+ *
+ * Don't know if we can even do that.
+ */
+void octeon_fau_disable (void)
+{
+}
+
+
+

Added: projects/mips/sys/dev/le/octeon_fau.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/dev/le/octeon_fau.h	Sun Jun 14 03:57:03 2009	(r194151)
@@ -0,0 +1,185 @@
+/*------------------------------------------------------------------
+ * octeon_fau.h        Fetch & Add Unit
+ *
+ *------------------------------------------------------------------
+ */
+
+
+#ifndef ___OCTEON_FAU__H___
+#define ___OCTEON_FAU__H___
+
+
+
+
+typedef enum {
+   OCTEON_FAU_OP_SIZE_8  = 0,
+   OCTEON_FAU_OP_SIZE_16 = 1,
+   OCTEON_FAU_OP_SIZE_32 = 2,
+   OCTEON_FAU_OP_SIZE_64 = 3
+} octeon_fau_op_size_t;
+
+
+
+#define OCTEON_FAU_LOAD_IO_ADDRESS    octeon_build_io_address(0x1e, 0)
+#define OCTEON_FAU_BITS_SCRADDR       63,56
+#define OCTEON_FAU_BITS_LEN           55,48
+#define OCTEON_FAU_BITS_INEVAL        35,14
+#define OCTEON_FAU_BITS_TAGWAIT       13,13
+#define OCTEON_FAU_BITS_NOADD         13,13
+#define OCTEON_FAU_BITS_SIZE          12,11
+#define OCTEON_FAU_BITS_REGISTER      10,0
+
+#define OCTEON_FAU_REG_64_ADDR(x) ((x <<3) + OCTEON_FAU_REG_64_START)
+typedef enum
+{
+    OCTEON_FAU_REG_64_START		= 0, 
+    OCTEON_FAU_REG_OQ_ADDR_INDEX 	= OCTEON_FAU_REG_64_ADDR(0),
+    OCTEON_FAU_REG_OQ_ADDR_END 		= OCTEON_FAU_REG_64_ADDR(31),
+    OCTEON_FAU_REG_64_END		= OCTEON_FAU_REG_64_ADDR(39),
+} octeon_fau_reg_64_t;
+
+#define OCTEON_FAU_REG_32_ADDR(x) ((x <<2) + OCTEON_FAU_REG_32_START)
+typedef enum
+{
+    OCTEON_FAU_REG_32_START          = OCTEON_FAU_REG_64_END,
+    OCTEON_FAU_REG_32_END            = OCTEON_FAU_REG_32_ADDR(0),
+} octeon_fau_reg_32_t;
+
+
+
+/*
+ * octeon_fau_atomic_address
+ *
+ * Builds a I/O address for accessing the FAU
+ *
+ * @param tagwait Should the atomic add wait for the current tag switch
+ *                operation to complete.
+ *                - 0 = Don't wait
+ *                - 1 = Wait for tag switch to complete
+ * @param reg     FAU atomic register to access. 0 <= reg < 4096.
+ *                - Step by 2 for 16 bit access.
+ *                - Step by 4 for 32 bit access.
+ *                - Step by 8 for 64 bit access.
+ * @param value   Signed value to add.
+ *                Note: When performing 32 and 64 bit access, only the low
+ *                22 bits are available.
+ * @return Address to read from for atomic update
+ */
+static inline uint64_t octeon_fau_atomic_address (uint64_t tagwait, uint64_t reg,
+                                               int64_t value)
+{
+    return (OCTEON_ADD_IO_SEG(OCTEON_FAU_LOAD_IO_ADDRESS) |
+            octeon_build_bits(OCTEON_FAU_BITS_INEVAL, value) |
+            octeon_build_bits(OCTEON_FAU_BITS_TAGWAIT, tagwait) |
+            octeon_build_bits(OCTEON_FAU_BITS_REGISTER, reg));
+}
+
+
+/*
+ * octeon_fau_store_address
+ *
+ * Builds a store I/O address for writing to the FAU
+ *
+ * noadd  0 = Store value is atomically added to the current value
+ *               1 = Store value is atomically written over the current value
+ * reg    FAU atomic register to access. 0 <= reg < 4096.
+ *               - Step by 2 for 16 bit access.
+ *               - Step by 4 for 32 bit access.
+ *               - Step by 8 for 64 bit access.
+ * Returns Address to store for atomic update
+ */
+static inline uint64_t octeon_fau_store_address (uint64_t noadd, uint64_t reg)
+{
+    return (OCTEON_ADD_IO_SEG(OCTEON_FAU_LOAD_IO_ADDRESS) |
+            octeon_build_bits(OCTEON_FAU_BITS_NOADD, noadd) |
+            octeon_build_bits(OCTEON_FAU_BITS_REGISTER, reg));
+}
+
+
+/*
+ * octeon_fau_atomic_add32
+ *
+ * Perform an atomic 32 bit add
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 4096.
+ *                - Step by 4 for 32 bit access.
+ * @param value   Signed value to add.
+ */
+static inline void octeon_fau_atomic_add32 (octeon_fau_reg_32_t reg, int32_t value)
+{
+    oct_write32(octeon_fau_store_address(0, reg), value);
+}
+
+/*
+ * octeon_fau_fetch_and_add
+ *
+ * reg     FAU atomic register to access. 0 <= reg < 4096.
+ *                - Step by 8 for 64 bit access.
+ * value   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * returns Value of the register before the update
+ */
+static inline int64_t octeon_fau_fetch_and_add64 (octeon_fau_reg_64_t reg,
+                                               int64_t  val64)
+{
+
+    return (oct_read64(octeon_fau_atomic_address(0, reg, val64)));
+}
+
+/*
+ * octeon_fau_fetch_and_add32
+ *
+ * reg     FAU atomic register to access. 0 <= reg < 4096.
+ *                - Step by 8 for 64 bit access.
+ * value   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * returns Value of the register before the update
+ */
+static inline int32_t octeon_fau_fetch_and_add32 (octeon_fau_reg_64_t reg,
+                                               int32_t val32)
+{
+    return (oct_read32(octeon_fau_atomic_address(0, reg, val32)));
+}
+
+/*
+ * octeon_fau_atomic_write32
+ *
+ * Perform an atomic 32 bit write
+ *
+ * @param reg     FAU atomic register to access. 0 <= reg < 4096.
+ *                - Step by 4 for 32 bit access.
+ * @param value   Signed value to write.
+ */
+static inline void octeon_fau_atomic_write32(octeon_fau_reg_32_t reg, int32_t value)
+{
+    oct_write32(octeon_fau_store_address(1, reg), value);
+}
+
+
+/*
+ * octeon_fau_atomic_write64
+ *
+ * Perform an atomic 32 bit write
+ *
+ * reg    FAU atomic register to access. 0 <= reg < 4096.
+ *                - Step by 8 for 64 bit access.
+ * value   Signed value to write.
+ */
+static inline void octeon_fau_atomic_write64 (octeon_fau_reg_64_t reg, int64_t value)
+{
+    oct_write64(octeon_fau_store_address(1, reg), value);
+}
+
+
+static inline void octeon_fau_atomic_add64 (octeon_fau_reg_64_t reg, int64_t value)
+{
+    oct_write64_int64(octeon_fau_store_address(0, reg), value);
+}
+
+
+extern void octeon_fau_init(void);
+extern void octeon_fau_enable(void);
+extern void octeon_fau_disable(void);
+
+
+#endif  /* ___OCTEON_FAU__H___ */

Added: projects/mips/sys/dev/le/octeon_fpa.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/dev/le/octeon_fpa.c	Sun Jun 14 03:57:03 2009	(r194151)
@@ -0,0 +1,186 @@
+/*------------------------------------------------------------------
+ * octeon_fpa.c        Free Pool Allocator
+ *
+ *------------------------------------------------------------------
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+
+#include "octeon_fpa.h"
+
+
+//#define FPA_DEBUG 1
+
+/*
+ * octeon_dump_fpa
+ *
+ */
+void octeon_dump_fpa (void)
+{
+    int i;
+    octeon_fpa_ctl_status_t status;
+    octeon_fpa_queue_available_t q_avail;
+
+    status.word64 = oct_read64(OCTEON_FPA_CTL_STATUS);
+    if (!status.bits.enb) {
+        printf("\n  FPA Disabled");
+        /*
+         * No dumping if disabled
+         */
+        return;
+    }
+    printf(" FPA  Ctrl-Status-reg 0x%llX := 0x%llX  EN %X  M1_E %X  M0_E %X\n",
+           OCTEON_FPA_CTL_STATUS, status.word64,
+           status.bits.enb, status.bits.mem1_err, status.bits.mem0_err);
+    for (i = 0; i < OCTEON_FPA_QUEUES; i++) {
+        printf("   Pool: %d\n", i);
+
+        q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (i)*8ull));
+        printf("   Avail-reg 0x%llX :=   Size: 0x%X\n",
+               (OCTEON_FPA_QUEUE_AVAILABLE + (i)*8ull), q_avail.bits.queue_size);
+    }
+}
+
+void octeon_dump_fpa_pool (u_int pool)
+{
+    octeon_fpa_ctl_status_t status;
+    octeon_fpa_queue_available_t q_avail;
+
+    status.word64 = oct_read64(OCTEON_FPA_CTL_STATUS);
+    if (!status.bits.enb) {
+        printf("\n  FPA Disabled");
+        /*
+         * No dumping if disabled
+         */
+        return;
+    }
+    printf(" FPA  Ctrl-Status-reg 0x%llX := 0x%llX  EN %X  M1_E %X  M0_E %X\n",
+           OCTEON_FPA_CTL_STATUS, status.word64,
+           status.bits.enb, status.bits.mem1_err, status.bits.mem0_err);
+    q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull));
+    printf("   FPA Pool: %u   Avail-reg 0x%llX :=   Size: 0x%X\n", pool,
+           (OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull), q_avail.bits.queue_size);
+}
+
+
+u_int octeon_fpa_pool_size (u_int pool)
+{
+    octeon_fpa_queue_available_t q_avail;
+    u_int size = 0;
+
+    if (pool < 7) {
+            q_avail.word64 = oct_read64((OCTEON_FPA_QUEUE_AVAILABLE + (pool)*8ull));
+            size = q_avail.bits.queue_size;
+    }
+    return (size);
+}
+
+
+/*
+ * octeon_enable_fpa
+ *
+ * configure fpa with defaults and then mark it enabled.
+ */
+void octeon_enable_fpa (void)
+{
+    int i;
+    octeon_fpa_ctl_status_t status;
+    octeon_fpa_fpf_marks_t marks;
+
+    for (i = 0; i < OCTEON_FPA_QUEUES; i++) {
+        marks.word64 = oct_read64((OCTEON_FPA_FPF_MARKS + (i)*8ull));
+
+        marks.bits.fpf_wr = 0xe0;
+        oct_write64((OCTEON_FPA_FPF_MARKS + (i)*8ull), marks.word64);
+    }
+
+    /* Enforce a 10 cycle delay between config and enable */
+    octeon_wait(10);
+
+    status.word64 = 0;
+    status.bits.enb = 1;
+    oct_write64(OCTEON_FPA_CTL_STATUS, status.word64);
+}
+
+
+//#define FPA_DEBUG_TERSE 1
+
+/*
+ * octeon_fpa_fill_pool_mem
+ *
+ * Fill the specified FPA pool with elem_num number of
+ * elements of size elem_size_words * 8
+ */
+void octeon_fpa_fill_pool_mem (u_int pool, u_int elem_size_words, u_int elem_num)
+{
+    void *memory;
+    u_int bytes, elem_size_bytes;
+    u_int block_size;
+
+#ifdef FPA_DEBUG
+    u_int elems = elem_num;
+    printf(" FPA fill: Pool %u  elem_size_words %u   Num: %u\n", pool, elem_size_words, elem_num);
+#endif
+    elem_size_bytes = elem_size_words * sizeof(uint64_t);
+    block_size = OCTEON_ALIGN(elem_size_bytes);
+
+//    block_size = ((elem_size_bytes / OCTEON_FPA_POOL_ALIGNMENT) + 1) * OCTEON_FPA_POOL_ALIGNMENT;
+
+    bytes = (elem_num * block_size);
+
+#ifdef FPA_DEBUG
+    printf(" elem_size_bytes = words * 8 = %u;  block_size %u\n", elem_size_bytes, block_size);
+#endif
+
+
+#ifdef FPA_DEBUG
+    int block = 0;
+
+    printf(" %% Filling Pool %u  with %u blocks of %u bytes  %u words\n",
+           pool, elem_num, elem_size_bytes, elem_size_words);
+#endif
+
+//    memory = malloc(bytes, M_DEVBUF, M_NOWAIT | M_ZERO);
+    memory = contigmalloc(bytes, M_DEVBUF, M_NOWAIT | M_ZERO,
+                          0, 0x20000000,
+                          OCTEON_FPA_POOL_ALIGNMENT, 0);
+
+    if (memory == NULL) {
+        printf(" %% FPA pool %u could not be filled with %u bytes\n",
+               pool, bytes);
+        return;
+    }
+
+    /*
+     * Forward Align allocated mem to needed alignment. Don't worry about growth, we
+     * already preallocated extra
+     */
+#ifdef FPA_DEBUG
+    printf(" %% Huge MemBlock  0x%X   Bytes %u\n", memory, bytes);
+#endif
+
+    memory = (void *) OCTEON_ALIGN(memory);
+
+#ifdef FPA_DEBUG_TERSE
+    printf("FPA fill: %u  Count: %u  SizeBytes: %u  SizeBytesAligned: %u  1st: 0x%X = 0x%X\n",
+           pool, elem_num, elem_size_bytes, block_size, memory, OCTEON_PTR2PHYS(memory));
+#endif
+
+//    memory = (void *) ((((u_int) memory / OCTEON_FPA_POOL_ALIGNMENT) + 1) * OCTEON_FPA_POOL_ALIGNMENT);
+
+    while (elem_num--) {
+#ifdef FPA_DEBUG
+        if (((elems - elem_num) < 4) || (elem_num < 4))
+        printf(" %% Block %d:  0x%X  Phys 0x%X   Bytes %u\n", block, memory, OCTEON_PTR2PHYS(memory), elem_size_bytes);
+        block++;
+#endif
+        octeon_fpa_free(memory, pool, 0);
+        memory = (void *) (((u_long) memory) + block_size);
+    }
+}
+

Added: projects/mips/sys/dev/le/octeon_fpa.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/dev/le/octeon_fpa.h	Sun Jun 14 03:57:03 2009	(r194151)
@@ -0,0 +1,246 @@
+/*------------------------------------------------------------------
+ * octeon_fpa.h      Free Pool Allocator
+ *
+ *------------------------------------------------------------------
+ */
+
+
+#ifndef ___OCTEON_FPA__H___
+#define ___OCTEON_FPA__H___
+
+
+#define OCTEON_FPA_FPA_OUTPUT_BUFFER_POOL           2    /* Same in octeon_rgmx.h */
+
+
+/*
+ * OCTEON_FPA_FPF_MARKS = FPA's Queue Free Page FIFO Read Write Marks
+ *
+ * The high and low watermark register that determines when we write and
+ * read free pages from L2C for Queue.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved                : 42;      /* Must be zero */
+        uint64_t fpf_wr                  : 11;      /* Write Hi Water mark */
+        uint64_t fpf_rd                  : 11;      /* Read Lo Water mark */
+    } bits;
+} octeon_fpa_fpf_marks_t;
+
+
+/*
+ * OCTEON_FPA_CTL_STATUS = FPA's Control/Status Register
+ *
+ * The FPA's interrupt enable register.
+ * - Use with the CVMX_FPA_CTL_STATUS CSR.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved                : 49;      /* Must be zero */
+        uint64_t enb                     : 1;       /* Enable */
+        uint64_t mem1_err                : 7;       /* ECC flip 1 */
+        uint64_t mem0_err                : 7;       /* ECC flip 0 */
+    } bits;
+} octeon_fpa_ctl_status_t;
+
+
+/*
+ * OCTEON_FPA_FPF_SIZE = FPA's Queue N Free Page FIFO Size
+ *
+ * The number of page pointers that will be kept local to the FPA for
+ *  this Queue. FPA Queues are assigned in order from Queue 0 to
+ *  Queue 7, though only Queue 0 through Queue x can be used.
+ * The sum of the 8 (0-7)OCTEON_FPA_FPF#_SIZE registers must be limited to 2048.
+ * - Use with the CVMX_FPA_FPF0_SIZE CSR.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved                : 52;      /* Must be zero */
+      /*
+       * The number of entries assigned in the FPA FIFO (used to hold
+       * page-pointers) for this Queue.
+       * The value of this register must divisable by 2, and the FPA will
+       * ignore bit [0] of this register.
+       * The total of the FPF_SIZ field of the 8 (0-7)OCTEON_FPA_FPF#_MARKS
+       * registers must not exceed 2048.
+       * After writing this field the FPA will need 10 core clock cycles
+       * to be ready for operation. The assignment of location in
+       * the FPA FIFO must start with Queue 0, then 1, 2, etc.
+       * The number of useable entries will be FPF_SIZ-2.
+       */
+        uint64_t fpf_siz                 : 12;
+    } bits;
+} octeon_fpa_fpf_size_t;
+
+/*
+ *OCTEON_FPA_INT_ENB = FPA's Interrupt Enable
+ *
+ * The FPA's interrupt enable register.
+ * - Use with the CVMX_FPA_INT_ENB CSR.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved                : 60;  /* Must be zero */
+        uint64_t fed1_dbe                : 1;   /* Int iff bit3 Int-Sum set */
+        uint64_t fed1_sbe                : 1;   /* Int iff bit2 Int-Sum set */
+        uint64_t fed0_dbe                : 1;   /* Int iff bit1 Int-Sum set */
+        uint64_t fed0_sbe                : 1;   /* Int iff bit0 Int-Sum set */
+    } bits;
+} octeon_fpa_int_enb_t;
+
+/**
+ *OCTEON_FPA_INT_SUM = FPA's Interrupt Summary Register
+ *
+ * Contains the diffrent interrupt summary bits of the FPA.
+ * - Use with the CVMX_FPA_INT_SUM CSR.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved                : 60;      /**< Must be zero */
+        uint64_t fed1_dbe                : 1;
+        uint64_t fed1_sbe                : 1;
+        uint64_t fed0_dbe                : 1;
+        uint64_t fed0_sbe                : 1;
+    } bits;
+} octeon_fpa_int_sum_t;
+
+
+/*
+ *OCTEON_FPA_QUEUE_PAGES_AVAILABLE = FPA's Queue 0-7 Free Page Available Register
+ *
+ * The number of page pointers that are available in the FPA and local DRAM.
+ * - Use with the CVMX_FPA_QUEX_AVAILABLE(0..7) CSR.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved                : 38;      /* Must be zero */
+        uint64_t queue_size              : 26;      /* free pages available */
+    } bits;
+} octeon_fpa_queue_available_t;
+
+
+/*
+ *OCTEON_FPA_QUEUE_PAGE_INDEX
+ *
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved                : 39;      /* Must be zero */
+        uint64_t page_index              : 25;      /* page_index */
+    } bits;
+} octeon_fpa_queue_page_index_t;
+
+
+#define OCTEON_DID_FPA			5ULL
+
+#define	OCTEON_FPA_POOL_ALIGNMENT	(OCTEON_CACHE_LINE_SIZE)
+
+
+/*
+ * Externs
+ */
+extern void octeon_dump_fpa(void);
+extern void octeon_dump_fpa_pool(u_int pool);
+extern u_int octeon_fpa_pool_size(u_int pool);
+extern void octeon_enable_fpa(void);
+extern void octeon_fpa_fill_pool_mem(u_int pool,
+                                     u_int block_size_words,
+                                     u_int block_num);
+
+/*
+ * octeon_fpa_free
+ *
+ * Free a mem-block to FPA pool.
+ *
+ * Takes away this 'buffer' from SW and passes it to FPA for management.
+ *
+ *  pool is FPA pool num, ptr is block ptr, num_cache_lines is number of
+ *  cache lines to invalidate (not written back).
+ */
+static inline void octeon_fpa_free (void *ptr, u_int pool,
+                                    u_int num_cache_lines)
+{
+    octeon_addr_t free_ptr;
+
+    free_ptr.word64 = (uint64_t) OCTEON_PTR2PHYS(ptr);
+
+    free_ptr.sfilldidspace.didspace = OCTEON_ADDR_DIDSPACE(
+        OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA, pool));
+
+    /*
+     * Do not 'sync'
+     *     asm volatile ("sync\n");
+     */
+    oct_write64(free_ptr.word64, num_cache_lines);
+}
+
+
+
+/*
+ * octeon_fpa_alloc
+ *
+ * Allocate a new block from the FPA
+ *
+ * Buffer passes away from FPA management to SW control
+ */
+static inline void *octeon_fpa_alloc (u_int pool)
+{
+    uint64_t address;
+
+    address = oct_read64(OCTEON_ADDR_DID(OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA,
+                                                              pool)));
+    if (address) {
+
+/*
+ * 32 bit FPA pointers only
+ */
+
+        /*
+         * We only use 32 bit pointers at this time
+         */
+        return ((void *) OCTEON_PHYS2PTR(address & 0xffffffff));
+    }
+    return (NULL);
+}
+
+
+static inline uint64_t octeon_fpa_alloc_phys (u_int pool)
+{
+
+    return (oct_read64(OCTEON_ADDR_DID(OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA,
+                                                            pool))));
+}
+
+
+#if 0
+
+/*
+ * octeon_fpa_alloc
+ *
+ * Allocate a new block from the FPA
+ *
+ * Buffer passes away from FPA management to SW control
+ */
+static inline void *octeon_fpa_alloc (u_int pool)
+{
+    uint64_t address;
+
+    address = oct_read64(OCTEON_ADDR_DID(OCTEON_ADDR_FULL_DID(OCTEON_DID_FPA,
+                                                              pool)));
+    if (address) {
+        return ((void *) (oct_ptr_size) OCTEON_PHYS2PTR(address));
+    }
+    return (NULL);
+}
+
+#endif
+
+
+
+#endif /* ___OCTEON_FPA__H___ */

Added: projects/mips/sys/dev/le/octeon_ipd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/dev/le/octeon_ipd.c	Sun Jun 14 03:57:03 2009	(r194151)
@@ -0,0 +1,106 @@
+/*------------------------------------------------------------------
+ * octeon_ipd.c      Input Packet Unit
+ *
+ *------------------------------------------------------------------
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include "octeon_ipd.h"
+
+/*
+ * octeon_ipd_enable
+ *
+ * enable ipd
+ */
+void octeon_ipd_enable (void)
+{
+    octeon_ipd_ctl_status_t octeon_ipd_reg;
+
+    octeon_ipd_reg.word64 = oct_read64(OCTEON_IPD_CTL_STATUS);
+    octeon_ipd_reg.bits.ipd_en = 1;
+    oct_write64(OCTEON_IPD_CTL_STATUS, octeon_ipd_reg.word64);
+}
+
+
+/*
+ * octeon_ipd_disable
+ *
+ * disable ipd
+ */
+void octeon_ipd_disable (void)
+{
+    octeon_ipd_ctl_status_t octeon_ipd_reg;
+
+    octeon_ipd_reg.word64 = oct_read64(OCTEON_IPD_CTL_STATUS);
+    octeon_ipd_reg.bits.ipd_en = 0;
+    oct_write64(OCTEON_IPD_CTL_STATUS, octeon_ipd_reg.word64);
+}
+
+
+/*
+ * octeon_ipd_config
+ *
+ * Configure IPD
+ *
+ * mbuff_size Packets buffer size in 8 byte words
+ * first_mbuff_skip
+ *                   Number of 8 byte words to skip in the first buffer
+ * not_first_mbuff_skip
+ *                   Number of 8 byte words to skip in each following buffer
+ * first_back Must be same as first_mbuff_skip / Cache_Line_size
+ * second_back
+ *                   Must be same as not_first_mbuff_skip / Cache_Line_Size
+ * wqe_fpa_pool
+ *                   FPA pool to get work entries from
+ * cache_mode
+ * back_pres_enable_flag
+ *                   Enable or disable port back pressure
+ */
+void octeon_ipd_config (u_int mbuff_size,
+                        u_int first_mbuff_skip,
+                        u_int not_first_mbuff_skip,
+                        u_int first_back,
+                        u_int second_back,
+                        u_int wqe_fpa_pool,
+                        octeon_ipd_mode_t cache_mode,
+                        u_int back_pres_enable_flag)
+{
+    octeon_ipd_mbuff_first_skip_t first_skip;
+    octeon_ipd_mbuff_not_first_skip_t not_first_skip;
+    octeon_ipd_mbuff_size_t size;
+    octeon_ipd_first_next_ptr_back_t first_back_struct;
+    octeon_ipd_second_next_ptr_back_t second_back_struct;
+    octeon_ipd_wqe_fpa_pool_t wqe_pool;
+    octeon_ipd_ctl_status_t octeon_ipd_ctl_reg;
+
+    first_skip.word64 = 0;
+    first_skip.bits.skip_sz = first_mbuff_skip;
+    oct_write64(OCTEON_IPD_1ST_MBUFF_SKIP, first_skip.word64);
+
+    not_first_skip.word64 = 0;
+    not_first_skip.bits.skip_sz = not_first_mbuff_skip;
+    oct_write64(OCTEON_IPD_NOT_1ST_MBUFF_SKIP, not_first_skip.word64);
+
+    size.word64 = 0;
+    size.bits.mb_size = mbuff_size;
+    oct_write64(OCTEON_IPD_PACKET_MBUFF_SIZE, size.word64);
+
+    first_back_struct.word64 = 0;
+    first_back_struct.bits.back = first_back;
+    oct_write64(OCTEON_IPD_1ST_NEXT_PTR_BACK, first_back_struct.word64);
+
+    second_back_struct.word64 = 0;
+    second_back_struct.bits.back = second_back;
+    oct_write64(OCTEON_IPD_2ND_NEXT_PTR_BACK, second_back_struct.word64);
+
+    wqe_pool.word64 = 0;
+    wqe_pool.bits.wqe_pool = wqe_fpa_pool;
+    oct_write64(OCTEON_IPD_WQE_FPA_QUEUE, wqe_pool.word64);
+
+    octeon_ipd_ctl_reg.word64 = 0;
+    octeon_ipd_ctl_reg.bits.opc_mode = cache_mode;
+    octeon_ipd_ctl_reg.bits.pbp_en = back_pres_enable_flag;
+    oct_write64(OCTEON_IPD_CTL_STATUS, octeon_ipd_ctl_reg.word64);
+}

Added: projects/mips/sys/dev/le/octeon_ipd.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/dev/le/octeon_ipd.h	Sun Jun 14 03:57:03 2009	(r194151)
@@ -0,0 +1,164 @@
+/*------------------------------------------------------------------
+ * octeon_ipd.h      Input Packet Unit
+ *
+ *------------------------------------------------------------------
+ */
+
+
+#ifndef ___OCTEON_IPD__H___
+#define ___OCTEON_IPD__H___
+
+
+
+typedef enum {
+   OCTEON_IPD_OPC_MODE_STT = 0LL,   /* All blocks DRAM, not cached in L2 */
+   OCTEON_IPD_OPC_MODE_STF = 1LL,   /* All blocks into  L2 */
+   OCTEON_IPD_OPC_MODE_STF1_STT = 2LL,   /* 1st block L2, rest DRAM */
+   OCTEON_IPD_OPC_MODE_STF2_STT = 3LL    /* 1st, 2nd blocks L2, rest DRAM */
+} octeon_ipd_mode_t;
+
+
+
+
+/*
+ * IPD_CTL_STATUS = IPS'd Control Status Register
+ *  The number of words in a MBUFF used for packet data store.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved	: 58;      /* Reserved */
+        uint64_t pkt_lend       : 1;       /* Pkt Lil-Endian Writes to L2C */
+        uint64_t wqe_lend       : 1;       /* WQE Lik-Endian Writes to L2C */
+        uint64_t pbp_en         : 1;       /* Enable Back-Pressure */
+        octeon_ipd_mode_t opc_mode : 2;       /* Pkt data in Mem/L2-cache ? */
+        uint64_t ipd_en         : 1;       /* Enable IPD */
+    } bits;
+} octeon_ipd_ctl_status_t;
+
+
+/*
+ * IPD_1ST_NEXT_PTR_BACK = IPD First Next Pointer Back Values
+ *
+ * Contains the Back Field for use in creating the Next Pointer Header
+ *    for the First MBUF
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved	: 60;      /* Must be zero */
+        uint64_t back		: 4;       /* Used to find head of buffer from the nxt-hdr-ptr. */
+    } bits;
+} octeon_ipd_first_next_ptr_back_t;
+
+
+/*
+ * IPD_INTERRUPT_ENB = IPD Interrupt Enable Register
+ *
+ * Used to enable the various interrupting conditions of IPD
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved       : 59;      /* Must be zero */
+        uint64_t bp_sub		: 1;       /* BP subtract is illegal val */
+        uint64_t prc_par3       : 1;       /* PBM Bits [127:96] Parity Err */
+        uint64_t prc_par2       : 1;       /* PBM Bits [ 95:64] Parity Err */
+        uint64_t prc_par1       : 1;       /* PBM Bits [ 63:32] Parity Err */
+        uint64_t prc_par0       : 1;       /* PBM Bits [ 31:0 ] Parity Err */
+    } bits;
+} octeon_ipd_int_enb_t;
+
+
+/*
+ * IPD_INTERRUPT_SUM = IPD Interrupt Summary Register
+ *
+ * Set when an interrupt condition occurs, write '1' to clear.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved	: 59;      /* Must be zero */
+        uint64_t bp_sub         : 1;       /* BP subtract is illegal val */
+        uint64_t prc_par3       : 1;       /* PBM Bits [127:96] Parity Err */
+        uint64_t prc_par2       : 1;       /* PBM Bits [ 95:64] Parity Err */
+        uint64_t prc_par1       : 1;       /* PBM Bits [ 63:32] Parity Err */
+        uint64_t prc_par0       : 1;       /* PBM Bits [ 31:0 ] Parity Err */
+    } bits;
+} octeon_ipd_int_sum_t;
+
+
+/**
+ * IPD_1ST_MBUFF_SKIP = IPD First MBUFF Word Skip Size
+ *
+ * The number of words that the IPD will skip when writing the first MBUFF.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved	: 58;      /* Must be zero */
+        uint64_t skip_sz        : 6;       /* 64bit words from the top of */
+        				   /*  1st MBUFF that the IPD will */
+					   /*  store the next-pointer. */
+        				   /*  [0..32]  &&             */
+                                           /*    (skip_sz + 16) <= IPD_PACKET_MBUFF_SIZE[MB_SIZE]. */
+    } bits;
+} octeon_ipd_mbuff_first_skip_t;
+
+
+/*
+ * IPD_PACKET_MBUFF_SIZE = IPD's PACKET MUBUF Size In Words
+ *
+ * The number of words in a MBUFF used for packet data store.
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved	: 52;      /* Must be zero */
+        uint64_t mb_size        : 12;      /* 64bit words in a MBUF. */
+        				   /* Must be [32..2048] */
+					   /* Is also the size of the FPA's */
+					   /*   Queue-0 Free-Page */
+    } bits;
+} octeon_ipd_mbuff_size_t;
+
+
+/*
+ * IPD_WQE_FPA_QUEUE = IPD Work-Queue-Entry FPA Page Size
+ *
+ * Which FPA Queue (0-7) to fetch page-pointers from for WQE's
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved	: 61;    /* Must be zero */
+        uint64_t wqe_pool       : 3;     /* FPA Pool to fetch WQE Page-ptrs */
+    } bits;
+} octeon_ipd_wqe_fpa_pool_t;
+
+
+
+
+/* End of Control and Status Register (CSR) definitions */
+
+typedef octeon_ipd_mbuff_first_skip_t octeon_ipd_mbuff_not_first_skip_t;
+typedef octeon_ipd_first_next_ptr_back_t octeon_ipd_second_next_ptr_back_t;
+
+
+/*
+ * Externs
+ */
+extern void octeon_ipd_enable(void);
+extern void octeon_ipd_disable(void);
+extern void octeon_ipd_config(u_int mbuff_size,
+                              u_int first_mbuff_skip,
+                              u_int not_first_mbuff_skip,
+                              u_int first_back,
+                              u_int second_back,
+                              u_int wqe_fpa_pool,
+                              octeon_ipd_mode_t cache_mode,
+                              u_int back_pres_enable_flag);
+
+
+
+#endif   /*  ___OCTEON_IPD__H___ */

Added: projects/mips/sys/dev/le/octeon_pip.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/dev/le/octeon_pip.h	Sun Jun 14 03:57:03 2009	(r194151)
@@ -0,0 +1,179 @@
+/*
+ * octeon_pip.h		Packet Input Processing Block
+ *
+ */
+
+
+
+#ifndef __OCTEON_PIP_H__
+#define __OCTEON_PIP_H__
+
+/** 
+ * Enumeration representing the amount of packet processing
+ * and validation performed by the input hardware.
+ */
+typedef enum
+{
+    OCTEON_PIP_PORT_CFG_MODE_NONE = 0ull,  /**< Packet input doesn't perform any
+                                            processing of the input packet. */
+    OCTEON_PIP_PORT_CFG_MODE_SKIPL2 = 1ull,/**< Full packet processing is performed
+                                            with pointer starting at the L2
+                                            (ethernet MAC) header. */
+    OCTEON_PIP_PORT_CFG_MODE_SKIPIP = 2ull /**< Input packets are assumed to be IP.
+                                            Results from non IP packets is
+                                            undefined. Pointers reference the
+                                            beginning of the IP header. */
+} octeon_pip_port_parse_mode_t;
+
+
+
+#define OCTEON_PIP_PRT_CFGX(offset)	(0x80011800A0000200ull+((offset)*8))
+#define OCTEON_PIP_PRT_TAGX(offset)	(0x80011800A0000400ull+((offset)*8))
+#define OCTEON_PIP_STAT_INB_PKTS(port)	(0x80011800A0001A00ull+((port) * 32))
+#define OCTEON_PIP_STAT_INB_ERRS(port)	(0x80011800A0001A10ull+((port) * 32))
+
+/*
+ * PIP Global Config
+ */
+typedef union {
+    uint64_t word64;
+    struct {
+        uint64_t reserved2	: 45;	/* Must be zero */
+        uint64_t tag_syn	: 1;	/* Not Include src_crc in TCP..*/
+        uint64_t ip6_udp	: 1;	/* IPv6/UDP checksum is mandatory */
+        uint64_t max_l2		: 1;	/* Largest L2 frame. 0/1 : 1500/1535 */
+        uint64_t reserved1	: 5;	/* Must be zero */
+        uint64_t raw_shf	: 3;	/* PCI RAW Packet shift/pad amount */
+        uint64_t reserved0	: 5;	/* Must be zero */
+        uint64_t nip_shf	: 3;	/* Non-IP shift/pad amount */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906140357.n5E3v3aI034425>