| /* |
| * Copyright (c) 2018-2020 The Linux Foundation. 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 The Linux Foundation nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| #ifndef IPA_TABLE_H |
| #define IPA_TABLE_H |
| |
| #include <stdint.h> |
| #include <stdbool.h> |
| #include <linux/msm_ipa.h> |
| |
| #define IPA_TABLE_MAX_ENTRIES 5120 |
| |
| #define IPA_TABLE_INVALID_ENTRY 0x0 |
| |
| #undef VALID_INDEX |
| #define VALID_INDEX(idx) \ |
| ( (idx) != IPA_TABLE_INVALID_ENTRY ) |
| |
| #undef VALID_RULE_HDL |
| #define VALID_RULE_HDL(hdl) \ |
| ( (hdl) != IPA_TABLE_INVALID_ENTRY ) |
| |
| #undef GOTO_REC |
| #define GOTO_REC(tbl, rec_idx) \ |
| ( (tbl)->table_addr + ((rec_idx) * (tbl)->entry_size) ) |
| |
| typedef enum |
| { |
| IPA_NAT_BASE_TBL = 0, |
| IPA_NAT_EXPN_TBL = 1, |
| IPA_NAT_INDX_TBL = 2, |
| IPA_NAT_INDEX_EXPN_TBL = 3, |
| IPA_IPV6CT_BASE_TBL = 4, |
| IPA_IPV6CT_EXPN_TBL = 5, |
| } ipa_table_dma_type; |
| |
| #define VALID_IPA_TABLE_DMA_TYPE(t) \ |
| ( (t) >= IPA_NAT_BASE_TBL && (t) <= IPA_IPV6CT_EXPN_TBL ) |
| |
| /* |
| * --------- NAT Rule Handle Entry ID structure --------- |
| * |
| * +-----------+-----------+------------------+----------------+ |
| * | 1 bit | 2 bits | 12 bits | 1 bit | |
| * +-----------+-----------+------------------+----------------+ |
| * | 0 - DDR | reserved | index into table | 0 - base | |
| * | 1 - SRAM | | | 1 - expansion | |
| * +-----------+-----------+------------------+----------------+ |
| */ |
| #define IPA_TABLE_TYPE_BITS 0x00000001 |
| #define IPA_TABLE_TYPE_MASK 0x00000001 |
| #define IPA_TABLE_INDX_MASK 0x00000FFF |
| #define IPA_TABLE_TYPE_MEM_SHIFT 15 |
| |
| #undef BREAK_RULE_HDL |
| #define BREAK_RULE_HDL(tbl, hdl, mt, iet, indx) \ |
| do { \ |
| mt = ((hdl) >> IPA_TABLE_TYPE_MEM_SHIFT) & IPA_TABLE_TYPE_MASK; \ |
| iet = (hdl) & IPA_TABLE_TYPE_MASK; \ |
| indx = ((hdl) >> IPA_TABLE_TYPE_BITS) & IPA_TABLE_INDX_MASK; \ |
| indx += (iet) ? tbl->table_entries : 0; \ |
| /*IPADBG("hdl(%u) -> mt(%u) iet(%u) indx(%u)\n", hdl, mt, iet, indx);*/ \ |
| } while ( 0 ) |
| |
| typedef int (*entry_validity_checker)( |
| void* entry); |
| |
| typedef uint16_t (*entry_next_index_getter)( |
| void* entry); |
| |
| typedef uint16_t (*entry_prev_index_getter)( |
| void* entry, |
| uint16_t entry_index, |
| void* meta, |
| uint16_t base_table_size); |
| |
| typedef void (*entry_prev_index_setter)( |
| void* entry, |
| uint16_t entry_index, |
| uint16_t prev_index, |
| void* meta, |
| uint16_t base_table_size); |
| |
| typedef int (*entry_head_inserter)( |
| void* entry, |
| void* user_data, |
| uint16_t* dma_command_data); |
| |
| typedef int (*entry_tail_inserter)( |
| void* entry, |
| void* user_data); |
| |
| typedef uint16_t (*entry_delete_head_dma_command_data_getter)( |
| void* head, |
| void* next_entry); |
| |
| typedef struct |
| { |
| entry_validity_checker entry_is_valid; |
| entry_next_index_getter entry_get_next_index; |
| entry_prev_index_getter entry_get_prev_index; |
| entry_prev_index_setter entry_set_prev_index; |
| entry_head_inserter entry_head_insert; |
| entry_tail_inserter entry_tail_insert; |
| entry_delete_head_dma_command_data_getter |
| entry_get_delete_head_dma_command_data; |
| } ipa_table_entry_interface; |
| |
| typedef enum |
| { |
| HELP_UPDATE_HEAD = 0, |
| HELP_UPDATE_ENTRY = 1, |
| HELP_DELETE_HEAD = 2, |
| |
| HELP_UPDATE_MAX, |
| } dma_help_type; |
| |
| #undef VALID_DMA_HELP_TYPE |
| #define VALID_DMA_HELP_TYPE(t) \ |
| ( (t) >= HELP_UPDATE_HEAD && (t) < HELP_UPDATE_MAX ) |
| |
| typedef struct |
| { |
| uint32_t offset; |
| ipa_table_dma_type table_type; |
| ipa_table_dma_type expn_table_type; |
| uint8_t table_indx; |
| } ipa_table_dma_cmd_helper; |
| |
| typedef struct |
| { |
| char name[IPA_RESOURCE_NAME_MAX]; |
| |
| enum ipa3_nat_mem_in nmi; |
| |
| int entry_size; |
| |
| uint16_t table_entries; |
| uint16_t expn_table_entries; |
| uint32_t tot_tbl_ents; |
| |
| uint8_t* table_addr; |
| uint8_t* expn_table_addr; |
| |
| uint16_t cur_tbl_cnt; |
| uint16_t cur_expn_tbl_cnt; |
| |
| ipa_table_entry_interface* entry_interface; |
| |
| ipa_table_dma_cmd_helper* dma_help[HELP_UPDATE_MAX]; |
| |
| void* meta; |
| int meta_entry_size; |
| } ipa_table; |
| |
| typedef struct |
| { |
| uint16_t prev_index; |
| void* prev_entry; |
| |
| uint16_t curr_index; |
| void* curr_entry; |
| |
| uint16_t next_index; |
| void* next_entry; |
| } ipa_table_iterator; |
| |
| |
| void ipa_table_init( |
| ipa_table* table, |
| const char* table_name, |
| enum ipa3_nat_mem_in nmi, |
| int entry_size, |
| void* meta, |
| int meta_entry_size, |
| ipa_table_entry_interface* entry_interface); |
| |
| int ipa_table_calculate_entries_num( |
| ipa_table* table, |
| uint16_t number_of_entries, |
| enum ipa3_nat_mem_in nmi); |
| |
| int ipa_table_calculate_size( |
| ipa_table* table); |
| |
| uint8_t* ipa_table_calculate_addresses( |
| ipa_table* table, |
| uint8_t* base_addr); |
| |
| void ipa_table_reset( |
| ipa_table* table); |
| |
| int ipa_table_add_entry( |
| ipa_table* table, |
| void* user_data, |
| uint16_t* index, |
| uint32_t* rule_hdl, |
| struct ipa_ioc_nat_dma_cmd* cmd); |
| |
| void ipa_table_create_delete_command( |
| ipa_table* table, |
| struct ipa_ioc_nat_dma_cmd* cmd, |
| ipa_table_iterator* iterator); |
| |
| void ipa_table_delete_entry( |
| ipa_table* table, |
| ipa_table_iterator* iterator, |
| uint8_t is_prev_empty); |
| |
| void ipa_table_erase_entry( |
| ipa_table* table, |
| uint16_t index); |
| |
| int ipa_table_get_entry( |
| ipa_table* table, |
| uint32_t entry_handle, |
| void** entry, |
| uint16_t* entry_index); |
| |
| void* ipa_table_get_entry_by_index( |
| ipa_table* table, |
| uint16_t index); |
| |
| void ipa_table_dma_cmd_helper_init( |
| ipa_table_dma_cmd_helper* dma_cmd_helper, |
| uint8_t table_indx, |
| ipa_table_dma_type table_type, |
| ipa_table_dma_type expn_table_type, |
| uint32_t offset); |
| |
| void ipa_table_dma_cmd_generate( |
| ipa_table_dma_cmd_helper* dma_cmd_helper, |
| uint8_t is_expn, |
| uint32_t entry_offset, |
| uint16_t data, |
| struct ipa_ioc_nat_dma_cmd* cmd); |
| |
| int ipa_table_iterator_init( |
| ipa_table_iterator* iterator, |
| ipa_table* table, |
| void* curr_entry, |
| uint16_t curr_index); |
| |
| int ipa_table_iterator_next( |
| ipa_table_iterator* iterator, |
| ipa_table* table); |
| |
| int ipa_table_iterator_end( |
| ipa_table_iterator* iterator, |
| ipa_table* table, |
| uint16_t head_index, |
| void* head); |
| |
| int ipa_table_iterator_is_head_with_tail( |
| ipa_table_iterator* iterator); |
| |
| int ipa_calc_num_sram_table_entries( |
| uint32_t sram_size, |
| uint32_t table1_ent_size, |
| uint32_t table2_ent_size, |
| uint16_t* num_entries_ptr); |
| |
| typedef int (*ipa_table_walk_cb)( |
| ipa_table* table_ptr, |
| uint32_t rule_hdl, |
| void* record_ptr, |
| uint16_t record_index, |
| void* meta_record_ptr, |
| uint16_t meta_record_index, |
| void* arb_data_ptr ); |
| |
| typedef enum |
| { |
| WHEN_SLOT_EMPTY = 0, |
| WHEN_SLOT_FILLED = 1, |
| |
| WHEN_SLOT_MAX |
| } When2Callback; |
| |
| #define VALID_WHEN2CALLBACK(w) \ |
| ( (w) >= WHEN_SLOT_EMPTY && (w) < WHEN_SLOT_MAX ) |
| |
| int ipa_table_walk( |
| ipa_table* table, |
| uint16_t start_index, |
| When2Callback when, |
| ipa_table_walk_cb walk_cb, |
| void* arb_data_ptr ); |
| |
| int ipa_table_add_dma_cmd( |
| ipa_table* tbl_ptr, |
| dma_help_type help_type, |
| void* rec_ptr, |
| uint16_t rec_index, |
| uint16_t data_for_entry, |
| struct ipa_ioc_nat_dma_cmd* cmd_ptr ); |
| |
| #endif |