1 /***********************license start***************
2 * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * * Neither the name of Cavium Networks nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written
23 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
25 * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
26 * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
27 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
28 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
29 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
30 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
31 * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT
32 * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
35 * For any questions regarding licensing please contact marketing@caviumnetworks.com
37 ***********************license end**************************************/
41 /*------------------------------------------------------------------
42 * octeon_rgmx.h RGMII Ethernet Interfaces
44 *------------------------------------------------------------------
48 #ifndef ___OCTEON_RGMX__H___
49 #define ___OCTEON_RGMX__H___
53 #define OCTEON_FPA_PACKET_POOL 0
54 #define OCTEON_FPA_WQE_RX_POOL 1
55 #define OCTEON_FPA_OUTPUT_BUFFER_POOL 2
56 #define OCTEON_FPA_WQE_POOL_SIZE (1 * OCTEON_CACHE_LINE_SIZE)
57 #define OCTEON_FPA_OUTPUT_BUFFER_POOL_SIZE (8 * OCTEON_CACHE_LINE_SIZE)
58 #define OCTEON_FPA_PACKET_POOL_SIZE (16 * OCTEON_CACHE_LINE_SIZE)
60 #define OCTEON_POW_WORK_REQUEST(wait) (0x8001600000000000ull | (wait<<3))
77 * Work queue entry format
83 uint64_t next_ptr : 40;
88 uint64_t tag_type : 3;
96 uint64_t ip_offset : 8;
97 uint64_t vlan_valid : 1;
98 uint64_t unassigned : 2;
99 uint64_t vlan_cfi : 1;
100 uint64_t vlan_id :12;
101 uint64_t unassigned2 :12;
102 uint64_t dec_ipcomp : 1;
103 uint64_t tcp_or_udp : 1;
104 uint64_t dec_ipsec : 1;
106 uint64_t software : 1;
107 uint64_t L4_error : 1;
108 uint64_t is_frag : 1;
110 uint64_t is_bcast : 1;
111 uint64_t is_mcast : 1;
113 uint64_t rcv_error : 1;
114 uint64_t err_code : 8;
120 uint64_t vlan_valid : 1;
121 uint64_t unassigned : 2;
122 uint64_t vlan_cfi : 1;
123 uint64_t vlan_id :12;
124 uint64_t unassigned2 :16;
125 uint64_t software : 1;
126 uint64_t unassigned3 : 1;
127 uint64_t is_rarp : 1;
129 uint64_t is_bcast : 1;
130 uint64_t is_mcast : 1;
132 uint64_t rcv_error : 1;
133 uint64_t err_code : 8;
136 octeon_buf_ptr_t packet_ptr;
137 uint8_t packet_data[96];
144 uint64_t scraddr : 8; /**< the (64-bit word) location in scratchpad to write to (if len != 0) */
145 uint64_t len : 8; /**< the number of words in the response (0 => no response) */
146 uint64_t did : 8; /**< the ID of the device on the non-coherent bus */
148 uint64_t wait : 1; /**< if set, don't return load response until work is available */
149 uint64_t unused2 : 3;
152 } octeon_pow_iobdma_store_t;
156 * Wait flag values for pow functions.
161 OCTEON_POW_NO_WAIT = 0,
166 static inline void * phys_to_virt (unsigned long address)
168 return (void *)(address + 0x80000000UL);
171 // decode within DMA space
173 OCTEON_ADD_WIN_DMA_ADD = 0L, // add store data to the write buffer entry, allocating it if necessary
174 OCTEON_ADD_WIN_DMA_SENDMEM = 1L, // send out the write buffer entry to DRAM
175 // store data must be normal DRAM memory space address in this case
176 OCTEON_ADD_WIN_DMA_SENDDMA = 2L, // send out the write buffer entry as an IOBDMA command
177 // see OCTEON_ADD_WIN_DMA_SEND_DEC for data contents
178 OCTEON_ADD_WIN_DMA_SENDIO = 3L, // send out the write buffer entry as an IO write
179 // store data must be normal IO space address in this case
180 OCTEON_ADD_WIN_DMA_SENDSINGLE = 4L, // send out a single-tick command on the NCB bus
181 // no write buffer data needed/used
182 } octeon_add_win_dma_dec_t;
185 #define OCTEON_OCT_DID_FPA 5ULL
186 #define OCTEON_OCT_DID_TAG 12ULL
187 #define OCTEON_OCT_DID_TAG_SWTAG OCTEON_ADDR_FULL_DID(OCTEON_OCT_DID_TAG, 0ULL)
190 #define OCTEON_IOBDMA_OFFSET (-3*1024ll)
191 #define OCTEON_IOBDMA_SEP 16
192 #define OCTEON_IOBDMA_SENDSINGLE (OCTEON_IOBDMA_OFFSET + \
193 (OCTEON_ADD_WIN_DMA_SENDSINGLE *\
196 static inline void octeon_send_single (uint64_t data)
198 oct_write64((uint64_t)(OCTEON_IOBDMA_SENDSINGLE * (long long)8), data);
202 static inline void octeon_pow_work_request_async_nocheck (int scratch_addr,
203 octeon_pow_wait_t wait)
205 octeon_pow_iobdma_store_t data;
207 /* scratch_addr must be 8 byte aligned */
208 data.bits.scraddr = scratch_addr >> 3;
210 data.bits.did = OCTEON_OCT_DID_TAG_SWTAG;
211 data.bits.wait = wait;
212 octeon_send_single(data.word64);
218 * octeon_gmx_inf_mode
220 * GMX_INF_MODE = Interface Mode
226 struct gmxx_inf_mode_s
228 uint64_t reserved_3_63 : 61;
229 uint64_t p0mii : 1; /**< Port 0 Interface Mode
232 uint64_t en : 1; /**< Interface Enable */
233 uint64_t type : 1; /**< Interface Mode
237 struct gmxx_inf_mode_cn3020
239 uint64_t reserved_2_63 : 62;
240 uint64_t en : 1; /**< Interface Enable */
241 uint64_t type : 1; /**< Interface Mode
242 0: All three ports are RGMII ports
243 1: prt0 is RGMII, prt1 is GMII, and prt2 is unused */
245 struct gmxx_inf_mode_s cn30xx;
246 struct gmxx_inf_mode_cn3020 cn31xx;
247 struct gmxx_inf_mode_cn3020 cn36xx;
248 struct gmxx_inf_mode_cn3020 cn38xx;
249 struct gmxx_inf_mode_cn3020 cn38xxp2;
250 struct gmxx_inf_mode_cn3020 cn56xx;
251 struct gmxx_inf_mode_cn3020 cn58xx;
252 } octeon_gmxx_inf_mode_t;
260 uint64_t reserved : 60; /* Reserved */
261 uint64_t slottime : 1; /* Slot Time for Half-Duplex */
262 /* operation - 0 = 512 bitimes (10/100Mbs operation) */
263 /* - 1 = 4096 bitimes (1000Mbs operation) */
264 uint64_t duplex : 1; /* Duplex - 0 = Half Duplex */
265 /* (collisions/extentions/bursts) - 1 = Full Duplex */
266 uint64_t speed : 1; /* Link Speed - 0 = 10/100Mbs */
267 /* operation - 1 = 1000Mbs operation */
268 uint64_t en : 1; /* Link Enable */
270 } octeon_rgmx_prtx_cfg_t;
274 * GMX_RX_INBND = RGMX InBand Link Status
280 uint64_t reserved : 60; /* Reserved */
281 uint64_t duplex : 1; /* 0 = Half, 1 = Full */
282 uint64_t speed : 2; /* Inbound Link Speed */
283 /* 00 = 2.5Mhz, 01 = 25Mhz */
284 /* 10 = 125MHz, 11 = Reserved */
285 uint64_t status : 1; /* Inbound Status Up/Down */
287 } octeon_rgmx_rxx_rx_inbnd_t;
295 uint64_t all_drop : 32;
296 uint64_t slow_drop : 32;
298 } octeon_rgmx_ipd_queue_red_marks_t;
305 uint64_t reserved : 15;
306 uint64_t use_pagecount : 1;
307 uint64_t new_con : 8;
308 uint64_t avg_con : 8;
309 uint64_t prb_con : 32;
311 } octeon_rgmx_ipd_red_q_param_t;
319 uint64_t reserved : 46;
320 uint64_t bp_enable : 1;
321 uint64_t page_count : 17;
323 } octeon_ipd_port_bp_page_count_t;
330 uint64_t prb_dly : 14;
331 uint64_t avg_dly : 14;
332 uint64_t port_enable : 36;
334 } octeon_ipd_red_port_enable_t;
338 * Tag type definitions
342 OCTEON_POW_TAG_TYPE_ORDERED = 0L, /**< Tag ordering is maintained */
343 OCTEON_POW_TAG_TYPE_ATOMIC = 1L, /**< Tag ordering is maintained, and at most one PP has the tag */
344 OCTEON_POW_TAG_TYPE_NULL = 2L, /**< The work queue entry from the order
345 - NEVER tag switch from NULL to NULL */
346 OCTEON_POW_TAG_TYPE_NULL_NULL = 3L /**< A tag switch to NULL, and there is no space reserved in POW
347 - NEVER tag switch to NULL_NULL
348 - NEVER tag switch from NULL_NULL
349 - NULL_NULL is entered at the beginning of time and on a deschedule.
350 - NULL_NULL can be exited by a new work request. A NULL_SWITCH load can also switch the state to NULL */
351 } octeon_pow_tag_type_t ;
354 * This structure defines the response to a load/SENDSINGLE to POW (except CSR reads)
361 // response to new work request loads
363 uint64_t no_work : 1; // set when no new work queue entry was returned
364 // If there was de-scheduled work, the HW will definitely
365 // return it. When this bit is set, it could mean
367 // - There was no work, or
368 // - There was no work that the HW could find. This
369 // case can happen, regardless of the wait bit value
370 // in the original request, when there is work
371 // in the IQ's that is too deep down the list.
372 uint64_t unused : 23;
373 uint64_t addr : 40; // 36 in O1 -- the work queue pointer
376 // response to NULL_RD request loads
378 uint64_t unused : 62;
379 uint64_t state : 2; // of type octeon_pow_tag_type_t
380 // state is one of the following:
381 // OCTEON_POW_TAG_TYPE_ORDERED
382 // OCTEON_POW_TAG_TYPE_ATOMIC
383 // OCTEON_POW_TAG_TYPE_NULL
384 // OCTEON_POW_TAG_TYPE_NULL_NULL
387 } octeon_pow_tag_load_resp_t;
391 * This structure describes the address to load stuff from POW
396 // address for new work request loads (did<2:0> == 0)
398 uint64_t mem_region :2;
400 uint64_t is_io : 1; // must be one
401 uint64_t did : 8; // the ID of POW -- did<2:0> == 0 in this case
404 uint64_t wait : 1; // if set, don't return load response until work is available
405 uint64_t mbzl : 3; // must be zero
406 } swork; // physical address
409 // address for NULL_RD request (did<2:0> == 4)
410 // when this is read, HW attempts to change the state to NULL if it is NULL_NULL
411 // (the hardware cannot switch from NULL_NULL to NULL if a POW entry is not available -
412 // software may need to recover by finishing another piece of work before a POW
413 // entry can ever become available.)
415 uint64_t mem_region :2;
417 uint64_t is_io : 1; // must be one
418 uint64_t did : 8; // the ID of POW -- did<2:0> == 4 in this case
421 uint64_t mbzl : 3; // must be zero
422 } snull_rd; // physical address
424 // address for CSR accesses
426 uint64_t mem_region :2;
428 uint64_t is_io : 1; // must be one
429 uint64_t did : 8; // the ID of POW -- did<2:0> == 7 in this case
431 uint64_t csraddr:36; // only 36 bits in O1, addr<2:0> must be zero
432 } stagcsr; // physical address
434 } octeon_pow_load_addr_t;
437 static inline void octeon_pow_tag_switch_wait (void)
439 uint64_t switch_complete;
443 OCTEON_CHORD_HEX(&switch_complete);
444 } while (!switch_complete);
450 static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck (octeon_pow_wait_t wait)
452 octeon_pow_load_addr_t ptr;
453 octeon_pow_tag_load_resp_t result;
456 ptr.swork.mem_region = OCTEON_IO_SEG;
458 ptr.swork.did = OCTEON_OCT_DID_TAG_SWTAG;
459 ptr.swork.wait = wait;
461 result.word64 = oct_read64(ptr.word64);
463 if (result.s_work.no_work || !result.s_work.addr) {
466 return (octeon_wqe_t *) MIPS_PHYS_TO_KSEG0(result.s_work.addr);
469 static inline octeon_wqe_t *octeon_pow_work_request_sync_nocheck_debug (octeon_pow_wait_t wait)
471 octeon_pow_load_addr_t ptr;
472 octeon_pow_tag_load_resp_t result;
475 ptr.swork.mem_region = OCTEON_IO_SEG;
477 ptr.swork.did = OCTEON_OCT_DID_TAG_SWTAG;
478 ptr.swork.wait = wait;
480 result.word64 = oct_read64(ptr.word64);
482 printf("WQE Result: 0x%llX No-work %X Addr %llX Ptr: %p\n",
483 (unsigned long long)result.word64, result.s_work.no_work,
484 (unsigned long long)result.s_work.addr,
485 (void *)MIPS_PHYS_TO_KSEG0(result.s_work.addr));
487 if (result.s_work.no_work || !result.s_work.addr) {
490 return (octeon_wqe_t *) MIPS_PHYS_TO_KSEG0(result.s_work.addr);
493 static inline octeon_wqe_t *octeon_pow_work_request_sync (octeon_pow_wait_t wait)
495 octeon_pow_tag_switch_wait();
496 return (octeon_pow_work_request_sync_nocheck(wait));
500 static inline octeon_wqe_t *octeon_pow_work_request_sync_debug (octeon_pow_wait_t wait)
502 octeon_pow_tag_switch_wait();
503 return (octeon_pow_work_request_sync_nocheck_debug(wait));
509 * Gets result of asynchronous work request. Performs a IOBDMA sync
510 * to wait for the response.
512 * @param scratch_addr Scratch memory address to get result from
513 * Byte address, must be 8 byte aligned.
514 * @return Returns the WQE from the scratch register, or NULL if no work was available.
516 static inline octeon_wqe_t *octeon_pow_work_response_async(int scratch_addr)
518 octeon_pow_tag_load_resp_t result;
521 result.word64 = oct_scratch_read64(scratch_addr);
523 if (result.s_work.no_work) {
526 return (octeon_wqe_t*) MIPS_PHYS_TO_KSEG0(result.s_work.addr);
532 * The address from POW is a physical address. Adjust for back ptr, as well as
533 * make it accessible using KSEG0.
535 static inline void *octeon_pow_pktptr_to_kbuffer (octeon_buf_ptr_t pkt_ptr)
537 return ((void *)MIPS_PHYS_TO_KSEG0(
538 ((pkt_ptr.bits.addr >> 7) - pkt_ptr.bits.back) << 7));
541 #define INTERFACE(port) (port >> 4) /* Ports 0-15 are interface 0, 16-31 are interface 1 */
542 #define INDEX(port) (port & 0xf)
545 #define OCTEON_RGMX_PRTX_CFG(index,interface) (0x8001180008000010ull+((index)*2048)+((interface)*0x8000000ull))
546 #define OCTEON_RGMX_SMACX(offset,block_id) (0x8001180008000230ull+((offset)*2048)+((block_id)*0x8000000ull))
547 #define OCTEON_RGMX_RXX_ADR_CAM0(offset,block_id) (0x8001180008000180ull+((offset)*2048)+((block_id)*0x8000000ull))
548 #define OCTEON_RGMX_RXX_ADR_CAM1(offset,block_id) (0x8001180008000188ull+((offset)*2048)+((block_id)*0x8000000ull))
549 #define OCTEON_RGMX_RXX_ADR_CAM2(offset,block_id) (0x8001180008000190ull+((offset)*2048)+((block_id)*0x8000000ull))
550 #define OCTEON_RGMX_RXX_ADR_CAM3(offset,block_id) (0x8001180008000198ull+((offset)*2048)+((block_id)*0x8000000ull))
551 #define OCTEON_RGMX_RXX_ADR_CAM4(offset,block_id) (0x80011800080001A0ull+((offset)*2048)+((block_id)*0x8000000ull))
552 #define OCTEON_RGMX_RXX_ADR_CAM5(offset,block_id) (0x80011800080001A8ull+((offset)*2048)+((block_id)*0x8000000ull))
553 #define OCTEON_RGMX_RXX_ADR_CTL(offset,block_id) (0x8001180008000100ull+((offset)*2048)+((block_id)*0x8000000ull))
554 #define OCTEON_RGMX_RXX_ADR_CAM_EN(offset,block_id) (0x8001180008000108ull+((offset)*2048)+((block_id)*0x8000000ull))
555 #define OCTEON_RGMX_INF_MODE(block_id) (0x80011800080007F8ull+((block_id)*0x8000000ull))
556 #define OCTEON_RGMX_TX_PRTS(block_id) (0x8001180008000480ull+((block_id)*0x8000000ull))
557 #define OCTEON_ASXX_RX_PRT_EN(block_id) (0x80011800B0000000ull+((block_id)*0x8000000ull))
558 #define OCTEON_ASXX_TX_PRT_EN(block_id) (0x80011800B0000008ull+((block_id)*0x8000000ull))
559 #define OCTEON_RGMX_TXX_THRESH(offset,block_id) (0x8001180008000210ull+((offset)*2048)+((block_id)*0x8000000ull))
560 #define OCTEON_ASXX_TX_HI_WATERX(offset,block_id) (0x80011800B0000080ull+((offset)*8)+((block_id)*0x8000000ull))
561 #define OCTEON_ASXX_RX_CLK_SETX(offset,block_id) (0x80011800B0000020ull+((offset)*8)+((block_id)*0x8000000ull))
562 #define OCTEON_ASXX_TX_CLK_SETX(offset,block_id) (0x80011800B0000048ull+((offset)*8)+((block_id)*0x8000000ull))
563 #define OCTEON_RGMX_RXX_RX_INBND(offset,block_id) (0x8001180008000060ull+((offset)*2048)+((block_id)*0x8000000ull))
564 #define OCTEON_RGMX_TXX_CLK(offset,block_id) (0x8001180008000208ull+((offset)*2048)+((block_id)*0x8000000ull))
565 #define OCTEON_RGMX_TXX_SLOT(offset,block_id) (0x8001180008000220ull+((offset)*2048)+((block_id)*0x8000000ull))
566 #define OCTEON_RGMX_TXX_BURST(offset,block_id) (0x8001180008000228ull+((offset)*2048)+((block_id)*0x8000000ull))
567 #define OCTEON_PIP_GBL_CTL (0x80011800A0000020ull)
568 #define OCTEON_PIP_GBL_CFG (0x80011800A0000028ull)
569 #define OCTEON_PIP_PRT_CFGX(offset) (0x80011800A0000200ull+((offset)*8))
570 #define OCTEON_PIP_PRT_TAGX(offset) (0x80011800A0000400ull+((offset)*8))
578 #define OCTEON_POW_CORE_GROUP_MASK(core) (0x8001670000000000ull + (8 * core))
580 #define OCTEON_CIU_INT_EN0(CORE,IP) (0x8001070000000200ull + (IP * 16) + \
582 #define OCTEON_CIU_INT_SUM0(CORE,IP) (0x8001070000000000ull + (IP * 8) + \
584 #define OCTEON_CIU_TIMX(offset) (0x8001070000000480ull+((offset)*8))
586 #define OCTEON_POW_WQ_INT_THRX(offset) ((0x8001670000000080ull+((offset)*8)))
587 #define OCTEON_POW_WQ_INT_CNTX(offset) ((0x8001670000000100ull+((offset)*8)))
588 #define OCTEON_POW_QOS_THRX(offset) ((0x8001670000000180ull+((offset)*8)))
589 #define OCTEON_POW_QOS_RNDX(offset) ((0x80016700000001C0ull+((offset)*8)))
590 #define OCTEON_POW_WQ_INT_PC (0x8001670000000208ull)
591 #define OCTEON_POW_NW_TIM (0x8001670000000210ull)
592 #define OCTEON_POW_ECC_ERR (0x8001670000000218ull)
593 #define OCTEON_POW_INT_CTL (0x8001670000000220ull)
594 #define OCTEON_POW_NOS_CNT (0x8001670000000228ull)
595 #define OCTEON_POW_WS_PCX(offset) ((0x8001670000000280ull+((offset)*8)))
596 #define OCTEON_POW_WA_PCX(offset) ((0x8001670000000300ull+((offset)*8)))
597 #define OCTEON_POW_IQ_CNTX(offset) ((0x8001670000000340ull+((offset)*8)))
598 #define OCTEON_POW_WA_COM_PC (0x8001670000000380ull)
599 #define OCTEON_POW_IQ_COM_CNT (0x8001670000000388ull)
600 #define OCTEON_POW_TS_PC (0x8001670000000390ull)
601 #define OCTEON_POW_DS_PC (0x8001670000000398ull)
602 #define OCTEON_POW_BIST_STAT (0x80016700000003F8ull)
605 #define OCTEON_POW_WQ_INT (0x8001670000000200ull)
607 #define OCTEON_IPD_PORT_BP_COUNTERS_PAIRX(offset) (0x80014F00000001B8ull+((offset)*8))
610 * Current Counts that triggered interrupt
612 #define OCTEON_POW_WQ_INT_CNTX(offset) ((0x8001670000000100ull+((offset)*8)))
616 #define OCTEON_RGMX_ADRCTL_CAM_MODE_REJECT_DMAC 0
617 #define OCTEON_RGMX_ADRCTL_ACCEPT_BROADCAST 1
618 #define OCTEON_RGMX_ADRCTL_REJECT_ALL_MULTICAST 2
619 #define OCTEON_RGMX_ADRCTL_ACCEPT_ALL_MULTICAST 4
620 #define OCTEON_RGMX_ADRCTL_CAM_MODE_ACCEPT_DMAC 8
623 #define RGMX_LOCK_INIT(_sc, _name) \
624 mtx_init(&(_sc)->mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
625 #define RGMX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx)
626 #define RGMX_LOCK(_sc) mtx_lock(&(_sc)->mtx)
627 #define RGMX_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx)
628 #define RGMX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED)
630 #endif /* ___OCTEON_RGMX__H___ */