From: Satha Koteswara Rao <satha.rao@caviumnetworks.com> To: <linux-kernel@vger.kernel.org> Cc: <sgoutham@cavium.com>, <rric@kernel.org>, <davem@davemloft.net>, <david.daney@cavium.com>, <rvatsavayi@caviumnetworks.com>, <derek.chickles@caviumnetworks.com>, <satha.rao@caviumnetworks.com>, <philip.romanov@cavium.com>, <netdev@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org> Subject: [RFC PATCH 6/7] HW Filter Table access API's Date: Wed, 21 Dec 2016 14:16:50 +0530 [thread overview] Message-ID: <1482310011-1862-7-git-send-email-satha.rao@caviumnetworks.com> (raw) In-Reply-To: <1482310011-1862-1-git-send-email-satha.rao@caviumnetworks.com> --- drivers/net/ethernet/cavium/thunder/tbl_access.c | 262 +++++++++++++++++++++++ drivers/net/ethernet/cavium/thunder/tbl_access.h | 61 ++++++ 2 files changed, 323 insertions(+) create mode 100644 drivers/net/ethernet/cavium/thunder/tbl_access.c create mode 100644 drivers/net/ethernet/cavium/thunder/tbl_access.h diff --git a/drivers/net/ethernet/cavium/thunder/tbl_access.c b/drivers/net/ethernet/cavium/thunder/tbl_access.c new file mode 100644 index 0000000..6be31eb --- /dev/null +++ b/drivers/net/ethernet/cavium/thunder/tbl_access.c @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2015 Cavium, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + */ + +#include <linux/uaccess.h> +#include "pf_globals.h" +#include "pf_locals.h" +#include "tbl_access.h" + +struct tns_table_s *get_table_information(int table_id) +{ + int i; + + for (i = 0; i < TNS_MAX_TABLE; i++) { + if (!tbl_info[i].sdata.valid) + continue; + + if (tbl_info[i].sdata.tbl_id == table_id) + return &tbl_info[i]; + } + + return NULL; +} + +int tbl_write(int node, int table_id, int tbl_index, void *key, void *mask, + void *data) +{ + int i; + struct tns_table_s *tbl = get_table_information(table_id); + int bck_cnt, data_index, data_offset; + u64 data_entry[4]; + + if (!tbl) { + filter_dbg(FERR, "Invalid Table ID: %d\n", table_id); + return TNS_ERR_INVALID_TBL_ID; + } + + bck_cnt = tbl->sdata.data_width / tbl->sdata.data_size; + data_index = (tbl_index / bck_cnt); + data_offset = (tbl_index % bck_cnt); + //TCAM Table, we need to parse key & mask into single array + if (tbl->sdata.tbl_type == TNS_TBL_TYPE_TT) { + struct filter_keymask_s *tk = (struct filter_keymask_s *)key; + struct filter_keymask_s *tm = (struct filter_keymask_s *)mask; + u8 km[32]; + u64 mod_key, mod_mask, temp_mask; + int index = 0, offset = 0; + + memset(km, 0x0, 32); + +/* TCAM truth table data creation. Translation from data/mask to following + * truth table: + * + * Mask Data Content + * 0 0 X + * 0 1 1 + * 1 0 0 + * 1 1 Always Mismatch + * + */ + mod_mask = ~tk->key_value; + temp_mask = tm->key_value; + mod_key = tk->key_value; + mod_key = mod_key & (~temp_mask); + mod_mask = mod_mask & (~temp_mask); + + for (i = 0; i < 64; i++) { + km[index] = km[index] | (((mod_mask >> i) & 0x1) << + offset); + km[index] = km[index] | (((mod_key >> i) & 0x1) << + (offset + 1)); + offset += 2; + if (offset == 8) { + offset = 0; + index += 1; + } + } + km[index] = 0x2; + if (tns_write_register_indirect(node, + (tbl->sdata.key_base_addr + + (tbl_index * 32)), 32, + (void *)&km[0])) { + filter_dbg(FERR, "key write failed node %d tbl ID %d", + node, table_id); + filter_dbg(FERR, " index %d\n", tbl_index); + return TNS_ERR_DRIVER_WRITE; + } + } + + /* Data Writes are ReadModifyWrite */ + if (tns_read_register_indirect(node, (tbl->sdata.data_base_addr + + (data_index * 32)), 32, + (void *)&data_entry[0])) { + filter_dbg(FERR, "data read failed node %d tbl ID %d idx %d\n", + node, table_id, tbl_index); + return TNS_ERR_DRIVER_READ; + } + memcpy(&data_entry[data_offset], data, tbl->sdata.data_size / 8); + if (tns_write_register_indirect(node, (tbl->sdata.data_base_addr + + (data_index * 32)), 32, + (void *)&data_entry[0])) { + filter_dbg(FERR, "data write failed node %d tbl ID %d idx %d\n", + node, table_id, tbl_index); + return TNS_ERR_DRIVER_WRITE; + } + + return TNS_NO_ERR; +} + +int tbl_read(int node, int table_id, int tbl_index, void *key, void *mask, + void *data) +{ + struct tns_table_s *tbl = get_table_information(table_id); + int i, bck_cnt, data_index, data_offset; + u64 data_entry[4]; + u8 km[32]; + + if (!tbl) { + filter_dbg(FERR, "Invalid Table ID: %d\n", table_id); + return TNS_ERR_INVALID_TBL_ID; + } + + bck_cnt = tbl->sdata.data_width / tbl->sdata.data_size; + data_index = (tbl_index / bck_cnt); + data_offset = (tbl_index % bck_cnt); + + //TCAM Table, we need to parse key & mask into single array + if (tbl->sdata.tbl_type == TNS_TBL_TYPE_TT) { + memset(km, 0x0, 32); + + if (tns_read_register_indirect(node, (tbl->sdata.key_base_addr + + (tbl_index * 32)), 32, + (void *)&km[0])) { + filter_dbg(FERR, "key read failed node %d tbl ID %d", + node, table_id); + filter_dbg(FERR, " idx %d\n", tbl_index); + return TNS_ERR_DRIVER_READ; + } + if (!(km[((tbl->sdata.key_size * 2) / 8)] == 0x2)) + return TNS_ERR_MAC_FILTER_INVALID_ENTRY; + } + + if (tns_read_register_indirect(node, (tbl->sdata.data_base_addr + + (data_index * 32)), 32, + (void *)&data_entry[0])) { + filter_dbg(FERR, "data read failed node %d tbl ID %d idx %d\n", + node, table_id, tbl_index); + return TNS_ERR_DRIVER_READ; + } + memcpy(data, (void *)(&data_entry[data_offset]), + (tbl->sdata.data_size / 8)); + + if (tbl->sdata.tbl_type == TNS_TBL_TYPE_TT) { + struct filter_keymask_s *tk = (struct filter_keymask_s *)key; + struct filter_keymask_s *tm = (struct filter_keymask_s *)mask; + u8 temp_km; + int index = 0, offset = 0; + + tk->key_value = 0x0ull; + tm->key_value = 0x0ull; + temp_km = km[0]; + for (i = 0; i < 64; i++) { + tm->key_value = tm->key_value | + ((temp_km & 0x1ull) << i); + temp_km >>= 1; + tk->key_value = tk->key_value | + ((temp_km & 0x1ull) << i); + temp_km >>= 1; + offset += 2; + if (offset == 8) { + offset = 0; + index += 1; + temp_km = km[index]; + } + } + tm->key_value = ~tm->key_value & ~tk->key_value; + tk->is_valid = 1; + tm->is_valid = 0; + } + + return TNS_NO_ERR; +} + +int invalidate_table_entry(int node, int table_id, int tbl_idx) +{ + struct tns_table_s *tbl = get_table_information(table_id); + + if (!tbl) { + filter_dbg(FERR, "Invalid Table ID: %d\n", table_id); + return TNS_ERR_INVALID_TBL_ID; + } + + if (tbl->sdata.tbl_type == TNS_TBL_TYPE_TT) { + u8 km[32]; + + memset(km, 0x0, 32); + km[((tbl->sdata.key_size * 2) / 8)] = 0x1; + + if (tns_write_register_indirect(node, + (tbl->sdata.key_base_addr + + (tbl_idx * 32)), 32, + (void *)&km[0])) { + filter_dbg(FERR, "%s failed node %d tbl ID %d idx %d\n", + __func__, node, table_id, tbl_idx); + return TNS_ERR_DRIVER_WRITE; + } + } + + return TNS_NO_ERR; +} + +int alloc_table_index(int node, int table_id, int *index) +{ + int err = 0; + struct tns_table_s *tbl = get_table_information(table_id); + + if (!tbl) { + filter_dbg(FERR, "%s Invalid TableID %d\n", __func__, table_id); + return TNS_ERR_INVALID_TBL_ID; + } + + if (*index == -1) { + *index = find_first_zero_bit(tbl->ddata[node].bitmap, + tbl->sdata.depth); + + if (*index < 0 || *index >= tbl->sdata.depth) + err = -ENOSPC; + else + __set_bit(*index, tbl->ddata[node].bitmap); + + return err; + } else if (*index < 0 || *index >= tbl->sdata.depth) { + filter_dbg(FERR, "%s Out of bound index %d requested[0...%d]\n", + __func__, *index, tbl->sdata.depth); + return TNS_ERR_MAC_FILTER_INVALID_ENTRY; + } + if (test_and_set_bit(*index, tbl->ddata[node].bitmap)) + filter_dbg(FDEBUG, "%s Entry Already exists\n", __func__); + + return err; +} + +void free_table_index(int node, int table_id, int index) +{ + struct tns_table_s *tbl = get_table_information(table_id); + + if (!tbl) { + filter_dbg(FERR, "%s Invalid TableID %d\n", __func__, table_id); + return; + } + if (index < 0 || index >= tbl->sdata.depth) { + filter_dbg(FERR, "%s Invalid Index %d Max Limit %d\n", + __func__, index, tbl->sdata.depth); + return; + } + + __clear_bit(index, tbl->ddata[node].bitmap); +} diff --git a/drivers/net/ethernet/cavium/thunder/tbl_access.h b/drivers/net/ethernet/cavium/thunder/tbl_access.h new file mode 100644 index 0000000..c098410 --- /dev/null +++ b/drivers/net/ethernet/cavium/thunder/tbl_access.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 Cavium, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + */ + +#ifndef __TBL_ACCESS_H__ +#define __TBL_ACCESS_H__ + +#define TNS_MAX_TABLE 8 + +enum { + TNS_TBL_TYPE_DT, + TNS_TBL_TYPE_HT, + TNS_TBL_TYPE_TT, + TNS_TBL_TYPE_MAX +}; + +struct table_static_s { + u8 tbl_type; + u8 tbl_id; + u8 valid; + u8 rsvd; + u16 key_size; + u16 data_size; + u16 data_width; + u16 key_width; + u32 depth; + u64 key_base_addr; + u64 data_base_addr; + u8 tbl_name[32]; +}; + +struct table_dynamic_s { + unsigned long *bitmap; +}; + +struct tns_table_s { + struct table_static_s sdata; + struct table_dynamic_s ddata[MAX_NUMNODES]; +}; + +enum { + MAC_FILTER_TABLE = 102, + VLAN_FILTER_TABLE = 103, + MAC_EVIF_TABLE = 140, + VLAN_EVIF_TABLE = 201, + PORT_CONFIG_TABLE = 202, + TABLE_ID_END +}; + +extern struct tns_table_s tbl_info[TNS_MAX_TABLE]; + +struct filter_keymask_s { + u8 is_valid; + u64 key_value; +}; + +#endif /* __TBL_ACCESS_H__ */ -- 1.8.3.1
next prev parent reply other threads:[~2016-12-21 9:04 UTC|newest] Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-12-21 8:46 [RFC PATCH 0/7] ThunderX Embedded switch support Satha Koteswara Rao 2016-12-21 8:46 ` [RFC PATCH 1/7] PF driver modified to enable HW filter support, changes works in backward compatibility mode Enable required things in Makefile Enable LZ4 dependecy inside config file Satha Koteswara Rao 2016-12-21 13:05 ` Sunil Kovvuri 2016-12-26 14:20 ` Koteshwar Rao, Satha 2016-12-27 4:19 ` Sunil Kovvuri 2016-12-21 8:46 ` [RFC PATCH 2/7] VF driver changes to enable hooks to get kernel notifications Satha Koteswara Rao 2016-12-21 8:46 ` [RFC PATCH 3/7] Enable pause frame support Satha Koteswara Rao [not found] ` <DM5PR07MB2889471E0668C95BD2A266709E930@DM5PR07MB2889.namprd07.prod.outlook.com> 2016-12-26 14:21 ` Koteshwar Rao, Satha 2016-12-21 8:46 ` [RFC PATCH 4/7] HW Filter Initialization code and register access APIs Satha Koteswara Rao 2016-12-21 12:36 ` Sunil Kovvuri 2016-12-26 14:13 ` Koteshwar Rao, Satha 2016-12-21 8:46 ` [RFC PATCH 5/7] Multiple VF's grouped together under single physical port called PF group PF Group maintainance API's Satha Koteswara Rao 2016-12-21 12:43 ` Sunil Kovvuri 2016-12-26 14:16 ` Koteshwar Rao, Satha 2016-12-21 8:46 ` Satha Koteswara Rao [this message] 2016-12-21 8:46 ` [RFC PATCH 7/7] Get notifications from PF driver and configure filter block based on request data Satha Koteswara Rao 2016-12-21 12:03 ` [RFC PATCH 0/7] ThunderX Embedded switch support Sunil Kovvuri 2016-12-26 14:04 ` Koteshwar Rao, Satha 2016-12-26 14:55 ` Andrew Lunn
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1482310011-1862-7-git-send-email-satha.rao@caviumnetworks.com \ --to=satha.rao@caviumnetworks.com \ --cc=davem@davemloft.net \ --cc=david.daney@cavium.com \ --cc=derek.chickles@caviumnetworks.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=netdev@vger.kernel.org \ --cc=philip.romanov@cavium.com \ --cc=rric@kernel.org \ --cc=rvatsavayi@caviumnetworks.com \ --cc=sgoutham@cavium.com \ --subject='Re: [RFC PATCH 6/7] HW Filter Table access API'\''s' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).