Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_rgmx.h =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_rgmx.h (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_rgmx.h (nonexistent) @@ -1,630 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/* $FreeBSD$ */ - -/*------------------------------------------------------------------ - * octeon_rgmx.h RGMII Ethernet Interfaces - * - *------------------------------------------------------------------ - */ - - -#ifndef ___OCTEON_RGMX__H___ -#define ___OCTEON_RGMX__H___ - - - -#define OCTEON_FPA_PACKET_POOL 0 -#define OCTEON_FPA_WQE_RX_POOL 1 -#define OCTEON_FPA_OUTPUT_BUFFER_POOL 2 -#define OCTEON_FPA_WQE_POOL_SIZE (1 * OCTEON_CACHE_LINE_SIZE) -#define OCTEON_FPA_OUTPUT_BUFFER_POOL_SIZE (8 * OCTEON_CACHE_LINE_SIZE) -#define OCTEON_FPA_PACKET_POOL_SIZE (16 * OCTEON_CACHE_LINE_SIZE) - -#define OCTEON_POW_WORK_REQUEST(wait) (0x8001600000000000ull | (wait<<3)) - -typedef union -{ - void* ptr; - uint64_t word64; - struct - { - uint64_t i : 1; - uint64_t back : 4; - uint64_t pool : 3; - uint64_t size :16; - uint64_t addr :40; - } bits; -} octeon_buf_ptr_t; - -/** - * Work queue entry format - */ -typedef struct -{ - uint16_t hw_chksum; - uint8_t unused; - uint64_t next_ptr : 40; - uint64_t len :16; - uint64_t ipprt : 6; - uint64_t qos : 3; - uint64_t grp : 4; - uint64_t tag_type : 3; - uint64_t tag :32; - union - { - uint64_t word64; - struct - { - uint64_t bufs : 8; - uint64_t ip_offset : 8; - uint64_t vlan_valid : 1; - uint64_t unassigned : 2; - uint64_t vlan_cfi : 1; - uint64_t vlan_id :12; - uint64_t unassigned2 :12; - uint64_t dec_ipcomp : 1; - uint64_t tcp_or_udp : 1; - uint64_t dec_ipsec : 1; - uint64_t is_v6 : 1; - uint64_t software : 1; - uint64_t L4_error : 1; - uint64_t is_frag : 1; - uint64_t IP_exc : 1; - uint64_t is_bcast : 1; - uint64_t is_mcast : 1; - uint64_t not_IP : 1; - uint64_t rcv_error : 1; - uint64_t err_code : 8; - } bits; - struct - { - uint64_t bufs : 8; - uint64_t unused : 8; - uint64_t vlan_valid : 1; - uint64_t unassigned : 2; - uint64_t vlan_cfi : 1; - uint64_t vlan_id :12; - uint64_t unassigned2 :16; - uint64_t software : 1; - uint64_t unassigned3 : 1; - uint64_t is_rarp : 1; - uint64_t is_arp : 1; - uint64_t is_bcast : 1; - uint64_t is_mcast : 1; - uint64_t not_IP : 1; - uint64_t rcv_error : 1; - uint64_t err_code : 8; - } snoip; - } word2; - octeon_buf_ptr_t packet_ptr; - uint8_t packet_data[96]; -} octeon_wqe_t; - -typedef union { - uint64_t word64; - - struct { - uint64_t scraddr : 8; /**< the (64-bit word) location in scratchpad to write to (if len != 0) */ - uint64_t len : 8; /**< the number of words in the response (0 => no response) */ - uint64_t did : 8; /**< the ID of the device on the non-coherent bus */ - uint64_t unused :36; - uint64_t wait : 1; /**< if set, don't return load response until work is available */ - uint64_t unused2 : 3; - } bits; - -} octeon_pow_iobdma_store_t; - - -/** - * Wait flag values for pow functions. - */ -typedef enum -{ - OCTEON_POW_WAIT = 1, - OCTEON_POW_NO_WAIT = 0, -} octeon_pow_wait_t; - - - -static inline void * phys_to_virt (unsigned long address) -{ - return (void *)(address + 0x80000000UL); -} - -// decode within DMA space -typedef enum { - OCTEON_ADD_WIN_DMA_ADD = 0L, // add store data to the write buffer entry, allocating it if necessary - OCTEON_ADD_WIN_DMA_SENDMEM = 1L, // send out the write buffer entry to DRAM - // store data must be normal DRAM memory space address in this case - OCTEON_ADD_WIN_DMA_SENDDMA = 2L, // send out the write buffer entry as an IOBDMA command - // see OCTEON_ADD_WIN_DMA_SEND_DEC for data contents - OCTEON_ADD_WIN_DMA_SENDIO = 3L, // send out the write buffer entry as an IO write - // store data must be normal IO space address in this case - OCTEON_ADD_WIN_DMA_SENDSINGLE = 4L, // send out a single-tick command on the NCB bus - // no write buffer data needed/used -} octeon_add_win_dma_dec_t; - - -#define OCTEON_OCT_DID_FPA 5ULL -#define OCTEON_OCT_DID_TAG 12ULL -#define OCTEON_OCT_DID_TAG_SWTAG OCTEON_ADDR_FULL_DID(OCTEON_OCT_DID_TAG, 0ULL) - - -#define OCTEON_IOBDMA_OFFSET (-3*1024ll) -#define OCTEON_IOBDMA_SEP 16 -#define OCTEON_IOBDMA_SENDSINGLE (OCTEON_IOBDMA_OFFSET + \ - (OCTEON_ADD_WIN_DMA_SENDSINGLE *\ - OCTEON_IOBDMA_SEP)) - -static inline void octeon_send_single (uint64_t data) -{ - oct_write64((uint64_t)(OCTEON_IOBDMA_SENDSINGLE * (long long)8), data); -} - - -static inline void octeon_pow_work_request_async_nocheck (int scratch_addr, - octeon_pow_wait_t wait) -{ - octeon_pow_iobdma_store_t data; - - /* scratch_addr must be 8 byte aligned */ - data.bits.scraddr = scratch_addr >> 3; - data.bits.len = 1; - data.bits.did = OCTEON_OCT_DID_TAG_SWTAG; - data.bits.wait = wait; - octeon_send_single(data.word64); -} - - - -/** - * octeon_gmx_inf_mode - * - * GMX_INF_MODE = Interface Mode - * - */ -typedef union -{ - uint64_t word64; - struct gmxx_inf_mode_s - { - uint64_t reserved_3_63 : 61; - uint64_t p0mii : 1; /**< Port 0 Interface Mode - 0: Port 0 is RGMII - 1: Port 0 is MII */ - uint64_t en : 1; /**< Interface Enable */ - uint64_t type : 1; /**< Interface Mode - 0: RGMII Mode - 1: Spi4 Mode */ - } bits; - struct gmxx_inf_mode_cn3020 - { - uint64_t reserved_2_63 : 62; - uint64_t en : 1; /**< Interface Enable */ - uint64_t type : 1; /**< Interface Mode - 0: All three ports are RGMII ports - 1: prt0 is RGMII, prt1 is GMII, and prt2 is unused */ - } cn3020; - struct gmxx_inf_mode_s cn30xx; - struct gmxx_inf_mode_cn3020 cn31xx; - struct gmxx_inf_mode_cn3020 cn36xx; - struct gmxx_inf_mode_cn3020 cn38xx; - struct gmxx_inf_mode_cn3020 cn38xxp2; - struct gmxx_inf_mode_cn3020 cn56xx; - struct gmxx_inf_mode_cn3020 cn58xx; -} octeon_gmxx_inf_mode_t; - - - - -typedef union { - uint64_t word64; - struct { - uint64_t reserved : 60; /* Reserved */ - uint64_t slottime : 1; /* Slot Time for Half-Duplex */ - /* operation - 0 = 512 bitimes (10/100Mbs operation) */ - /* - 1 = 4096 bitimes (1000Mbs operation) */ - uint64_t duplex : 1; /* Duplex - 0 = Half Duplex */ - /* (collisions/extentions/bursts) - 1 = Full Duplex */ - uint64_t speed : 1; /* Link Speed - 0 = 10/100Mbs */ - /* operation - 1 = 1000Mbs operation */ - uint64_t en : 1; /* Link Enable */ - } bits; -} octeon_rgmx_prtx_cfg_t; - - -/* - * GMX_RX_INBND = RGMX InBand Link Status - * - */ -typedef union { - uint64_t word64; - struct { - uint64_t reserved : 60; /* Reserved */ - uint64_t duplex : 1; /* 0 = Half, 1 = Full */ - uint64_t speed : 2; /* Inbound Link Speed */ - /* 00 = 2.5Mhz, 01 = 25Mhz */ - /* 10 = 125MHz, 11 = Reserved */ - uint64_t status : 1; /* Inbound Status Up/Down */ - } bits; -} octeon_rgmx_rxx_rx_inbnd_t; - - - -typedef union -{ - uint64_t word64; - struct { - uint64_t all_drop : 32; - uint64_t slow_drop : 32; - } bits; -} octeon_rgmx_ipd_queue_red_marks_t; - - -typedef union -{ - uint64_t word64; - struct { - uint64_t reserved : 15; - uint64_t use_pagecount : 1; - uint64_t new_con : 8; - uint64_t avg_con : 8; - uint64_t prb_con : 32; - } bits; -} octeon_rgmx_ipd_red_q_param_t; - - - -typedef union -{ - uint64_t word64; - struct { - uint64_t reserved : 46; - uint64_t bp_enable : 1; - uint64_t page_count : 17; - } bits; -} octeon_ipd_port_bp_page_count_t; - - -typedef union -{ - uint64_t word64; - struct { - uint64_t prb_dly : 14; - uint64_t avg_dly : 14; - uint64_t port_enable : 36; - } bits; -} octeon_ipd_red_port_enable_t; - - -/** - * Tag type definitions - */ -typedef enum -{ - OCTEON_POW_TAG_TYPE_ORDERED = 0L, /**< Tag ordering is maintained */ - OCTEON_POW_TAG_TYPE_ATOMIC = 1L, /**< Tag ordering is maintained, and at most one PP has the tag */ - OCTEON_POW_TAG_TYPE_NULL = 2L, /**< The work queue entry from the order - - NEVER tag switch from NULL to NULL */ - OCTEON_POW_TAG_TYPE_NULL_NULL = 3L /**< A tag switch to NULL, and there is no space reserved in POW - - NEVER tag switch to NULL_NULL - - NEVER tag switch from NULL_NULL - - NULL_NULL is entered at the beginning of time and on a deschedule. - - NULL_NULL can be exited by a new work request. A NULL_SWITCH load can also switch the state to NULL */ -} octeon_pow_tag_type_t ; - -/** - * This structure defines the response to a load/SENDSINGLE to POW (except CSR reads) - */ -typedef union { - uint64_t word64; - - octeon_wqe_t *wqp; - - // response to new work request loads - struct { - uint64_t no_work : 1; // set when no new work queue entry was returned - // If there was de-scheduled work, the HW will definitely - // return it. When this bit is set, it could mean - // either mean: - // - There was no work, or - // - There was no work that the HW could find. This - // case can happen, regardless of the wait bit value - // in the original request, when there is work - // in the IQ's that is too deep down the list. - uint64_t unused : 23; - uint64_t addr : 40; // 36 in O1 -- the work queue pointer - } s_work; - - // response to NULL_RD request loads - struct { - uint64_t unused : 62; - uint64_t state : 2; // of type octeon_pow_tag_type_t - // state is one of the following: - // OCTEON_POW_TAG_TYPE_ORDERED - // OCTEON_POW_TAG_TYPE_ATOMIC - // OCTEON_POW_TAG_TYPE_NULL - // OCTEON_POW_TAG_TYPE_NULL_NULL - } s_null_rd; - -} octeon_pow_tag_load_resp_t; - - -/* - * This structure describes the address to load stuff from POW - */ -typedef union { - uint64_t word64; - - // address for new work request loads (did<2:0> == 0) - struct { - uint64_t mem_region :2; - uint64_t mbz :13; - uint64_t is_io : 1; // must be one - uint64_t did : 8; // the ID of POW -- did<2:0> == 0 in this case - uint64_t unaddr : 4; - uint64_t unused :32; - uint64_t wait : 1; // if set, don't return load response until work is available - uint64_t mbzl : 3; // must be zero - } swork; // physical address - - - // address for NULL_RD request (did<2:0> == 4) - // when this is read, HW attempts to change the state to NULL if it is NULL_NULL - // (the hardware cannot switch from NULL_NULL to NULL if a POW entry is not available - - // software may need to recover by finishing another piece of work before a POW - // entry can ever become available.) - struct { - uint64_t mem_region :2; - uint64_t mbz :13; - uint64_t is_io : 1; // must be one - uint64_t did : 8; // the ID of POW -- did<2:0> == 4 in this case - uint64_t unaddr : 4; - uint64_t unused :33; - uint64_t mbzl : 3; // must be zero - } snull_rd; // physical address - - // address for CSR accesses - struct { - uint64_t mem_region :2; - uint64_t mbz :13; - uint64_t is_io : 1; // must be one - uint64_t did : 8; // the ID of POW -- did<2:0> == 7 in this case - uint64_t unaddr : 4; - uint64_t csraddr:36; // only 36 bits in O1, addr<2:0> must be zero - } stagcsr; // physical address - -} octeon_pow_load_addr_t; - - -static inline void octeon_pow_tag_switch_wait (void) -{ - uint64_t switch_complete; - - do - { - OCTEON_CHORD_HEX(&switch_complete); - } while (!switch_complete); - - return; -} - - -static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck (octeon_pow_wait_t wait) -{ - octeon_pow_load_addr_t ptr; - octeon_pow_tag_load_resp_t result; - - ptr.word64 = 0; - ptr.swork.mem_region = OCTEON_IO_SEG; - ptr.swork.is_io = 1; - ptr.swork.did = OCTEON_OCT_DID_TAG_SWTAG; - ptr.swork.wait = wait; - - result.word64 = oct_read64(ptr.word64); - - if (result.s_work.no_work || !result.s_work.addr) { - return NULL; - } - return (octeon_wqe_t *) MIPS_PHYS_TO_KSEG0(result.s_work.addr); -} - -static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck_debug (octeon_pow_wait_t wait) -{ - octeon_pow_load_addr_t ptr; - octeon_pow_tag_load_resp_t result; - - ptr.word64 = 0; - ptr.swork.mem_region = OCTEON_IO_SEG; - ptr.swork.is_io = 1; - ptr.swork.did = OCTEON_OCT_DID_TAG_SWTAG; - ptr.swork.wait = wait; - - result.word64 = oct_read64(ptr.word64); - - printf("WQE Result: 0x%llX No-work %X Addr %llX Ptr: %p\n", - (unsigned long long)result.word64, result.s_work.no_work, - (unsigned long long)result.s_work.addr, - (void *)MIPS_PHYS_TO_KSEG0(result.s_work.addr)); - - if (result.s_work.no_work || !result.s_work.addr) { - return NULL; - } - return (octeon_wqe_t *) MIPS_PHYS_TO_KSEG0(result.s_work.addr); -} - -static inline octeon_wqe_t *octeon_pow_work_request_sync (octeon_pow_wait_t wait) -{ - octeon_pow_tag_switch_wait(); - return (octeon_pow_work_request_sync_nocheck(wait)); -} - - -static inline octeon_wqe_t *octeon_pow_work_request_sync_debug (octeon_pow_wait_t wait) -{ - octeon_pow_tag_switch_wait(); - return (octeon_pow_work_request_sync_nocheck_debug(wait)); -} - - - -/** - * Gets result of asynchronous work request. Performs a IOBDMA sync - * to wait for the response. - * - * @param scratch_addr Scratch memory address to get result from - * Byte address, must be 8 byte aligned. - * @return Returns the WQE from the scratch register, or NULL if no work was available. - */ -static inline octeon_wqe_t *octeon_pow_work_response_async(int scratch_addr) -{ - octeon_pow_tag_load_resp_t result; - - OCTEON_SYNCIOBDMA; - result.word64 = oct_scratch_read64(scratch_addr); - - if (result.s_work.no_work) { - return NULL; - } - return (octeon_wqe_t*) MIPS_PHYS_TO_KSEG0(result.s_work.addr); -} - - - -/* - * The address from POW is a physical address. Adjust for back ptr, as well as - * make it accessible using KSEG0. - */ -static inline void *octeon_pow_pktptr_to_kbuffer (octeon_buf_ptr_t pkt_ptr) -{ - return ((void *)MIPS_PHYS_TO_KSEG0( - ((pkt_ptr.bits.addr >> 7) - pkt_ptr.bits.back) << 7)); -} - -#define INTERFACE(port) (port >> 4) /* Ports 0-15 are interface 0, 16-31 are interface 1 */ -#define INDEX(port) (port & 0xf) - - -#define OCTEON_RGMX_PRTX_CFG(index,interface) (0x8001180008000010ull+((index)*2048)+((interface)*0x8000000ull)) -#define OCTEON_RGMX_SMACX(offset,block_id) (0x8001180008000230ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_RXX_ADR_CAM0(offset,block_id) (0x8001180008000180ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_RXX_ADR_CAM1(offset,block_id) (0x8001180008000188ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_RXX_ADR_CAM2(offset,block_id) (0x8001180008000190ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_RXX_ADR_CAM3(offset,block_id) (0x8001180008000198ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_RXX_ADR_CAM4(offset,block_id) (0x80011800080001A0ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_RXX_ADR_CAM5(offset,block_id) (0x80011800080001A8ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_RXX_ADR_CTL(offset,block_id) (0x8001180008000100ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_RXX_ADR_CAM_EN(offset,block_id) (0x8001180008000108ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_INF_MODE(block_id) (0x80011800080007F8ull+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_TX_PRTS(block_id) (0x8001180008000480ull+((block_id)*0x8000000ull)) -#define OCTEON_ASXX_RX_PRT_EN(block_id) (0x80011800B0000000ull+((block_id)*0x8000000ull)) -#define OCTEON_ASXX_TX_PRT_EN(block_id) (0x80011800B0000008ull+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_TXX_THRESH(offset,block_id) (0x8001180008000210ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_ASXX_TX_HI_WATERX(offset,block_id) (0x80011800B0000080ull+((offset)*8)+((block_id)*0x8000000ull)) -#define OCTEON_ASXX_RX_CLK_SETX(offset,block_id) (0x80011800B0000020ull+((offset)*8)+((block_id)*0x8000000ull)) -#define OCTEON_ASXX_TX_CLK_SETX(offset,block_id) (0x80011800B0000048ull+((offset)*8)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_RXX_RX_INBND(offset,block_id) (0x8001180008000060ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_TXX_CLK(offset,block_id) (0x8001180008000208ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_TXX_SLOT(offset,block_id) (0x8001180008000220ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_RGMX_TXX_BURST(offset,block_id) (0x8001180008000228ull+((offset)*2048)+((block_id)*0x8000000ull)) -#define OCTEON_PIP_GBL_CTL (0x80011800A0000020ull) -#define OCTEON_PIP_GBL_CFG (0x80011800A0000028ull) -#define OCTEON_PIP_PRT_CFGX(offset) (0x80011800A0000200ull+((offset)*8)) -#define OCTEON_PIP_PRT_TAGX(offset) (0x80011800A0000400ull+((offset)*8)) - - - -#define OUR_CORE 0 -#define IP2 0 -#define IP3 1 -#define CIU_TIMERS 4 -#define OCTEON_POW_CORE_GROUP_MASK(core) (0x8001670000000000ull + (8 * core)) - -#define OCTEON_CIU_INT_EN0(CORE,IP) (0x8001070000000200ull + (IP * 16) + \ - ((CORE) * 32)) -#define OCTEON_CIU_INT_SUM0(CORE,IP) (0x8001070000000000ull + (IP * 8) + \ - ((CORE) * 32)) -#define OCTEON_CIU_TIMX(offset) (0x8001070000000480ull+((offset)*8)) - -#define OCTEON_POW_WQ_INT_THRX(offset) ((0x8001670000000080ull+((offset)*8))) -#define OCTEON_POW_WQ_INT_CNTX(offset) ((0x8001670000000100ull+((offset)*8))) -#define OCTEON_POW_QOS_THRX(offset) ((0x8001670000000180ull+((offset)*8))) -#define OCTEON_POW_QOS_RNDX(offset) ((0x80016700000001C0ull+((offset)*8))) -#define OCTEON_POW_WQ_INT_PC (0x8001670000000208ull) -#define OCTEON_POW_NW_TIM (0x8001670000000210ull) -#define OCTEON_POW_ECC_ERR (0x8001670000000218ull) -#define OCTEON_POW_INT_CTL (0x8001670000000220ull) -#define OCTEON_POW_NOS_CNT (0x8001670000000228ull) -#define OCTEON_POW_WS_PCX(offset) ((0x8001670000000280ull+((offset)*8))) -#define OCTEON_POW_WA_PCX(offset) ((0x8001670000000300ull+((offset)*8))) -#define OCTEON_POW_IQ_CNTX(offset) ((0x8001670000000340ull+((offset)*8))) -#define OCTEON_POW_WA_COM_PC (0x8001670000000380ull) -#define OCTEON_POW_IQ_COM_CNT (0x8001670000000388ull) -#define OCTEON_POW_TS_PC (0x8001670000000390ull) -#define OCTEON_POW_DS_PC (0x8001670000000398ull) -#define OCTEON_POW_BIST_STAT (0x80016700000003F8ull) - - -#define OCTEON_POW_WQ_INT (0x8001670000000200ull) - -#define OCTEON_IPD_PORT_BP_COUNTERS_PAIRX(offset) (0x80014F00000001B8ull+((offset)*8)) - -/* - * Current Counts that triggered interrupt - */ -#define OCTEON_POW_WQ_INT_CNTX(offset) ((0x8001670000000100ull+((offset)*8))) - - - -#define OCTEON_RGMX_ADRCTL_CAM_MODE_REJECT_DMAC 0 -#define OCTEON_RGMX_ADRCTL_ACCEPT_BROADCAST 1 -#define OCTEON_RGMX_ADRCTL_REJECT_ALL_MULTICAST 2 -#define OCTEON_RGMX_ADRCTL_ACCEPT_ALL_MULTICAST 4 -#define OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC 8 - - -#define RGMX_LOCK_INIT(_sc, _name) \ - mtx_init(&(_sc)->mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) -#define RGMX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx) -#define RGMX_LOCK(_sc) mtx_lock(&(_sc)->mtx) -#define RGMX_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) -#define RGMX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED) - -#endif /* ___OCTEON_RGMX__H___ */ Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_rgmx.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pip.h =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pip.h (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pip.h (nonexistent) @@ -1,219 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/* $FreeBSD$ */ - -/* - * 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 */ - } bits; -} octeon_pip_gbl_cfg_t; - - -typedef union { - uint64_t word64; - struct { - uint64_t reserved4 : 37; /* Must be zero */ - uint64_t qos : 3; /* Default POW QoS queue */ - uint64_t qos_wat : 4; /* Bitfield to enable QoS watcher */ - /* look up tables. 4 per port. */ - uint64_t reserved3 : 1; /* Must be zero */ - uint64_t spare : 1; /* Must be zero */ - uint64_t qos_diff : 1; /* Use IP diffserv to determine */ - /* the queue in the POW */ - uint64_t qos_vlan : 1; /* Use the VLAN tag to determine */ - /* the queue in the POW */ - uint64_t reserved2 : 3; /* Must be zero */ - uint64_t crc_en : 1; /* Enable HW checksum */ - uint64_t reserved1 : 2; /* Must be zero */ - octeon_pip_port_parse_mode_t mode : 2; /* Raw/Parsed/IP/etc */ - uint64_t reserved0 : 1; /* Must be zero */ - uint64_t skip : 7; /* 8 byte words to skip in the */ - /* beginning of a packet buffer */ - } bits; -} octeon_pip_port_cfg_t; - - - -/* - * Packet input to POW interface. How input packets are tagged for - * the POW is controlled here. - */ -typedef union { - uint64_t word64; - struct { - uint64_t reserved : 24; /**< Reserved */ - uint64_t grptagbase : 4; /**< Offset to use when computing group from tag bits - when GRPTAG is set. Only applies to IP packets. - (PASS2 only) */ - uint64_t grptagmask : 4; /**< Which bits of the tag to exclude when computing - group when GRPTAG is set. Only applies to IP packets. - (PASS2 only) */ - uint64_t grptag : 1; /**< When set, use the lower bit of the tag to compute - the group in the work queue entry - GRP = WQE[TAG[3:0]] & ~GRPTAGMASK + GRPTAGBASE. - Only applies to IP packets. (PASS2 only) */ - uint64_t spare : 1; /**< Spare bit - (PASS2 only) */ - uint64_t tag_mode : 2; /**< Which tag algorithm to use - 0 = always use tuple tag algorithm - 1 = always use mask tag algorithm - 2 = if packet is IP, use tuple else use mask - 3 = tuple XOR mask - (PASS2 only) */ - uint64_t inc_vs : 2; /**< determines the VLAN ID (VID) to be included in - tuple tag when VLAN stacking is detected - 0 = do not include VID in tuple tag generation - 1 = include VID (VLAN0) in hash - 2 = include VID (VLAN1) in hash - 3 = include VID ([VLAN0,VLAN1]) in hash - (PASS2 only) */ - uint64_t inc_vlan : 1; /**< when set, the VLAN ID is included in tuple tag - when VLAN stacking is not detected - 0 = do not include VID in tuple tag generation - 1 = include VID in hash - (PASS2 only) */ - uint64_t inc_prt_flag : 1; /**< sets whether the port is included in tuple tag */ - uint64_t ip6_dprt_flag : 1; /**< sets whether the TCP/UDP dst port is - included in tuple tag for IPv6 packets */ - uint64_t ip4_dprt_flag : 1; /**< sets whether the TCP/UDP dst port is - included in tuple tag for IPv4 */ - uint64_t ip6_sprt_flag : 1; /**< sets whether the TCP/UDP src port is - included in tuple tag for IPv6 packets */ - uint64_t ip4_sprt_flag : 1; /**< sets whether the TCP/UDP src port is - included in tuple tag for IPv4 */ - uint64_t ip6_nxth_flag : 1; /**< sets whether ipv6 includes next header in tuple - tag hash */ - uint64_t ip4_pctl_flag : 1; /**< sets whether ipv4 includes protocol in tuple - tag hash */ - uint64_t ip6_dst_flag : 1; /**< sets whether ipv6 includes dst address in tuple - tag hash */ - uint64_t ip4_dst_flag : 1; /**< sets whether ipv4 includes dst address in tuple - tag hash */ - uint64_t ip6_src_flag : 1; /**< sets whether ipv6 includes src address in tuple - tag hash */ - uint64_t ip4_src_flag : 1; /**< sets whether ipv4 includes src address in tuple - tag hash */ - uint64_t tcp6_tag_type : 2; /**< sets the tag_type of a TCP packet (IPv6) - 0 = ordered tags - 1 = atomic tags - 2 = Null tags */ - uint64_t tcp4_tag_type : 2; /**< sets the tag_type of a TCP packet (IPv4) - 0 = ordered tags - 1 = atomic tags - 2 = Null tags */ - uint64_t ip6_tag_type : 2; /**< sets whether IPv6 packet tag type - 0 = ordered tags - 1 = atomic tags - 2 = Null tags */ - uint64_t ip4_tag_type : 2; /**< sets whether IPv4 packet tag type - 0 = ordered tags - 1 = atomic tags - 2 = Null tags */ - uint64_t non_tag_type : 2; /**< sets whether non-IP packet tag type - 0 = ordered tags - 1 = atomic tags - 2 = Null tags */ - uint64_t grp : 4; /* POW group for input pkts */ - } bits; -} octeon_pip_port_tag_cfg_t; - - -/** - * Configure an ethernet input port - * - * @param port_num Port number to configure - * @param port_cfg Port hardware configuration - * @param port_tag_cfg - * Port POW tagging configuration - */ -static inline void octeon_pip_config_port(u_int port_num, - octeon_pip_port_cfg_t port_cfg, - octeon_pip_port_tag_cfg_t port_tag_cfg) -{ - oct_write64(OCTEON_PIP_PRT_CFGX(port_num), port_cfg.word64); - oct_write64(OCTEON_PIP_PRT_TAGX(port_num), port_tag_cfg.word64); -} - - -#endif /* __OCTEON_PIP_H__ */ Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pip.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pko.c =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pko.c (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pko.c (nonexistent) @@ -1,378 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/*------------------------------------------------------------------ - * octeon_pko.c Packet Output Unit - * - *------------------------------------------------------------------ - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -#include -#include "octeon_fau.h" -#include "octeon_fpa.h" -#include "octeon_pko.h" - - -/* - * - */ -static void octeon_pko_clear_port_counts (u_int port) -{ - u_int port_num; - octeon_pko_read_idx_t octeon_pko_idx; - - octeon_pko_idx.word64 = 0; - octeon_pko_idx.bits.idx = port; - octeon_pko_idx.bits.inc = 0; - oct_write64(OCTEON_PKO_REG_READ_IDX, octeon_pko_idx.word64); - - port_num = port; - oct_write64(OCTEON_PKO_MEM_COUNT0, port_num); - port_num = port; - oct_write64(OCTEON_PKO_MEM_COUNT1, port_num); -} - -/* - * octeon_pko_init - * - */ -void octeon_pko_init (void) -{ - u_int queue, port; - octeon_pko_read_idx_t octeon_pko_idx; - octeon_pko_queue_cfg_t octeon_pko_queue_cfg; - - for (port = 0; port < OCTEON_PKO_PORTS_MAX; port++) { - octeon_pko_clear_port_counts(port); - } - - octeon_pko_idx.word64 = 0; - octeon_pko_idx.bits.idx = 0; - octeon_pko_idx.bits.inc = 1; - oct_write64(OCTEON_PKO_REG_READ_IDX, octeon_pko_idx.word64); - for (queue = 0; queue < OCTEON_PKO_QUEUES_MAX; queue++) { - - octeon_pko_queue_cfg.word64 = 0; - octeon_pko_queue_cfg.bits.queue = queue; - octeon_pko_queue_cfg.bits.port = OCTEON_PKO_PORT_ILLEGAL; - octeon_pko_queue_cfg.bits.buf_ptr = 0; - oct_write64(OCTEON_PKO_MEM_QUEUE_PTRS, octeon_pko_queue_cfg.word64); - } -} - - -/* - * octeon_pko_enable - * - * enable pko - */ -void octeon_pko_enable (void) -{ - - /* - * PKO enable - */ - oct_write64(OCTEON_PKO_REG_FLAGS, 3); /* octeon_pko_enable() */ -} - - -/* - * octeon_pko_disable - * - * disable pko - */ -void octeon_pko_disable (void) -{ - - /* - * PKO disable - */ - oct_write64(OCTEON_PKO_REG_FLAGS, 0); /* pko_disable() */ -} - -/* - * octeon_pko_config_cmdbuf_global_defaults - * - */ -void octeon_pko_config_cmdbuf_global_defaults (u_int cmdbuf_pool, - u_int cmdbuf_pool_elem_size ) -{ - octeon_pko_pool_cfg_t octeon_pko_pool_config; - - octeon_pko_pool_config.word64 = 0; - octeon_pko_pool_config.bits.pool = cmdbuf_pool; - octeon_pko_pool_config.bits.size = cmdbuf_pool_elem_size; - oct_write64(OCTEON_PKO_CMD_BUF, octeon_pko_pool_config.word64); -} - -/* - * octeon_pko_config_rgmx_ports - * - * Configure rgmx pko. Always enables 4 + 4 ports - */ -void octeon_pko_config_rgmx_ports (void) -{ - octeon_pko_reg_gmx_port_mode_t octeon_pko_gmx_mode; - - octeon_pko_gmx_mode.word64 = 0; - octeon_pko_gmx_mode.bits.mode0 = 2; /* 16 >> 2 == 4 ports */ - octeon_pko_gmx_mode.bits.mode1 = 2; /* 16 >> 2 == 4 ports */ - oct_write64(OCTEON_PKO_GMX_PORT_MODE, octeon_pko_gmx_mode.word64); -} - - -/* - * octeon_pko_config - * - * Configure PKO - * - */ -void octeon_pko_config (void) -{ -} - -/* - * octeon_pko_get_port_status - * - * Get the status counters for a PKO port. - * - * port_num Port number to get statistics for. - * clear Set to 1 to clear the counters after they are read - * status Where to put the results. - */ -void octeon_pko_get_port_status (u_int port, u_int clear, - octeon_pko_port_status_t *status) -{ - octeon_word_t packet_num; - octeon_pko_read_idx_t octeon_pko_idx; - - packet_num.word64 = 0; - - octeon_pko_idx.word64 = 0; - octeon_pko_idx.bits.idx = port; - octeon_pko_idx.bits.inc = 0; - oct_write64(OCTEON_PKO_REG_READ_IDX, octeon_pko_idx.word64); - - packet_num.word64 = oct_read64(OCTEON_PKO_MEM_COUNT0); - status->packets = packet_num.bits.word32lo; - - status->octets = oct_read64(OCTEON_PKO_MEM_COUNT1); - status->doorbell = oct_read64(OCTEON_PKO_MEM_DEBUG9); - status->doorbell = (status->doorbell >> 8) & 0xfffff; - if (clear) { - octeon_pko_clear_port_counts(port); - } -} - -static void octeon_pko_doorbell_data_dump(uint64_t port); - -static void octeon_pko_doorbell_data_dump (uint64_t port) -{ - octeon_pko_port_status_t status; - - octeon_pko_get_port_status(port, 0, &status); - printf("\n Port #%lld Pkts %ld Bytes %lld DoorBell %lld", - (unsigned long long)port, status.packets, - (unsigned long long)status.octets, - (unsigned long long)status.doorbell); -} - -/* - * octeon_pko_show - * - * Show the OCTEON_PKO status & configs - */ -void octeon_pko_show (u_int start_port, u_int end_port) -{ - u_int queue, queue_max, gmx_int0_ports, gmx_int1_ports; - u_int port; - uint64_t val64; - octeon_pko_port_status_t status; - octeon_pko_pool_cfg_t octeon_pko_pool_config; - octeon_pko_read_idx_t octeon_pko_idx; - octeon_pko_queue_mode_t octeon_pko_queue_mode; - octeon_pko_reg_gmx_port_mode_t octeon_pko_gmx_mode; - octeon_pko_crc_ports_enable_t octeon_pko_crc_ports; - octeon_pko_queue_cfg_t octeon_pko_queue_cfg; - - printf("\n\nPKO Status:"); - val64 = oct_read64(OCTEON_PKO_REG_FLAGS); - if ((val64 & 0x3) != 0x3) { - printf(" Disabled"); - return; - } else { - printf(" Enabled"); - } - octeon_pko_queue_mode.word64 = oct_read64(OCTEON_PKO_QUEUE_MODE); - queue_max = (128 >> octeon_pko_queue_mode.bits.mode); - octeon_pko_gmx_mode.word64 = oct_read64(OCTEON_PKO_GMX_PORT_MODE); - gmx_int0_ports = (16 >> octeon_pko_gmx_mode.bits.mode0); - gmx_int1_ports = (16 >> octeon_pko_gmx_mode.bits.mode1); - octeon_pko_crc_ports.word64 = oct_read64(OCTEON_PKO_REG_CRC_ENABLE); - printf("\n Total Queues: 0..%d Ports GMX0 %d GMX1 %d CRC 0x%X", - queue_max - 1, gmx_int0_ports, gmx_int1_ports, - octeon_pko_crc_ports.bits.crc_ports_mask); - - octeon_pko_pool_config.word64 = oct_read64(OCTEON_PKO_CMD_BUF); - printf("\n CmdBuf Pool: %d CmdBuf Size in Words: %d Bytes: %d", - octeon_pko_pool_config.bits.pool, octeon_pko_pool_config.bits.size, - octeon_pko_pool_config.bits.size * 8); - - octeon_pko_idx.word64 = 0; - octeon_pko_idx.bits.idx = 0; - octeon_pko_idx.bits.inc = 1; - oct_write64(OCTEON_PKO_REG_READ_IDX, octeon_pko_idx.word64); - for (queue = 0; queue < queue_max; queue++) { - - octeon_pko_queue_cfg.word64 = oct_read64(OCTEON_PKO_MEM_QUEUE_PTRS); - if (!octeon_pko_queue_cfg.bits.buf_ptr) continue; - printf("\n Port # %d Queue %3d [%d] BufPtr: 0x%llX Mask: %X%s", - octeon_pko_queue_cfg.bits.port, octeon_pko_queue_cfg.bits.queue, - octeon_pko_queue_cfg.bits.index, - (unsigned long long)octeon_pko_queue_cfg.bits.buf_ptr, - octeon_pko_queue_cfg.bits.qos_mask, - (octeon_pko_queue_cfg.bits.tail)? " Last":""); - } - printf("\n"); - - for (port = start_port; port < (end_port + 1); port++) { - - octeon_pko_get_port_status(port, 0, &status); - octeon_pko_doorbell_data_dump(port); - - } -} - - - - -/* - * octeon_pko_config_port - * - * Configure a output port and the associated queues for use. - * - */ -octeon_pko_status_t octeon_pko_config_port (u_int port, - u_int base_queue, - u_int num_queues, - const u_int priority[], - u_int pko_output_cmdbuf_fpa_pool, - octeon_pko_sw_queue_info_t sw_queues[]) -{ - octeon_pko_status_t result_code; - u_int queue; - octeon_pko_queue_cfg_t qconfig; - - if ((port >= OCTEON_PKO_PORTS_MAX) && (port != OCTEON_PKO_PORT_ILLEGAL)) { - printf("\n%% Error: octeon_pko_config_port: Invalid port %u", port); - return (OCTEON_PKO_INVALID_PORT); - } - - if ((base_queue + num_queues) > OCTEON_PKO_QUEUES_MAX) { - printf("\n%% Error: octeon_pko_config_port: Invalid queue range"); - return (OCTEON_PKO_INVALID_QUEUE); - } - - result_code = OCTEON_PKO_SUCCESS; - - for (queue = 0; queue < num_queues; queue++) { - uint64_t buf_ptr = 0; - - qconfig.word64 = 0; - qconfig.bits.tail = (queue == (num_queues - 1)) ? 1 : 0; - qconfig.bits.index = queue; - qconfig.bits.port = port; - qconfig.bits.queue = base_queue + queue; - - /* Convert the priority into an enable bit field. */ - /* Try to space the bits out evenly so the pkts don't get grouped up */ - switch ((int)priority[queue]) { - case 0: qconfig.bits.qos_mask = 0x00; break; - case 1: qconfig.bits.qos_mask = 0x01; break; - case 2: qconfig.bits.qos_mask = 0x11; break; - case 3: qconfig.bits.qos_mask = 0x49; break; - case 4: qconfig.bits.qos_mask = 0x55; break; - case 5: qconfig.bits.qos_mask = 0x57; break; - case 6: qconfig.bits.qos_mask = 0x77; break; - case 7: qconfig.bits.qos_mask = 0x7f; break; - case 8: qconfig.bits.qos_mask = 0xff; break; - default: - printf("\n%% Error: octeon_pko_config_port Invalid priority %llu", - (unsigned long long)priority[queue]); - qconfig.bits.qos_mask = 0xff; - result_code = OCTEON_PKO_INVALID_PRIORITY; - break; - } - if (port != OCTEON_PKO_PORT_ILLEGAL) { - - buf_ptr = octeon_fpa_alloc_phys(pko_output_cmdbuf_fpa_pool); - if (!buf_ptr) { - printf("\n%% Error: octeon_pko_config_port: Unable to allocate"); - return (OCTEON_PKO_NO_MEMORY); - } - - sw_queues[queue].xmit_command_state = (buf_ptr << OCTEON_PKO_INDEX_BITS); - octeon_spinlock_init(&(sw_queues[queue].lock)); - -//#define DEBUG_TX - -#ifdef DEBUG_TX - printf(" PKO: port %u pool: %u base+queue %u %u %u buf_ptr: 0x%llX\n", - port, - pko_output_cmdbuf_fpa_pool, - base_queue, queue, base_queue+queue, - buf_ptr); - -#endif - qconfig.bits.buf_ptr = buf_ptr; - oct_write64(OCTEON_PKO_MEM_QUEUE_PTRS, qconfig.word64); - - } - } - - return (result_code); -} - Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pko.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pko.h =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pko.h (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pko.h (nonexistent) @@ -1,332 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/* $FreeBSD$ */ - -/*------------------------------------------------------------------ - * octeon_pko.h Packet Output Block - * - *------------------------------------------------------------------ - */ - - -#ifndef ___OCTEON_PKO__H___ -#define ___OCTEON_PKO__H___ - - - -/* - * PKO Command Buffer Register. - * Specify Pool-# and Size of each entry in Pool. For Output Cmd Buffers. - */ -typedef union { - uint64_t word64; - struct { - uint64_t unused_mbz : 41; /* Must be zero */ - uint64_t pool : 3; /* FPA Pool to use */ - uint64_t unused_mbz2 : 7; /* Must be zero */ - uint64_t size : 13; /* Size of the pool blocks */ - } bits; -} octeon_pko_pool_cfg_t; - - -/* - * PKO GMX Mode Register - * Specify the # of GMX1 ports and GMX0 ports - */ -typedef union { - uint64_t word64; - struct { - uint64_t unused_mbz : 58; /* MBZ */ - uint64_t mode1 : 3; /* # GMX1 ports; */ - /* 16 >> MODE1, 0 <= MODE1 <=4 */ - uint64_t mode0 : 3; /* # GMX0 ports; */ - /* 16 >> MODE0, 0 <= MODE0 <=4 */ - } bits; -} octeon_pko_reg_gmx_port_mode_t; - - -typedef union { - uint64_t word64; - struct { - uint64_t unused_mbz : 62; /* MBZ */ - uint64_t mode : 2; /* Queues Mode */ - } bits; -} octeon_pko_queue_mode_t; - - -typedef union { - uint64_t word64; - struct { - uint64_t unused_mbz : 32; /* MBZ */ - uint64_t crc_ports_mask : 32; /* CRC Ports Enable mask */ - } bits; -} octeon_pko_crc_ports_enable_t; - - - -#define OCTEON_PKO_QUEUES_MAX 128 -#define OCTEON_PKO_PORTS_MAX 36 -#define OCTEON_PKO_PORT_ILLEGAL 63 - -/* Defines how the PKO command buffer FAU register is used */ - -#define OCTEON_PKO_INDEX_BITS 12 -#define OCTEON_PKO_INDEX_MASK ((1ull << OCTEON_PKO_INDEX_BITS) - 1) - - - -typedef enum { - OCTEON_PKO_SUCCESS, - OCTEON_PKO_INVALID_PORT, - OCTEON_PKO_INVALID_QUEUE, - OCTEON_PKO_INVALID_PRIORITY, - OCTEON_PKO_NO_MEMORY -} octeon_pko_status_t; - - -typedef struct { - long packets; - uint64_t octets; - uint64_t doorbell; -} octeon_pko_port_status_t; - - -typedef union { - uint64_t word64; - struct { - octeon_mips_space_t mem_space : 2; /* Octeon IO_SEG */ - uint64_t unused_mbz :13; /* Must be zero */ - uint64_t is_io : 1; /* Must be one */ - uint64_t did : 8; /* device-ID on non-coherent bus*/ - uint64_t unused_mbz2 : 4; /* Must be zero */ - uint64_t unused_mbz3 :18; /* Must be zero */ - uint64_t port : 6; /* output port */ - uint64_t queue : 9; /* output queue to send */ - uint64_t unused_mbz4 : 3; /* Must be zero */ - } bits; -} octeon_pko_doorbell_address_t; - -/* - * Structure of the first packet output command word. - */ -typedef union { - uint64_t word64; - struct { - octeon_fau_op_size_t size1 : 2; /* The size of reg1 operation */ - /* - could be 8, 16, 32, or 64 bits */ - octeon_fau_op_size_t size0 : 2; /* The size of the reg0 operation */ - /* - could be 8, 16, 32, or 64 bits */ - uint64_t subone1 : 1; /* Subtract 1, else sub pkt size */ - uint64_t reg1 :11; /* The register, subtract will be */ - /* done if reg1 is non-zero */ - uint64_t subone0 : 1; /* Subtract 1, else sub pkt size */ - uint64_t reg0 :11; /* The register, subtract will be */ - /* done if reg0 is non-zero */ - uint64_t unused : 2; /* Must be zero */ - uint64_t wqp : 1; /* If rsp, then word3 contains a */ - /* ptr to a work queue entry */ - uint64_t rsp : 1; /* HW will respond when done */ - uint64_t gather : 1; /* If set, the supplied pkt_ptr is */ - /* a ptr to a list of pkt_ptr's */ - uint64_t ipoffp1 : 7; /* Off to IP hdr. For HW checksum */ - uint64_t ignore_i : 1; /* Ignore I bit in all pointers */ - uint64_t dontfree : 1; /* Don't free buffs containing pkt */ - uint64_t segs : 6; /* Number of segs. If gather set, */ - /* also gather list length */ - uint64_t total_bytes :16; /* Includes L2, w/o trailing CRC */ - } bits; -} octeon_pko_command_word0_t; - - -typedef union { - void* ptr; - uint64_t word64; - struct { - uint64_t i : 1; /* Invert the "free" pick of the overall pkt. */ - /* For inbound pkts, HW always sets this to 0 */ - uint64_t back : 4; /* Amount to back up to get to buffer start */ - /* in cache lines. This is mostly less than 1 */ - /* complete cache line; so the value is zero */ - uint64_t pool : 3; /* FPA pool that the buffer belongs to */ - uint64_t size :16; /* segment size (bytes) pointed at by addr */ - uint64_t addr :40; /* Ptr to 1st data byte. NOT buffer */ - } bits; -} octeon_pko_packet_ptr_t; - - -/* - * Definition of the hardware structure used to configure an - * output queue. - */ -typedef union { - uint64_t word64; - struct { - uint64_t unused_mbz : 3; /* Must be zero */ - uint64_t qos_mask : 8; /* Control Mask priority */ - /* across 8 QOS levels */ - uint64_t buf_ptr : 36; /* Command buffer pointer, */ - /* 8 byte-aligned */ - uint64_t tail : 1; /* Set if this queue is the tail */ - /* of the port queue array */ - uint64_t index : 3; /* Index (distance from head) in */ - /* the port queue array */ - uint64_t port : 6; /* Port ID for this queue mapping */ - uint64_t queue : 7; /* Hardware queue number */ - } bits; -} octeon_pko_queue_cfg_t; - - -typedef union { - uint64_t word64; - struct { - uint64_t unused_mbz : 48; - uint64_t inc : 8; - uint64_t idx : 8; - } bits; -} octeon_pko_read_idx_t; - - -typedef struct octeon_pko_sw_queue_info_t_ -{ - uint64_t xmit_command_state; - octeon_spinlock_t lock; - uint32_t pad[29]; -} octeon_pko_sw_queue_info_t; - - - -#define OCTEON_DID_PKT 10ULL -#define OCTEON_DID_PKT_SEND OCTEON_ADDR_FULL_DID(OCTEON_DID_PKT,2ULL) - - -/* - * Ring the packet output doorbell. This tells the packet - * output hardware that "len" command words have been added - * to its pending list. This command includes the required - * SYNCW before the doorbell ring. - * - * @param port Port the packet is for - * @param queue Queue the packet is for - * @param len Length of the command in 64 bit words - */ -extern void octeon_pko_doorbell_data(u_int port); - -//#define CORE_0_ONLY 1 - -static inline void octeon_pko_ring_doorbell (u_int port, u_int queue, - u_int len) -{ - octeon_pko_doorbell_address_t ptr; - - ptr.word64 = 0; - ptr.bits.mem_space = OCTEON_IO_SEG; - ptr.bits.did = OCTEON_DID_PKT_SEND; - ptr.bits.is_io = 1; - ptr.bits.port = port; - ptr.bits.queue = queue; - OCTEON_SYNCWS; - oct_write64(ptr.word64, len); -} - - - -#define OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0 1 -#define OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1 1 -#define OCTEON_PKO_QUEUES_PER_PORT_PCI 1 - -/* - * octeon_pko_get_base_queue - * - * For a given port number, return the base pko output queue - * for the port. - */ -static inline u_int octeon_pko_get_base_queue (u_int port) -{ - if (port < 16) { - return (port * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0); - } - if (port < 32) { - return (16 * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0 + - (port - 16) * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1); - } - return (16 * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0 + - 16 * OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1 + - (port - 32) * OCTEON_PKO_QUEUES_PER_PORT_PCI); -} - - -/* - * For a given port number, return the number of pko output queues. - * - * @param port Port number - * @return Number of output queues - */ -static inline u_int octeon_pko_get_num_queues(u_int port) -{ - if (port < 16) { - return (OCTEON_PKO_QUEUES_PER_PORT_INTERFACE0); - } else if (port<32) { - return (OCTEON_PKO_QUEUES_PER_PORT_INTERFACE1); - } - - return (OCTEON_PKO_QUEUES_PER_PORT_PCI); -} - - - -/* - * Externs - */ -extern void octeon_pko_init(void); -extern void octeon_pko_enable(void); -extern void octeon_pko_disable(void); -extern void octeon_pko_show(u_int start_port, u_int end_port); -extern void octeon_pko_config(void); -extern void octeon_pko_config_cmdbuf_global_defaults(u_int cmdbuf_pool, u_int elem_size); -extern void octeon_pko_config_rgmx_ports(void); -extern void octeon_pko_get_port_status(u_int, u_int, octeon_pko_port_status_t *status); -extern octeon_pko_status_t octeon_pko_config_port(u_int port, - u_int base_queue, - u_int num_queues, - const u_int priority[], - u_int pko_output_cmdbuf_fpa_pool, - octeon_pko_sw_queue_info_t sw_queues[]); - - -#endif /* ___OCTEON_PKO__H___ */ Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_pko.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_rgmx.c =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_rgmx.c (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_rgmx.c (nonexistent) @@ -1,2328 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/* - * octeon_rgmx.c RGMII Ethernet Interfaces on Octeon - * - */ - - -/* - * Driver for the Reduced Gigabit Media Independent Interface (RGMII) - * present on the Cavium Networks' Octeon chip. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include - -#include "octeon_fau.h" -#include "octeon_fpa.h" -#include "octeon_ipd.h" -#include "octeon_pko.h" -#include "octeon_pip.h" -#include "octeon_rgmx.h" - - -/* The "battleship" boards have 8 ports */ -#define OCTEON_RGMX_NUM_PORTS_MAX 8 -#define NUM_TX_PACKETS 80 -#define NUM_RX_PACKETS 300 -#define MAX_RX_BUFS (NUM_RX_PACKETS) * (OCTEON_RGMX_NUM_PORTS_MAX) -#define MAX_TX_BUFS (NUM_TX_PACKETS) -#define OCTEON_RGMX_DEV_NAME "rgmx" -#define OCTEON_RGMX_MIN_PORT 0 -#define OCTEON_RGMX_MAX_PORT 19 -#define OCTEON_RGMX_OQUEUE_PER_PORT 8 - - -#define OCTEON_RGMX_SCHEDULED_ISRS 1 /* Use Scheduled ISRs from kernel tasks */ - - -#ifndef POW_MAX_LOOP -#define POW_MAX_LOOP 0x800 -#endif - - -/* - * CIU related stuff for enabling POW interrupts - */ -#define OCTEON_RGMX_CIU_INTX CIU_INT_0 -#define OCTEON_RGMX_CIU_ENX CIU_EN_0 - -MALLOC_DEFINE(M_RGMII_WQE, "rgmii_wqe", "FPA pool for WQEs"); - -/* Driver data */ - -struct rgmx_softc_dev { - device_t sc_dev; /* Device ID */ - uint64_t link_status; - struct ifnet *ifp; - int sc_unit; - - u_int port; - u_int idx; - u_char ieee[6]; - - u_short txb_size; /* size of TX buffer, in bytes */ - - /* Transmission buffer management. */ - u_short txb_free; /* free bytes in TX buffer */ - u_char txb_count; /* number of packets in TX buffer */ - u_char txb_sched; /* number of scheduled packets */ - - /* Media information. */ - struct ifmedia media; /* used by if_media. */ - u_short mbitmap; /* bitmap for supported media; see bit2media */ - int defmedia; /* default media */ - struct ifqueue tx_pending_queue; /* Queue of mbuf given to PKO currently */ - octeon_pko_sw_queue_info_t *outq_ptr; - - struct mtx mtx; -}; - - -/* - * Device methods - */ -static int rgmii_probe(device_t); -static void rgmii_identify(driver_t *, device_t); -static int rgmii_attach(device_t); - - - -/* - * Octeon specific routines - */ -static int octeon_has_4ports(void); -static void octeon_config_rgmii_port(u_int port); -static void octeon_rgmx_config_pip(u_int port); -static void octeon_line_status_loop(void *); -static void octeon_rx_loop(void *); -static void octeon_config_hw_units_post_ports(void); -static void octeon_config_hw_units_pre_ports(void); -static void octeon_config_hw_units_port(struct rgmx_softc_dev *sc, u_int port); -static struct rgmx_softc_dev *get_rgmx_softc(u_int port); -static void octeon_rgmx_start_port(u_int port); -static u_int octeon_rgmx_stop_port(u_int port); -static u_int get_rgmx_port_ordinal(u_int port); -static void octeon_rgmx_set_mac(u_int port); -static void octeon_rgmx_init_sc(struct rgmx_softc_dev *sc, device_t dev, u_int port, u_int num_devices); -static int octeon_rgmx_init_ifnet(struct rgmx_softc_dev *sc); -static void octeon_rgmx_stop(struct rgmx_softc_dev *sc); -static void octeon_rgmx_config_speed(u_int port, u_int); -#ifdef DEBUG_RGMX_DUMP -static void octeon_dump_rgmx_stats(u_int port); -static void octeon_dump_pow_stats(void); -#endif -#ifdef __not_used__ -static void rgmx_timer_periodic(void); -#endif -static void octeon_rgmx_enable_RED_all(int, int); - -#ifdef OCTEON_RGMX_SCHEDULED_ISRS -static void octeon_rgmx_isr_link(void *context, int pending); -static void octeon_rgmx_isr_rxtx(void *context, int pending); -static int octeon_rgmx_intr_fast(void *arg); -#else -static int octeon_rgmx_intr(void *arg); -#endif - - - - - - - -/* Standard driver entry points. These can be static. */ -static void octeon_rgmx_init (void *); -//static driver_intr_t rgmx_intr; -static void octeon_rgmx_config_cam (struct ifnet *); -static int octeon_rgmx_ioctl (struct ifnet *, u_long, caddr_t); -static void octeon_rgmx_output_start (struct ifnet *); -static void octeon_rgmx_output_start_locked (struct ifnet *); -static int octeon_rgmx_medchange (struct ifnet *); -static void octeon_rgmx_medstat (struct ifnet *, struct ifmediareq *); - - -/* Mapping between media bitmap (in fe_softc.mbitmap) and ifm_media. */ -static int const bit2media [] = { - IFM_ETHER | IFM_AUTO, - IFM_ETHER | IFM_MANUAL, - IFM_ETHER | IFM_10_T, - IFM_ETHER | IFM_10_2, - IFM_ETHER | IFM_10_5, - IFM_ETHER | IFM_10_FL, - IFM_ETHER | IFM_10_T, - /* More can be added here... */ -}; - -/* Mapping between media bitmap (in fe_softc.mbitmap) and ifm_media. */ -#define MB_HA 0x0001 -#define MB_HM 0x0002 -#define MB_HT 0x0004 -#define MB_H2 0x0008 -#define MB_H5 0x0010 -#define MB_HF 0x0020 -#define MB_FT 0x0040 - -#define LEBLEN (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) - - -static struct rgmx_softc_dev *rgmx_scdev_array[OCTEON_RGMX_NUM_PORTS_MAX] = {NULL}; -static u_int port_array[OCTEON_RGMX_NUM_PORTS_MAX] = {0}; -static u_int num_devices = 0; -static octeon_pko_sw_queue_info_t output_queues_array[OCTEON_RGMX_NUM_PORTS_MAX * OCTEON_RGMX_OQUEUE_PER_PORT]; -static struct resource *irq_res; /* Interrupt resource. */ -static void *int_handler_tag; - - -#ifdef OCTEON_RGMX_SCHEDULED_ISRS - -struct task link_isr_task; -struct task rxtx_isr_task; -struct taskqueue *tq; /* private task queue */ - -#endif - - - -static u_int get_rgmx_port_ordinal (u_int port) -{ - u_int idx; - - for (idx = 0; idx < OCTEON_RGMX_NUM_PORTS_MAX; idx++) { - if (port_array[idx] == port) { - return (idx); - } - } - return (-1); -} - -static struct rgmx_softc_dev *get_rgmx_softc (u_int port) -{ - u_int idx; - - idx = get_rgmx_port_ordinal(port); - if (idx != -1) { - return (rgmx_scdev_array[idx]); - } - return (NULL); -} - - - -static void octeon_rgmx_init_sc (struct rgmx_softc_dev *sc, device_t dev, u_int port, u_int num_devices) -{ - int ii; - - /* No software-controllable media selection. */ - sc->mbitmap = MB_HM; - sc->defmedia = MB_HM; - - sc->sc_dev = dev; - sc->port = port; - sc->idx = num_devices; - sc->link_status = 0; - sc->sc_unit = num_devices; - sc->mbitmap = MB_HT; - sc->defmedia = MB_HT; - sc->tx_pending_queue.ifq_maxlen = NUM_TX_PACKETS; - sc->tx_pending_queue.ifq_head = sc->tx_pending_queue.ifq_tail = NULL; - sc->tx_pending_queue.ifq_len = sc->tx_pending_queue.ifq_drops = 0; - mtx_init(&sc->tx_pending_queue.ifq_mtx, "if->sc->txpq.ifqmtx", NULL, MTX_DEF); - - sc->outq_ptr = &(output_queues_array[num_devices * OCTEON_RGMX_OQUEUE_PER_PORT]); - - for (ii = 0; ii < 6; ii++) { - sc->ieee[ii] = octeon_mac_addr[ii]; - } - sc->ieee[5] += get_rgmx_port_ordinal(port); - -} - -static int octeon_rgmx_init_ifnet (struct rgmx_softc_dev *sc) -{ - struct ifnet *ifp; - - ifp = sc->ifp = if_alloc(IFT_ETHER); - if (NULL == ifp) { - device_printf(sc->sc_dev, "can not ifalloc for rgmx port\n"); - return (ENOSPC); - } - /* - * Initialize ifnet structure - */ - ifp->if_softc = sc; - if_initname(sc->ifp, device_get_name(sc->sc_dev), device_get_unit(sc->sc_dev)); - ifp->if_start = octeon_rgmx_output_start; - ifp->if_ioctl = octeon_rgmx_ioctl; - ifp->if_hwassist = CSUM_TCP | CSUM_UDP; - ifp->if_capabilities = IFCAP_HWCSUM; - ifp->if_capenable = ifp->if_capabilities; - ifp->if_init = octeon_rgmx_init; - ifp->if_linkmib = NULL; // &sc->mibdata; - ifp->if_linkmiblen = 0; // sizeof (sc->mibdata); - /* - * Set fixed interface flags. - */ - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; -// | IFF_NEEDSGIANT; - if (ifp->if_snd.ifq_maxlen == 0) - ifp->if_snd.ifq_maxlen = ifqmaxlen; - - ifmedia_init(&sc->media, 0, octeon_rgmx_medchange, octeon_rgmx_medstat); - ifmedia_add(&sc->media, bit2media[0], 0, NULL); - ifmedia_set(&sc->media, bit2media[0]); - - ether_ifattach(sc->ifp, sc->ieee); - - return (0); -} - - - -/* Driver methods */ - - -/* ------------------------------------------------------------------- * - * rgmii_identify() * - * ------------------------------------------------------------------- */ -static void rgmii_identify (driver_t *drv, device_t parent) -{ - BUS_ADD_CHILD(parent, 0, "rgmii", 0); -} - - -/* ------------------------------------------------------------------- * - * rgmii_probe() * - * ------------------------------------------------------------------- */ -static int rgmii_probe (device_t dev) -{ - if (device_get_unit(dev) != 0) - panic("can't probe/attach more rgmii devices\n"); - - device_set_desc(dev, "Octeon RGMII"); - return (0); -} - - - -/* ------------------------------------------------------------------- * - * rgmii_attach() * - * ------------------------------------------------------------------- */ -static int rgmii_attach (device_t dev) -{ - struct rgmx_softc_dev *sc; - device_t child; - int iface, port, nr_ports, error; - void *softc; - int irq_rid; - - octeon_config_hw_units_pre_ports(); - - /* Count interfaces and ports*/ - octeon_gmxx_inf_mode_t iface_mode; - iface_mode.word64 = 0; - - for (iface = 0; iface < 2; iface++) { - iface_mode.word64 = oct_read64(OCTEON_RGMX_INF_MODE(iface)); - - /* interface is either disabled or SPI */ - if (!iface_mode.bits.en) - continue; - if (octeon_get_chipid() == OCTEON_CN3020_CHIP) { - nr_ports = 2; - } else { - nr_ports = (octeon_has_4ports()) ? 4 : 3; - if (iface_mode.bits.type ) { - if (octeon_get_chipid() == OCTEON_CN5020_CHIP) - nr_ports = 2; - else - continue; - } - } - - oct_write64(OCTEON_RGMX_TX_PRTS(iface), nr_ports); - - for (port = iface * 16; port < iface * 16 + nr_ports; port++) { - - child = device_add_child(dev, OCTEON_RGMX_DEV_NAME, num_devices); - if (child == NULL) - panic("%s: device_add_child() failed\n", __func__); - - softc = malloc(sizeof(struct rgmx_softc_dev), M_DEVBUF, M_NOWAIT | M_ZERO); - if (!softc) { - panic("%s malloc failed for softc\n", __func__); - } - device_set_softc(child, softc); - device_set_desc(child, "Octeon RGMII"); - sc = device_get_softc(child); - if (!sc) { - printf(" No sc\n"); - num_devices++; - continue; - } - port_array[num_devices] = port; - rgmx_scdev_array[num_devices] = sc; - RGMX_LOCK_INIT(sc, device_get_nameunit(child)); - octeon_rgmx_init_sc(sc, child, port, num_devices); - octeon_config_hw_units_port(sc, port); - if (octeon_rgmx_init_ifnet(sc)) { - device_printf(dev, " ifinit failed for rgmx port %u\n", port); - return (ENOSPC); - } - num_devices++; - } - } - - octeon_config_hw_units_post_ports(); - - irq_rid = 0; - irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &irq_rid, 0, 0, 1, RF_SHAREABLE | RF_ACTIVE); - if (irq_res == NULL) { - device_printf(dev, "failed to allocate irq\n"); - return (ENXIO); - } - - -#ifdef OCTEON_RGMX_SCHEDULED_ISRS - /* - * Single task queues for all child devices. Since POW gives us a unified - * interrupt based on POW groups, not based on PORTs. - */ - TASK_INIT(&rxtx_isr_task, 0, octeon_rgmx_isr_rxtx, NULL); - TASK_INIT(&link_isr_task, 0, octeon_rgmx_isr_link, NULL); - tq = taskqueue_create_fast("octeon_rgmx_taskq", M_NOWAIT, - taskqueue_thread_enqueue, &tq); - taskqueue_start_threads(&tq, 1, PI_NET, "%s taskq", device_get_nameunit(dev)); - - error = bus_setup_intr(dev, irq_res, INTR_TYPE_NET, octeon_rgmx_intr_fast, NULL, - NULL, &int_handler_tag); - if (error != 0) { - device_printf(dev, "bus_setup_intr returned %d\n", error); - taskqueue_free(tq); - tq = NULL; - return (error); - } - -#else /* OCTEON_RGMX_SCHEDULED_ISRS */ - - error = bus_setup_intr(dev, irq_res, INTR_TYPE_NET, octeon_rgmx_intr, NULL, - NULL, &int_handler_tag); - - if (error != 0) { - device_printf(dev, "bus_setup_intr returned %d\n", error); - tq = NULL; - return (error); - } - -#endif /* OCTEON_RGMX_SCHEDULED_ISRS */ - - return (bus_generic_attach(dev)); -} - - - - -#define OCTEON_MAX_RGMX_PORT_NUMS 32 - - - -#define OCTEON_POW_RX_GROUP_NUM 0 -#define OCTEON_POW_TX_GROUP_NUM 1 /* If using TX WQE from PKO */ - -#define OCTEON_POW_RX_GROUP_MASK (1 << OCTEON_POW_RX_GROUP_NUM) -#define OCTEON_POW_TX_GROUP_MASK (1 << OCTEON_POW_TX_GROUP_NUM) -#define OCTEON_POW_ALL_OUR_GROUPS_MASK (OCTEON_POW_RX_GROUP_MASK | OCTEON_POW_RX_GROUP_MASK) -#define OCTEON_POW_ALL_GROUPS_MASK 0xffff -#define OCTEON_POW_WORKQUEUE_INT (0x8001670000000200ull) -#define OCTEON_POW_WORKQUEUE_INT_PC (0x8001670000000208ull) -#define OCTEON_POW_WORKQUEUE_INT_THRESHOLD(group_num) ((0x8001670000000080ull+((group_num)*0x8))) -#define OCTEON_RGMX_POW_NOS_CNT (0x8001670000000228ull) -#define OCTEON_POW_INT_CNTR(core) (0x8001670000000100ull+((core)*0x8)) -#define OCTEON_POW_INPT_Q_ALL_QOS (0x8001670000000388ull) -#define OCTEON_POW_INPT_QOS_GRP(grp) (0x8001670000000340ull + ((grp) * 0x8)) - - - - -#define NUM_RX_PACKETS_CTL (MAX_RX_BUFS + 3000) -#define NUM_TX_PACKETS_CTL 40 - -#define FPA_NOPOOL 0 - -#define OCTEON_FPA_RX_PACKET_POOL 0 -#define OCTEON_FPA_RX_PACKET_POOL_WORDS 208 /* 2048 bytes */ -#define OCTEON_FPA_RX_PACKET_POOL_ELEM_SIZE (OCTEON_FPA_RX_PACKET_POOL_WORDS) -#define OCTEON_FPA_RX_PACKET_POOL_ELEMENTS (MAX_RX_BUFS) -#define OCTEON_RX_MAX_SIZE (OCTEON_FPA_RX_PACKET_POOL_WORDS * sizeof(uint64_t)) - -#define OCTEON_FPA_WQE_RX_POOL 1 -#define OCTEON_FPA_WQE_RX_WORDS (OCTEON_CACHE_LINE_SIZE/8) -#define OCTEON_FPA_WQE_RX_POOL_ELEM_SIZE (OCTEON_FPA_WQE_RX_WORDS) -#define OCTEON_FPA_WQE_RX_POOL_ELEMENTS (NUM_RX_PACKETS_CTL) - -#define OCTEON_FPA_TX_PACKET_POOL 2 -#define OCTEON_FPA_TX_PACKET_POOL_WORDS 208 /* 2048 bytes */ -#define OCTEON_FPA_TX_PACKET_POOL_ELEM_SIZE (OCTEON_FPA_TX_PACKET_POOL_WORDS) -#define OCTEON_FPA_TX_PACKET_POOL_ELEMENTS (MAX_TX_BUFS) -#define OCTEON_TX_MAX_SIZE (OCTEON_FPA_TX_PACKET_POOL_WORDS * sizeof(uint64_t)) - -#define OCTEON_FPA_TX_CMDBUF_POOL 3 -#define OCTEON_FPA_TX_CMD_SIZE 2 -#define OCTEON_FPA_TX_CMD_NUM 300 -#define OCTEON_FPA_TX_CMDBUF_POOL_WORDS (OCTEON_FPA_TX_CMD_SIZE * OCTEON_FPA_TX_CMD_NUM) -#define OCTEON_FPA_TX_CMDBUF_POOL_ELEM_SIZE (OCTEON_FPA_TX_CMDBUF_POOL_WORDS +1) -#define OCTEON_FPA_TX_CMDBUF_POOL_ELEMENTS (30 * OCTEON_RGMX_NUM_PORTS_MAX) - -#define FIRST_PARTICLE_SKIP 0 -#define NOT_FIRST_PARTICLE_SKIP 0 - -#define ENABLE_BACK_PRESSURE 0 -#define RGMX_MAX_PAK_RECEIVE 5000000 - - -#ifdef OCTEON_RGMX_SCHEDULED_ISRS - - -static void octeon_rgmx_isr_link (void *context, int pending) -{ - octeon_line_status_loop(NULL); -} - - -static void octeon_rgmx_isr_rxtx (void *context, int pending) -{ - octeon_rx_loop(NULL); -} - - -/********************************************************************* - * - * Fast Interrupt Service routine - * - *********************************************************************/ - -//#define OCTEON_RGMX_POW_TIME_THR_INTS 1 - - -static int octeon_rgmx_intr_fast(void *arg) -{ - - int handled_flag = 0; - uint64_t ciu_summary; - - ciu_summary = ciu_get_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, - OCTEON_RGMX_CIU_ENX); - - if (ciu_summary & CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)) { - - /* - * Timer Interrupt for link status checks - * Acknowledging it will mask it for this cycle. - */ - ciu_clear_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, - OCTEON_RGMX_CIU_ENX, - CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)); - - taskqueue_enqueue(taskqueue_fast, &link_isr_task); - handled_flag = 1; - } - - if (ciu_summary & OCTEON_POW_ALL_GROUPS_MASK) { -#ifndef OCTEON_RGMX_POW_TIME_THR_INTS - /* - * When using POW IQ/DSQ size based interrupts, then - * ack the interrupts right away. So they don't interrupt - * until the queue size goes to 0 again. - */ - oct_write64(OCTEON_POW_WORKQUEUE_INT, - 0x10001 << OCTEON_POW_RX_GROUP_NUM); - -#else - /* - * We use POW thresholds based interrupt signalled on timer - * countdown. Acknowledge it now so that it doesn't - * interrupt us until next countdown to zero. - */ - oct_write64(OCTEON_POW_WORKQUEUE_INT, - 0x1 << OCTEON_POW_RX_GROUP_NUM); -#endif - - taskqueue_enqueue(tq, &rxtx_isr_task); - handled_flag = 1; - } - - return ((handled_flag) ? FILTER_HANDLED : FILTER_STRAY); -} - - -#else /* ! OCTEON_RGMX_SCHEDULED_ISRS */ - - -/* - * octeon_rgmx_intr - * - * This is direct inline isr. Will do all its work and heavy-lifting in interrupt context. - * - * Also note that the RGMX_LOCK/UNLOCK code will have to checked/added, since that is new and - * was not supported with this model. - */ -static int octeon_rgmx_intr (void *arg) -{ - int flag = 0; - uint64_t ciu_summary; - - /* - * read ciu to see if any bits are pow - */ - while (1) { - ciu_summary = ciu_get_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, - OCTEON_RGMX_CIU_ENX); - - if ((ciu_summary & (OCTEON_POW_ALL_GROUPS_MASK | CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1))) == 0) { - break; - } - - flag = 1; - - if (ciu_summary & OCTEON_POW_ALL_GROUPS_MASK) { - octeon_rx_loop(NULL); - /* - * Acknowledge the interrupt after processing queues. - */ - oct_write64(OCTEON_POW_WORKQUEUE_INT, OCTEON_POW_RX_GROUP_MASK); - } - if (ciu_summary & CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)) { - octeon_line_status_loop(NULL); - ciu_clear_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, - OCTEON_RGMX_CIU_ENX, - CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)); - } - } - - return ((flag) ? FILTER_HANDLED : FILTER_STRAY); -} - - -#endif /* OCTEON_RGMX_SCHEDULED_ISRS */ - - - -static struct mbuf *octeon_rgmx_build_new_rx_mbuf(struct ifnet *ifp, void *data_start, u_int totlen); - -static struct mbuf *octeon_rgmx_build_new_rx_mbuf (struct ifnet *ifp, void *data_start, u_int totlen) -{ - struct mbuf *m, *m0, *newm; - caddr_t newdata; - int len; - - if (totlen <= ETHER_HDR_LEN || totlen > LEBLEN - ETHER_CRC_LEN) { -#ifdef LEDEBUG - if_printf(ifp, "invalid packet size %d; dropping\n", totlen); -#endif - return (NULL); - } - - MGETHDR(m0, M_DONTWAIT, MT_DATA); - if (m0 == NULL) { - return (NULL); - } - - /* Initialize packet header info. */ - m0->m_pkthdr.rcvif = ifp; - m0->m_pkthdr.len = totlen; - m0->m_pkthdr.csum_flags = CSUM_IP_CHECKED | CSUM_IP_VALID | CSUM_DATA_VALID | CSUM_PSEUDO_HDR; - m0->m_pkthdr.csum_data = 0xffff; - len = MHLEN; - m = m0; - - while (totlen > 0) { - if (totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) - goto octeon_rgmx_build_new_rx_mbuf_bad; - len = MCLBYTES; - } - - if (m == m0) { - newdata = (caddr_t)ALIGN(m->m_data + ETHER_HDR_LEN) - ETHER_HDR_LEN; - len -= newdata - m->m_data; - m->m_data = newdata; - } - - /* Set the length of this mbuf. */ - m->m_len = len = min(totlen, len); - bcopy(data_start, mtod(m, caddr_t), len); - data_start = (void *) (((u_long) (data_start)) + len); - - totlen -= len; - if (totlen > 0) { - MGET(newm, M_DONTWAIT, MT_DATA); - if (newm == 0) - goto octeon_rgmx_build_new_rx_mbuf_bad; - len = MLEN; - m = m->m_next = newm; - } - } - - return (m0); - -octeon_rgmx_build_new_rx_mbuf_bad: - - m_freem(m0); - return (NULL); -} - - - -//#define DEBUG_RX 1 - -static void octeon_rgmx_rx_process_work (octeon_wqe_t *work, u_int port) -{ - struct rgmx_softc_dev *sc; - struct ifnet *ifp; - u_int len; - void *data_start, *new_data_start; - struct mbuf *mbuf; - -//#define DEBUG_RX_PKT_DUMP 1 -#ifdef DEBUG_RX_PKT_DUMP - int i; u_char *dc; -#endif - - data_start = octeon_pow_pktptr_to_kbuffer(work->packet_ptr); - -//#define DEBUG_RX2 -#ifdef DEBUG_RX2 - printf(" WQE 0x%X: port:%u ", work, port); - printf(" Grp: %u, %llX Tag: %u %llX type: %u 0x%llx\n", - work->grp, work->grp, work->tag, work->tag, work->tag_type, work->tag_type); -#endif - - if ((port >= OCTEON_RGMX_MIN_PORT) || (port <= OCTEON_RGMX_MAX_PORT)) { - - sc = get_rgmx_softc(port); - - if (!sc || !sc->ifp) { - - printf(" octeon_rgmx_rx_process_work No sc or sc->ifp - port:%u", port); - } else { - - ifp = sc->ifp; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - - if (!work->word2.bits.rcv_error) { - - len = work->len; - - /* - * We cannot pass the same FPA phys-buffer higher up. - * User space will not be able to use this phys-buffer. - * - * Start building a mbuf packet here using data_start & len. - */ - - new_data_start = data_start; - if (!work->word2.bits.not_IP) { - new_data_start = (void *) (((unsigned long) (new_data_start)) + 14); - /* mark it as checksum checked */ - } else { - new_data_start = (void *) (((unsigned long) (new_data_start)) + 8); - } - -#ifdef DEBUG_RX_PKT_DUMP - dc = new_data_start; printf("In:\n"); - for (i = 0; i < len; i++) { if (!(i % 16)) printf ("\n"); printf(" %02X", dc[i]); } -#endif - - mbuf = octeon_rgmx_build_new_rx_mbuf(ifp, new_data_start, len); - if (mbuf) { -// printf(" Passing pkt to ifp: pkt_len: %u len: %u ", mbuf->m_pkthdr.len, mbuf->m_len); -#ifdef DEBUG_RX_PKT_DUMP - - dc = mtod(mbuf, u_char *); printf("\n"); printf("In: "); - for (i = 0; i < mbuf->m_len; i++) { if (!(i % 16)) printf ("\n"); printf(" %02X", dc[i]); } - -#endif - - /* Feed the packet to upper layer. */ - (*ifp->if_input)(ifp, mbuf); - ifp->if_ipackets++; - - } else { /* mbuf error */ - if_printf(ifp, "mbuf rx construct error\n"); - printf(" mbuf rx construct error\n"); - ifp->if_ierrors++; - } /* mbuf error */ - - } else { /* rcv_error */ - ifp->if_ierrors++; - } /* rcv_error */ - - } /* IFF_DRV_RUNNING */ - - } /* sc && sc->ifp */ - - } else { /* port number */ - printf(" rgmx_rx:%u bad port\n", port); - } - - octeon_fpa_free(data_start, OCTEON_FPA_RX_PACKET_POOL, 0); - octeon_fpa_free((void *)work, OCTEON_FPA_WQE_RX_POOL, 0); -} - - - - -/* ------------------------------------------------------------------- * - * octeon_rx_loop() * - * ------------------------------------------------------------------- */ - - -//#define OCTEON_VISUAL_RGMX 1 -#ifdef OCTEON_VISUAL_RGMX -static int where0 = 0; -static int where1 = 0; -#endif - -static void octeon_rx_loop (void *unused) -{ - u_int core_id; - uint64_t prev_grp_mask; - u_int pak_count; - octeon_wqe_t *work; - - core_id = octeon_get_core_num(); - pak_count = 0; - - /* Only allow work for our group */ - prev_grp_mask = oct_read64(OCTEON_POW_CORE_GROUP_MASK(core_id)); - oct_write64(OCTEON_POW_CORE_GROUP_MASK(core_id), OCTEON_POW_ALL_GROUPS_MASK); - - -#ifdef OCTEON_VISUAL_RGMX - octeon_led_run_wheel(&where0, 3); -#endif - while(1) { - - if (pak_count++ > RGMX_MAX_PAK_RECEIVE) { - break; - } - - work = octeon_pow_work_request_sync(OCTEON_POW_WAIT); - - if (work == NULL) { - /* - * No more incoming packets. We can take a break now. - */ - break; - } - -#ifdef OCTEON_VISUAL_RGMX - octeon_led_run_wheel(&where1, 4); -#endif - octeon_rgmx_rx_process_work(work, work->ipprt); - - } - - oct_write64(OCTEON_POW_CORE_GROUP_MASK(core_id), prev_grp_mask); -} - - -static void *octeon_rgmx_write_mbufs_to_fpa_buff (struct rgmx_softc_dev *sc, struct mbuf *m, u_int len) -{ - struct mbuf *mp; - void *data_area; - u_char *write_offset; - - /* - * FIXME - * - * Compare len with max FPA-tx-packet size. Or else we will possibly corrupt the next pkt. - */ - - - /* - * Get an FPA buffer from Xmit-packets FPA pool - */ - data_area = octeon_fpa_alloc(OCTEON_FPA_TX_PACKET_POOL); - if (!data_area) { - /* - * Fail. No room. No resources. - */ - return (NULL); - } - - /* - * Transfer the data from mbuf chain to the transmission buffer. - */ - write_offset = data_area; - for (mp = m; mp != 0; mp = mp->m_next) { - if (mp->m_len) { - bcopy(mtod(mp, caddr_t), write_offset, mp->m_len); - write_offset = (u_char *) (((u_long) write_offset) + mp->m_len); - } - } - return (data_area); -} - - -static u_int octeon_rgmx_pko_xmit_packet (struct rgmx_softc_dev *sc, void *out_buff, u_int len, u_int checksum) -{ - octeon_pko_command_word0_t pko_cmd; - octeon_pko_packet_ptr_t pko_pkt_word; - u_long temp; - u_short xmit_cmd_index; - uint64_t *xmit_cmd_ptr; - uint64_t xmit_cmd_state; - int queue = 0; // we should randomize queue # based on core num. Using same - // queue 0 for this port, by all cores on is less efficient. - - /* - * Prepare the PKO buffer and command word. - * Cmd Buf Word 0 - * No FAU - * Set #-segs and #-bytes - */ - pko_cmd.word64 = 0; - pko_cmd.bits.segs = 1; - pko_cmd.bits.total_bytes = len; - if (checksum) { - pko_cmd.bits.ipoffp1 = ETHER_HDR_LEN + 1; /* IPOffP1 is +1 based. 1 means offset 0 */ - } - - /* - * Build the PKO buffer pointer. PKO Cmd Buf Word 1 - */ - pko_pkt_word.word64 = 0; - pko_pkt_word.bits.addr = OCTEON_PTR2PHYS(out_buff); - pko_pkt_word.bits.pool = OCTEON_FPA_TX_PACKET_POOL; - pko_pkt_word.bits.size = 2048; // dummy. Actual len is above. - -#ifdef DEBUG_TX - printf(" PKO: 0x%llX 0x%llX ", pko_cmd.word64, pko_pkt_word.word64); -#endif - - /* - * Get the queue command ptr location from the per port per queue, pko info struct. - */ - octeon_spinlock_lock(&(sc->outq_ptr[queue].lock)); -#ifdef DEBUG_TX - printf(" xmit: sc->outq_ptr[queue].xmit_command_state: 0x%llX ", sc->outq_ptr[queue].xmit_command_state); -#endif - xmit_cmd_state = sc->outq_ptr[queue].xmit_command_state; - sc->outq_ptr[queue].xmit_command_state = xmit_cmd_state + 2; - - temp = (u_long) (xmit_cmd_state >> OCTEON_PKO_INDEX_BITS); -#ifdef DEBUG_TX - printf(" temp: 0x%X ", temp); -#endif - xmit_cmd_ptr = (uint64_t *) MIPS_PHYS_TO_KSEG0(temp); - xmit_cmd_index = xmit_cmd_state & OCTEON_PKO_INDEX_MASK; - xmit_cmd_ptr += xmit_cmd_index; - - /* - * We end the PKO cmd buffer at odd boundary. Towards the end we will have - * 4 or 3 or 2 or 1 or 0 word remaining. Case of 4, 2, or 0 can never happen. - * We only care when we have 3 words remaining. In this case we write our 2 words - * for PKO command and 3rd word as chain for next PKO cmd buffer. - */ - xmit_cmd_ptr[0] = pko_cmd.word64; - - if (xmit_cmd_index < (OCTEON_FPA_TX_CMDBUF_POOL_WORDS - 2)) { - /* - * Plenty of space left. Write our 2nd word and worry the next time. - */ - xmit_cmd_ptr[1] = pko_pkt_word.word64; - - } else { - /* - * 3 words or less are left. We write our 2nd word now and then put in a chain link - * to new PKO cmd buf. - */ - uint64_t phys_cmd_buf = octeon_fpa_alloc_phys(OCTEON_FPA_TX_CMDBUF_POOL); - - if (!phys_cmd_buf) { - /* - * FPA pool for xmit-buffer-commands is empty. - */ - sc->outq_ptr[queue].xmit_command_state -= 2; - octeon_spinlock_unlock(&(sc->outq_ptr[queue].lock)); - return (0); - } - - xmit_cmd_ptr[1] = pko_pkt_word.word64; - xmit_cmd_ptr[2] = phys_cmd_buf; - - sc->outq_ptr[queue].xmit_command_state = (phys_cmd_buf << OCTEON_PKO_INDEX_BITS); - } - /* - * Unlock queue structures. - */ - octeon_spinlock_unlock(&(sc->outq_ptr[queue].lock)); - - /* - * 2 words incremented in PKO. Ring the doorbell. - */ -#ifdef DEBUG_TX - printf(" Ringing doorbell: Port %u Queue %u words 2", sc->port, octeon_pko_get_base_queue(sc->port) + queue); -#endif - octeon_pko_ring_doorbell(sc->port, octeon_pko_get_base_queue(sc->port) + queue, 2); - - return (1); -} - - -static void octeon_rgmx_xmit_mark_buffers_done(struct rgmx_softc_dev *sc, u_int n); - -static void octeon_rgmx_xmit_mark_buffers_done (struct rgmx_softc_dev *sc, u_int n) -{ - struct mbuf *m; - u_int i; - - for (i = 0; i < n; i++) { - /* - * Remove packets in queue. Leaving a lag of 3, to allow for PKO in-flight xmission - */ - if (_IF_QLEN(&sc->tx_pending_queue) > 4) { - IF_DEQUEUE(&sc->tx_pending_queue, m); - if (!m) { - break; // Queue became empty now. Break out. - } - /* - * Return the mbuf to system. - */ - m_freem(m); - } - } - if (!i) { - return; // Nothing removed from queue. - } - - /* - * The transmitter is no more active. - * Reset output active flag and watchdog timer. - */ - sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; -} - - -#define OCTEON_RGMX_FLUSH_N_XMIT_MBUFS_EACH_LOOP 5 -#define OCTEON_RGMX_FLUSH_PENDING_MBUFS_MAX 1000 - -#ifdef __not_used__ -/* - * octeon_rgmx_output_flush - * - * Drop all packets queued at ifnet layer. - */ -static void octeon_rgmx_output_flush (struct ifnet *ifp) -{ - struct mbuf *m; - u_int max_flush = OCTEON_RGMX_FLUSH_PENDING_MBUFS_MAX; /* Arbitrarily high number */ - - while (max_flush-- && _IF_QLEN(&ifp->if_snd)) { - /* - * Get the next mbuf Packet chain to flush. - */ - IF_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) { - /* No more packets to flush */ - break; - } - _IF_DROP(&ifp->if_snd); - m_freem(m); - ifp->if_oerrors++; - } -} -#endif - -/* - * octeon_rgmx_output_start - * - * Start output on interface. - */ -static void octeon_rgmx_output_start (struct ifnet *ifp) -{ - struct rgmx_softc_dev *sc = ifp->if_softc; - - RGMX_LOCK(sc); - octeon_rgmx_output_start_locked(ifp); - RGMX_UNLOCK(sc); -} - - - -/* - * octeon_rgmx_output_start_locked - * - * Start output on interface. Assume Driver locked - */ -static void octeon_rgmx_output_start_locked (struct ifnet *ifp) -{ - struct rgmx_softc_dev *sc = ifp->if_softc; - struct mbuf *m; - u_int len, need_l4_checksum; - void *out_buff; - - /* - * Take out some of the last queued mbuf's from xmit-pending queue - */ - octeon_rgmx_xmit_mark_buffers_done(sc, OCTEON_RGMX_FLUSH_N_XMIT_MBUFS_EACH_LOOP); - - while (1) { - /* - * See if there is room to put another packet in the buffer. - * We *could* do better job by peeking the send queue to - * know the length of the next packet. Current version just - * tests against the worst case (i.e., longest packet). FIXME. - * - * When adding the packet-peek feature, don't forget adding a - * test on txb_count against QUEUEING_MAX. - * There is a little chance the packet count exceeds - * the limit. Assume transmission buffer is 8KB (2x8KB - * configuration) and an application sends a bunch of small - * (i.e., minimum packet sized) packets rapidly. An 8KB - * buffer can hold 130 blocks of 62 bytes long... - */ - - /* - * If unable to send more. - */ - if (_IF_QLEN(&sc->tx_pending_queue) >= MAX_TX_BUFS) { - printf(" Xmit not possible. NO room %u", _IF_QLEN(&sc->tx_pending_queue)); - goto indicate_active; - } - - - /* - * Get the next mbuf chain for a packet to send. - */ - IF_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) { - /* No more packets to send. */ - goto indicate_inactive; - } - - len = m->m_pkthdr.len; - /* - * Should never send big packets. If such a packet is passed, - * it should be a bug of upper layer. We just ignore it. - * ... Partial (too short) packets, neither. - */ - if (len < ETHER_HDR_LEN || - len > ETHER_MAX_LEN - ETHER_CRC_LEN) { - /* - * Fail. Bad packet size. Return the mbuf to system. - */ - if_printf(ifp, - "got an out-of-spec packet (%u bytes) to send\n", len); - m_freem(m); - goto indicate_active; - } - - /* - * Copy the mbuf chain into the transmission buffer. - * txb_* variables are updated as necessary. - */ - out_buff = octeon_rgmx_write_mbufs_to_fpa_buff(sc, m, len); - if (!out_buff) { - /* - * No FPA physical buf resource. - * Let's requeue it back. And slow it down for a while. - */ - IF_PREPEND(&ifp->if_snd, m); - goto indicate_active; - } - - need_l4_checksum = (m->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP)) ? 1 : 0; - - /* - * put the mbuf onto pending queue - */ -//#define DEBUG_TX_PKT_DUMP 1 -#ifdef DEBUG_TX_PKT_DUMP - int ii; - u_char *dc = out_buff; - - printf("\n"); printf("Out: "); - for (ii = 0; ii < len; ii++) printf(" %X", dc[ii]); printf("\n"); -#endif - - ETHER_BPF_MTAP(ifp, m); - - IF_ENQUEUE(&sc->tx_pending_queue, m); - - /* - * Pass the mbuf data packet to PKO for xmission. - */ - octeon_rgmx_pko_xmit_packet(sc, out_buff, len, need_l4_checksum); - - ifp->if_opackets++; - } - -indicate_inactive: - /* - * We are using the !OACTIVE flag to indicate to - * the outside world that we can accept an - * additional packet rather than that the - * transmitter is _actually_ active. Indeed, the - * transmitter may be active, but if we haven't - * filled all the buffers with data then we still - * want to accept more. - */ - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - return; - - -indicate_active: - /* - * The transmitter is active, and there are no room for - * more outgoing packets in the transmission buffer. - */ - ifp->if_oerrors++; -// sc->mibdata.dot3StatsInternalMacTransmitErrors++; - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return; -} - - - - -/* ------------------------------------------------------------------- * - * octeon_config_hw_units() * - * ------------------------------------------------------------------- * - * - * Initialize Octeon hardware components. To get the RGMX going. - * - */ -static void octeon_config_hw_units_pre_ports (void) -{ - - /* Enable FPA */ - octeon_enable_fpa(); - - /* Enable PKO */ - octeon_pko_enable(); - - /* Init PKO */ - octeon_pko_init(); - - - /* Fill FPA */ - - /* - * Input Buffers Pool - * Pool 0 - */ - octeon_fpa_fill_pool_mem(OCTEON_FPA_RX_PACKET_POOL, OCTEON_FPA_RX_PACKET_POOL_ELEM_SIZE, - OCTEON_FPA_RX_PACKET_POOL_ELEMENTS); - - /* - * WQE Blocks Pool - * Pool 1 - */ - octeon_fpa_fill_pool_mem(OCTEON_FPA_WQE_RX_POOL, OCTEON_FPA_WQE_RX_POOL_ELEM_SIZE, - OCTEON_FPA_WQE_RX_POOL_ELEMENTS); - - /* - * PKO Command Pool - * Pool 3 - */ - octeon_fpa_fill_pool_mem(OCTEON_FPA_TX_CMDBUF_POOL, OCTEON_FPA_TX_CMDBUF_POOL_ELEM_SIZE, - OCTEON_FPA_TX_CMDBUF_POOL_ELEMENTS); - - /* - * Output Buffers Pool - * Pool 2 - */ - octeon_fpa_fill_pool_mem(OCTEON_FPA_TX_PACKET_POOL, OCTEON_FPA_TX_PACKET_POOL_ELEM_SIZE, - OCTEON_FPA_TX_PACKET_POOL_ELEMENTS); - - - - octeon_rgmx_enable_RED_all(OCTEON_FPA_RX_PACKET_POOL_ELEMENTS >> 2, OCTEON_FPA_RX_PACKET_POOL_ELEMENTS >> 3); - - /* Configure IPD */ - octeon_ipd_config(OCTEON_FPA_RX_PACKET_POOL_WORDS, - FIRST_PARTICLE_SKIP / 8, - NOT_FIRST_PARTICLE_SKIP / 8, - FIRST_PARTICLE_SKIP / 128, - NOT_FIRST_PARTICLE_SKIP / 128, - OCTEON_FPA_WQE_RX_POOL, - OCTEON_IPD_OPC_MODE_STF, - ENABLE_BACK_PRESSURE); - - /* - * PKO setup Output Command Buffers - */ - octeon_pko_config_cmdbuf_global_defaults(OCTEON_FPA_TX_CMDBUF_POOL, - OCTEON_FPA_TX_CMDBUF_POOL_ELEM_SIZE); - -} - - - -static void octeon_config_hw_units_port (struct rgmx_softc_dev *sc, u_int port) -{ - const u_int priorities[8] = {8,8,8,8,8,8,8,8}; - u_int total_queues, base_queue; - - octeon_config_rgmii_port(port); - - total_queues = octeon_pko_get_num_queues(port); - base_queue = octeon_pko_get_base_queue(port); - /* Packet output configures Queue and Ports */ - octeon_pko_config_port(port, base_queue, - total_queues, - priorities, - OCTEON_FPA_TX_CMDBUF_POOL, - sc->outq_ptr); - - octeon_rgmx_set_mac(port); - - /* Setup Port input tagging */ - octeon_rgmx_config_pip(port); -} - - -typedef union -{ - uint64_t word64; - struct - { - uint64_t rsvd3 : 35; - uint64_t enable : 1; - uint64_t time_thr : 4; - uint64_t rsvd2 : 1; - uint64_t ds_thr : 11; - uint64_t rsvd : 1; - uint64_t iq_thr : 11; - } bits; -} octeon_rgmx_pow_int_threshold_t; - -typedef union -{ - uint64_t word64; - struct - { - uint64_t rsvd : 36; - uint64_t tc_cnt : 4; - uint64_t ds_cnt : 12; - uint64_t iq_cnt : 12; - } bits; -} octeon_rgmx_pow_int_cnt_t; - -typedef union -{ - uint64_t word64; - struct - { - uint64_t rsvd3 : 4; - uint64_t thr_freq : 28; // R/O - uint64_t rsvd2 : 4; - uint64_t thr_period : 20; - uint64_t rsvd : 8; - } bits; -} octeon_rgmx_pow_int_pc_t; - - -typedef union -{ - uint64_t word64; - struct - { - uint64_t rsvd : 52; - uint64_t nos_cnt : 12; - } bits; -} octeon_rgmx_pow_nos_cnt; - - - -typedef union -{ - uint64_t word64; - struct - { - uint64_t rsvd : 32; - uint64_t inb_pkts : 32; - } bits; -} octeon_rgmx_pip_inb_pkts; - -typedef union -{ - uint64_t word64; - struct - { - uint64_t rsvd : 48; - uint64_t inb_errs : 16; - } bits; -} octeon_rgmx_pip_inb_errs; - - - -typedef union -{ - uint64_t word64; - struct - { - uint64_t rsvd : 32; - uint64_t iq_cnt : 32; - } bits; -} octeon_pow_inpt_q_all_qos; - - - -typedef union -{ - uint64_t word64; - struct - { - uint64_t rsvd : 32; - uint64_t iq_cnt : 32; - } bits; -} octeon_pow_inpt_q_grp_qos; - - -static void octeon_config_hw_units_post_ports (void) -{ - - octeon_rgmx_pow_int_threshold_t thr; - octeon_rgmx_pow_int_pc_t intpc; - - thr.word64 = 0; - intpc.word64 = 0; - intpc.bits.thr_freq = (500 * 1000 * 1000) / (1000 * 16 * 256); - -#ifdef OCTEON_RGMX_POW_TIME_THR_INTS - thr.bits.enable = 1; - thr.bits.time_thr = 0xf; - oct_write64(OCTEON_POW_WORKQUEUE_INT_THRESHOLD(OCTEON_POW_RX_GROUP_NUM), thr.word64); - - oct_write64(OCTEON_POW_WORKQUEUE_INT_PC, intpc.word64); - -#else - thr.bits.ds_thr = thr.bits.iq_thr = 1; // Only if doing absolute queue-cnt interrupts. - oct_write64(OCTEON_POW_WORKQUEUE_INT_THRESHOLD(OCTEON_POW_RX_GROUP_NUM), thr.word64); -#endif - - ciu_enable_interrupts(PCPU_GET(cpuid), OCTEON_RGMX_CIU_INTX, OCTEON_RGMX_CIU_ENX, - (OCTEON_POW_RX_GROUP_MASK | - CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)), CIU_MIPS_IP2); - - ciu_clear_int_summary(CIU_THIS_CORE, OCTEON_RGMX_CIU_INTX, - OCTEON_RGMX_CIU_ENX, CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)); - - octeon_ciu_start_gtimer(CIU_GENTIMER_NUM_1, OCTEON_GENTIMER_PERIODIC, - OCTEON_GENTIMER_LEN_1SEC); - /* - * Enable IPD - */ - octeon_ipd_enable(); -} - - - - - -static void octeon_rgmx_config_pip (u_int port) -{ - octeon_pip_gbl_cfg_t pip_config; - octeon_pip_port_cfg_t pip_port_config; - octeon_pip_port_tag_cfg_t pip_tag_config; - - /* - * PIP Global config - */ - pip_config.word64 = 0; - pip_config.bits.max_l2 = 1; - oct_write64(OCTEON_PIP_GBL_CFG, pip_config.word64); - - /* - * PIP Port config - */ - pip_port_config.word64 = 0; - pip_port_config.bits.mode = OCTEON_PIP_PORT_CFG_MODE_SKIPL2; - pip_port_config.bits.qos = port & 0x7; - pip_port_config.bits.crc_en = 1; - - - /* - * PIP -> POW tags config - * - * We don't use any pkt input fields for tag hash, except for Port# - */ - pip_tag_config.word64 = 0; - - pip_tag_config.bits.grptag = 0; - pip_tag_config.bits.grptagmask = 0xf; - pip_tag_config.bits.grptagbase = 1; - - pip_tag_config.bits.ip6_src_flag = 0; - pip_tag_config.bits.ip6_dst_flag = 0; - pip_tag_config.bits.ip6_sprt_flag = 0; - pip_tag_config.bits.ip6_dprt_flag = 0; - pip_tag_config.bits.ip6_nxth_flag = 0; - - pip_tag_config.bits.ip4_src_flag = 1; - pip_tag_config.bits.ip4_dst_flag = 1; - pip_tag_config.bits.ip4_sprt_flag = 1; - pip_tag_config.bits.ip4_dprt_flag = 1; - pip_tag_config.bits.ip4_pctl_flag = 1; - - pip_tag_config.bits.tcp6_tag_type = 0; - pip_tag_config.bits.tcp4_tag_type = 0; - pip_tag_config.bits.ip6_tag_type = 0; - pip_tag_config.bits.ip4_tag_type = 0; - pip_tag_config.bits.inc_prt_flag = 1; - pip_tag_config.bits.non_tag_type = OCTEON_POW_TAG_TYPE_NULL; - pip_tag_config.bits.grp = OCTEON_POW_RX_GROUP_NUM; - - octeon_pip_config_port(port, pip_port_config, pip_tag_config); - - oct_write64(OCTEON_POW_CORE_GROUP_MASK(OUR_CORE), OCTEON_POW_ALL_GROUPS_MASK); - -} - - -/* - * octeon_rgmx_stop_port - * - */ -static u_int octeon_rgmx_stop_port (u_int port) -{ - int interface = INTERFACE(port); - int index = INDEX(port); - octeon_rgmx_prtx_cfg_t gmx_cfg; - u_int last_enabled = 0; - - gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, interface)); - last_enabled = (gmx_cfg.bits.en == 1); - gmx_cfg.bits.en = 0; - oct_write64(OCTEON_RGMX_PRTX_CFG(index, interface), gmx_cfg.word64); - return (last_enabled); -} - -static void octeon_rgmx_start_port(u_int port) -{ - int interface = INTERFACE(port); - int index = INDEX(port); - octeon_rgmx_prtx_cfg_t gmx_cfg; - - gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, interface)); - gmx_cfg.bits.en = 1; - oct_write64(OCTEON_RGMX_PRTX_CFG(index, interface), gmx_cfg.word64); -} - - -static void octeon_rgmx_stop (struct rgmx_softc_dev *sc) -{ - octeon_rgmx_stop_port(sc->port); - - /* Reset transmitter variables and interface flags. */ - sc->ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); - sc->txb_count = 0; - sc->txb_sched = 0; -} - - -/* Change the media selection. */ -static int octeon_rgmx_medchange (struct ifnet *ifp) -{ - struct rgmx_softc_dev *sc = ifp->if_softc; - -#ifdef DIAGNOSTIC - /* If_media should not pass any request for a media which this - interface doesn't support. */ - int b; - - for (b = 0; bit2media[b] != 0; b++) { - if (bit2media[b] == sc->media.ifm_media) break; - } - if (((1 << b) & sc->mbitmap) == 0) { - if_printf(sc->ifp, - "got an unsupported media request (0x%x)\n", - sc->media.ifm_media); - return EINVAL; - } -#endif - - /* We don't actually change media when the interface is down. - fe_init() will do the job, instead. Should we also wait - until the transmission buffer being empty? Changing the - media when we are sending a frame will cause two garbages - on wires, one on old media and another on new. FIXME */ - if (sc->ifp->if_flags & IFF_UP) { - printf(" Media change requested while IF is up\n"); - } else { - printf(" Media change requested while IF is Down\n"); - } - - return 0; -} - - -static void octeon_rgmx_medstat (struct ifnet *ifp, struct ifmediareq *ifm) -{ - struct rgmx_softc_dev *sc = ifp->if_softc; - octeon_rgmx_rxx_rx_inbnd_t link_status; - - octeon_rgmx_config_speed(sc->port, 1); - - RGMX_LOCK(sc); - - ifm->ifm_status = IFM_AVALID; - ifm->ifm_active = IFM_ETHER; - - /* - * Parse link status. - */ - link_status.word64 = sc->link_status; - - if (!link_status.bits.status) { - RGMX_UNLOCK(sc); - return; - } - - ifm->ifm_status |= IFM_ACTIVE; - - switch (link_status.bits.speed) { - case 0: - ifm->ifm_active |= IFM_10_T; - break; - case 1: - ifm->ifm_active |= IFM_100_TX; - break; - case 2: - ifm->ifm_active |= IFM_1000_T;; - break; - default: - /* Unknown! */ - break; - } - - /* - * Check duplex. - */ - if (link_status.bits.duplex == 1) - ifm->ifm_active |= IFM_FDX; - else - ifm->ifm_active |= IFM_HDX; - - RGMX_UNLOCK(sc); -} - -static void octeon_rgmx_config_cam(struct ifnet *ifp) -{ - struct rgmx_softc_dev *sc = ifp->if_softc; - u_int port = sc->port; - int index = INDEX(port); - int iface = INTERFACE(port); - u_int last_enabled; - uint64_t adr_ctl; - - last_enabled = octeon_rgmx_stop_port(port); - - adr_ctl = oct_read64(OCTEON_RGMX_RXX_ADR_CTL(index, iface)); - - /* - * Always accept broadcast traffic. - */ - if ((adr_ctl & OCTEON_RGMX_ADRCTL_ACCEPT_BROADCAST) == 0) - adr_ctl |= OCTEON_RGMX_ADRCTL_ACCEPT_BROADCAST; - - /* - * Accept all multicast in all multicast mode and in - * promiscuous mode. - * - * XXX Since we don't handle programming the CAM for - * multicast filtering, always accept all multicast. - */ - adr_ctl &= ~OCTEON_RGMX_ADRCTL_REJECT_ALL_MULTICAST; - adr_ctl |= OCTEON_RGMX_ADRCTL_ACCEPT_ALL_MULTICAST; - - /* - * In promiscuous mode, the CAM is shut off, so reject everything. - * Otherwise, filter using the CAM. - */ - if ((ifp->if_flags & IFF_PROMISC) != 0) { - adr_ctl &= ~OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC; - adr_ctl |= OCTEON_RGMX_ADRCTL_CAM_MODE_REJECT_DMAC; - } else { - adr_ctl &= ~OCTEON_RGMX_ADRCTL_CAM_MODE_REJECT_DMAC; - adr_ctl |= OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC; - } - - oct_write64(OCTEON_RGMX_RXX_ADR_CTL(index, iface), adr_ctl); - - /* - * If in promiscuous mode, disable the CAM. - */ - if ((ifp->if_flags & IFF_PROMISC) != 0) - oct_write64(OCTEON_RGMX_RXX_ADR_CAM_EN(index, iface), 0); - else - oct_write64(OCTEON_RGMX_RXX_ADR_CAM_EN(index, iface), 1); - - if (last_enabled) octeon_rgmx_start_port(port); -} - -static int octeon_rgmx_ioctl (struct ifnet * ifp, u_long command, caddr_t data) -{ - struct rgmx_softc_dev *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - int error = 0; - - if (!sc) { - printf(" octeon_rgmx_ioctl. No sc\n"); - return (0); - } - switch (command) { - - case SIOCSIFFLAGS: - /* - * Switch interface state between "running" and - * "stopped", reflecting the UP flag. - */ - if (ifp->if_flags & IFF_UP) { - /* - * New state is IFF_UP - * Restart or Start now, if driver is not running currently. - */ - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - octeon_rgmx_init(sc); - } - octeon_rgmx_config_cam(ifp); - } else { - /* - * New state is IFF_DOWN. - * Stop & shut it down now, if driver is running currently. - */ - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { - octeon_rgmx_stop(sc); - } - } - break; - - case SIOCADDMULTI: - case SIOCDELMULTI: - break; - - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - /* Let if_media to handle these commands and to call - us back. */ - error = ifmedia_ioctl(ifp, ifr, &sc->media, command); - break; - - case SIOCSIFCAP: - { - int mask; - - ifp->if_hwassist &= ~CSUM_TSO; - ifp->if_capenable &= ~IFCAP_VLAN_HWTAGGING; - mask = ifr->ifr_reqcap ^ ifp->if_capenable; - if (mask & IFCAP_HWCSUM) { - ifp->if_capenable ^= IFCAP_HWCSUM; - if (ifp->if_capenable & IFCAP_TXCSUM) { - ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); - } else { - ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP); - } - } - } - break; - - default: - error = ether_ioctl(ifp, command, data); - break; - } - - return (error); -} - -static void octeon_rgmx_init (void *xsc) -{ - struct rgmx_softc_dev *sc = xsc; - - /* Enable interrupts. */ - /* For RGMX they are already enabled earlier */ - - /* Enable transmitter and receiver. */ - /* For RGMX they are already enabled earlier */ - - /* Flush out all HW receive buffers for this interface. */ - /* For RGMX, no means to flush an individual port */ - - /* Set 'running' flag, because we are now running. */ - sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; - - /* Set the HW Address filter. aka program Mac-addr & Multicast filters */ - /* For RGMX this was taken care of via set_mac_addr() */ - - /* Kick start the output */ - /* Hopefully PKO is running and will pick up packets via the timer or receive loop */ - - /* Set link status. */ - octeon_rgmx_config_speed(sc->port, 1); -} - - - -static void octeon_rgmx_config_speed (u_int port, u_int report_link) -{ - int index = INDEX(port); - int iface = INTERFACE(port); - struct rgmx_softc_dev *sc; - octeon_rgmx_rxx_rx_inbnd_t link_status, old_link_status; - octeon_rgmx_prtx_cfg_t gmx_cfg; - uint64_t val64_tx_clk, val64_tx_slot, val64_tx_burst; - u_int last_enabled; - - sc = get_rgmx_softc(port); - if (!sc) { - printf(" config_speed didn't find sc int:%u port:%u", iface, port); - return; - } - - /* - * Look up interface-port speed params - */ - link_status.word64 = oct_read64(OCTEON_RGMX_RXX_RX_INBND(index, iface)); - - RGMX_LOCK(sc); - - /* - * Compre to prev known state. If same then nothing to do. - */ - if (link_status.word64 == sc->link_status) { - RGMX_UNLOCK(sc); - return; - } - old_link_status.word64 = sc->link_status; - - /* - * Compare to previous state modulo link status. If only link - * status is different, we don't need to change media. - */ - if (old_link_status.bits.duplex != link_status.bits.duplex || - old_link_status.bits.speed != link_status.bits.speed) { - last_enabled = octeon_rgmx_stop_port(port); - - gmx_cfg.word64 = oct_read64(OCTEON_RGMX_PRTX_CFG(index, iface)); - - /* - * Duplex - * XXX Set based on link_status.bits.duplex? - */ - gmx_cfg.bits.duplex = 1; - - switch (link_status.bits.speed) { - case 0: /* 10Mbps */ - gmx_cfg.bits.speed = 0; - gmx_cfg.bits.slottime = 0; - val64_tx_clk = 50; val64_tx_slot = 0x40; val64_tx_burst = 0; - break; - - case 1: /* 100Mbps */ - gmx_cfg.bits.speed = 0; - gmx_cfg.bits.slottime = 0; - val64_tx_clk = 5; val64_tx_slot = 0x40; val64_tx_burst = 0; - break; - - case 2: /* 1Gbps */ - gmx_cfg.bits.speed = 1; - gmx_cfg.bits.slottime = 1; - val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000; - break; - - case 3: /* ?? */ - default: - gmx_cfg.bits.speed = 1; - gmx_cfg.bits.slottime = 1; - val64_tx_clk = 1; val64_tx_slot = 0x200; val64_tx_burst = 0x2000; - break; - } - - oct_write64(OCTEON_RGMX_TXX_CLK(index, iface), val64_tx_clk); - oct_write64(OCTEON_RGMX_TXX_SLOT(index, iface), val64_tx_slot); - oct_write64(OCTEON_RGMX_TXX_BURST(index, iface), val64_tx_burst); - - oct_write64(OCTEON_RGMX_PRTX_CFG(index, iface), gmx_cfg.word64); - - if (last_enabled) octeon_rgmx_start_port(port); - } - - /* - * Now check and possibly change link status. - */ - if (link_status.bits.status != old_link_status.bits.status) { - if (report_link) { - if (link_status.bits.status) { - if_link_state_change(sc->ifp, LINK_STATE_UP); - } else { - if_link_state_change(sc->ifp, LINK_STATE_DOWN); - } - } - } - - if (report_link) { - sc->link_status = link_status.word64; - } else { - /* - * We can't update link status proper since we can't - * change it in the interface, so keep the old link - * status intact but note the current speed and duplex - * settings. - */ - link_status.bits.status = old_link_status.bits.status; - sc->link_status = link_status.word64; - } - - RGMX_UNLOCK(sc); -} - - - -#ifdef DEBUG_RGMX_DUMP -static void octeon_dump_rgmx_stats (u_int port) -{ - -} -#endif - -#ifdef __not_used__ -static void rgmx_timer_periodic (void) -{ - u_int port; - int index; - struct rgmx_softc_dev *sc; - struct ifnet *ifp; - - for (index = 0; index < OCTEON_RGMX_NUM_PORTS_MAX; index ++) { - - port = port_array[index]; - sc = rgmx_scdev_array[index]; - - /* - * Skip over ports/slots not in service. - */ - if ((port < OCTEON_RGMX_MIN_PORT) || (port > OCTEON_RGMX_MAX_PORT)) { - continue; - } - if ((NULL == sc) || (((struct rgmx_softc_dev *)-1) == sc)) { - continue; - } - - /* - * Now look for anamolous conditions - */ - if (sc != get_rgmx_softc(port)) { - printf(" port %u sc %p not in sync with index: %u\n", - port, sc, index); - continue; - } - - if (sc->port != port) { - printf(" port %u sc %p port-> %u not in sync with index: %u\n", - port, sc, sc->port, index); - continue; - } - - ifp = sc->ifp; - if (ifp == NULL) { - printf(" port %u sc %p . Bad ifp %p\n", port, sc, ifp); - continue; - } - - /* - * Check if packets queued at ifnet layer. Kick start output if we can. - */ - if (sc->ifp->if_flags & IFF_UP) { - octeon_rgmx_output_start(ifp); - } else { - octeon_rgmx_output_flush(ifp); - } - - /* - * Check if line status changed ? Adjust ourselves. - */ - octeon_rgmx_config_speed(port, 1); - } -} -#endif - -#ifdef DEBUG_RGMX_DUMP -static void octeon_dump_pow_stats(void) -{ - octeon_rgmx_pow_nos_cnt nos_cnt; - octeon_rgmx_pow_int_pc_t intpc; - octeon_rgmx_pow_int_threshold_t thr; - octeon_rgmx_pow_int_cnt_t int_cnt; - int core = octeon_get_core_num(); - octeon_pow_inpt_q_all_qos inpt_q_all; - octeon_pow_inpt_q_grp_qos inpt_q_grp; - octeon_rgmx_pip_inb_pkts pkts; - octeon_rgmx_pip_inb_errs errs; - static u_int pkts0 = 0; - static u_int pkts1 = 0; - static u_int errs0 = 0; - static u_int errs1 = 0; - int i; - - - nos_cnt.word64 = oct_read64(OCTEON_RGMX_POW_NOS_CNT); - if (nos_cnt.bits.nos_cnt) printf(" *** No sched cnt %u\n", nos_cnt.bits.nos_cnt); - printf(" \nGroup mask: 0x%llX WorkQueue Int : 0x%llX\n", oct_read64(OCTEON_POW_CORE_GROUP_MASK(OUR_CORE)), oct_read64(OCTEON_POW_WORKQUEUE_INT)); - intpc.word64 = oct_read64(OCTEON_POW_WORKQUEUE_INT_PC); - printf(" Intr Periodic Cntr: PC %u thr: %u\n", intpc.bits.thr_freq, intpc.bits.thr_period); - thr.word64 = oct_read64(OCTEON_POW_WORKQUEUE_INT_THRESHOLD(OCTEON_POW_RX_GROUP_NUM)); - printf(" Thresholds iq %u ds %u time %u enable %u\n", - thr.bits.iq_thr, thr.bits.ds_thr, thr.bits.time_thr, thr.bits.enable); - int_cnt.word64 = oct_read64(OCTEON_POW_INT_CNTR(core)); - printf(" Int_cnt iq_cnt %u ds_cnt %u tc_cnt %u\n", - int_cnt.bits.iq_cnt, int_cnt.bits.ds_cnt, int_cnt.bits.tc_cnt); - pkts.word64 = oct_read64(OCTEON_PIP_STAT_INB_PKTS(16)); pkts0 += pkts.bits.inb_pkts; - errs.word64 = oct_read64(OCTEON_PIP_STAT_INB_ERRS(16)); errs0 += errs.bits.inb_errs; - pkts.word64 = oct_read64(OCTEON_PIP_STAT_INB_PKTS(17)); pkts1 += pkts.bits.inb_pkts; - errs.word64 = oct_read64(OCTEON_PIP_STAT_INB_ERRS(17)); errs1 += errs.bits.inb_errs; - printf(" PIP inbound pkts(16): %u Errors: %u inbound(17): %u Errors: %u\n", pkts0, errs0, pkts1, errs1); - inpt_q_all.word64 = oct_read64(OCTEON_POW_INPT_Q_ALL_QOS); - printf(" All queued pkt in qos Levels: %u -- ", inpt_q_all.bits.iq_cnt); - for (i = 0 ; i < 7; i++) { - inpt_q_grp.word64 = oct_read64(OCTEON_POW_INPT_QOS_GRP(i)); - if (inpt_q_grp.bits.iq_cnt) printf(" Grp-%u: %u ", i, inpt_q_grp.bits.iq_cnt); - } -} -#endif - -/* ------------------------------------------------------------------- * - * octeon_line_status_loop() * - * ------------------------------------------------------------------- */ -static void octeon_line_status_loop (void *unused) -{ - struct rgmx_softc_dev *sc; - u_int idx; - - for (idx = 0; idx < num_devices; idx++) { - sc = rgmx_scdev_array[idx]; - if (sc && sc->ifp) { - if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)) { - octeon_rgmx_config_speed(sc->port, 1); - - octeon_rgmx_output_start(sc->ifp); - } - } - } - -//#define DEBUG_RGMX_DUMP -#ifdef DEBUG_RGMX_DUMP - static int count = 0; - - if (++count > 5) { - count = 0; -// octeon_dump_fpa_pool(OCTEON_FPA_RX_PACKET_POOL); -// octeon_dump_fpa_pool(OCTEON_FPA_WQE_RX_POOL); -// octeon_dump_fpa_pool(OCTEON_FPA_TX_PACKET_POOL); - octeon_dump_rgmx_stats(16); - octeon_dump_pow_stats(); - } -#endif -} - - -/* ------------------------------------------------------------------- * - * octeon_rgmx_set_mac * - * ------------------------------------------------------------------- * - * - * octeon_rgmx_set_mac - * - * Program the ethernet HW address - * - */ -static void octeon_rgmx_set_mac (u_int port) -{ - struct rgmx_softc_dev *sc; - u_int iface = INTERFACE(port); - u_int index = INDEX(port); - int ii; - uint64_t mac = 0; - u_int last_enabled; - - sc = get_rgmx_softc(port); - if (!sc) { - printf(" octeon_rgmx_set_mac Missing sc. port:%u", port); - return; - } - - for (ii = 0; ii < 6; ii++) { - mac = (mac << 8) | (uint64_t)(sc->ieee[ii]); - } - - last_enabled = octeon_rgmx_stop_port(port); - - oct_write64(OCTEON_RGMX_SMACX(index, iface), mac); - oct_write64(OCTEON_RGMX_RXX_ADR_CAM0(index, iface), sc->ieee[0]); - oct_write64(OCTEON_RGMX_RXX_ADR_CAM1(index, iface), sc->ieee[1]); - oct_write64(OCTEON_RGMX_RXX_ADR_CAM2(index, iface), sc->ieee[2]); - oct_write64(OCTEON_RGMX_RXX_ADR_CAM3(index, iface), sc->ieee[3]); - oct_write64(OCTEON_RGMX_RXX_ADR_CAM4(index, iface), sc->ieee[4]); - oct_write64(OCTEON_RGMX_RXX_ADR_CAM5(index, iface), sc->ieee[5]); - oct_write64(OCTEON_RGMX_RXX_ADR_CTL(index, iface), - OCTEON_RGMX_ADRCTL_ACCEPT_BROADCAST | - OCTEON_RGMX_ADRCTL_ACCEPT_ALL_MULTICAST | - OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC); - oct_write64(OCTEON_RGMX_RXX_ADR_CAM_EN(index, iface), 1); - if (last_enabled) octeon_rgmx_start_port(port); -} - - -/* ------------------------------------------------------------------- * - * octeon_config_rgmii_port() * - * ------------------------------------------------------------------- */ -static void octeon_config_rgmii_port (u_int port) -{ - u_int iface = INTERFACE(port); - u_int index = INDEX(port); - - /* - * Configure an RGMII port - */ - octeon_rgmx_prtx_cfg_t gmx_cfg; - - /* Enable ASX */ - oct_write64(OCTEON_ASXX_RX_PRT_EN(iface), oct_read64(OCTEON_ASXX_RX_PRT_EN(iface)) | (1<sc_dev; - - /* - * Make sure that sc/dev are the parent Root structs. Not one - * of the rgmxN childs. - */ - if (int_handler_tag != NULL) { - bus_teardown_intr(dev, irq_res, int_handler_tag); - int_handler_tag = NULL; - } - -#ifdef OCTEON_RGMX_SCHEDULED_ISRS - if (tq != NULL) { - taskqueue_drain(tq, &rxtx_isr_task); - taskqueue_drain(taskqueue_fast, &link_isr_task); - taskqueue_free(tq); - tq = NULL; - } -#endif - -} -#endif - -static device_method_t rgmii_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, rgmii_probe), - DEVMETHOD(device_identify, rgmii_identify), - DEVMETHOD(device_attach, rgmii_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - { 0, 0 } -}; - -static driver_t rgmii_driver = { - "rgmii", rgmii_methods, sizeof(struct rgmx_softc_dev) -}; - -static devclass_t rgmii_devclass; - -DRIVER_MODULE(rgmii, nexus, rgmii_driver, rgmii_devclass, 0, 0); Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_rgmx.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fpa.c =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fpa.c (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fpa.c (nonexistent) @@ -1,230 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/*------------------------------------------------------------------ - * octeon_fpa.c Free Pool Allocator - * - *------------------------------------------------------------------ - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - - -#include -#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, (unsigned long long)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, (unsigned long long)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 %p 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: %p = %p\n", - pool, elem_num, elem_size_bytes, block_size, memory, - (void *)(intptr_t)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: %p Phys %p Bytes %u\n", block, memory, - (void *)(intptr_t)OCTEON_PTR2PHYS(memory), elem_size_bytes); - block++; -#endif - octeon_fpa_free(memory, pool, 0); - memory = (void *) (((u_long) memory) + block_size); - } -} - Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fpa.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fpa.h =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fpa.h (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fpa.h (nonexistent) @@ -1,259 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/* $FreeBSD$ */ - -/*------------------------------------------------------------------ - * 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 - */ -/*XXX mips64 issue */ - return ((void *) MIPS_PHYS_TO_KSEG0(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)))); -} - -#endif /* ___OCTEON_FPA__H___ */ Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fpa.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_ipd.c =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_ipd.c (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_ipd.c (nonexistent) @@ -1,148 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/*------------------------------------------------------------------ - * octeon_ipd.c Input Packet Unit - * - *------------------------------------------------------------------ - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#include -#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); -} Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_ipd.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_ipd.h =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_ipd.h (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_ipd.h (nonexistent) @@ -1,204 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/* $FreeBSD$ */ - -/*------------------------------------------------------------------ - * 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___ */ Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_ipd.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fau.h =================================================================== --- user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fau.h (revision 211690) +++ user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fau.h (nonexistent) @@ -1,220 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/* $FreeBSD$ */ - -/*------------------------------------------------------------------ - * 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); -} - - -#endif /* ___OCTEON_FAU__H___ */ Property changes on: user/imp/tbemd/sys/mips/cavium/dev/rgmii/octeon_fau.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property