1325618Ssbruno/* 2325618Ssbruno * BSD LICENSE 3325618Ssbruno * 4325618Ssbruno * Copyright(c) 2017 Cavium, Inc.. All rights reserved. 5325618Ssbruno * All rights reserved. 6325618Ssbruno * 7325618Ssbruno * Redistribution and use in source and binary forms, with or without 8325618Ssbruno * modification, are permitted provided that the following conditions 9325618Ssbruno * are met: 10325618Ssbruno * 11325618Ssbruno * * Redistributions of source code must retain the above copyright 12325618Ssbruno * notice, this list of conditions and the following disclaimer. 13325618Ssbruno * * Redistributions in binary form must reproduce the above copyright 14325618Ssbruno * notice, this list of conditions and the following disclaimer in 15325618Ssbruno * the documentation and/or other materials provided with the 16325618Ssbruno * distribution. 17325618Ssbruno * * Neither the name of Cavium, Inc. nor the names of its 18325618Ssbruno * contributors may be used to endorse or promote products derived 19325618Ssbruno * from this software without specific prior written permission. 20325618Ssbruno * 21325618Ssbruno * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22325618Ssbruno * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23325618Ssbruno * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24325618Ssbruno * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25325618Ssbruno * OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26325618Ssbruno * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27325618Ssbruno * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28325618Ssbruno * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29325618Ssbruno * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30325618Ssbruno * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31325618Ssbruno * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32325618Ssbruno */ 33325618Ssbruno/*$FreeBSD: stable/11/sys/dev/liquidio/lio_rss.c 325618 2017-11-09 19:52:56Z sbruno $*/ 34325618Ssbruno 35325618Ssbruno#ifdef RSS 36325618Ssbruno 37325618Ssbruno#include "lio_bsd.h" 38325618Ssbruno#include "lio_common.h" 39325618Ssbruno#include "lio_droq.h" 40325618Ssbruno#include "lio_iq.h" 41325618Ssbruno#include "lio_response_manager.h" 42325618Ssbruno#include "lio_device.h" 43325618Ssbruno#include "lio_ctrl.h" 44325618Ssbruno#include "lio_main.h" 45325618Ssbruno#include "lio_network.h" 46325618Ssbruno#include "lio_rss.h" 47325618Ssbruno 48325618Ssbrunoint lio_send_rss_param(struct lio *lio); 49325618Ssbruno 50325618Ssbrunostatic void 51325618Ssbrunolio_set_rss_callback(struct octeon_device *oct, uint32_t status, void *arg) 52325618Ssbruno{ 53325618Ssbruno struct lio_soft_command *sc = (struct lio_soft_command *)arg; 54325618Ssbruno 55325618Ssbruno if (status) 56325618Ssbruno lio_dev_err(oct, "Failed to SET RSS params\n"); 57325618Ssbruno else 58325618Ssbruno lio_dev_info(oct, "SET RSS params\n"); 59325618Ssbruno 60325618Ssbruno lio_free_soft_command(oct, sc); 61325618Ssbruno} 62325618Ssbruno 63325618Ssbrunostatic void 64325618Ssbrunolio_set_rss_info(struct lio *lio) 65325618Ssbruno{ 66325618Ssbruno struct octeon_device *oct = lio->oct_dev; 67325618Ssbruno struct lio_rss_params_set *rss_set = &lio->rss_set; 68325618Ssbruno uint32_t rss_hash_config; 69325618Ssbruno int i; 70325618Ssbruno uint8_t queue_id; 71325618Ssbruno 72325618Ssbruno for (i = 0; i < LIO_RSS_TABLE_SZ; i++) { 73325618Ssbruno queue_id = rss_get_indirection_to_bucket(i); 74325618Ssbruno queue_id = queue_id % oct->num_oqs; 75325618Ssbruno rss_set->fw_itable[i] = queue_id; 76325618Ssbruno } 77325618Ssbruno 78325618Ssbruno rss_hash_config = rss_gethashconfig(); 79325618Ssbruno if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4) 80325618Ssbruno rss_set->hashinfo |= LIO_RSS_HASH_IPV4; 81325618Ssbruno 82325618Ssbruno if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4) 83325618Ssbruno rss_set->hashinfo |= LIO_RSS_HASH_TCP_IPV4; 84325618Ssbruno 85325618Ssbruno if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6) 86325618Ssbruno rss_set->hashinfo |= LIO_RSS_HASH_IPV6; 87325618Ssbruno 88325618Ssbruno if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6) 89325618Ssbruno rss_set->hashinfo |= LIO_RSS_HASH_TCP_IPV6; 90325618Ssbruno 91325618Ssbruno if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX) 92325618Ssbruno rss_set->hashinfo |= LIO_RSS_HASH_IPV6_EX; 93325618Ssbruno 94325618Ssbruno if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6_EX) 95325618Ssbruno rss_set->hashinfo |= LIO_RSS_HASH_TCP_IPV6_EX; 96325618Ssbruno} 97325618Ssbruno 98325618Ssbrunoint 99325618Ssbrunolio_send_rss_param(struct lio *lio) 100325618Ssbruno{ 101325618Ssbruno struct octeon_device *oct = lio->oct_dev; 102325618Ssbruno struct lio_soft_command *sc = NULL; 103325618Ssbruno union octeon_cmd *cmd = NULL; 104325618Ssbruno struct lio_rss_params *rss_param; 105325618Ssbruno int i, retval; 106325618Ssbruno 107325618Ssbruno sc = lio_alloc_soft_command(oct, 108325618Ssbruno OCTEON_CMD_SIZE + sizeof(struct lio_rss_params), 0, 0); 109325618Ssbruno 110325618Ssbruno if (sc == NULL) { 111325618Ssbruno lio_dev_err(oct, "%s: Soft command allocation failed\n", 112325618Ssbruno __func__); 113325618Ssbruno return (ENOMEM); 114325618Ssbruno } 115325618Ssbruno 116325618Ssbruno sc->iq_no = lio->linfo.txpciq[0].s.q_no; 117325618Ssbruno 118325618Ssbruno lio_prepare_soft_command(oct, sc, LIO_OPCODE_NIC, LIO_OPCODE_NIC_CMD, 0, 119325618Ssbruno 0, 0); 120325618Ssbruno 121325618Ssbruno sc->callback = lio_set_rss_callback; 122325618Ssbruno sc->callback_arg = sc; 123325618Ssbruno sc->wait_time = 1000; 124325618Ssbruno 125325618Ssbruno cmd = (union octeon_cmd *)sc->virtdptr; 126325618Ssbruno cmd->cmd64 = 0; 127325618Ssbruno cmd->s.cmd = LIO_CMD_SET_RSS; 128325618Ssbruno 129325618Ssbruno rss_param = (struct lio_rss_params *)(cmd + 1); 130325618Ssbruno rss_param->param.flags = 0; 131325618Ssbruno rss_param->param.itablesize = LIO_RSS_TABLE_SZ; 132325618Ssbruno rss_param->param.hashkeysize = LIO_RSS_KEY_SZ; 133325618Ssbruno 134325618Ssbruno lio_set_rss_info(lio); 135325618Ssbruno rss_param->param.hashinfo = lio->rss_set.hashinfo; 136325618Ssbruno memcpy(rss_param->itable, (void *)lio->rss_set.fw_itable, 137325618Ssbruno (size_t)rss_param->param.itablesize); 138325618Ssbruno 139325618Ssbruno lio_dev_info(oct, "RSS itable: Size %u\n", rss_param->param.itablesize); 140325618Ssbruno for (i = 0; i < rss_param->param.itablesize; i += 8) { 141325618Ssbruno lio_dev_dbg(oct, " %03u:%2u, %03u:%2u, %03u:%2u, %03u:%2u, %03u:%2u, %03u:%2u, %03u:%2u, %03u:%2u\n", 142325618Ssbruno i + 0, rss_param->itable[i + 0], 143325618Ssbruno i + 1, rss_param->itable[i + 1], 144325618Ssbruno i + 2, rss_param->itable[i + 2], 145325618Ssbruno i + 3, rss_param->itable[i + 3], 146325618Ssbruno i + 4, rss_param->itable[i + 4], 147325618Ssbruno i + 5, rss_param->itable[i + 5], 148325618Ssbruno i + 6, rss_param->itable[i + 6], 149325618Ssbruno i + 7, rss_param->itable[i + 7]); 150325618Ssbruno } 151325618Ssbruno 152325618Ssbruno rss_getkey(lio->rss_set.key); 153325618Ssbruno 154325618Ssbruno memcpy(rss_param->key, (void *)lio->rss_set.key, 155325618Ssbruno (size_t)rss_param->param.hashkeysize); 156325618Ssbruno 157325618Ssbruno /* swap cmd and rss params */ 158325618Ssbruno lio_swap_8B_data((uint64_t *)cmd, 159325618Ssbruno ((OCTEON_CMD_SIZE + LIO_RSS_PARAM_SIZE) >> 3)); 160325618Ssbruno 161325618Ssbruno retval = lio_send_soft_command(oct, sc); 162325618Ssbruno if (retval == LIO_IQ_SEND_FAILED) { 163325618Ssbruno lio_dev_err(oct, 164325618Ssbruno "%s: Sending soft command failed, status: %x\n", 165325618Ssbruno __func__, retval); 166325618Ssbruno lio_free_soft_command(oct, sc); 167325618Ssbruno return (-1); 168325618Ssbruno } 169325618Ssbruno 170325618Ssbruno return (0); 171325618Ssbruno} 172325618Ssbruno 173325618Ssbruno#endif /* RSS */ 174