1b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * This file is part of the Chelsio T4 Ethernet driver for Linux. 3b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 4b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Copyright (c) 2003-2010 Chelsio Communications, Inc. All rights reserved. 5b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 6b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * This software is available to you under a choice of one of two 7b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * licenses. You may choose to be licensed under the terms of the GNU 8b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * General Public License (GPL) Version 2, available from the file 9b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * COPYING in the main directory of this source tree, or the 10b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * OpenIB.org BSD license below: 11b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 12b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Redistribution and use in source and binary forms, with or 13b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * without modification, are permitted provided that the following 14b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * conditions are met: 15b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 16b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * - Redistributions of source code must retain the above 17b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * copyright notice, this list of conditions and the following 18b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * disclaimer. 19b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 20b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * - Redistributions in binary form must reproduce the above 21b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * copyright notice, this list of conditions and the following 22b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * disclaimer in the documentation and/or other materials 23b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * provided with the distribution. 24b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 25b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * SOFTWARE. 33b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 34b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 35b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 36b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 37b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/bitmap.h> 38b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/crc32.h> 39b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/ctype.h> 40b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/debugfs.h> 41b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/err.h> 42b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/etherdevice.h> 43b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/firmware.h> 4401789349ee52e4a3faf376f1485303d9723c4f1fJiri Pirko#include <linux/if.h> 45b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/if_vlan.h> 46b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/init.h> 47b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/log2.h> 48b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/mdio.h> 49b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/module.h> 50b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/moduleparam.h> 51b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/mutex.h> 52b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/netdevice.h> 53b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/pci.h> 54b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/aer.h> 55b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/rtnetlink.h> 56b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/sched.h> 57b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/seq_file.h> 58b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/sockios.h> 59b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/vmalloc.h> 60b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <linux/workqueue.h> 61b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <net/neighbour.h> 62b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <net/netevent.h> 63b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include <asm/uaccess.h> 64b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 65b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include "cxgb4.h" 66b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include "t4_regs.h" 67b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include "t4_msg.h" 68b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include "t4fw_api.h" 69b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#include "l2t.h" 70b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 7199e6d06521f2a522ff5aaa812552f68220507c67Dimitris Michailidis#define DRV_VERSION "1.3.0-ko" 72b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define DRV_DESC "Chelsio T4 Network Driver" 73b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 74b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 75b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Max interrupt hold-off timer value in us. Queues fall back to this value 76b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * under extreme memory pressure so it's largish to give the system time to 77b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * recover. 78b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 79b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define MAX_SGE_TIMERVAL 200U 80b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 817ee9ff94857dd27144521118173786a03d490efbCasey Leedom#ifdef CONFIG_PCI_IOV 827ee9ff94857dd27144521118173786a03d490efbCasey Leedom/* 837ee9ff94857dd27144521118173786a03d490efbCasey Leedom * Virtual Function provisioning constants. We need two extra Ingress Queues 847ee9ff94857dd27144521118173786a03d490efbCasey Leedom * with Interrupt capability to serve as the VF's Firmware Event Queue and 857ee9ff94857dd27144521118173786a03d490efbCasey Leedom * Forwarded Interrupt Queue (when using MSI mode) -- neither will have Free 867ee9ff94857dd27144521118173786a03d490efbCasey Leedom * Lists associated with them). For each Ethernet/Control Egress Queue and 877ee9ff94857dd27144521118173786a03d490efbCasey Leedom * for each Free List, we need an Egress Context. 887ee9ff94857dd27144521118173786a03d490efbCasey Leedom */ 897ee9ff94857dd27144521118173786a03d490efbCasey Leedomenum { 907ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NPORTS = 1, /* # of "ports" per VF */ 917ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NQSETS = 2, /* # of "Queue Sets" per VF */ 927ee9ff94857dd27144521118173786a03d490efbCasey Leedom 937ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NVI = VFRES_NPORTS, /* # of Virtual Interfaces */ 947ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NETHCTRL = VFRES_NQSETS, /* # of EQs used for ETH or CTRL Qs */ 957ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NIQFLINT = VFRES_NQSETS+2,/* # of ingress Qs/w Free List(s)/intr */ 967ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NIQ = 0, /* # of non-fl/int ingress queues */ 977ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NEQ = VFRES_NQSETS*2, /* # of egress queues */ 987ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_TC = 0, /* PCI-E traffic class */ 997ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NEXACTF = 16, /* # of exact MPS filters */ 1007ee9ff94857dd27144521118173786a03d490efbCasey Leedom 1017ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_R_CAPS = FW_CMD_CAP_DMAQ|FW_CMD_CAP_VF|FW_CMD_CAP_PORT, 1027ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_WX_CAPS = FW_CMD_CAP_DMAQ|FW_CMD_CAP_VF, 1037ee9ff94857dd27144521118173786a03d490efbCasey Leedom}; 1047ee9ff94857dd27144521118173786a03d490efbCasey Leedom 1057ee9ff94857dd27144521118173786a03d490efbCasey Leedom/* 1067ee9ff94857dd27144521118173786a03d490efbCasey Leedom * Provide a Port Access Rights Mask for the specified PF/VF. This is very 1077ee9ff94857dd27144521118173786a03d490efbCasey Leedom * static and likely not to be useful in the long run. We really need to 1087ee9ff94857dd27144521118173786a03d490efbCasey Leedom * implement some form of persistent configuration which the firmware 1097ee9ff94857dd27144521118173786a03d490efbCasey Leedom * controls. 1107ee9ff94857dd27144521118173786a03d490efbCasey Leedom */ 1117ee9ff94857dd27144521118173786a03d490efbCasey Leedomstatic unsigned int pfvfres_pmask(struct adapter *adapter, 1127ee9ff94857dd27144521118173786a03d490efbCasey Leedom unsigned int pf, unsigned int vf) 1137ee9ff94857dd27144521118173786a03d490efbCasey Leedom{ 1147ee9ff94857dd27144521118173786a03d490efbCasey Leedom unsigned int portn, portvec; 1157ee9ff94857dd27144521118173786a03d490efbCasey Leedom 1167ee9ff94857dd27144521118173786a03d490efbCasey Leedom /* 1177ee9ff94857dd27144521118173786a03d490efbCasey Leedom * Give PF's access to all of the ports. 1187ee9ff94857dd27144521118173786a03d490efbCasey Leedom */ 1197ee9ff94857dd27144521118173786a03d490efbCasey Leedom if (vf == 0) 1207ee9ff94857dd27144521118173786a03d490efbCasey Leedom return FW_PFVF_CMD_PMASK_MASK; 1217ee9ff94857dd27144521118173786a03d490efbCasey Leedom 1227ee9ff94857dd27144521118173786a03d490efbCasey Leedom /* 1237ee9ff94857dd27144521118173786a03d490efbCasey Leedom * For VFs, we'll assign them access to the ports based purely on the 1247ee9ff94857dd27144521118173786a03d490efbCasey Leedom * PF. We assign active ports in order, wrapping around if there are 1257ee9ff94857dd27144521118173786a03d490efbCasey Leedom * fewer active ports than PFs: e.g. active port[pf % nports]. 1267ee9ff94857dd27144521118173786a03d490efbCasey Leedom * Unfortunately the adapter's port_info structs haven't been 1277ee9ff94857dd27144521118173786a03d490efbCasey Leedom * initialized yet so we have to compute this. 1287ee9ff94857dd27144521118173786a03d490efbCasey Leedom */ 1297ee9ff94857dd27144521118173786a03d490efbCasey Leedom if (adapter->params.nports == 0) 1307ee9ff94857dd27144521118173786a03d490efbCasey Leedom return 0; 1317ee9ff94857dd27144521118173786a03d490efbCasey Leedom 1327ee9ff94857dd27144521118173786a03d490efbCasey Leedom portn = pf % adapter->params.nports; 1337ee9ff94857dd27144521118173786a03d490efbCasey Leedom portvec = adapter->params.portvec; 1347ee9ff94857dd27144521118173786a03d490efbCasey Leedom for (;;) { 1357ee9ff94857dd27144521118173786a03d490efbCasey Leedom /* 1367ee9ff94857dd27144521118173786a03d490efbCasey Leedom * Isolate the lowest set bit in the port vector. If we're at 1377ee9ff94857dd27144521118173786a03d490efbCasey Leedom * the port number that we want, return that as the pmask. 1387ee9ff94857dd27144521118173786a03d490efbCasey Leedom * otherwise mask that bit out of the port vector and 1397ee9ff94857dd27144521118173786a03d490efbCasey Leedom * decrement our port number ... 1407ee9ff94857dd27144521118173786a03d490efbCasey Leedom */ 1417ee9ff94857dd27144521118173786a03d490efbCasey Leedom unsigned int pmask = portvec ^ (portvec & (portvec-1)); 1427ee9ff94857dd27144521118173786a03d490efbCasey Leedom if (portn == 0) 1437ee9ff94857dd27144521118173786a03d490efbCasey Leedom return pmask; 1447ee9ff94857dd27144521118173786a03d490efbCasey Leedom portn--; 1457ee9ff94857dd27144521118173786a03d490efbCasey Leedom portvec &= ~pmask; 1467ee9ff94857dd27144521118173786a03d490efbCasey Leedom } 1477ee9ff94857dd27144521118173786a03d490efbCasey Leedom /*NOTREACHED*/ 1487ee9ff94857dd27144521118173786a03d490efbCasey Leedom} 1497ee9ff94857dd27144521118173786a03d490efbCasey Leedom#endif 1507ee9ff94857dd27144521118173786a03d490efbCasey Leedom 151b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisenum { 152b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MEMWIN0_APERTURE = 65536, 153b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MEMWIN0_BASE = 0x30000, 154b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MEMWIN1_APERTURE = 32768, 155b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MEMWIN1_BASE = 0x28000, 156b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MEMWIN2_APERTURE = 2048, 157b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MEMWIN2_BASE = 0x1b800, 158b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 159b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 160b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisenum { 161b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MAX_TXQ_ENTRIES = 16384, 162b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MAX_CTRL_TXQ_ENTRIES = 1024, 163b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MAX_RSPQ_ENTRIES = 16384, 164b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MAX_RX_BUFFERS = 16384, 165b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MIN_TXQ_ENTRIES = 32, 166b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MIN_CTRL_TXQ_ENTRIES = 32, 167b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MIN_RSPQ_ENTRIES = 128, 168b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MIN_FL_ENTRIES = 16 169b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 170b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 171b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ 172b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ 173b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) 174b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 175060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis#define CH_DEVICE(devid, data) { PCI_VDEVICE(CHELSIO, devid), (data) } 176b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 177b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { 178060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis CH_DEVICE(0xa000, 0), /* PE10K */ 179ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4001, -1), 180ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4002, -1), 181ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4003, -1), 182ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4004, -1), 183ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4005, -1), 184ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4006, -1), 185ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4007, -1), 186ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4008, -1), 187ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4009, -1), 188ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x400a, -1), 189ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4401, 4), 190ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4402, 4), 191ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4403, 4), 192ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4404, 4), 193ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4405, 4), 194ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4406, 4), 195ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4407, 4), 196ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4408, 4), 197ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x4409, 4), 198ccea790ef033cc890ca4b416a783e9f9dffe556eDimitris Michailidis CH_DEVICE(0x440a, 4), 199f637d577cfe7b9fabf09a7e6a3c59f62b3225cd5Vipul Pandya CH_DEVICE(0x440d, 4), 200f637d577cfe7b9fabf09a7e6a3c59f62b3225cd5Vipul Pandya CH_DEVICE(0x440e, 4), 201b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis { 0, } 202b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 203b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 204b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define FW_FNAME "cxgb4/t4fw.bin" 205b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 206b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_DESCRIPTION(DRV_DESC); 207b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_AUTHOR("Chelsio Communications"); 208b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_LICENSE("Dual BSD/GPL"); 209b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_VERSION(DRV_VERSION); 210b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_DEVICE_TABLE(pci, cxgb4_pci_tbl); 211b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_FIRMWARE(FW_FNAME); 212b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 213b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int dflt_msg_enable = DFLT_MSG_ENABLE; 214b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 215b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidismodule_param(dflt_msg_enable, int, 0644); 216b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_PARM_DESC(dflt_msg_enable, "Chelsio T4 default message enable bitmap"); 217b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 218b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 219b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * The driver uses the best interrupt scheme available on a platform in the 220b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * order MSI-X, MSI, legacy INTx interrupts. This parameter determines which 221b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * of these schemes the driver may consider as follows: 222b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 223b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * msi = 2: choose from among all three options 224b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * msi = 1: only consider MSI and INTx interrupts 225b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * msi = 0: force INTx interrupts 226b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 227b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int msi = 2; 228b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 229b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidismodule_param(msi, int, 0644); 230b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_PARM_DESC(msi, "whether to use INTx (0), MSI (1) or MSI-X (2)"); 231b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 232b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 233b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Queue interrupt hold-off timer values. Queues default to the first of these 234b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * upon creation. 235b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 236b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic unsigned int intr_holdoff[SGE_NTIMERS - 1] = { 5, 10, 20, 50, 100 }; 237b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 238b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidismodule_param_array(intr_holdoff, uint, NULL, 0644); 239b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_PARM_DESC(intr_holdoff, "values for queue interrupt hold-off timers " 240b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "0..4 in microseconds"); 241b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 242b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic unsigned int intr_cnt[SGE_NCOUNTERS - 1] = { 4, 8, 16 }; 243b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 244b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidismodule_param_array(intr_cnt, uint, NULL, 0644); 245b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_PARM_DESC(intr_cnt, 246b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "thresholds 1..3 for queue interrupt packet counters"); 247b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 248eb93992207dadb946a3b5cf4544957dc924a6f58Rusty Russellstatic bool vf_acls; 249b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 250b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#ifdef CONFIG_PCI_IOV 251b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidismodule_param(vf_acls, bool, 0644); 252b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_PARM_DESC(vf_acls, "if set enable virtualization L2 ACL enforcement"); 253b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 254b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic unsigned int num_vf[4]; 255b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 256b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidismodule_param_array(num_vf, uint, NULL, 0644); 257b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisMODULE_PARM_DESC(num_vf, "number of VFs for each of PFs 0-3"); 258b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#endif 259b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 260b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic struct dentry *cxgb4_debugfs_root; 261b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 262b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic LIST_HEAD(adapter_list); 263b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic DEFINE_MUTEX(uld_mutex); 264b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic struct cxgb4_uld_info ulds[CXGB4_ULD_MAX]; 265b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic const char *uld_str[] = { "RDMA", "iSCSI" }; 266b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 267b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void link_report(struct net_device *dev) 268b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 269b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!netif_carrier_ok(dev)) 270b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev_info(dev, "link down\n"); 271b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else { 272b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis static const char *fc[] = { "no", "Rx", "Tx", "Tx/Rx" }; 273b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 274b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const char *s = "10Mbps"; 275b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *p = netdev_priv(dev); 276b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 277b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis switch (p->link_cfg.speed) { 278b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis case SPEED_10000: 279b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s = "10Gbps"; 280b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis break; 281b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis case SPEED_1000: 282b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s = "1000Mbps"; 283b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis break; 284b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis case SPEED_100: 285b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s = "100Mbps"; 286b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis break; 287b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 288b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 289b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s, 290b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis fc[p->link_cfg.fc]); 291b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 292b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 293b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 294b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisvoid t4_os_link_changed(struct adapter *adapter, int port_id, int link_stat) 295b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 296b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct net_device *dev = adapter->port[port_id]; 297b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 298b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* Skip changes from disabled ports. */ 299b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (netif_running(dev) && link_stat != netif_carrier_ok(dev)) { 300b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (link_stat) 301b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netif_carrier_on(dev); 302b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else 303b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netif_carrier_off(dev); 304b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 305b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis link_report(dev); 306b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 307b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 308b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 309b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisvoid t4_os_portmod_changed(const struct adapter *adap, int port_id) 310b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 311b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis static const char *mod_str[] = { 312a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis NULL, "LR", "SR", "ER", "passive DA", "active DA", "LRM" 313b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis }; 314b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 315b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct net_device *dev = adap->port[port_id]; 316b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *pi = netdev_priv(dev); 317b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 318b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (pi->mod_type == FW_PORT_MOD_TYPE_NONE) 319b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev_info(dev, "port module unplugged\n"); 320a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis else if (pi->mod_type < ARRAY_SIZE(mod_str)) 321b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev_info(dev, "%s module inserted\n", mod_str[pi->mod_type]); 322b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 323b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 324b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 325b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Configure the exact and hash address filters to handle a port's multicast 326b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * and secondary unicast MAC addresses. 327b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 328b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_addr_filters(const struct net_device *dev, bool sleep) 329b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 330b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u64 mhash = 0; 331b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u64 uhash = 0; 332b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis bool free = true; 333b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u16 filt_idx[7]; 334b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const u8 *addr[7]; 335b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret, naddr = 0; 336b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct netdev_hw_addr *ha; 337b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int uc_cnt = netdev_uc_count(dev); 3384a35ecf8bf1c4b039503fa554100fe85c761de76David S. Miller int mc_cnt = netdev_mc_count(dev); 339b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *pi = netdev_priv(dev); 340060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis unsigned int mb = pi->adapter->fn; 341b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 342b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* first do the secondary unicast addresses */ 343b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev_for_each_uc_addr(ha, dev) { 344b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis addr[naddr++] = ha->addr; 345b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (--uc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) { 346060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_alloc_mac_filt(pi->adapter, mb, pi->viid, free, 347b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis naddr, addr, filt_idx, &uhash, sleep); 348b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 349b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 350b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 351b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free = false; 352b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis naddr = 0; 353b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 354b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 355b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 356b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* next set up the multicast addresses */ 3574a35ecf8bf1c4b039503fa554100fe85c761de76David S. Miller netdev_for_each_mc_addr(ha, dev) { 3584a35ecf8bf1c4b039503fa554100fe85c761de76David S. Miller addr[naddr++] = ha->addr; 3594a35ecf8bf1c4b039503fa554100fe85c761de76David S. Miller if (--mc_cnt == 0 || naddr >= ARRAY_SIZE(addr)) { 360060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_alloc_mac_filt(pi->adapter, mb, pi->viid, free, 361b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis naddr, addr, filt_idx, &mhash, sleep); 362b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 363b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 364b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 365b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free = false; 366b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis naddr = 0; 367b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 368b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 369b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 370060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis return t4_set_addr_hash(pi->adapter, mb, pi->viid, uhash != 0, 371b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis uhash | mhash, sleep); 372b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 373b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 374b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 375b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Set Rx properties of a port, such as promiscruity, address filters, and MTU. 376b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * If @mtu is -1 it is left unchanged. 377b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 378b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok) 379b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 380b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret; 381b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 382b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 383b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = set_addr_filters(dev, sleep_ok); 384b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret == 0) 385060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, mtu, 386b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (dev->flags & IFF_PROMISC) ? 1 : 0, 387f8f5aafa960883bc3f1b8f85f1cf8199d0c85879Dimitris Michailidis (dev->flags & IFF_ALLMULTI) ? 1 : 0, 1, -1, 388b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis sleep_ok); 389b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 390b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 391b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 392b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 393b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * link_start - enable a port 394b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @dev: the port to enable 395b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 396b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Performs the MAC and PHY actions needed to enable a port. 397b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 398b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int link_start(struct net_device *dev) 399b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 400b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret; 401b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 402060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis unsigned int mb = pi->adapter->fn; 403b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 404b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 405b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * We do not set address filters and promiscuity here, the stack does 406b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * that step explicitly. 407b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 408060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_set_rxmode(pi->adapter, mb, pi->viid, dev->mtu, -1, -1, -1, 40919ecae2c8fd5e54e40ace914a41d8e1beb41612cDimitris Michailidis !!(dev->features & NETIF_F_HW_VLAN_RX), true); 410b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret == 0) { 411060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_change_mac(pi->adapter, mb, pi->viid, 412b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->xact_addr_filt, dev->dev_addr, true, 413b6bd29e793c1747e0b4be8791d5738acea3a86dfDimitris Michailidis true); 414b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret >= 0) { 415b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->xact_addr_filt = ret; 416b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = 0; 417b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 418b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 419b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret == 0) 420060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_link_start(pi->adapter, mb, pi->tx_chan, 421060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis &pi->link_cfg); 422b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret == 0) 423060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_enable_vi(pi->adapter, mb, pi->viid, true, true); 424b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 425b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 426b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 427b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 428b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Response queue handler for the FW event queue. 429b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 430b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, 431b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct pkt_gl *gl) 432b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 433b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u8 opcode = ((const struct rss_header *)rsp)->opcode; 434b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 435b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis rsp++; /* skip RSS header */ 436b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (likely(opcode == CPL_SGE_EGR_UPDATE)) { 437b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct cpl_sge_egr_update *p = (void *)rsp; 438b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int qid = EGR_QID(ntohl(p->opcode_qid)); 439e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis struct sge_txq *txq; 440b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 441e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis txq = q->adap->sge.egr_map[qid - q->adap->sge.egr_start]; 442b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis txq->restarts++; 443e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis if ((u8 *)txq < (u8 *)q->adap->sge.ofldtxq) { 444b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_eth_txq *eq; 445b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 446b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis eq = container_of(txq, struct sge_eth_txq, q); 447b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netif_tx_wake_queue(eq->txq); 448b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else { 449b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_ofld_txq *oq; 450b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 451b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis oq = container_of(txq, struct sge_ofld_txq, q); 452b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis tasklet_schedule(&oq->qresume_tsk); 453b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 454b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else if (opcode == CPL_FW6_MSG || opcode == CPL_FW4_MSG) { 455b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct cpl_fw6_msg *p = (void *)rsp; 456b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 457b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (p->type == 0) 458b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_handle_fw_rpl(q->adap, p->data); 459b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else if (opcode == CPL_L2T_WRITE_RPL) { 460b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct cpl_l2t_write_rpl *p = (void *)rsp; 461b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 462b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis do_l2t_write_rpl(q->adap, p); 463b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else 464b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_err(q->adap->pdev_dev, 465b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "unexpected CPL %#x on FW event queue\n", opcode); 466b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 467b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 468b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 469b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 470b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * uldrx_handler - response queue handler for ULD queues 471b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @q: the response queue that received the packet 472b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @rsp: the response queue descriptor holding the offload message 473b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @gl: the gather list of packet fragments 474b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 475b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Deliver an ingress offload packet to a ULD. All processing is done by 476b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * the ULD, we just maintain statistics. 477b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 478b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int uldrx_handler(struct sge_rspq *q, const __be64 *rsp, 479b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct pkt_gl *gl) 480b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 481b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_ofld_rxq *rxq = container_of(q, struct sge_ofld_rxq, rspq); 482b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 483b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ulds[q->uld].rx_handler(q->adap->uld_handle[q->uld], rsp, gl)) { 484b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis rxq->stats.nomem++; 485b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -1; 486b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 487b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (gl == NULL) 488b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis rxq->stats.imm++; 489b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else if (gl == CXGB4_MSG_AN) 490b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis rxq->stats.an++; 491b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else 492b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis rxq->stats.pkts++; 493b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 494b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 495b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 496b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void disable_msi(struct adapter *adapter) 497b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 498b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adapter->flags & USING_MSIX) { 499b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_disable_msix(adapter->pdev); 500b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->flags &= ~USING_MSIX; 501b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else if (adapter->flags & USING_MSI) { 502b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_disable_msi(adapter->pdev); 503b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->flags &= ~USING_MSI; 504b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 505b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 506b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 507b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 508b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Interrupt handler for non-data events used with MSI-X. 509b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 510b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic irqreturn_t t4_nondata_intr(int irq, void *cookie) 511b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 512b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap = cookie; 513b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 514b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u32 v = t4_read_reg(adap, MYPF_REG(PL_PF_INT_CAUSE)); 515b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (v & PFSW) { 516b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->swintr = 1; 517b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_write_reg(adap, MYPF_REG(PL_PF_INT_CAUSE), v); 518b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 519b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_slow_intr_handler(adap); 520b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return IRQ_HANDLED; 521b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 522b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 523b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 524b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Name the MSI-X interrupts. 525b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 526b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void name_msix_vecs(struct adapter *adap) 527b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 528ba27816cd8167c64652406d86ca78bcc5989f20fDimitris Michailidis int i, j, msi_idx = 2, n = sizeof(adap->msix_info[0].desc); 529b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 530b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* non-data interrupts */ 531b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis snprintf(adap->msix_info[0].desc, n, "%s", adap->port[0]->name); 532b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 533b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* FW events */ 534b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis snprintf(adap->msix_info[1].desc, n, "%s-FWeventq", 535b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis adap->port[0]->name); 536b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 537b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* Ethernet queues */ 538b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adap, j) { 539b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct net_device *d = adap->port[j]; 540b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *pi = netdev_priv(d); 541b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 542ba27816cd8167c64652406d86ca78bcc5989f20fDimitris Michailidis for (i = 0; i < pi->nqsets; i++, msi_idx++) 543b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis snprintf(adap->msix_info[msi_idx].desc, n, "%s-Rx%d", 544b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis d->name, i); 545b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 546b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 547b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* offload queues */ 548ba27816cd8167c64652406d86ca78bcc5989f20fDimitris Michailidis for_each_ofldrxq(&adap->sge, i) 549ba27816cd8167c64652406d86ca78bcc5989f20fDimitris Michailidis snprintf(adap->msix_info[msi_idx++].desc, n, "%s-ofld%d", 550b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis adap->port[0]->name, i); 551ba27816cd8167c64652406d86ca78bcc5989f20fDimitris Michailidis 552ba27816cd8167c64652406d86ca78bcc5989f20fDimitris Michailidis for_each_rdmarxq(&adap->sge, i) 553ba27816cd8167c64652406d86ca78bcc5989f20fDimitris Michailidis snprintf(adap->msix_info[msi_idx++].desc, n, "%s-rdma%d", 554b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis adap->port[0]->name, i); 555b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 556b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 557b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int request_msix_queue_irqs(struct adapter *adap) 558b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 559b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge *s = &adap->sge; 560b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int err, ethqidx, ofldqidx = 0, rdmaqidx = 0, msi = 2; 561b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 562b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = request_irq(adap->msix_info[1].vec, t4_sge_intr_msix, 0, 563b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->msix_info[1].desc, &s->fw_evtq); 564b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 565b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 566b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 567b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_ethrxq(s, ethqidx) { 568b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0, 569b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->msix_info[msi].desc, 570b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis &s->ethrxq[ethqidx].rspq); 571b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 572b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto unwind; 573b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi++; 574b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 575b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_ofldrxq(s, ofldqidx) { 576b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0, 577b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->msix_info[msi].desc, 578b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis &s->ofldrxq[ofldqidx].rspq); 579b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 580b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto unwind; 581b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi++; 582b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 583b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_rdmarxq(s, rdmaqidx) { 584b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0, 585b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->msix_info[msi].desc, 586b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis &s->rdmarxq[rdmaqidx].rspq); 587b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 588b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto unwind; 589b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi++; 590b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 591b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 592b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 593b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisunwind: 594b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while (--rdmaqidx >= 0) 595b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adap->msix_info[--msi].vec, 596b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis &s->rdmarxq[rdmaqidx].rspq); 597b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while (--ofldqidx >= 0) 598b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adap->msix_info[--msi].vec, 599b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis &s->ofldrxq[ofldqidx].rspq); 600b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while (--ethqidx >= 0) 601b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adap->msix_info[--msi].vec, &s->ethrxq[ethqidx].rspq); 602b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adap->msix_info[1].vec, &s->fw_evtq); 603b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 604b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 605b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 606b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void free_msix_queue_irqs(struct adapter *adap) 607b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 608b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i, msi = 2; 609b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge *s = &adap->sge; 610b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 611b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adap->msix_info[1].vec, &s->fw_evtq); 612b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_ethrxq(s, i) 613b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adap->msix_info[msi++].vec, &s->ethrxq[i].rspq); 614b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_ofldrxq(s, i) 615b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adap->msix_info[msi++].vec, &s->ofldrxq[i].rspq); 616b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_rdmarxq(s, i) 617b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adap->msix_info[msi++].vec, &s->rdmarxq[i].rspq); 618b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 619b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 620b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 621671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis * write_rss - write the RSS table for a given port 622671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis * @pi: the port 623671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis * @queues: array of queue indices for RSS 624671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis * 625671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis * Sets up the portion of the HW RSS table for the port's VI to distribute 626671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis * packets to the Rx queues in @queues. 627671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis */ 628671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidisstatic int write_rss(const struct port_info *pi, const u16 *queues) 629671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis{ 630671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis u16 *rss; 631671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis int i, err; 632671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis const struct sge_eth_rxq *q = &pi->adapter->sge.ethrxq[pi->first_qset]; 633671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 634671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis rss = kmalloc(pi->rss_size * sizeof(u16), GFP_KERNEL); 635671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis if (!rss) 636671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis return -ENOMEM; 637671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 638671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis /* map the queue indices to queue ids */ 639671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis for (i = 0; i < pi->rss_size; i++, queues++) 640671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis rss[i] = q[*queues].rspq.abs_id; 641671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 642060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis err = t4_config_rss_range(pi->adapter, pi->adapter->fn, pi->viid, 0, 643060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis pi->rss_size, rss, pi->rss_size); 644671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis kfree(rss); 645671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis return err; 646671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis} 647671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 648671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis/** 649b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * setup_rss - configure RSS 650b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @adap: the adapter 651b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 652671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis * Sets up RSS for each port. 653b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 654b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int setup_rss(struct adapter *adap) 655b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 656671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis int i, err; 657b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 658b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adap, i) { 659b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *pi = adap2pinfo(adap, i); 660b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 661671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis err = write_rss(pi, pi->rss); 662b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 663b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 664b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 665b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 666b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 667b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 668b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 669e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis * Return the channel of the ingress queue with the given qid. 670e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis */ 671e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidisstatic unsigned int rxq_to_chan(const struct sge *p, unsigned int qid) 672e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis{ 673e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis qid -= p->ingr_start; 674e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis return netdev2pinfo(p->ingr_map[qid]->netdev)->tx_chan; 675e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis} 676e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis 677e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis/* 678b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Wait until all NAPI handlers are descheduled. 679b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 680b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void quiesce_rx(struct adapter *adap) 681b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 682b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i; 683b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 684b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) { 685b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_rspq *q = adap->sge.ingr_map[i]; 686b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 687b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (q && q->handler) 688b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis napi_disable(&q->napi); 689b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 690b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 691b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 692b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 693b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Enable NAPI scheduling and interrupt generation for all Rx queues. 694b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 695b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void enable_rx(struct adapter *adap) 696b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 697b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i; 698b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 699b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(adap->sge.ingr_map); i++) { 700b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_rspq *q = adap->sge.ingr_map[i]; 701b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 702b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!q) 703b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis continue; 704b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (q->handler) 705b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis napi_enable(&q->napi); 706b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 0-increment GTS to start the timer and enable interrupts */ 707b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_write_reg(adap, MYPF_REG(SGE_PF_GTS), 708b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis SEINTARM(q->intr_params) | 709b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis INGRESSQID(q->cntxt_id)); 710b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 711b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 712b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 713b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 714b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * setup_sge_queues - configure SGE Tx/Rx/response queues 715b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @adap: the adapter 716b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 717b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Determines how many sets of SGE queues to use and initializes them. 718b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * We support multiple queue sets per port if we have MSI-X, otherwise 719b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * just one queue set per port. 720b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 721b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int setup_sge_queues(struct adapter *adap) 722b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 723b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int err, msi_idx, i, j; 724b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge *s = &adap->sge; 725b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 726b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis bitmap_zero(s->starving_fl, MAX_EGRQ); 727b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis bitmap_zero(s->txq_maperr, MAX_EGRQ); 728b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 729b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adap->flags & USING_MSIX) 730b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi_idx = 1; /* vector 0 is for non-queue interrupts */ 731b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else { 732b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_sge_alloc_rxq(adap, &s->intrq, false, adap->port[0], 0, 733b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis NULL, NULL); 734b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 735b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 736b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi_idx = -((int)s->intrq.abs_id + 1); 737b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 738b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 739b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_sge_alloc_rxq(adap, &s->fw_evtq, true, adap->port[0], 740b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi_idx, NULL, fwevtq_handler); 741b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) { 742b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisfreeout: t4_free_sge_resources(adap); 743b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 744b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 745b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 746b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adap, i) { 747b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct net_device *dev = adap->port[i]; 748b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 749b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_eth_rxq *q = &s->ethrxq[pi->first_qset]; 750b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_eth_txq *t = &s->ethtxq[pi->first_qset]; 751b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 752b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (j = 0; j < pi->nqsets; j++, q++) { 753b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (msi_idx > 0) 754b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi_idx++; 755b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev, 756b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi_idx, &q->fl, 757b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_ethrx_handler); 758b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 759b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto freeout; 760b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis q->rspq.idx = j; 761b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memset(&q->stats, 0, sizeof(q->stats)); 762b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 763b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (j = 0; j < pi->nqsets; j++, t++) { 764b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_sge_alloc_eth_txq(adap, t, dev, 765b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev_get_tx_queue(dev, j), 766b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->fw_evtq.cntxt_id); 767b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 768b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto freeout; 769b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 770b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 771b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 772b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis j = s->ofldqsets / adap->params.nports; /* ofld queues per channel */ 773b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_ofldrxq(s, i) { 774b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_ofld_rxq *q = &s->ofldrxq[i]; 775b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct net_device *dev = adap->port[i / j]; 776b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 777b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (msi_idx > 0) 778b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi_idx++; 779b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_sge_alloc_rxq(adap, &q->rspq, false, dev, msi_idx, 780b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis &q->fl, uldrx_handler); 781b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 782b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto freeout; 783b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memset(&q->stats, 0, sizeof(q->stats)); 784b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ofld_rxq[i] = q->rspq.abs_id; 785b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_sge_alloc_ofld_txq(adap, &s->ofldtxq[i], dev, 786b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->fw_evtq.cntxt_id); 787b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 788b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto freeout; 789b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 790b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 791b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_rdmarxq(s, i) { 792b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_ofld_rxq *q = &s->rdmarxq[i]; 793b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 794b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (msi_idx > 0) 795b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi_idx++; 796b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_sge_alloc_rxq(adap, &q->rspq, false, adap->port[i], 797b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis msi_idx, &q->fl, uldrx_handler); 798b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 799b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto freeout; 800b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memset(&q->stats, 0, sizeof(q->stats)); 801b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->rdma_rxq[i] = q->rspq.abs_id; 802b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 803b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 804b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adap, i) { 805b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 806b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Note that ->rdmarxq[i].rspq.cntxt_id below is 0 if we don't 807b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * have RDMA queues, and that's the right value. 808b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 809b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_sge_alloc_ctrl_txq(adap, &s->ctrlq[i], adap->port[i], 810b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->fw_evtq.cntxt_id, 811b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->rdmarxq[i].rspq.cntxt_id); 812b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 813b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto freeout; 814b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 815b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 816b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_write_reg(adap, MPS_TRC_RSS_CONTROL, 817b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) | 818b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis QUEUENUMBER(s->ethrxq[0].rspq.abs_id)); 819b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 820b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 821b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 822b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 823b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Returns 0 if new FW was successfully loaded, a positive errno if a load was 824b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * started but failed, and a negative errno if flash load couldn't start. 825b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 826b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int upgrade_fw(struct adapter *adap) 827b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 828b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret; 829b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u32 vers; 830b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct fw_hdr *hdr; 831b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct firmware *fw; 832b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct device *dev = adap->pdev_dev; 833b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 834b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = request_firmware(&fw, FW_FNAME, dev); 835b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) { 836b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_err(dev, "unable to load firmware image " FW_FNAME 837b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ", error %d\n", ret); 838b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 839b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 840b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 841b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis hdr = (const struct fw_hdr *)fw->data; 842b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis vers = ntohl(hdr->fw_ver); 843b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (FW_HDR_FW_VER_MAJOR_GET(vers) != FW_VERSION_MAJOR) { 844b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = -EINVAL; /* wrong major version, won't do */ 845b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out; 846b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 847b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 848b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 849b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * If the flash FW is unusable or we found something newer, load it. 850b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 851b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (FW_HDR_FW_VER_MAJOR_GET(adap->params.fw_vers) != FW_VERSION_MAJOR || 852b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis vers > adap->params.fw_vers) { 853b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = -t4_load_fw(adap, fw->data, fw->size); 854b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!ret) 855b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_info(dev, "firmware upgraded to version %pI4 from " 856b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_FNAME "\n", &hdr->fw_ver); 857b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 858b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisout: release_firmware(fw); 859b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 860b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 861b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 862b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 863b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. 864b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * The allocated memory is cleared. 865b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 866b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisvoid *t4_alloc_mem(size_t size) 867b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 86889bf67f1f080c947c92f8773482d9e57767ca292Eric Dumazet void *p = kzalloc(size, GFP_KERNEL); 869b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 870b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!p) 87189bf67f1f080c947c92f8773482d9e57767ca292Eric Dumazet p = vzalloc(size); 872b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return p; 873b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 874b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 875b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 876b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Free memory allocated through alloc_mem(). 877b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 87831b9c19bfe32bed7fdf80cd0b1aa9d0f0569844astephen hemmingerstatic void t4_free_mem(void *addr) 879b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 880b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (is_vmalloc_addr(addr)) 881b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis vfree(addr); 882b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else 883b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis kfree(addr); 884b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 885b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 886b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic inline int is_offload(const struct adapter *adap) 887b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 888b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return adap->params.offload; 889b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 890b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 891b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 892b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Implementation of ethtool operations. 893b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 894b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 895b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic u32 get_msglevel(struct net_device *dev) 896b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 897b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return netdev2adap(dev)->msg_enable; 898b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 899b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 900b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void set_msglevel(struct net_device *dev, u32 val) 901b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 902b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev2adap(dev)->msg_enable = val; 903b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 904b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 905b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic char stats_strings[][ETH_GSTRING_LEN] = { 906b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxOctetsOK ", 907b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxFramesOK ", 908b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxBroadcastFrames ", 909b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxMulticastFrames ", 910b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxUnicastFrames ", 911b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxErrorFrames ", 912b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 913b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxFrames64 ", 914b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxFrames65To127 ", 915b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxFrames128To255 ", 916b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxFrames256To511 ", 917b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxFrames512To1023 ", 918b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxFrames1024To1518 ", 919b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxFrames1519ToMax ", 920b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 921b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxFramesDropped ", 922b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxPauseFrames ", 923b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxPPP0Frames ", 924b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxPPP1Frames ", 925b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxPPP2Frames ", 926b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxPPP3Frames ", 927b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxPPP4Frames ", 928b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxPPP5Frames ", 929b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxPPP6Frames ", 930b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxPPP7Frames ", 931b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 932b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxOctetsOK ", 933b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFramesOK ", 934b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxBroadcastFrames ", 935b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxMulticastFrames ", 936b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxUnicastFrames ", 937b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 938b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFramesTooLong ", 939b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxJabberErrors ", 940b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFCSErrors ", 941b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxLengthErrors ", 942b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxSymbolErrors ", 943b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxRuntFrames ", 944b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 945b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFrames64 ", 946b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFrames65To127 ", 947b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFrames128To255 ", 948b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFrames256To511 ", 949b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFrames512To1023 ", 950b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFrames1024To1518 ", 951b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxFrames1519ToMax ", 952b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 953b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxPauseFrames ", 954b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxPPP0Frames ", 955b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxPPP1Frames ", 956b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxPPP2Frames ", 957b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxPPP3Frames ", 958b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxPPP4Frames ", 959b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxPPP5Frames ", 960b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxPPP6Frames ", 961b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxPPP7Frames ", 962b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 963b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxBG0FramesDropped ", 964b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxBG1FramesDropped ", 965b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxBG2FramesDropped ", 966b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxBG3FramesDropped ", 967b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxBG0FramesTrunc ", 968b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxBG1FramesTrunc ", 969b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxBG2FramesTrunc ", 970b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxBG3FramesTrunc ", 971b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 972b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TSO ", 973b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "TxCsumOffload ", 974b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "RxCsumGood ", 975b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "VLANextractions ", 976b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "VLANinsertions ", 9774a6346d4ea63b5e1390babf22f1cc0f113d8082bDimitris Michailidis "GROpackets ", 9784a6346d4ea63b5e1390babf22f1cc0f113d8082bDimitris Michailidis "GROmerged ", 979b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 980b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 981b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int get_sset_count(struct net_device *dev, int sset) 982b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 983b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis switch (sset) { 984b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis case ETH_SS_STATS: 985b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ARRAY_SIZE(stats_strings); 986b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis default: 987b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EOPNOTSUPP; 988b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 989b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 990b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 991b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define T4_REGMAP_SIZE (160 * 1024) 992b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 993b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int get_regs_len(struct net_device *dev) 994b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 995b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return T4_REGMAP_SIZE; 996b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 997b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 998b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int get_eeprom_len(struct net_device *dev) 999b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1000b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return EEPROMSIZE; 1001b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1002b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1003b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 1004b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1005b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = netdev2adap(dev); 1006b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 100723020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 100823020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones strlcpy(info->version, DRV_VERSION, sizeof(info->version)); 100923020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones strlcpy(info->bus_info, pci_name(adapter->pdev), 101023020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones sizeof(info->bus_info)); 1011b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 101284b405011166e663fe9ef56c29b1d76f59b35568Rick Jones if (adapter->params.fw_vers) 1013b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis snprintf(info->fw_version, sizeof(info->fw_version), 1014b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "%u.%u.%u.%u, TP %u.%u.%u.%u", 1015b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_HDR_FW_VER_MAJOR_GET(adapter->params.fw_vers), 1016b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_HDR_FW_VER_MINOR_GET(adapter->params.fw_vers), 1017b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_HDR_FW_VER_MICRO_GET(adapter->params.fw_vers), 1018b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_HDR_FW_VER_BUILD_GET(adapter->params.fw_vers), 1019b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_HDR_FW_VER_MAJOR_GET(adapter->params.tp_vers), 1020b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_HDR_FW_VER_MINOR_GET(adapter->params.tp_vers), 1021b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_HDR_FW_VER_MICRO_GET(adapter->params.tp_vers), 1022b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_HDR_FW_VER_BUILD_GET(adapter->params.tp_vers)); 1023b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1024b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1025b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void get_strings(struct net_device *dev, u32 stringset, u8 *data) 1026b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1027b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (stringset == ETH_SS_STATS) 1028b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memcpy(data, stats_strings, sizeof(stats_strings)); 1029b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1030b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1031b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 1032b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * port stats maintained per queue of the port. They should be in the same 1033b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * order as in stats_strings above. 1034b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 1035b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstruct queue_port_stats { 1036b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u64 tso; 1037b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u64 tx_csum; 1038b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u64 rx_csum; 1039b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u64 vlan_ex; 1040b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u64 vlan_ins; 10414a6346d4ea63b5e1390babf22f1cc0f113d8082bDimitris Michailidis u64 gro_pkts; 10424a6346d4ea63b5e1390babf22f1cc0f113d8082bDimitris Michailidis u64 gro_merged; 1043b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 1044b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1045b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void collect_sge_port_stats(const struct adapter *adap, 1046b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *p, struct queue_port_stats *s) 1047b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1048b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i; 1049b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct sge_eth_txq *tx = &adap->sge.ethtxq[p->first_qset]; 1050b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct sge_eth_rxq *rx = &adap->sge.ethrxq[p->first_qset]; 1051b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1052b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memset(s, 0, sizeof(*s)); 1053b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < p->nqsets; i++, rx++, tx++) { 1054b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->tso += tx->tso; 1055b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->tx_csum += tx->tx_cso; 1056b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->rx_csum += rx->stats.rx_cso; 1057b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->vlan_ex += rx->stats.vlan_ex; 1058b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->vlan_ins += tx->vlan_ins; 10594a6346d4ea63b5e1390babf22f1cc0f113d8082bDimitris Michailidis s->gro_pkts += rx->stats.lro_pkts; 10604a6346d4ea63b5e1390babf22f1cc0f113d8082bDimitris Michailidis s->gro_merged += rx->stats.lro_merged; 1061b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1062b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1063b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1064b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void get_stats(struct net_device *dev, struct ethtool_stats *stats, 1065b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u64 *data) 1066b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1067b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 1068b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = pi->adapter; 1069b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1070b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_get_port_stats(adapter, pi->tx_chan, (struct port_stats *)data); 1071b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1072b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis data += sizeof(struct port_stats) / sizeof(u64); 1073b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis collect_sge_port_stats(adapter, pi, (struct queue_port_stats *)data); 1074b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1075b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1076b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 1077b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Return a version number to identify the type of adapter. The scheme is: 1078b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * - bits 0..9: chip version 1079b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * - bits 10..15: chip revision 1080835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis * - bits 16..23: register dump version 1081b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 1082b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic inline unsigned int mk_adap_vers(const struct adapter *ap) 1083b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1084835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis return 4 | (ap->params.rev << 10) | (1 << 16); 1085b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1086b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1087b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void reg_block_dump(struct adapter *ap, void *buf, unsigned int start, 1088b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int end) 1089b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1090b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u32 *p = buf + start; 1091b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1092b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for ( ; start <= end; start += sizeof(u32)) 1093b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis *p++ = t4_read_reg(ap, start); 1094b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1095b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1096b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void get_regs(struct net_device *dev, struct ethtool_regs *regs, 1097b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis void *buf) 1098b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1099b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis static const unsigned int reg_ranges[] = { 1100b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1008, 0x1108, 1101b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1180, 0x11b4, 1102b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x11fc, 0x123c, 1103b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1300, 0x173c, 1104b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1800, 0x18fc, 1105b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x3000, 0x30d8, 1106b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x30e0, 0x5924, 1107b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x5960, 0x59d4, 1108b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x5a00, 0x5af8, 1109b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6000, 0x6098, 1110b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6100, 0x6150, 1111b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6200, 0x6208, 1112b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6240, 0x6248, 1113b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6280, 0x6338, 1114b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6370, 0x638c, 1115b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6400, 0x643c, 1116b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6500, 0x6524, 1117b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6a00, 0x6a38, 1118b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6a60, 0x6a78, 1119b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6b00, 0x6b84, 1120b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6bf0, 0x6c84, 1121b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6cf0, 0x6d84, 1122b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6df0, 0x6e84, 1123b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6ef0, 0x6f84, 1124b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x6ff0, 0x7084, 1125b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x70f0, 0x7184, 1126b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x71f0, 0x7284, 1127b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x72f0, 0x7384, 1128b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x73f0, 0x7450, 1129b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x7500, 0x7530, 1130b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x7600, 0x761c, 1131b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x7680, 0x76cc, 1132b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x7700, 0x7798, 1133b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x77c0, 0x77fc, 1134b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x7900, 0x79fc, 1135b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x7b00, 0x7c38, 1136b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x7d00, 0x7efc, 1137b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x8dc0, 0x8e1c, 1138b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x8e30, 0x8e78, 1139b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x8ea0, 0x8f6c, 1140b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x8fc0, 0x9074, 1141b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x90fc, 0x90fc, 1142b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9400, 0x9458, 1143b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9600, 0x96bc, 1144b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9800, 0x9808, 1145b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9820, 0x983c, 1146b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9850, 0x9864, 1147b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9c00, 0x9c6c, 1148b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9c80, 0x9cec, 1149b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9d00, 0x9d6c, 1150b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9d80, 0x9dec, 1151b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9e00, 0x9e6c, 1152b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9e80, 0x9eec, 1153b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9f00, 0x9f6c, 1154b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x9f80, 0x9fec, 1155b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0xd004, 0xd03c, 1156b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0xdfc0, 0xdfe0, 1157b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0xe000, 0xea7c, 1158b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0xf000, 0x11190, 1159835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x19040, 0x1906c, 1160835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x19078, 0x19080, 1161835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x1908c, 0x19124, 1162b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x19150, 0x191b0, 1163b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x191d0, 0x191e8, 1164b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x19238, 0x1924c, 1165b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x193f8, 0x19474, 1166b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x19490, 0x194f8, 1167b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x19800, 0x19f30, 1168b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1a000, 0x1a06c, 1169b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1a0b0, 0x1a120, 1170b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1a128, 0x1a138, 1171b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1a190, 0x1a1c4, 1172b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1a1fc, 0x1a1fc, 1173b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e040, 0x1e04c, 1174835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x1e284, 0x1e28c, 1175b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e2c0, 0x1e2c0, 1176b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e2e0, 0x1e2e0, 1177b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e300, 0x1e384, 1178b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e3c0, 0x1e3c8, 1179b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e440, 0x1e44c, 1180835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x1e684, 0x1e68c, 1181b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e6c0, 0x1e6c0, 1182b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e6e0, 0x1e6e0, 1183b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e700, 0x1e784, 1184b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e7c0, 0x1e7c8, 1185b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1e840, 0x1e84c, 1186835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x1ea84, 0x1ea8c, 1187b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1eac0, 0x1eac0, 1188b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1eae0, 0x1eae0, 1189b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1eb00, 0x1eb84, 1190b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1ebc0, 0x1ebc8, 1191b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1ec40, 0x1ec4c, 1192835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x1ee84, 0x1ee8c, 1193b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1eec0, 0x1eec0, 1194b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1eee0, 0x1eee0, 1195b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1ef00, 0x1ef84, 1196b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1efc0, 0x1efc8, 1197b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f040, 0x1f04c, 1198835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x1f284, 0x1f28c, 1199b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f2c0, 0x1f2c0, 1200b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f2e0, 0x1f2e0, 1201b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f300, 0x1f384, 1202b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f3c0, 0x1f3c8, 1203b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f440, 0x1f44c, 1204835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x1f684, 0x1f68c, 1205b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f6c0, 0x1f6c0, 1206b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f6e0, 0x1f6e0, 1207b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f700, 0x1f784, 1208b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f7c0, 0x1f7c8, 1209b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1f840, 0x1f84c, 1210835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x1fa84, 0x1fa8c, 1211b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1fac0, 0x1fac0, 1212b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1fae0, 0x1fae0, 1213b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1fb00, 0x1fb84, 1214b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1fbc0, 0x1fbc8, 1215b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1fc40, 0x1fc4c, 1216835bb606faffcd761e7abbc6b5de89ea5c409123Dimitris Michailidis 0x1fe84, 0x1fe8c, 1217b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1fec0, 0x1fec0, 1218b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1fee0, 0x1fee0, 1219b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1ff00, 0x1ff84, 1220b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x1ffc0, 0x1ffc8, 1221b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x20000, 0x2002c, 1222b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x20100, 0x2013c, 1223b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x20190, 0x201c8, 1224b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x20200, 0x20318, 1225b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x20400, 0x20528, 1226b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x20540, 0x20614, 1227b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21000, 0x21040, 1228b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x2104c, 0x21060, 1229b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x210c0, 0x210ec, 1230b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21200, 0x21268, 1231b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21270, 0x21284, 1232b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x212fc, 0x21388, 1233b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21400, 0x21404, 1234b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21500, 0x21518, 1235b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x2152c, 0x2153c, 1236b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21550, 0x21554, 1237b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21600, 0x21600, 1238b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21608, 0x21628, 1239b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21630, 0x2163c, 1240b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21700, 0x2171c, 1241b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21780, 0x2178c, 1242b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21800, 0x21c38, 1243b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21c80, 0x21d7c, 1244b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x21e00, 0x21e04, 1245b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x22000, 0x2202c, 1246b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x22100, 0x2213c, 1247b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x22190, 0x221c8, 1248b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x22200, 0x22318, 1249b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x22400, 0x22528, 1250b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x22540, 0x22614, 1251b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23000, 0x23040, 1252b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x2304c, 0x23060, 1253b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x230c0, 0x230ec, 1254b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23200, 0x23268, 1255b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23270, 0x23284, 1256b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x232fc, 0x23388, 1257b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23400, 0x23404, 1258b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23500, 0x23518, 1259b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x2352c, 0x2353c, 1260b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23550, 0x23554, 1261b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23600, 0x23600, 1262b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23608, 0x23628, 1263b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23630, 0x2363c, 1264b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23700, 0x2371c, 1265b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23780, 0x2378c, 1266b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23800, 0x23c38, 1267b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23c80, 0x23d7c, 1268b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x23e00, 0x23e04, 1269b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x24000, 0x2402c, 1270b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x24100, 0x2413c, 1271b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x24190, 0x241c8, 1272b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x24200, 0x24318, 1273b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x24400, 0x24528, 1274b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x24540, 0x24614, 1275b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25000, 0x25040, 1276b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x2504c, 0x25060, 1277b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x250c0, 0x250ec, 1278b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25200, 0x25268, 1279b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25270, 0x25284, 1280b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x252fc, 0x25388, 1281b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25400, 0x25404, 1282b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25500, 0x25518, 1283b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x2552c, 0x2553c, 1284b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25550, 0x25554, 1285b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25600, 0x25600, 1286b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25608, 0x25628, 1287b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25630, 0x2563c, 1288b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25700, 0x2571c, 1289b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25780, 0x2578c, 1290b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25800, 0x25c38, 1291b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25c80, 0x25d7c, 1292b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x25e00, 0x25e04, 1293b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x26000, 0x2602c, 1294b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x26100, 0x2613c, 1295b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x26190, 0x261c8, 1296b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x26200, 0x26318, 1297b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x26400, 0x26528, 1298b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x26540, 0x26614, 1299b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27000, 0x27040, 1300b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x2704c, 0x27060, 1301b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x270c0, 0x270ec, 1302b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27200, 0x27268, 1303b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27270, 0x27284, 1304b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x272fc, 0x27388, 1305b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27400, 0x27404, 1306b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27500, 0x27518, 1307b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x2752c, 0x2753c, 1308b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27550, 0x27554, 1309b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27600, 0x27600, 1310b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27608, 0x27628, 1311b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27630, 0x2763c, 1312b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27700, 0x2771c, 1313b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27780, 0x2778c, 1314b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27800, 0x27c38, 1315b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27c80, 0x27d7c, 1316b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 0x27e00, 0x27e04 1317b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis }; 1318b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1319b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i; 1320b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *ap = netdev2adap(dev); 1321b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1322b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis regs->version = mk_adap_vers(ap); 1323b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1324b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memset(buf, 0, T4_REGMAP_SIZE); 1325b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(reg_ranges); i += 2) 1326b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis reg_block_dump(ap, buf, reg_ranges[i], reg_ranges[i + 1]); 1327b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1328b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1329b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int restart_autoneg(struct net_device *dev) 1330b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1331b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *p = netdev_priv(dev); 1332b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1333b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!netif_running(dev)) 1334b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EAGAIN; 1335b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (p->link_cfg.autoneg != AUTONEG_ENABLE) 1336b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1337060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis t4_restart_aneg(p->adapter, p->adapter->fn, p->tx_chan); 1338b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 1339b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1340b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1341c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidisstatic int identify_port(struct net_device *dev, 1342c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis enum ethtool_phys_id_state state) 1343b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1344c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis unsigned int val; 1345060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis struct adapter *adap = netdev2adap(dev); 1346060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis 1347c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis if (state == ETHTOOL_ID_ACTIVE) 1348c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis val = 0xffff; 1349c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis else if (state == ETHTOOL_ID_INACTIVE) 1350c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis val = 0; 1351c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis else 1352c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis return -EINVAL; 1353b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1354c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid, val); 1355b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1356b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1357b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps) 1358b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1359b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int v = 0; 1360b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1361a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XFI || 1362a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis type == FW_PORT_TYPE_BT_XAUI) { 1363b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_TP; 1364b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (caps & FW_PORT_CAP_SPEED_100M) 1365b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_100baseT_Full; 1366b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (caps & FW_PORT_CAP_SPEED_1G) 1367b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_1000baseT_Full; 1368b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (caps & FW_PORT_CAP_SPEED_10G) 1369b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_10000baseT_Full; 1370b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) { 1371b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_Backplane; 1372b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (caps & FW_PORT_CAP_SPEED_1G) 1373b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_1000baseKX_Full; 1374b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (caps & FW_PORT_CAP_SPEED_10G) 1375b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_10000baseKX4_Full; 1376b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else if (type == FW_PORT_TYPE_KR) 1377b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full; 1378a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis else if (type == FW_PORT_TYPE_BP_AP) 13797d5e77aafa39f3210b6273a44fe07508e837c3cbDimitris Michailidis v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | 13807d5e77aafa39f3210b6273a44fe07508e837c3cbDimitris Michailidis SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full; 13817d5e77aafa39f3210b6273a44fe07508e837c3cbDimitris Michailidis else if (type == FW_PORT_TYPE_BP4_AP) 13827d5e77aafa39f3210b6273a44fe07508e837c3cbDimitris Michailidis v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | 13837d5e77aafa39f3210b6273a44fe07508e837c3cbDimitris Michailidis SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full | 13847d5e77aafa39f3210b6273a44fe07508e837c3cbDimitris Michailidis SUPPORTED_10000baseKX4_Full; 1385a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis else if (type == FW_PORT_TYPE_FIBER_XFI || 1386a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis type == FW_PORT_TYPE_FIBER_XAUI || type == FW_PORT_TYPE_SFP) 1387b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_FIBRE; 1388b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1389b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (caps & FW_PORT_CAP_ANEG) 1390b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= SUPPORTED_Autoneg; 1391b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return v; 1392b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1393b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1394b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic unsigned int to_fw_linkcaps(unsigned int caps) 1395b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1396b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int v = 0; 1397b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1398b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (caps & ADVERTISED_100baseT_Full) 1399b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= FW_PORT_CAP_SPEED_100M; 1400b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (caps & ADVERTISED_1000baseT_Full) 1401b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= FW_PORT_CAP_SPEED_1G; 1402b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (caps & ADVERTISED_10000baseT_Full) 1403b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v |= FW_PORT_CAP_SPEED_10G; 1404b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return v; 1405b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1406b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1407b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 1408b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1409b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *p = netdev_priv(dev); 1410b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1411b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (p->port_type == FW_PORT_TYPE_BT_SGMII || 1412a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis p->port_type == FW_PORT_TYPE_BT_XFI || 1413b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis p->port_type == FW_PORT_TYPE_BT_XAUI) 1414b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->port = PORT_TP; 1415a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis else if (p->port_type == FW_PORT_TYPE_FIBER_XFI || 1416a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis p->port_type == FW_PORT_TYPE_FIBER_XAUI) 1417b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->port = PORT_FIBRE; 1418a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis else if (p->port_type == FW_PORT_TYPE_SFP) { 1419a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis if (p->mod_type == FW_PORT_MOD_TYPE_TWINAX_PASSIVE || 1420a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis p->mod_type == FW_PORT_MOD_TYPE_TWINAX_ACTIVE) 1421a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis cmd->port = PORT_DA; 1422a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis else 1423a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis cmd->port = PORT_FIBRE; 1424a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis } else 1425b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->port = PORT_OTHER; 1426b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1427b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (p->mdio_addr >= 0) { 1428b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->phy_address = p->mdio_addr; 1429b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->transceiver = XCVR_EXTERNAL; 1430b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ? 1431b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45; 1432b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else { 1433b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->phy_address = 0; /* not really, but no better option */ 1434b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->transceiver = XCVR_INTERNAL; 1435b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->mdio_support = 0; 1436b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1437b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1438b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->supported = from_fw_linkcaps(p->port_type, p->link_cfg.supported); 1439b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->advertising = from_fw_linkcaps(p->port_type, 1440b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis p->link_cfg.advertising); 1441707394972093e2056e1e8cc39be19cf9bcb3e7b3David Decotigny ethtool_cmd_speed_set(cmd, 1442707394972093e2056e1e8cc39be19cf9bcb3e7b3David Decotigny netif_carrier_ok(dev) ? p->link_cfg.speed : 0); 1443b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->duplex = DUPLEX_FULL; 1444b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->autoneg = p->link_cfg.autoneg; 1445b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->maxtxpkt = 0; 1446b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cmd->maxrxpkt = 0; 1447b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 1448b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1449b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1450b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic unsigned int speed_to_caps(int speed) 1451b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1452b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (speed == SPEED_100) 1453b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return FW_PORT_CAP_SPEED_100M; 1454b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (speed == SPEED_1000) 1455b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return FW_PORT_CAP_SPEED_1G; 1456b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (speed == SPEED_10000) 1457b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return FW_PORT_CAP_SPEED_10G; 1458b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 1459b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1460b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1461b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 1462b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1463b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int cap; 1464b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *p = netdev_priv(dev); 1465b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct link_config *lc = &p->link_cfg; 146625db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny u32 speed = ethtool_cmd_speed(cmd); 1467b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1468b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (cmd->duplex != DUPLEX_FULL) /* only full-duplex supported */ 1469b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1470b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1471b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!(lc->supported & FW_PORT_CAP_ANEG)) { 1472b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 1473b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * PHY offers a single speed. See if that's what's 1474b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * being requested. 1475b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 1476b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (cmd->autoneg == AUTONEG_DISABLE && 147725db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny (lc->supported & speed_to_caps(speed))) 147825db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny return 0; 1479b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1480b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1481b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1482b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (cmd->autoneg == AUTONEG_DISABLE) { 148325db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny cap = speed_to_caps(speed); 1484b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 148525db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny if (!(lc->supported & cap) || (speed == SPEED_1000) || 148625db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny (speed == SPEED_10000)) 1487b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1488b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lc->requested_speed = cap; 1489b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lc->advertising = 0; 1490b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else { 1491b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cap = to_fw_linkcaps(cmd->advertising); 1492b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!(lc->supported & cap)) 1493b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1494b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lc->requested_speed = 0; 1495b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lc->advertising = cap | FW_PORT_CAP_ANEG; 1496b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1497b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lc->autoneg = cmd->autoneg; 1498b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1499b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (netif_running(dev)) 1500060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis return t4_link_start(p->adapter, p->adapter->fn, p->tx_chan, 1501060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis lc); 1502b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 1503b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1504b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1505b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void get_pauseparam(struct net_device *dev, 1506b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct ethtool_pauseparam *epause) 1507b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1508b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *p = netdev_priv(dev); 1509b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1510b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; 1511b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0; 1512b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0; 1513b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1514b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1515b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_pauseparam(struct net_device *dev, 1516b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct ethtool_pauseparam *epause) 1517b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1518b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *p = netdev_priv(dev); 1519b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct link_config *lc = &p->link_cfg; 1520b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1521b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (epause->autoneg == AUTONEG_DISABLE) 1522b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lc->requested_fc = 0; 1523b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else if (lc->supported & FW_PORT_CAP_ANEG) 1524b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lc->requested_fc = PAUSE_AUTONEG; 1525b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else 1526b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1527b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1528b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (epause->rx_pause) 1529b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lc->requested_fc |= PAUSE_RX; 1530b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (epause->tx_pause) 1531b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lc->requested_fc |= PAUSE_TX; 1532b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (netif_running(dev)) 1533060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis return t4_link_start(p->adapter, p->adapter->fn, p->tx_chan, 1534060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis lc); 1535b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 1536b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1537b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1538b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) 1539b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1540b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *pi = netdev_priv(dev); 1541b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct sge *s = &pi->adapter->sge; 1542b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1543b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->rx_max_pending = MAX_RX_BUFFERS; 1544b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->rx_mini_max_pending = MAX_RSPQ_ENTRIES; 1545b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->rx_jumbo_max_pending = 0; 1546b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->tx_max_pending = MAX_TXQ_ENTRIES; 1547b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1548b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->rx_pending = s->ethrxq[pi->first_qset].fl.size - 8; 1549b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->rx_mini_pending = s->ethrxq[pi->first_qset].rspq.size; 1550b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->rx_jumbo_pending = 0; 1551b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->tx_pending = s->ethtxq[pi->first_qset].q.size; 1552b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1553b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1554b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) 1555b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1556b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i; 1557b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *pi = netdev_priv(dev); 1558b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = pi->adapter; 1559b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge *s = &adapter->sge; 1560b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1561b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (e->rx_pending > MAX_RX_BUFFERS || e->rx_jumbo_pending || 1562b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->tx_pending > MAX_TXQ_ENTRIES || 1563b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->rx_mini_pending > MAX_RSPQ_ENTRIES || 1564b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->rx_mini_pending < MIN_RSPQ_ENTRIES || 1565b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->rx_pending < MIN_FL_ENTRIES || e->tx_pending < MIN_TXQ_ENTRIES) 1566b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1567b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1568b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adapter->flags & FULL_INIT_DONE) 1569b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EBUSY; 1570b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1571b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < pi->nqsets; ++i) { 1572b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ethtxq[pi->first_qset + i].q.size = e->tx_pending; 1573b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ethrxq[pi->first_qset + i].fl.size = e->rx_pending + 8; 1574b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ethrxq[pi->first_qset + i].rspq.size = e->rx_mini_pending; 1575b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1576b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 1577b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1578b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1579b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int closest_timer(const struct sge *s, int time) 1580b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1581b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i, delta, match = 0, min_delta = INT_MAX; 1582b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1583b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(s->timer_val); i++) { 1584b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis delta = time - s->timer_val[i]; 1585b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (delta < 0) 1586b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis delta = -delta; 1587b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (delta < min_delta) { 1588b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis min_delta = delta; 1589b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis match = i; 1590b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1591b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1592b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return match; 1593b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1594b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1595b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int closest_thres(const struct sge *s, int thres) 1596b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1597b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i, delta, match = 0, min_delta = INT_MAX; 1598b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1599b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(s->counter_val); i++) { 1600b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis delta = thres - s->counter_val[i]; 1601b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (delta < 0) 1602b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis delta = -delta; 1603b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (delta < min_delta) { 1604b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis min_delta = delta; 1605b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis match = i; 1606b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1607b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1608b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return match; 1609b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1610b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1611b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 1612b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Return a queue's interrupt hold-off time in us. 0 means no timer. 1613b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 1614b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic unsigned int qtimer_val(const struct adapter *adap, 1615b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct sge_rspq *q) 1616b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1617b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int idx = q->intr_params >> 1; 1618b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1619b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return idx < SGE_NTIMERS ? adap->sge.timer_val[idx] : 0; 1620b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1621b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1622b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 1623b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * set_rxq_intr_params - set a queue's interrupt holdoff parameters 1624b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @adap: the adapter 1625b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @q: the Rx queue 1626b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @us: the hold-off time in us, or 0 to disable timer 1627b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @cnt: the hold-off packet count, or 0 to disable counter 1628b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 1629b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Sets an Rx queue's interrupt hold-off time and packet count. At least 1630b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * one of the two needs to be enabled for the queue to generate interrupts. 1631b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 1632b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_rxq_intr_params(struct adapter *adap, struct sge_rspq *q, 1633b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int us, unsigned int cnt) 1634b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1635b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if ((us | cnt) == 0) 1636b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cnt = 1; 1637b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1638b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (cnt) { 1639b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int err; 1640b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u32 v, new_idx; 1641b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1642b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis new_idx = closest_thres(&adap->sge, cnt); 1643b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (q->desc && q->pktcnt_idx != new_idx) { 1644b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* the queue has already been created, update it */ 1645b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v = FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) | 1646b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_IQ_INTCNTTHRESH) | 1647b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_PARAMS_PARAM_YZ(q->cntxt_id); 1648060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis err = t4_set_params(adap, adap->fn, adap->fn, 0, 1, &v, 1649060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis &new_idx); 1650b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 1651b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 1652b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1653b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis q->pktcnt_idx = new_idx; 1654b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1655b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1656b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis us = us == 0 ? 6 : closest_timer(&adap->sge, us); 1657b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis q->intr_params = QINTR_TIMER_IDX(us) | (cnt > 0 ? QINTR_CNT_EN : 0); 1658b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 1659b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1660b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1661b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) 1662b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1663b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *pi = netdev_priv(dev); 1664b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap = pi->adapter; 1665b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1666b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return set_rxq_intr_params(adap, &adap->sge.ethrxq[pi->first_qset].rspq, 1667b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis c->rx_coalesce_usecs, c->rx_max_coalesced_frames); 1668b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1669b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1670b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) 1671b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1672b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct port_info *pi = netdev_priv(dev); 1673b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct adapter *adap = pi->adapter; 1674b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct sge_rspq *rq = &adap->sge.ethrxq[pi->first_qset].rspq; 1675b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1676b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis c->rx_coalesce_usecs = qtimer_val(adap, rq); 1677b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis c->rx_max_coalesced_frames = (rq->intr_params & QINTR_CNT_EN) ? 1678b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->sge.counter_val[rq->pktcnt_idx] : 0; 1679b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 1680b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1681b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 16821478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis/** 16831478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * eeprom_ptov - translate a physical EEPROM address to virtual 16841478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * @phys_addr: the physical EEPROM address 16851478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * @fn: the PCI function number 16861478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * @sz: size of function-specific area 16871478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * 16881478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * Translate a physical EEPROM address to virtual. The first 1K is 16891478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * accessed through virtual addresses starting at 31K, the rest is 16901478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * accessed through virtual addresses starting at 0. 16911478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * 16921478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * The mapping is as follows: 16931478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * [0..1K) -> [31K..32K) 16941478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * [1K..1K+A) -> [31K-A..31K) 16951478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * [1K+A..ES) -> [0..ES-A-1K) 16961478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * 16971478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis * where A = @fn * @sz, and ES = EEPROM size. 1698b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 16991478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidisstatic int eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz) 1700b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 17011478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis fn *= sz; 1702b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (phys_addr < 1024) 1703b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return phys_addr + (31 << 10); 17041478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis if (phys_addr < 1024 + fn) 17051478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis return 31744 - fn + phys_addr - 1024; 1706b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (phys_addr < EEPROMSIZE) 17071478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis return phys_addr - 1024 - fn; 1708b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1709b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1710b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1711b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 1712b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * The next two routines implement eeprom read/write from physical addresses. 1713b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 1714b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v) 1715b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 17161478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); 1717b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1718b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (vaddr >= 0) 1719b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v); 1720b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return vaddr < 0 ? vaddr : 0; 1721b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1722b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1723b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v) 1724b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 17251478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); 1726b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1727b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (vaddr >= 0) 1728b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v); 1729b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return vaddr < 0 ? vaddr : 0; 1730b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1731b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1732b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define EEPROM_MAGIC 0x38E2F10C 1733b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1734b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, 1735b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u8 *data) 1736b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1737b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i, err = 0; 1738b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = netdev2adap(dev); 1739b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1740b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL); 1741b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!buf) 1742b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -ENOMEM; 1743b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1744b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis e->magic = EEPROM_MAGIC; 1745b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4) 1746b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = eeprom_rd_phys(adapter, i, (u32 *)&buf[i]); 1747b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1748b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!err) 1749b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memcpy(data, buf + e->offset, e->len); 1750b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis kfree(buf); 1751b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 1752b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1753b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1754b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, 1755b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u8 *data) 1756b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1757b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u8 *buf; 1758b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int err = 0; 1759b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u32 aligned_offset, aligned_len, *p; 1760b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = netdev2adap(dev); 1761b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1762b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (eeprom->magic != EEPROM_MAGIC) 1763b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1764b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1765b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis aligned_offset = eeprom->offset & ~3; 1766b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3; 1767b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 17681478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis if (adapter->fn > 0) { 17691478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis u32 start = 1024 + adapter->fn * EEPROMPFSIZE; 17701478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis 17711478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis if (aligned_offset < start || 17721478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis aligned_offset + aligned_len > start + EEPROMPFSIZE) 17731478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis return -EPERM; 17741478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis } 17751478b3ee931e83c7a94f61376e962574b28d23d6Dimitris Michailidis 1776b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) { 1777b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 1778b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * RMW possibly needed for first or last words. 1779b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 1780b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis buf = kmalloc(aligned_len, GFP_KERNEL); 1781b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!buf) 1782b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -ENOMEM; 1783b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf); 1784b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!err && aligned_len > 4) 1785b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = eeprom_rd_phys(adapter, 1786b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis aligned_offset + aligned_len - 4, 1787b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (u32 *)&buf[aligned_len - 4]); 1788b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 1789b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out; 1790b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memcpy(buf + (eeprom->offset & 3), data, eeprom->len); 1791b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else 1792b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis buf = data; 1793b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1794b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_seeprom_wp(adapter, false); 1795b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 1796b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out; 1797b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1798b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (p = (u32 *)buf; !err && aligned_len; aligned_len -= 4, p++) { 1799b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = eeprom_wr_phys(adapter, aligned_offset, *p); 1800b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis aligned_offset += 4; 1801b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 1802b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1803b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!err) 1804b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_seeprom_wp(adapter, true); 1805b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisout: 1806b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (buf != data) 1807b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis kfree(buf); 1808b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 1809b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1810b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1811b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_flash(struct net_device *netdev, struct ethtool_flash *ef) 1812b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1813b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret; 1814b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct firmware *fw; 1815b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap = netdev2adap(netdev); 1816b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1817b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ef->data[sizeof(ef->data) - 1] = '\0'; 1818b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = request_firmware(&fw, ef->data, adap->pdev_dev); 1819b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 1820b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 1821b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1822b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = t4_load_fw(adap, fw->data, fw->size); 1823b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis release_firmware(fw); 1824b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!ret) 1825b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_info(adap->pdev_dev, "loaded firmware %s\n", ef->data); 1826b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 1827b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1828b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1829b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define WOL_SUPPORTED (WAKE_BCAST | WAKE_MAGIC) 1830b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define BCAST_CRC 0xa0ccc1a6 1831b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1832b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 1833b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1834b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis wol->supported = WAKE_BCAST | WAKE_MAGIC; 1835b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis wol->wolopts = netdev2adap(dev)->wol; 1836b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memset(&wol->sopass, 0, sizeof(wol->sopass)); 1837b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1838b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1839b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 1840b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 1841b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int err = 0; 1842b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 1843b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1844b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (wol->wolopts & ~WOL_SUPPORTED) 1845b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 1846b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_wol_magic_enable(pi->adapter, pi->tx_chan, 1847b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (wol->wolopts & WAKE_MAGIC) ? dev->dev_addr : NULL); 1848b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (wol->wolopts & WAKE_BCAST) { 1849b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0xfe, ~0ULL, 1850b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ~0ULL, 0, false); 1851b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!err) 1852b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_wol_pat_enable(pi->adapter, pi->tx_chan, 1, 1853b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ~6ULL, ~0ULL, BCAST_CRC, true); 1854b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else 1855b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_wol_pat_enable(pi->adapter, pi->tx_chan, 0, 0, 0, 0, false); 1856b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 1857b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 1858b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 1859c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosławstatic int cxgb_set_features(struct net_device *dev, netdev_features_t features) 186087b6cf51acb4999fff7e6841986874b108679cb4Dimitris Michailidis{ 18612ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław const struct port_info *pi = netdev_priv(dev); 1862c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosław netdev_features_t changed = dev->features ^ features; 186319ecae2c8fd5e54e40ace914a41d8e1beb41612cDimitris Michailidis int err; 186419ecae2c8fd5e54e40ace914a41d8e1beb41612cDimitris Michailidis 18652ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław if (!(changed & NETIF_F_HW_VLAN_RX)) 18662ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław return 0; 186719ecae2c8fd5e54e40ace914a41d8e1beb41612cDimitris Michailidis 18682ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1, 18692ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław -1, -1, -1, 18702ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław !!(features & NETIF_F_HW_VLAN_RX), true); 18712ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław if (unlikely(err)) 18722ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław dev->features = features ^ NETIF_F_HW_VLAN_RX; 187319ecae2c8fd5e54e40ace914a41d8e1beb41612cDimitris Michailidis return err; 187487b6cf51acb4999fff7e6841986874b108679cb4Dimitris Michailidis} 187587b6cf51acb4999fff7e6841986874b108679cb4Dimitris Michailidis 18767850f63f1620512631445b901ae11cd149e7375cBen Hutchingsstatic u32 get_rss_table_size(struct net_device *dev) 1877671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis{ 1878671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis const struct port_info *pi = netdev_priv(dev); 1879671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 18807850f63f1620512631445b901ae11cd149e7375cBen Hutchings return pi->rss_size; 18817850f63f1620512631445b901ae11cd149e7375cBen Hutchings} 18827850f63f1620512631445b901ae11cd149e7375cBen Hutchings 18837850f63f1620512631445b901ae11cd149e7375cBen Hutchingsstatic int get_rss_table(struct net_device *dev, u32 *p) 18847850f63f1620512631445b901ae11cd149e7375cBen Hutchings{ 18857850f63f1620512631445b901ae11cd149e7375cBen Hutchings const struct port_info *pi = netdev_priv(dev); 18867850f63f1620512631445b901ae11cd149e7375cBen Hutchings unsigned int n = pi->rss_size; 18877850f63f1620512631445b901ae11cd149e7375cBen Hutchings 1888671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis while (n--) 18897850f63f1620512631445b901ae11cd149e7375cBen Hutchings p[n] = pi->rss[n]; 1890671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis return 0; 1891671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis} 1892671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 18937850f63f1620512631445b901ae11cd149e7375cBen Hutchingsstatic int set_rss_table(struct net_device *dev, const u32 *p) 1894671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis{ 1895671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis unsigned int i; 1896671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis struct port_info *pi = netdev_priv(dev); 1897671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 18987850f63f1620512631445b901ae11cd149e7375cBen Hutchings for (i = 0; i < pi->rss_size; i++) 18997850f63f1620512631445b901ae11cd149e7375cBen Hutchings pi->rss[i] = p[i]; 1900671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis if (pi->adapter->flags & FULL_INIT_DONE) 1901671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis return write_rss(pi, pi->rss); 1902671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis return 0; 1903671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis} 1904671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 1905671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidisstatic int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, 1906815c7db5c809ea3d5735de3131ecdf758b0e14ffBen Hutchings u32 *rules) 1907671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis{ 1908f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis const struct port_info *pi = netdev_priv(dev); 1909f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis 1910671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis switch (info->cmd) { 1911f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case ETHTOOL_GRXFH: { 1912f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis unsigned int v = pi->rss_mode; 1913f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis 1914f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = 0; 1915f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis switch (info->flow_type) { 1916f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case TCP_V4_FLOW: 1917f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis if (v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) 1918f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST | 1919f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis RXH_L4_B_0_1 | RXH_L4_B_2_3; 1920f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) 1921f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST; 1922f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis break; 1923f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case UDP_V4_FLOW: 1924f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis if ((v & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) && 1925f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis (v & FW_RSS_VI_CONFIG_CMD_UDPEN)) 1926f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST | 1927f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis RXH_L4_B_0_1 | RXH_L4_B_2_3; 1928f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis else if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) 1929f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST; 1930f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis break; 1931f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case SCTP_V4_FLOW: 1932f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case AH_ESP_V4_FLOW: 1933f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case IPV4_FLOW: 1934f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis if (v & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) 1935f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST; 1936f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis break; 1937f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case TCP_V6_FLOW: 1938f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis if (v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) 1939f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST | 1940f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis RXH_L4_B_0_1 | RXH_L4_B_2_3; 1941f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) 1942f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST; 1943f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis break; 1944f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case UDP_V6_FLOW: 1945f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis if ((v & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) && 1946f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis (v & FW_RSS_VI_CONFIG_CMD_UDPEN)) 1947f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST | 1948f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis RXH_L4_B_0_1 | RXH_L4_B_2_3; 1949f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis else if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) 1950f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST; 1951f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis break; 1952f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case SCTP_V6_FLOW: 1953f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case AH_ESP_V6_FLOW: 1954f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis case IPV6_FLOW: 1955f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis if (v & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) 1956f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = RXH_IP_SRC | RXH_IP_DST; 1957f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis break; 1958f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis } 1959f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis return 0; 1960f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis } 1961671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis case ETHTOOL_GRXRINGS: 1962f796564a5fd7be1a4597b66e2a516c18685641dfDimitris Michailidis info->data = pi->nqsets; 1963671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis return 0; 1964671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis } 1965671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis return -EOPNOTSUPP; 1966671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis} 1967671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 19689b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemmingerstatic const struct ethtool_ops cxgb_ethtool_ops = { 1969b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_settings = get_settings, 1970b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .set_settings = set_settings, 1971b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_drvinfo = get_drvinfo, 1972b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_msglevel = get_msglevel, 1973b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .set_msglevel = set_msglevel, 1974b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_ringparam = get_sge_param, 1975b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .set_ringparam = set_sge_param, 1976b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_coalesce = get_coalesce, 1977b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .set_coalesce = set_coalesce, 1978b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_eeprom_len = get_eeprom_len, 1979b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_eeprom = get_eeprom, 1980b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .set_eeprom = set_eeprom, 1981b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_pauseparam = get_pauseparam, 1982b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .set_pauseparam = set_pauseparam, 1983b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_link = ethtool_op_get_link, 1984b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_strings = get_strings, 1985c5e06360317d9c7a91de983749d136c4089e5379Dimitris Michailidis .set_phys_id = identify_port, 1986b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .nway_reset = restart_autoneg, 1987b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_sset_count = get_sset_count, 1988b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_ethtool_stats = get_stats, 1989b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_regs_len = get_regs_len, 1990b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_regs = get_regs, 1991b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .get_wol = get_wol, 1992b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .set_wol = set_wol, 1993671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis .get_rxnfc = get_rxnfc, 19947850f63f1620512631445b901ae11cd149e7375cBen Hutchings .get_rxfh_indir_size = get_rss_table_size, 1995671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis .get_rxfh_indir = get_rss_table, 1996671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis .set_rxfh_indir = set_rss_table, 1997b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .flash_device = set_flash, 1998b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 1999b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2000b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2001b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * debugfs support 2002b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2003b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic ssize_t mem_read(struct file *file, char __user *buf, size_t count, 2004b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis loff_t *ppos) 2005b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2006b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis loff_t pos = *ppos; 2007b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis loff_t avail = file->f_path.dentry->d_inode->i_size; 2008b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int mem = (uintptr_t)file->private_data & 3; 2009b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap = file->private_data - mem; 2010b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2011b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (pos < 0) 2012b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 2013b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (pos >= avail) 2014b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 2015b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (count > avail - pos) 2016b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis count = avail - pos; 2017b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2018b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while (count) { 2019b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis size_t len; 2020b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret, ofst; 2021b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis __be32 data[16]; 2022b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2023b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (mem == MEM_MC) 2024b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = t4_mc_read(adap, pos, data, NULL); 2025b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else 2026b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = t4_edc_read(adap, mem, pos, data, NULL); 2027b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret) 2028b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 2029b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2030b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ofst = pos % sizeof(data); 2031b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis len = min(count, sizeof(data) - ofst); 2032b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (copy_to_user(buf, (u8 *)data + ofst, len)) 2033b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EFAULT; 2034b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2035b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis buf += len; 2036b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pos += len; 2037b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis count -= len; 2038b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2039b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis count = pos - *ppos; 2040b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis *ppos = pos; 2041b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return count; 2042b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2043b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2044b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic const struct file_operations mem_debugfs_fops = { 2045b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .owner = THIS_MODULE, 2046234e340582901211f40d8c732afc49f0630ecf05Stephen Boyd .open = simple_open, 2047b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .read = mem_read, 20486038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = default_llseek, 2049b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 2050b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2051b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void __devinit add_debugfs_mem(struct adapter *adap, const char *name, 2052b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int idx, unsigned int size_mb) 2053b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2054b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct dentry *de; 2055b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2056b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis de = debugfs_create_file(name, S_IRUSR, adap->debugfs_root, 2057b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (void *)adap + idx, &mem_debugfs_fops); 2058b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (de && de->d_inode) 2059b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis de->d_inode->i_size = size_mb << 20; 2060b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2061b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2062b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int __devinit setup_debugfs(struct adapter *adap) 2063b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2064b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i; 2065b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2066b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (IS_ERR_OR_NULL(adap->debugfs_root)) 2067b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -1; 2068b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2069b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis i = t4_read_reg(adap, MA_TARGET_MEM_ENABLE); 2070b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (i & EDRAM0_ENABLE) 2071b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis add_debugfs_mem(adap, "edc0", MEM_EDC0, 5); 2072b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (i & EDRAM1_ENABLE) 2073b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis add_debugfs_mem(adap, "edc1", MEM_EDC1, 5); 2074b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (i & EXT_MEM_ENABLE) 2075b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis add_debugfs_mem(adap, "mc", MEM_MC, 2076b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis EXT_MEM_SIZE_GET(t4_read_reg(adap, MA_EXT_MEMORY_BAR))); 2077b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adap->l2t) 2078b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis debugfs_create_file("l2t", S_IRUSR, adap->debugfs_root, adap, 2079b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis &t4_l2t_fops); 2080b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 2081b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2082b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2083b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2084b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * upper-layer driver support 2085b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2086b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2087b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2088b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Allocate an active-open TID and set it to the supplied value. 2089b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2090b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisint cxgb4_alloc_atid(struct tid_info *t, void *data) 2091b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2092b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int atid = -1; 2093b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2094b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_bh(&t->atid_lock); 2095b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (t->afree) { 2096b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis union aopen_entry *p = t->afree; 2097b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2098b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis atid = p - t->atid_tab; 2099b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->afree = p->next; 2100b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis p->data = data; 2101b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->atids_in_use++; 2102b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2103b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_unlock_bh(&t->atid_lock); 2104b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return atid; 2105b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2106b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_alloc_atid); 2107b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2108b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2109b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Release an active-open TID. 2110b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2111b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisvoid cxgb4_free_atid(struct tid_info *t, unsigned int atid) 2112b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2113b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis union aopen_entry *p = &t->atid_tab[atid]; 2114b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2115b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_bh(&t->atid_lock); 2116b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis p->next = t->afree; 2117b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->afree = p; 2118b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->atids_in_use--; 2119b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_unlock_bh(&t->atid_lock); 2120b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2121b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_free_atid); 2122b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2123b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2124b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Allocate a server TID and set it to the supplied value. 2125b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2126b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisint cxgb4_alloc_stid(struct tid_info *t, int family, void *data) 2127b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2128b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int stid; 2129b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2130b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_bh(&t->stid_lock); 2131b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (family == PF_INET) { 2132b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stid = find_first_zero_bit(t->stid_bmap, t->nstids); 2133b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (stid < t->nstids) 2134b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis __set_bit(stid, t->stid_bmap); 2135b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else 2136b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stid = -1; 2137b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else { 2138b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stid = bitmap_find_free_region(t->stid_bmap, t->nstids, 2); 2139b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (stid < 0) 2140b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stid = -1; 2141b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2142b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (stid >= 0) { 2143b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->stid_tab[stid].data = data; 2144b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stid += t->stid_base; 2145b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->stids_in_use++; 2146b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2147b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_unlock_bh(&t->stid_lock); 2148b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return stid; 2149b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2150b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_alloc_stid); 2151b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2152b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2153b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Release a server TID. 2154b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2155b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisvoid cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family) 2156b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2157b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stid -= t->stid_base; 2158b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_bh(&t->stid_lock); 2159b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (family == PF_INET) 2160b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis __clear_bit(stid, t->stid_bmap); 2161b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else 2162b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis bitmap_release_region(t->stid_bmap, stid, 2); 2163b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->stid_tab[stid].data = NULL; 2164b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->stids_in_use--; 2165b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_unlock_bh(&t->stid_lock); 2166b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2167b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_free_stid); 2168b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2169b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2170b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Populate a TID_RELEASE WR. Caller must properly size the skb. 2171b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2172b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void mk_tid_release(struct sk_buff *skb, unsigned int chan, 2173b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int tid) 2174b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2175b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct cpl_tid_release *req; 2176b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2177b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis set_wr_txq(skb, CPL_PRIORITY_SETUP, chan); 2178b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis req = (struct cpl_tid_release *)__skb_put(skb, sizeof(*req)); 2179b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis INIT_TP_WR(req, tid); 2180b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid)); 2181b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2182b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2183b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2184b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Queue a TID release request and if necessary schedule a work queue to 2185b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * process it. 2186b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 218731b9c19bfe32bed7fdf80cd0b1aa9d0f0569844astephen hemmingerstatic void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, 218831b9c19bfe32bed7fdf80cd0b1aa9d0f0569844astephen hemminger unsigned int tid) 2189b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2190b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis void **p = &t->tid_tab[tid]; 2191b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap = container_of(t, struct adapter, tids); 2192b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2193b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_bh(&adap->tid_release_lock); 2194b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis *p = adap->tid_release_head; 2195b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* Low 2 bits encode the Tx channel number */ 2196b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tid_release_head = (void **)((uintptr_t)p | chan); 2197b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!adap->tid_release_task_busy) { 2198b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tid_release_task_busy = true; 2199b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis schedule_work(&adap->tid_release_task); 2200b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2201b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_unlock_bh(&adap->tid_release_lock); 2202b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2203b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2204b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2205b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Process the list of pending TID release requests. 2206b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2207b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void process_tid_release_list(struct work_struct *work) 2208b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2209b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sk_buff *skb; 2210b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap; 2211b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2212b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap = container_of(work, struct adapter, tid_release_task); 2213b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2214b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_bh(&adap->tid_release_lock); 2215b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while (adap->tid_release_head) { 2216b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis void **p = adap->tid_release_head; 2217b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int chan = (uintptr_t)p & 3; 2218b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis p = (void *)p - chan; 2219b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2220b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tid_release_head = *p; 2221b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis *p = NULL; 2222b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_unlock_bh(&adap->tid_release_lock); 2223b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2224b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while (!(skb = alloc_skb(sizeof(struct cpl_tid_release), 2225b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis GFP_KERNEL))) 2226b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis schedule_timeout_uninterruptible(1); 2227b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2228b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mk_tid_release(skb, chan, p - adap->tids.tid_tab); 2229b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_ofld_send(adap, skb); 2230b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_bh(&adap->tid_release_lock); 2231b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2232b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tid_release_task_busy = false; 2233b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_unlock_bh(&adap->tid_release_lock); 2234b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2235b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2236b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2237b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Release a TID and inform HW. If we are unable to allocate the release 2238b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * message we defer to a work queue. 2239b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2240b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisvoid cxgb4_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid) 2241b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2242b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis void *old; 2243b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sk_buff *skb; 2244b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap = container_of(t, struct adapter, tids); 2245b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2246b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis old = t->tid_tab[tid]; 2247b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC); 2248b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (likely(skb)) { 2249b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->tid_tab[tid] = NULL; 2250b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mk_tid_release(skb, chan, tid); 2251b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_ofld_send(adap, skb); 2252b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else 2253b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cxgb4_queue_tid_release(t, chan, tid); 2254b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (old) 2255b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis atomic_dec(&t->tids_in_use); 2256b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2257b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_remove_tid); 2258b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2259b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2260b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Allocate and initialize the TID tables. Returns 0 on success. 2261b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2262b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int tid_init(struct tid_info *t) 2263b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2264b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis size_t size; 2265b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int natids = t->natids; 2266b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2267b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis size = t->ntids * sizeof(*t->tid_tab) + natids * sizeof(*t->atid_tab) + 2268b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->nstids * sizeof(*t->stid_tab) + 2269b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis BITS_TO_LONGS(t->nstids) * sizeof(long); 2270b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->tid_tab = t4_alloc_mem(size); 2271b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!t->tid_tab) 2272b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -ENOMEM; 2273b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2274b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids]; 2275b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->stid_tab = (struct serv_entry *)&t->atid_tab[natids]; 2276b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->stid_bmap = (unsigned long *)&t->stid_tab[t->nstids]; 2277b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_init(&t->stid_lock); 2278b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_init(&t->atid_lock); 2279b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2280b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->stids_in_use = 0; 2281b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->afree = NULL; 2282b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->atids_in_use = 0; 2283b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis atomic_set(&t->tids_in_use, 0); 2284b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2285b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* Setup the free list for atid_tab and clear the stid bitmap. */ 2286b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (natids) { 2287b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while (--natids) 2288b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->atid_tab[natids - 1].next = &t->atid_tab[natids]; 2289b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t->afree = t->atid_tab; 2290b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2291b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis bitmap_zero(t->stid_bmap, t->nstids); 2292b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 2293b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2294b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2295b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 2296b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * cxgb4_create_server - create an IP server 2297b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @dev: the device 2298b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @stid: the server TID 2299b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @sip: local IP address to bind server to 2300b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @sport: the server's TCP port 2301b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @queue: queue to direct messages from this server to 2302b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 2303b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Create an IP server for the given port and address. 2304b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Returns <0 on error and one of the %NET_XMIT_* values on success. 2305b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2306b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisint cxgb4_create_server(const struct net_device *dev, unsigned int stid, 2307b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis __be32 sip, __be16 sport, unsigned int queue) 2308b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2309b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int chan; 2310b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sk_buff *skb; 2311b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap; 2312b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct cpl_pass_open_req *req; 2313b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2314b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis skb = alloc_skb(sizeof(*req), GFP_KERNEL); 2315b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!skb) 2316b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -ENOMEM; 2317b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2318b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap = netdev2adap(dev); 2319b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis req = (struct cpl_pass_open_req *)__skb_put(skb, sizeof(*req)); 2320b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis INIT_TP_WR(req, 0); 2321b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ, stid)); 2322b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis req->local_port = sport; 2323b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis req->peer_port = htons(0); 2324b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis req->local_ip = sip; 2325b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis req->peer_ip = htonl(0); 2326e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis chan = rxq_to_chan(&adap->sge, queue); 2327b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis req->opt0 = cpu_to_be64(TX_CHAN(chan)); 2328b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis req->opt1 = cpu_to_be64(CONN_POLICY_ASK | 2329b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); 2330b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return t4_mgmt_tx(adap, skb); 2331b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2332b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_create_server); 2333b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2334b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 2335b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * cxgb4_best_mtu - find the entry in the MTU table closest to an MTU 2336b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @mtus: the HW MTU table 2337b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @mtu: the target MTU 2338b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @idx: index of selected entry in the MTU table 2339b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 2340b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Returns the index and the value in the HW MTU table that is closest to 2341b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * but does not exceed @mtu, unless @mtu is smaller than any value in the 2342b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * table, in which case that smallest available value is selected. 2343b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2344b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisunsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu, 2345b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int *idx) 2346b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2347b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int i = 0; 2348b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2349b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while (i < NMTUS - 1 && mtus[i + 1] <= mtu) 2350b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ++i; 2351b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (idx) 2352b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis *idx = i; 2353b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return mtus[i]; 2354b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2355b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_best_mtu); 2356b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2357b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 2358b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * cxgb4_port_chan - get the HW channel of a port 2359b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @dev: the net device for the port 2360b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 2361b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Return the HW Tx channel of the given port. 2362b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2363b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisunsigned int cxgb4_port_chan(const struct net_device *dev) 2364b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2365b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return netdev2pinfo(dev)->tx_chan; 2366b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2367b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_port_chan); 2368b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2369b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 2370b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * cxgb4_port_viid - get the VI id of a port 2371b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @dev: the net device for the port 2372b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 2373b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Return the VI id of the given port. 2374b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2375b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisunsigned int cxgb4_port_viid(const struct net_device *dev) 2376b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2377b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return netdev2pinfo(dev)->viid; 2378b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2379b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_port_viid); 2380b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2381b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 2382b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * cxgb4_port_idx - get the index of a port 2383b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @dev: the net device for the port 2384b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 2385b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Return the index of the given port. 2386b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2387b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisunsigned int cxgb4_port_idx(const struct net_device *dev) 2388b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2389b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return netdev2pinfo(dev)->port_id; 2390b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2391b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_port_idx); 2392b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2393b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisvoid cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4, 2394b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct tp_tcp_stats *v6) 2395b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2396b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap = pci_get_drvdata(pdev); 2397b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2398b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock(&adap->stats_lock); 2399b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_tp_get_tcp_stats(adap, v4, v6); 2400b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_unlock(&adap->stats_lock); 2401b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2402b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_get_tcp_stats); 2403b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2404b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisvoid cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask, 2405b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const unsigned int *pgsz_order) 2406b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2407b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap = netdev2adap(dev); 2408b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2409b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_write_reg(adap, ULP_RX_ISCSI_TAGMASK, tag_mask); 2410b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_write_reg(adap, ULP_RX_ISCSI_PSZ, HPZ0(pgsz_order[0]) | 2411b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis HPZ1(pgsz_order[1]) | HPZ2(pgsz_order[2]) | 2412b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis HPZ3(pgsz_order[3])); 2413b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2414b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_iscsi_init); 2415b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2416b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic struct pci_driver cxgb4_driver; 2417b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2418b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void check_neigh_update(struct neighbour *neigh) 2419b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2420b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct device *parent; 2421b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct net_device *netdev = neigh->dev; 2422b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2423b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (netdev->priv_flags & IFF_802_1Q_VLAN) 2424b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev = vlan_dev_real_dev(netdev); 2425b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis parent = netdev->dev.parent; 2426b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (parent && parent->driver == &cxgb4_driver.driver) 2427b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_l2t_update(dev_get_drvdata(parent), neigh); 2428b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2429b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2430b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int netevent_cb(struct notifier_block *nb, unsigned long event, 2431b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis void *data) 2432b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2433b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis switch (event) { 2434b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis case NETEVENT_NEIGH_UPDATE: 2435b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis check_neigh_update(data); 2436b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis break; 2437b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis case NETEVENT_REDIRECT: 2438b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis default: 2439b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis break; 2440b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2441b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 2442b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2443b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2444b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic bool netevent_registered; 2445b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic struct notifier_block cxgb4_netevent_nb = { 2446b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .notifier_call = netevent_cb 2447b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 2448b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2449b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void uld_attach(struct adapter *adap, unsigned int uld) 2450b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2451b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis void *handle; 2452b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct cxgb4_lld_info lli; 2453b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2454b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.pdev = adap->pdev; 2455b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.l2t = adap->l2t; 2456b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.tids = &adap->tids; 2457b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.ports = adap->port; 2458b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.vr = &adap->vres; 2459b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.mtus = adap->params.mtus; 2460b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (uld == CXGB4_ULD_RDMA) { 2461b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.rxq_ids = adap->sge.rdma_rxq; 2462b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.nrxq = adap->sge.rdmaqs; 2463b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else if (uld == CXGB4_ULD_ISCSI) { 2464b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.rxq_ids = adap->sge.ofld_rxq; 2465b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.nrxq = adap->sge.ofldqsets; 2466b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2467b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.ntxq = adap->sge.ofldqsets; 2468b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.nchan = adap->params.nports; 2469b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.nports = adap->params.nports; 2470b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.wr_cred = adap->params.ofldq_wr_cred; 2471b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.adapter_type = adap->params.rev; 2472b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.iscsi_iolen = MAXRXDATA_GET(t4_read_reg(adap, TP_PARA_REG2)); 2473b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.udb_density = 1 << QUEUESPERPAGEPF0_GET( 2474060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis t4_read_reg(adap, SGE_EGRESS_QUEUES_PER_PAGE_PF) >> 2475060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis (adap->fn * 4)); 2476b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.ucq_density = 1 << QUEUESPERPAGEPF0_GET( 2477060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis t4_read_reg(adap, SGE_INGRESS_QUEUES_PER_PAGE_PF) >> 2478060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis (adap->fn * 4)); 2479b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS); 2480b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL); 2481b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis lli.fw_vers = adap->params.fw_vers; 2482b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2483b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis handle = ulds[uld].add(&lli); 2484b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (IS_ERR(handle)) { 2485b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_warn(adap->pdev_dev, 2486b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "could not attach to the %s driver, error %ld\n", 2487b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis uld_str[uld], PTR_ERR(handle)); 2488b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return; 2489b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2490b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2491b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->uld_handle[uld] = handle; 2492b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2493b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!netevent_registered) { 2494b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis register_netevent_notifier(&cxgb4_netevent_nb); 2495b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netevent_registered = true; 2496b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2497e29f5dbc9e9719af158a960e5c1d16f32740ebc3Dimitris Michailidis 2498e29f5dbc9e9719af158a960e5c1d16f32740ebc3Dimitris Michailidis if (adap->flags & FULL_INIT_DONE) 2499e29f5dbc9e9719af158a960e5c1d16f32740ebc3Dimitris Michailidis ulds[uld].state_change(handle, CXGB4_STATE_UP); 2500b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2501b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2502b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void attach_ulds(struct adapter *adap) 2503b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2504b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int i; 2505b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2506b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mutex_lock(&uld_mutex); 2507b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis list_add_tail(&adap->list_node, &adapter_list); 2508b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < CXGB4_ULD_MAX; i++) 2509b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ulds[i].add) 2510b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis uld_attach(adap, i); 2511b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mutex_unlock(&uld_mutex); 2512b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2513b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2514b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void detach_ulds(struct adapter *adap) 2515b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2516b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int i; 2517b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2518b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mutex_lock(&uld_mutex); 2519b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis list_del(&adap->list_node); 2520b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < CXGB4_ULD_MAX; i++) 2521b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adap->uld_handle[i]) { 2522b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ulds[i].state_change(adap->uld_handle[i], 2523b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis CXGB4_STATE_DETACH); 2524b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->uld_handle[i] = NULL; 2525b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2526b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (netevent_registered && list_empty(&adapter_list)) { 2527b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unregister_netevent_notifier(&cxgb4_netevent_nb); 2528b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netevent_registered = false; 2529b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2530b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mutex_unlock(&uld_mutex); 2531b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2532b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2533b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void notify_ulds(struct adapter *adap, enum cxgb4_state new_state) 2534b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2535b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int i; 2536b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2537b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mutex_lock(&uld_mutex); 2538b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < CXGB4_ULD_MAX; i++) 2539b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adap->uld_handle[i]) 2540b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ulds[i].state_change(adap->uld_handle[i], new_state); 2541b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mutex_unlock(&uld_mutex); 2542b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2543b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2544b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 2545b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * cxgb4_register_uld - register an upper-layer driver 2546b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @type: the ULD type 2547b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @p: the ULD methods 2548b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 2549b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Registers an upper-layer driver with this driver and notifies the ULD 2550b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * about any presently available devices that support its type. Returns 2551b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * %-EBUSY if a ULD of the same type is already registered. 2552b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2553b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisint cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p) 2554b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2555b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret = 0; 2556b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap; 2557b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2558b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (type >= CXGB4_ULD_MAX) 2559b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 2560b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mutex_lock(&uld_mutex); 2561b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ulds[type].add) { 2562b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = -EBUSY; 2563b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out; 2564b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2565b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ulds[type] = *p; 2566b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis list_for_each_entry(adap, &adapter_list, list_node) 2567b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis uld_attach(adap, type); 2568b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisout: mutex_unlock(&uld_mutex); 2569b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 2570b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2571b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_register_uld); 2572b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2573b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 2574b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * cxgb4_unregister_uld - unregister an upper-layer driver 2575b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @type: the ULD type 2576b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 2577b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Unregisters an existing upper-layer driver. 2578b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2579b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisint cxgb4_unregister_uld(enum cxgb4_uld type) 2580b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2581b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap; 2582b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2583b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (type >= CXGB4_ULD_MAX) 2584b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 2585b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mutex_lock(&uld_mutex); 2586b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis list_for_each_entry(adap, &adapter_list, list_node) 2587b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->uld_handle[type] = NULL; 2588b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ulds[type].add = NULL; 2589b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis mutex_unlock(&uld_mutex); 2590b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 2591b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2592b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris MichailidisEXPORT_SYMBOL(cxgb4_unregister_uld); 2593b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2594b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/** 2595b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * cxgb_up - enable the adapter 2596b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * @adap: adapter being enabled 2597b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 2598b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Called when the first port is enabled, this function performs the 2599b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * actions necessary to make an adapter operational, such as completing 2600b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * the initialization of HW modules, and enabling interrupts. 2601b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * 2602b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Must be called with the rtnl lock held. 2603b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2604b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int cxgb_up(struct adapter *adap) 2605b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2606aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis int err; 2607b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2608aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis err = setup_sge_queues(adap); 2609aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis if (err) 2610aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis goto out; 2611aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis err = setup_rss(adap); 2612aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis if (err) 2613aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis goto freeq; 2614b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2615b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adap->flags & USING_MSIX) { 2616aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis name_msix_vecs(adap); 2617b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = request_irq(adap->msix_info[0].vec, t4_nondata_intr, 0, 2618b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->msix_info[0].desc, adap); 2619b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 2620b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto irq_err; 2621b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2622b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = request_msix_queue_irqs(adap); 2623b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) { 2624b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adap->msix_info[0].vec, adap); 2625b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto irq_err; 2626b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2627b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else { 2628b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = request_irq(adap->pdev->irq, t4_intr_handler(adap), 2629b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (adap->flags & USING_MSI) ? 0 : IRQF_SHARED, 2630b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis adap->port[0]->name, adap); 2631b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 2632b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto irq_err; 2633b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2634b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis enable_rx(adap); 2635b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_sge_start(adap); 2636b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_intr_enable(adap); 2637aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis adap->flags |= FULL_INIT_DONE; 2638b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis notify_ulds(adap, CXGB4_STATE_UP); 2639b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis out: 2640b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 2641b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis irq_err: 2642b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_err(adap->pdev_dev, "request_irq failed, err %d\n", err); 2643aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis freeq: 2644aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis t4_free_sge_resources(adap); 2645b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out; 2646b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2647b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2648b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void cxgb_down(struct adapter *adapter) 2649b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2650b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_intr_disable(adapter); 2651b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cancel_work_sync(&adapter->tid_release_task); 2652b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->tid_release_task_busy = false; 2653204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis adapter->tid_release_head = NULL; 2654b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2655b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adapter->flags & USING_MSIX) { 2656b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_msix_queue_irqs(adapter); 2657b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adapter->msix_info[0].vec, adapter); 2658b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else 2659b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis free_irq(adapter->pdev->irq, adapter); 2660b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis quiesce_rx(adapter); 2661aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis t4_sge_stop(adapter); 2662aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis t4_free_sge_resources(adapter); 2663aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis adapter->flags &= ~FULL_INIT_DONE; 2664b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2665b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2666b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2667b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * net_device operations 2668b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2669b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int cxgb_open(struct net_device *dev) 2670b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2671b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int err; 2672b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 2673b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = pi->adapter; 2674b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 26756a3c869a6021f4abcd69aa5fbb15c63f69eb36feDimitris Michailidis netif_carrier_off(dev); 26766a3c869a6021f4abcd69aa5fbb15c63f69eb36feDimitris Michailidis 2677aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis if (!(adapter->flags & FULL_INIT_DONE)) { 2678aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis err = cxgb_up(adapter); 2679aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis if (err < 0) 2680aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis return err; 2681aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis } 2682b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2683f68707b805b7794bb7b208e327fbe0473c470d0bDimitris Michailidis err = link_start(dev); 2684f68707b805b7794bb7b208e327fbe0473c470d0bDimitris Michailidis if (!err) 2685f68707b805b7794bb7b208e327fbe0473c470d0bDimitris Michailidis netif_tx_start_all_queues(dev); 2686f68707b805b7794bb7b208e327fbe0473c470d0bDimitris Michailidis return err; 2687b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2688b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2689b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int cxgb_close(struct net_device *dev) 2690b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2691b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 2692b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = pi->adapter; 2693b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2694b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netif_tx_stop_all_queues(dev); 2695b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netif_carrier_off(dev); 2696060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis return t4_enable_vi(adapter, adapter->fn, pi->viid, false, false); 2697b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2698b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2699f5152c908a5b0be48ec9a58d0de8bdadd9385854Dimitris Michailidisstatic struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev, 2700f5152c908a5b0be48ec9a58d0de8bdadd9385854Dimitris Michailidis struct rtnl_link_stats64 *ns) 2701b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2702b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_stats stats; 2703b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *p = netdev_priv(dev); 2704b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = p->adapter; 2705b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2706b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock(&adapter->stats_lock); 2707b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_get_port_stats(adapter, p->tx_chan, &stats); 2708b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_unlock(&adapter->stats_lock); 2709b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2710b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->tx_bytes = stats.tx_octets; 2711b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->tx_packets = stats.tx_frames; 2712b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_bytes = stats.rx_octets; 2713b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_packets = stats.rx_frames; 2714b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->multicast = stats.rx_mcast_frames; 2715b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2716b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* detailed rx_errors */ 2717b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_length_errors = stats.rx_jabber + stats.rx_too_long + 2718b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stats.rx_runt; 2719b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_over_errors = 0; 2720b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_crc_errors = stats.rx_fcs_err; 2721b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_frame_errors = stats.rx_symbol_err; 2722b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_fifo_errors = stats.rx_ovflow0 + stats.rx_ovflow1 + 2723b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stats.rx_ovflow2 + stats.rx_ovflow3 + 2724b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stats.rx_trunc0 + stats.rx_trunc1 + 2725b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis stats.rx_trunc2 + stats.rx_trunc3; 2726b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_missed_errors = 0; 2727b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2728b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* detailed tx_errors */ 2729b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->tx_aborted_errors = 0; 2730b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->tx_carrier_errors = 0; 2731b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->tx_fifo_errors = 0; 2732b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->tx_heartbeat_errors = 0; 2733b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->tx_window_errors = 0; 2734b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2735b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->tx_errors = stats.tx_error_frames; 2736b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_errors = stats.rx_symbol_err + stats.rx_fcs_err + 2737b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors; 2738b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ns; 2739b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2740b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2741b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) 2742b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2743060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis unsigned int mbox; 2744b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret = 0, prtad, devad; 2745b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 2746b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data; 2747b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2748b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis switch (cmd) { 2749b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis case SIOCGMIIPHY: 2750b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (pi->mdio_addr < 0) 2751b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EOPNOTSUPP; 2752b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis data->phy_id = pi->mdio_addr; 2753b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis break; 2754b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis case SIOCGMIIREG: 2755b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis case SIOCSMIIREG: 2756b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (mdio_phy_id_is_c45(data->phy_id)) { 2757b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis prtad = mdio_phy_id_prtad(data->phy_id); 2758b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis devad = mdio_phy_id_devad(data->phy_id); 2759b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else if (data->phy_id < 32) { 2760b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis prtad = data->phy_id; 2761b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis devad = 0; 2762b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis data->reg_num &= 0x1f; 2763b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else 2764b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 2765b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2766060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis mbox = pi->adapter->fn; 2767b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (cmd == SIOCGMIIREG) 2768060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_mdio_rd(pi->adapter, mbox, prtad, devad, 2769b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis data->reg_num, &data->val_out); 2770b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis else 2771060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_mdio_wr(pi->adapter, mbox, prtad, devad, 2772b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis data->reg_num, data->val_in); 2773b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis break; 2774b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis default: 2775b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EOPNOTSUPP; 2776b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2777b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 2778b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2779b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2780b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void cxgb_set_rxmode(struct net_device *dev) 2781b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2782b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* unfortunately we can't return errors to the stack */ 2783b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis set_rxmode(dev, -1, false); 2784b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2785b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2786b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int cxgb_change_mtu(struct net_device *dev, int new_mtu) 2787b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2788b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret; 2789b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 2790b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2791b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (new_mtu < 81 || new_mtu > MAX_MTU) /* accommodate SACK */ 2792b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return -EINVAL; 2793060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, new_mtu, -1, 2794060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis -1, -1, -1, true); 2795b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!ret) 2796b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev->mtu = new_mtu; 2797b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 2798b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2799b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2800b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int cxgb_set_mac_addr(struct net_device *dev, void *p) 2801b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2802b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret; 2803b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sockaddr *addr = p; 2804b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 2805b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2806b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!is_valid_ether_addr(addr->sa_data)) 2807504f9b5a6bb5336ad434438d0cdd61a16db80129Danny Kukawka return -EADDRNOTAVAIL; 2808b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2809060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_change_mac(pi->adapter, pi->adapter->fn, pi->viid, 2810060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis pi->xact_addr_filt, addr->sa_data, true, true); 2811b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 2812b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 2813b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2814b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 2815b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->xact_addr_filt = ret; 2816b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 2817b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2818b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2819b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#ifdef CONFIG_NET_POLL_CONTROLLER 2820b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void cxgb_netpoll(struct net_device *dev) 2821b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2822b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = netdev_priv(dev); 2823b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adap = pi->adapter; 2824b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2825b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adap->flags & USING_MSIX) { 2826b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i; 2827b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_eth_rxq *rx = &adap->sge.ethrxq[pi->first_qset]; 2828b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2829b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = pi->nqsets; i; i--, rx++) 2830b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_sge_intr_msix(0, &rx->rspq); 2831b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else 2832b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_intr_handler(adap)(0, adap); 2833b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2834b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#endif 2835b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2836b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic const struct net_device_ops cxgb4_netdev_ops = { 2837b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .ndo_open = cxgb_open, 2838b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .ndo_stop = cxgb_close, 2839b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .ndo_start_xmit = t4_eth_xmit, 28409be793bfa38436f9142de219b6eef4d8dfa96606Dimitris Michailidis .ndo_get_stats64 = cxgb_get_stats, 2841b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .ndo_set_rx_mode = cxgb_set_rxmode, 2842b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .ndo_set_mac_address = cxgb_set_mac_addr, 28432ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław .ndo_set_features = cxgb_set_features, 2844b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .ndo_validate_addr = eth_validate_addr, 2845b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .ndo_do_ioctl = cxgb_ioctl, 2846b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .ndo_change_mtu = cxgb_change_mtu, 2847b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#ifdef CONFIG_NET_POLL_CONTROLLER 2848b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .ndo_poll_controller = cxgb_netpoll, 2849b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#endif 2850b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 2851b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2852b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisvoid t4_fatal_err(struct adapter *adap) 2853b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2854b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_set_reg_field(adap, SGE_CONTROL, GLOBALENABLE, 0); 2855b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_intr_disable(adap); 2856b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_alert(adap->pdev_dev, "encountered fatal error, adapter stopped\n"); 2857b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2858b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2859b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void setup_memwin(struct adapter *adap) 2860b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2861b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u32 bar0; 2862b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2863b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis bar0 = pci_resource_start(adap->pdev, 0); /* truncation intentional */ 2864b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 0), 2865b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (bar0 + MEMWIN0_BASE) | BIR(0) | 2866b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis WINDOW(ilog2(MEMWIN0_APERTURE) - 10)); 2867b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 1), 2868b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (bar0 + MEMWIN1_BASE) | BIR(0) | 2869b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis WINDOW(ilog2(MEMWIN1_APERTURE) - 10)); 2870b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_write_reg(adap, PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 2), 2871b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (bar0 + MEMWIN2_BASE) | BIR(0) | 2872b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis WINDOW(ilog2(MEMWIN2_APERTURE) - 10)); 28731ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis if (adap->vres.ocq.size) { 28741ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis unsigned int start, sz_kb; 28751ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis 28761ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis start = pci_resource_start(adap->pdev, 2) + 28771ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis OCQ_WIN_OFFSET(adap->pdev, &adap->vres); 28781ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis sz_kb = roundup_pow_of_two(adap->vres.ocq.size) >> 10; 28791ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis t4_write_reg(adap, 28801ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN, 3), 28811ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis start | BIR(1) | WINDOW(ilog2(sz_kb))); 28821ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis t4_write_reg(adap, 28831ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, 3), 28841ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis adap->vres.ocq.start); 28851ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis t4_read_reg(adap, 28861ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET, 3)); 28871ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis } 2888b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 2889b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 289002b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidisstatic int adap_init1(struct adapter *adap, struct fw_caps_config_cmd *c) 289102b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis{ 289202b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis u32 v; 289302b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis int ret; 289402b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis 289502b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis /* get device capabilities */ 289602b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis memset(c, 0, sizeof(*c)); 289702b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis c->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | 289802b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis FW_CMD_REQUEST | FW_CMD_READ); 289902b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis c->retval_len16 = htonl(FW_LEN16(*c)); 2900060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_wr_mbox(adap, adap->fn, c, sizeof(*c), c); 290102b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis if (ret < 0) 290202b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis return ret; 290302b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis 290402b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis /* select capabilities we'll be using */ 290502b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis if (c->niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) { 290602b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis if (!vf_acls) 290702b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis c->niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM); 290802b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis else 290902b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis c->niccaps = htons(FW_CAPS_CONFIG_NIC_VM); 291002b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis } else if (vf_acls) { 291102b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis dev_err(adap->pdev_dev, "virtualization ACLs not supported"); 291202b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis return ret; 291302b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis } 291402b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis c->op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | 291502b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis FW_CMD_REQUEST | FW_CMD_WRITE); 2916060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_wr_mbox(adap, adap->fn, c, sizeof(*c), NULL); 291702b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis if (ret < 0) 291802b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis return ret; 291902b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis 2920060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_config_glbl_rss(adap, adap->fn, 292102b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL, 292202b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis FW_RSS_GLB_CONFIG_CMD_TNLMAPEN | 292302b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis FW_RSS_GLB_CONFIG_CMD_TNLALLLKP); 292402b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis if (ret < 0) 292502b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis return ret; 292602b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis 2927060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_cfg_pfvf(adap, adap->fn, adap->fn, 0, MAX_EGRQ, 64, MAX_INGQ, 2928060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis 0, 0, 4, 0xf, 0xf, 16, FW_CMD_CAP_PF, FW_CMD_CAP_PF); 292902b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis if (ret < 0) 293002b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis return ret; 293102b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis 293202b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis t4_sge_init(adap); 293302b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis 293402b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis /* tweak some settings */ 293502b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis t4_write_reg(adap, TP_SHIFT_CNT, 0x64f8849); 293602b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis t4_write_reg(adap, ULP_RX_TDDP_PSZ, HPZ0(PAGE_SHIFT - 12)); 293702b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis t4_write_reg(adap, TP_PIO_ADDR, TP_INGRESS_CONFIG); 293802b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis v = t4_read_reg(adap, TP_PIO_DATA); 293902b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis t4_write_reg(adap, TP_PIO_DATA, v & ~CSUM_HAS_PSEUDO_HDR); 2940060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis 2941060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis /* get basic stuff going */ 2942060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis return t4_early_init(adap, adap->fn); 294302b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis} 294402b5fb8e14923ff9111de1a00004ccd593adaedbDimitris Michailidis 2945b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2946b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Max # of ATIDs. The absolute HW max is 16K but we keep it lower. 2947b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2948b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define MAX_ATIDS 8192U 2949b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2950b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2951b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Phase 0 of initialization: contact FW, obtain config, perform basic init. 2952b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 2953b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int adap_init0(struct adapter *adap) 2954b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 2955b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret; 2956b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u32 v, port_vec; 2957b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis enum dev_state state; 2958b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis u32 params[7], val[7]; 2959b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct fw_caps_config_cmd c; 2960b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2961b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = t4_check_fw_version(adap); 2962b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret == -EINVAL || ret > 0) { 2963b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (upgrade_fw(adap) >= 0) /* recache FW version */ 2964b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = t4_check_fw_version(adap); 2965b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2966b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 2967b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 2968b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2969b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* contact FW, request master */ 2970060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_fw_hello(adap, adap->fn, adap->fn, MASTER_MUST, &state); 2971b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) { 2972b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_err(adap->pdev_dev, "could not connect to FW, error %d\n", 2973b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret); 2974b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 2975b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 2976b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2977b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* reset device */ 2978060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_fw_reset(adap, adap->fn, PIORSTMODE | PIORST); 2979b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 2980b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto bye; 2981b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2982b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (v = 0; v < SGE_NTIMERS - 1; v++) 2983b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->sge.timer_val[v] = min(intr_holdoff[v], MAX_SGE_TIMERVAL); 2984b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->sge.timer_val[SGE_NTIMERS - 1] = MAX_SGE_TIMERVAL; 2985b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->sge.counter_val[0] = 1; 2986b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (v = 1; v < SGE_NCOUNTERS; v++) 2987b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->sge.counter_val[v] = min(intr_cnt[v - 1], 2988b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis THRESHOLD_3_MASK); 2989b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define FW_PARAM_DEV(param) \ 2990b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | \ 2991b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_##param)) 2992b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 2993a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis params[0] = FW_PARAM_DEV(CCLK); 2994060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_query_params(adap, adap->fn, adap->fn, 0, 1, params, val); 2995a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis if (ret < 0) 2996a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis goto bye; 2997a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis adap->params.vpd.cclk = val[0]; 2998a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis 2999a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis ret = adap_init1(adap, &c); 3000a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis if (ret < 0) 3001a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis goto bye; 3002a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis 3003b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define FW_PARAM_PFVF(param) \ 3004b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) | \ 3005060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_##param) | \ 3006060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis FW_PARAMS_PARAM_Y(adap->fn)) 3007b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3008b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[0] = FW_PARAM_DEV(PORTVEC); 3009b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[1] = FW_PARAM_PFVF(L2T_START); 3010b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[2] = FW_PARAM_PFVF(L2T_END); 3011b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[3] = FW_PARAM_PFVF(FILTER_START); 3012b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[4] = FW_PARAM_PFVF(FILTER_END); 3013e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis params[5] = FW_PARAM_PFVF(IQFLINT_START); 3014e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis params[6] = FW_PARAM_PFVF(EQ_START); 3015e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis ret = t4_query_params(adap, adap->fn, adap->fn, 0, 7, params, val); 3016b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 3017b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto bye; 3018b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis port_vec = val[0]; 3019b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tids.ftid_base = val[3]; 3020b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tids.nftids = val[4] - val[3] + 1; 3021e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis adap->sge.ingr_start = val[5]; 3022e46dab4d4be87769b09404135bc34f89e2e155d8Dimitris Michailidis adap->sge.egr_start = val[6]; 3023b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3024b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (c.ofldcaps) { 3025b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* query offload-related parameters */ 3026b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[0] = FW_PARAM_DEV(NTID); 3027b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[1] = FW_PARAM_PFVF(SERVER_START); 3028b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[2] = FW_PARAM_PFVF(SERVER_END); 3029b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[3] = FW_PARAM_PFVF(TDDP_START); 3030b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[4] = FW_PARAM_PFVF(TDDP_END); 3031b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[5] = FW_PARAM_DEV(FLOWC_BUFFIFO_SZ); 3032060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_query_params(adap, adap->fn, adap->fn, 0, 6, params, 3033060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis val); 3034b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 3035b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto bye; 3036b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tids.ntids = val[0]; 3037b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS); 3038b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tids.stid_base = val[1]; 3039b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->tids.nstids = val[2] - val[1] + 1; 3040b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.ddp.start = val[3]; 3041b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.ddp.size = val[4] - val[3] + 1; 3042b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->params.ofldq_wr_cred = val[5]; 3043b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->params.offload = 1; 3044b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3045b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (c.rdmacaps) { 3046b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[0] = FW_PARAM_PFVF(STAG_START); 3047b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[1] = FW_PARAM_PFVF(STAG_END); 3048b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[2] = FW_PARAM_PFVF(RQ_START); 3049b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[3] = FW_PARAM_PFVF(RQ_END); 3050b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[4] = FW_PARAM_PFVF(PBL_START); 3051b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[5] = FW_PARAM_PFVF(PBL_END); 3052060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_query_params(adap, adap->fn, adap->fn, 0, 6, params, 3053060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis val); 3054b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 3055b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto bye; 3056b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.stag.start = val[0]; 3057b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.stag.size = val[1] - val[0] + 1; 3058b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.rq.start = val[2]; 3059b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.rq.size = val[3] - val[2] + 1; 3060b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.pbl.start = val[4]; 3061b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.pbl.size = val[5] - val[4] + 1; 3062a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis 3063a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis params[0] = FW_PARAM_PFVF(SQRQ_START); 3064a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis params[1] = FW_PARAM_PFVF(SQRQ_END); 3065a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis params[2] = FW_PARAM_PFVF(CQ_START); 3066a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis params[3] = FW_PARAM_PFVF(CQ_END); 30671ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis params[4] = FW_PARAM_PFVF(OCQ_START); 30681ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis params[5] = FW_PARAM_PFVF(OCQ_END); 3069060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_query_params(adap, adap->fn, adap->fn, 0, 6, params, 3070060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis val); 3071a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis if (ret < 0) 3072a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis goto bye; 3073a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis adap->vres.qp.start = val[0]; 3074a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis adap->vres.qp.size = val[1] - val[0] + 1; 3075a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis adap->vres.cq.start = val[2]; 3076a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis adap->vres.cq.size = val[3] - val[2] + 1; 30771ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis adap->vres.ocq.start = val[4]; 30781ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis adap->vres.ocq.size = val[5] - val[4] + 1; 3079b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3080b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (c.iscsicaps) { 3081b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[0] = FW_PARAM_PFVF(ISCSI_START); 3082b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis params[1] = FW_PARAM_PFVF(ISCSI_END); 3083060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_query_params(adap, adap->fn, adap->fn, 0, 2, params, 3084060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis val); 3085b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 3086b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto bye; 3087b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.iscsi.start = val[0]; 3088b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->vres.iscsi.size = val[1] - val[0] + 1; 3089b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3090b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#undef FW_PARAM_PFVF 3091b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#undef FW_PARAM_DEV 3092b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3093b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->params.nports = hweight32(port_vec); 3094b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->params.portvec = port_vec; 3095b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->flags |= FW_OK; 3096b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3097b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* These are finalized by FW initialization, load their values now */ 3098b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis v = t4_read_reg(adap, TP_TIMER_RESOLUTION); 3099b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->params.tp.tre = TIMERRESOLUTION_GET(v); 3100b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_read_mtu_tbl(adap, adap->params.mtus, NULL); 3101b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd, 3102b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->params.b_wnd); 31037ee9ff94857dd27144521118173786a03d490efbCasey Leedom 31047ee9ff94857dd27144521118173786a03d490efbCasey Leedom#ifdef CONFIG_PCI_IOV 31057ee9ff94857dd27144521118173786a03d490efbCasey Leedom /* 31067ee9ff94857dd27144521118173786a03d490efbCasey Leedom * Provision resource limits for Virtual Functions. We currently 31077ee9ff94857dd27144521118173786a03d490efbCasey Leedom * grant them all the same static resource limits except for the Port 31087ee9ff94857dd27144521118173786a03d490efbCasey Leedom * Access Rights Mask which we're assigning based on the PF. All of 31097ee9ff94857dd27144521118173786a03d490efbCasey Leedom * the static provisioning stuff for both the PF and VF really needs 31107ee9ff94857dd27144521118173786a03d490efbCasey Leedom * to be managed in a persistent manner for each device which the 31117ee9ff94857dd27144521118173786a03d490efbCasey Leedom * firmware controls. 31127ee9ff94857dd27144521118173786a03d490efbCasey Leedom */ 31137ee9ff94857dd27144521118173786a03d490efbCasey Leedom { 31147ee9ff94857dd27144521118173786a03d490efbCasey Leedom int pf, vf; 31157ee9ff94857dd27144521118173786a03d490efbCasey Leedom 31167ee9ff94857dd27144521118173786a03d490efbCasey Leedom for (pf = 0; pf < ARRAY_SIZE(num_vf); pf++) { 31177ee9ff94857dd27144521118173786a03d490efbCasey Leedom if (num_vf[pf] <= 0) 31187ee9ff94857dd27144521118173786a03d490efbCasey Leedom continue; 31197ee9ff94857dd27144521118173786a03d490efbCasey Leedom 31207ee9ff94857dd27144521118173786a03d490efbCasey Leedom /* VF numbering starts at 1! */ 31217ee9ff94857dd27144521118173786a03d490efbCasey Leedom for (vf = 1; vf <= num_vf[pf]; vf++) { 3122060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_cfg_pfvf(adap, adap->fn, pf, vf, 31237ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NEQ, VFRES_NETHCTRL, 31247ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NIQFLINT, VFRES_NIQ, 31257ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_TC, VFRES_NVI, 31267ee9ff94857dd27144521118173786a03d490efbCasey Leedom FW_PFVF_CMD_CMASK_MASK, 31277ee9ff94857dd27144521118173786a03d490efbCasey Leedom pfvfres_pmask(adap, pf, vf), 31287ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_NEXACTF, 31297ee9ff94857dd27144521118173786a03d490efbCasey Leedom VFRES_R_CAPS, VFRES_WX_CAPS); 31307ee9ff94857dd27144521118173786a03d490efbCasey Leedom if (ret < 0) 31317ee9ff94857dd27144521118173786a03d490efbCasey Leedom dev_warn(adap->pdev_dev, "failed to " 31327ee9ff94857dd27144521118173786a03d490efbCasey Leedom "provision pf/vf=%d/%d; " 31337ee9ff94857dd27144521118173786a03d490efbCasey Leedom "err=%d\n", pf, vf, ret); 31347ee9ff94857dd27144521118173786a03d490efbCasey Leedom } 31357ee9ff94857dd27144521118173786a03d490efbCasey Leedom } 31367ee9ff94857dd27144521118173786a03d490efbCasey Leedom } 31377ee9ff94857dd27144521118173786a03d490efbCasey Leedom#endif 31387ee9ff94857dd27144521118173786a03d490efbCasey Leedom 31391ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis setup_memwin(adap); 3140b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 3141b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3142b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 3143b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * If a command timed out or failed with EIO FW does not operate within 3144b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * its spec or something catastrophic happened to HW/FW, stop issuing 3145b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * commands. 3146b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 3147b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisbye: if (ret != -ETIMEDOUT && ret != -EIO) 3148060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis t4_fw_bye(adap, adap->fn); 3149b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 3150b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3151b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3152204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis/* EEH callbacks */ 3153204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3154204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidisstatic pci_ers_result_t eeh_err_detected(struct pci_dev *pdev, 3155204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis pci_channel_state_t state) 3156204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis{ 3157204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis int i; 3158204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis struct adapter *adap = pci_get_drvdata(pdev); 3159204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3160204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (!adap) 3161204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis goto out; 3162204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3163204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis rtnl_lock(); 3164204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis adap->flags &= ~FW_OK; 3165204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis notify_ulds(adap, CXGB4_STATE_START_RECOVERY); 3166204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis for_each_port(adap, i) { 3167204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis struct net_device *dev = adap->port[i]; 3168204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3169204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis netif_device_detach(dev); 3170204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis netif_carrier_off(dev); 3171204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis } 3172204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (adap->flags & FULL_INIT_DONE) 3173204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis cxgb_down(adap); 3174204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis rtnl_unlock(); 3175204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis pci_disable_device(pdev); 3176204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidisout: return state == pci_channel_io_perm_failure ? 3177204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; 3178204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis} 3179204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3180204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidisstatic pci_ers_result_t eeh_slot_reset(struct pci_dev *pdev) 3181204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis{ 3182204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis int i, ret; 3183204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis struct fw_caps_config_cmd c; 3184204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis struct adapter *adap = pci_get_drvdata(pdev); 3185204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3186204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (!adap) { 3187204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis pci_restore_state(pdev); 3188204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis pci_save_state(pdev); 3189204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis return PCI_ERS_RESULT_RECOVERED; 3190204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis } 3191204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3192204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (pci_enable_device(pdev)) { 3193204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis dev_err(&pdev->dev, "cannot reenable PCI device after reset\n"); 3194204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis return PCI_ERS_RESULT_DISCONNECT; 3195204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis } 3196204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3197204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis pci_set_master(pdev); 3198204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis pci_restore_state(pdev); 3199204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis pci_save_state(pdev); 3200204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis pci_cleanup_aer_uncorrect_error_status(pdev); 3201204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3202204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (t4_wait_dev_ready(adap) < 0) 3203204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis return PCI_ERS_RESULT_DISCONNECT; 3204060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis if (t4_fw_hello(adap, adap->fn, adap->fn, MASTER_MUST, NULL)) 3205204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis return PCI_ERS_RESULT_DISCONNECT; 3206204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis adap->flags |= FW_OK; 3207204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (adap_init1(adap, &c)) 3208204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis return PCI_ERS_RESULT_DISCONNECT; 3209204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3210204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis for_each_port(adap, i) { 3211204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis struct port_info *p = adap2pinfo(adap, i); 3212204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3213060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis ret = t4_alloc_vi(adap, adap->fn, p->tx_chan, adap->fn, 0, 1, 3214060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis NULL, NULL); 3215204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (ret < 0) 3216204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis return PCI_ERS_RESULT_DISCONNECT; 3217204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis p->viid = ret; 3218204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis p->xact_addr_filt = -1; 3219204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis } 3220204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3221204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis t4_load_mtus(adap, adap->params.mtus, adap->params.a_wnd, 3222204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis adap->params.b_wnd); 32231ae970e0c047fbb1050865c6cf3ac68c7ca67dbaDimitris Michailidis setup_memwin(adap); 3224204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (cxgb_up(adap)) 3225204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis return PCI_ERS_RESULT_DISCONNECT; 3226204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis return PCI_ERS_RESULT_RECOVERED; 3227204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis} 3228204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3229204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidisstatic void eeh_resume(struct pci_dev *pdev) 3230204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis{ 3231204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis int i; 3232204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis struct adapter *adap = pci_get_drvdata(pdev); 3233204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3234204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (!adap) 3235204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis return; 3236204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3237204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis rtnl_lock(); 3238204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis for_each_port(adap, i) { 3239204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis struct net_device *dev = adap->port[i]; 3240204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3241204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis if (netif_running(dev)) { 3242204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis link_start(dev); 3243204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis cxgb_set_rxmode(dev); 3244204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis } 3245204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis netif_device_attach(dev); 3246204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis } 3247204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis rtnl_unlock(); 3248204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis} 3249204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3250204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidisstatic struct pci_error_handlers cxgb4_eeh = { 3251204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis .error_detected = eeh_err_detected, 3252204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis .slot_reset = eeh_slot_reset, 3253204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis .resume = eeh_resume, 3254204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis}; 3255204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis 3256b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic inline bool is_10g_port(const struct link_config *lc) 3257b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3258b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0; 3259b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3260b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3261b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic inline void init_rspq(struct sge_rspq *q, u8 timer_idx, u8 pkt_cnt_idx, 3262b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int size, unsigned int iqe_size) 3263b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3264b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis q->intr_params = QINTR_TIMER_IDX(timer_idx) | 3265b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis (pkt_cnt_idx < SGE_NCOUNTERS ? QINTR_CNT_EN : 0); 3266b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis q->pktcnt_idx = pkt_cnt_idx < SGE_NCOUNTERS ? pkt_cnt_idx : 0; 3267b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis q->iqe_len = iqe_size; 3268b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis q->size = size; 3269b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3270b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3271b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 3272b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Perform default configuration of DMA queues depending on the number and type 3273b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * of ports we found and the number of available CPUs. Most settings can be 3274b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * modified by the admin prior to actual use. 3275b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 3276b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void __devinit cfg_queues(struct adapter *adap) 3277b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3278b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge *s = &adap->sge; 3279b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i, q10g = 0, n10g = 0, qidx = 0; 3280b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3281b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adap, i) 3282b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis n10g += is_10g_port(&adap2pinfo(adap, i)->link_cfg); 3283b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3284b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 3285b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * We default to 1 queue per non-10G port and up to # of cores queues 3286b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * per 10G port. 3287b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 3288b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (n10g) 3289b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis q10g = (MAX_ETH_QSETS - (adap->params.nports - n10g)) / n10g; 3290b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (q10g > num_online_cpus()) 3291b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis q10g = num_online_cpus(); 3292b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3293b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adap, i) { 3294b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi = adap2pinfo(adap, i); 3295b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3296b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->first_qset = qidx; 3297b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->nqsets = is_10g_port(&pi->link_cfg) ? q10g : 1; 3298b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis qidx += pi->nqsets; 3299b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3300b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3301b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ethqsets = qidx; 3302b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->max_ethqsets = qidx; /* MSI-X may lower it later */ 3303b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3304b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (is_offload(adap)) { 3305b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 3306b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * For offload we use 1 queue/channel if all ports are up to 1G, 3307b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * otherwise we divide all available queues amongst the channels 3308b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * capped by the number of available cores. 3309b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 3310b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (n10g) { 3311b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis i = min_t(int, ARRAY_SIZE(s->ofldrxq), 3312b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis num_online_cpus()); 3313b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ofldqsets = roundup(i, adap->params.nports); 3314b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else 3315b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ofldqsets = adap->params.nports; 3316b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* For RDMA one Rx queue per channel suffices */ 3317b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->rdmaqs = adap->params.nports; 3318b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3319b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3320b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(s->ethrxq); i++) { 3321b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_eth_rxq *r = &s->ethrxq[i]; 3322b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3323b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis init_rspq(&r->rspq, 0, 0, 1024, 64); 3324b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis r->fl.size = 72; 3325b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3326b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3327b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(s->ethtxq); i++) 3328b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ethtxq[i].q.size = 1024; 3329b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3330b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(s->ctrlq); i++) 3331b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ctrlq[i].q.size = 512; 3332b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3333b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(s->ofldtxq); i++) 3334b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ofldtxq[i].q.size = 1024; 3335b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3336b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(s->ofldrxq); i++) { 3337b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_ofld_rxq *r = &s->ofldrxq[i]; 3338b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3339b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis init_rspq(&r->rspq, 0, 0, 1024, 64); 3340b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis r->rspq.uld = CXGB4_ULD_ISCSI; 3341b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis r->fl.size = 72; 3342b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3343b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3344b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(s->rdmarxq); i++) { 3345b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge_ofld_rxq *r = &s->rdmarxq[i]; 3346b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3347b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis init_rspq(&r->rspq, 0, 0, 511, 64); 3348b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis r->rspq.uld = CXGB4_ULD_RDMA; 3349b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis r->fl.size = 72; 3350b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3351b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3352b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis init_rspq(&s->fw_evtq, 6, 0, 512, 64); 3353b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis init_rspq(&s->intrq, 6, 0, 2 * MAX_INGQ, 64); 3354b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3355b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3356b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 3357b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Reduce the number of Ethernet queues across all ports to at most n. 3358b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * n provides at least one queue per port. 3359b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 3360b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void __devinit reduce_ethqs(struct adapter *adap, int n) 3361b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3362b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i; 3363b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi; 3364b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3365b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while (n < adap->sge.ethqsets) 3366b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adap, i) { 3367b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi = adap2pinfo(adap, i); 3368b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (pi->nqsets > 1) { 3369b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->nqsets--; 3370b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->sge.ethqsets--; 3371b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adap->sge.ethqsets <= n) 3372b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis break; 3373b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3374b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3375b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3376b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis n = 0; 3377b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adap, i) { 3378b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi = adap2pinfo(adap, i); 3379b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->first_qset = n; 3380b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis n += pi->nqsets; 3381b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3382b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3383b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3384b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis/* 2 MSI-X vectors needed for the FW queue and non-data interrupts */ 3385b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#define EXTRA_VECS 2 3386b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3387b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int __devinit enable_msix(struct adapter *adap) 3388b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3389b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ofld_need = 0; 3390b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i, err, want, need; 3391b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct sge *s = &adap->sge; 3392b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unsigned int nchan = adap->params.nports; 3393b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct msix_entry entries[MAX_INGQ + 1]; 3394b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3395b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < ARRAY_SIZE(entries); ++i) 3396b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis entries[i].entry = i; 3397b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3398b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis want = s->max_ethqsets + EXTRA_VECS; 3399b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (is_offload(adap)) { 3400b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis want += s->rdmaqs + s->ofldqsets; 3401b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* need nchan for each possible ULD */ 3402b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ofld_need = 2 * nchan; 3403b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3404b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis need = adap->params.nports + EXTRA_VECS + ofld_need; 3405b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3406b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis while ((err = pci_enable_msix(adap->pdev, entries, want)) >= need) 3407b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis want = err; 3408b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3409b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!err) { 3410b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 3411b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Distribute available vectors to the various queue groups. 3412b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Every group gets its minimum requirement and NIC gets top 3413b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * priority for leftovers. 3414b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 3415b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis i = want - EXTRA_VECS - ofld_need; 3416b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (i < s->max_ethqsets) { 3417b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->max_ethqsets = i; 3418b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (i < s->ethqsets) 3419b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis reduce_ethqs(adap, i); 3420b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3421b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (is_offload(adap)) { 3422b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis i = want - EXTRA_VECS - s->max_ethqsets; 3423b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis i -= ofld_need - nchan; 3424b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis s->ofldqsets = (i / nchan) * nchan; /* round down */ 3425b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3426b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for (i = 0; i < want; ++i) 3427b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adap->msix_info[i].vec = entries[i].vector; 3428b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else if (err > 0) 3429b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_info(adap->pdev_dev, 3430b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "only %d MSI-X vectors left, not using MSI-X\n", err); 3431b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 3432b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3433b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3434b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#undef EXTRA_VECS 3435b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3436671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidisstatic int __devinit init_rss(struct adapter *adap) 3437671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis{ 3438671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis unsigned int i, j; 3439671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 3440671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis for_each_port(adap, i) { 3441671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis struct port_info *pi = adap2pinfo(adap, i); 3442671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 3443671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis pi->rss = kcalloc(pi->rss_size, sizeof(u16), GFP_KERNEL); 3444671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis if (!pi->rss) 3445671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis return -ENOMEM; 3446671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis for (j = 0; j < pi->rss_size; j++) 3447278bc4296bd64ffd1d3913b487dc8a520e423a7aBen Hutchings pi->rss[j] = ethtool_rxfh_indir_default(j, pi->nqsets); 3448671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis } 3449671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis return 0; 3450671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis} 3451671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 3452118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidisstatic void __devinit print_port_info(const struct net_device *dev) 3453b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3454b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis static const char *base[] = { 3455a0881cab6c0a1c8ad48a4ab0b971c8e786dadf1cDimitris Michailidis "R XFI", "R XAUI", "T SGMII", "T XFI", "T XAUI", "KX4", "CX4", 34567d5e77aafa39f3210b6273a44fe07508e837c3cbDimitris Michailidis "KX", "KR", "R SFP+", "KR/KX", "KR/KX/KX4" 3457b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis }; 3458b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3459b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis char buf[80]; 3460118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis char *bufp = buf; 3461f1a051b93090ad920e88748023ab0dea3a6e2ad7Dimitris Michailidis const char *spd = ""; 3462118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis const struct port_info *pi = netdev_priv(dev); 3463118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis const struct adapter *adap = pi->adapter; 3464f1a051b93090ad920e88748023ab0dea3a6e2ad7Dimitris Michailidis 3465f1a051b93090ad920e88748023ab0dea3a6e2ad7Dimitris Michailidis if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_2_5GB) 3466f1a051b93090ad920e88748023ab0dea3a6e2ad7Dimitris Michailidis spd = " 2.5 GT/s"; 3467f1a051b93090ad920e88748023ab0dea3a6e2ad7Dimitris Michailidis else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_5_0GB) 3468f1a051b93090ad920e88748023ab0dea3a6e2ad7Dimitris Michailidis spd = " 5 GT/s"; 3469b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3470118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M) 3471118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis bufp += sprintf(bufp, "100/"); 3472118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G) 3473118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis bufp += sprintf(bufp, "1000/"); 3474118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) 3475118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis bufp += sprintf(bufp, "10G/"); 3476118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis if (bufp != buf) 3477118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis --bufp; 3478118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis sprintf(bufp, "BASE-%s", base[pi->port_type]); 3479118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis 3480118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis netdev_info(dev, "Chelsio %s rev %d %s %sNIC PCIe x%d%s%s\n", 3481118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis adap->params.vpd.id, adap->params.rev, buf, 3482118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis is_offload(adap) ? "R" : "", adap->params.pci.width, spd, 3483118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis (adap->flags & USING_MSIX) ? " MSI-X" : 3484118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis (adap->flags & USING_MSI) ? " MSI" : ""); 3485118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis netdev_info(dev, "S/N: %s, E/C: %s\n", 3486118969ed21b6895045b0a5a8a32feac1c9341096Dimitris Michailidis adap->params.vpd.sn, adap->params.vpd.ec); 3487b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3488b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3489ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidisstatic void __devinit enable_pcie_relaxed_ordering(struct pci_dev *dev) 3490ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis{ 3491ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis u16 v; 3492ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis int pos; 3493ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis 3494ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis pos = pci_pcie_cap(dev); 3495ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis if (pos > 0) { 3496ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &v); 3497ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis v |= PCI_EXP_DEVCTL_RELAX_EN; 3498ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, v); 3499ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis } 3500ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis} 3501ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis 3502065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis/* 3503065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis * Free the following resources: 3504065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis * - memory used for tables 3505065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis * - MSI/MSI-X 3506065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis * - net devices 3507065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis * - resources FW is holding for us 3508065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis */ 3509065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidisstatic void free_some_resources(struct adapter *adapter) 3510065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis{ 3511065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis unsigned int i; 3512065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis 3513065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis t4_free_mem(adapter->l2t); 3514065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis t4_free_mem(adapter->tids.tid_tab); 3515065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis disable_msi(adapter); 3516065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis 3517065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis for_each_port(adapter, i) 3518671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis if (adapter->port[i]) { 3519671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis kfree(adap2pinfo(adapter, i)->rss); 3520065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis free_netdev(adapter->port[i]); 3521671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis } 3522065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis if (adapter->flags & FW_OK) 3523060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis t4_fw_bye(adapter, adapter->fn); 3524065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis} 3525065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis 35262ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN) 352735d35682041686572d5158993dede90bc73dc1d9Dimitris Michailidis#define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \ 3528b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA) 3529b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3530b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int __devinit init_one(struct pci_dev *pdev, 3531b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis const struct pci_device_id *ent) 3532b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3533b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int func, i, err; 3534b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct port_info *pi; 3535c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosław bool highdma = false; 3536b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = NULL; 3537b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3538b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis printk_once(KERN_INFO "%s - version %s\n", DRV_DESC, DRV_VERSION); 3539b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3540b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = pci_request_regions(pdev, KBUILD_MODNAME); 3541b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) { 3542b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* Just info, some other driver may have claimed the device. */ 3543b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_info(&pdev->dev, "cannot obtain PCI resources\n"); 3544b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 3545b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3546b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3547060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis /* We control everything through one PF */ 3548b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis func = PCI_FUNC(pdev->devfn); 3549060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis if (func != ent->driver_data) { 3550204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis pci_save_state(pdev); /* to restore SR-IOV later */ 3551b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto sriov; 3552204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis } 3553b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3554b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = pci_enable_device(pdev); 3555b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) { 3556b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_err(&pdev->dev, "cannot enable PCI device\n"); 3557b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_release_regions; 3558b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3559b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3560b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { 3561c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosław highdma = true; 3562b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); 3563b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) { 3564b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_err(&pdev->dev, "unable to obtain 64-bit DMA for " 3565b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "coherent allocations\n"); 3566b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_disable_device; 3567b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3568b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } else { 3569b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 3570b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) { 3571b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_err(&pdev->dev, "no usable DMA configuration\n"); 3572b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_disable_device; 3573b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3574b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3575b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3576b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_enable_pcie_error_reporting(pdev); 3577ef306b50b983be4873aed453c1feeaab22f3a098Dimitris Michailidis enable_pcie_relaxed_ordering(pdev); 3578b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_set_master(pdev); 3579b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_save_state(pdev); 3580b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3581b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); 3582b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!adapter) { 3583b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = -ENOMEM; 3584b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_disable_device; 3585b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3586b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3587b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->regs = pci_ioremap_bar(pdev, 0); 3588b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!adapter->regs) { 3589b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_err(&pdev->dev, "cannot map device registers\n"); 3590b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = -ENOMEM; 3591b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_free_adapter; 3592b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3593b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3594b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->pdev = pdev; 3595b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->pdev_dev = &pdev->dev; 3596060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis adapter->fn = func; 3597b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->msg_enable = dflt_msg_enable; 3598b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map)); 3599b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3600b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_init(&adapter->stats_lock); 3601b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis spin_lock_init(&adapter->tid_release_lock); 3602b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3603b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis INIT_WORK(&adapter->tid_release_task, process_tid_release_list); 3604b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3605b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = t4_prep_adapter(adapter); 3606b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 3607b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_unmap_bar; 3608b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = adap_init0(adapter); 3609b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 3610b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_unmap_bar; 3611b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3612b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adapter, i) { 3613b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct net_device *netdev; 3614b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3615b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev = alloc_etherdev_mq(sizeof(struct port_info), 3616b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis MAX_ETH_QSETS); 3617b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!netdev) { 3618b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = -ENOMEM; 3619b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_free_dev; 3620b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3621b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3622b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis SET_NETDEV_DEV(netdev, &pdev->dev); 3623b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3624b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->port[i] = netdev; 3625b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi = netdev_priv(netdev); 3626b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->adapter = adapter; 3627b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->xact_addr_filt = -1; 3628b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pi->port_id = i; 3629b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev->irq = pdev->irq; 3630b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 36312ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław netdev->hw_features = NETIF_F_SG | TSO_FLAGS | 36322ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | 36332ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław NETIF_F_RXCSUM | NETIF_F_RXHASH | 36342ed28baa7076083b56c1e70ccd927b7870117c59Michał Mirosław NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; 3635c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosław if (highdma) 3636c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosław netdev->hw_features |= NETIF_F_HIGHDMA; 3637c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosław netdev->features |= netdev->hw_features; 3638b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev->vlan_features = netdev->features & VLAN_FEAT; 3639b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 364001789349ee52e4a3faf376f1485303d9723c4f1fJiri Pirko netdev->priv_flags |= IFF_UNICAST_FLT; 364101789349ee52e4a3faf376f1485303d9723c4f1fJiri Pirko 3642b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis netdev->netdev_ops = &cxgb4_netdev_ops; 3643b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops); 3644b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3645b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3646b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_set_drvdata(pdev, adapter); 3647b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3648b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adapter->flags & FW_OK) { 3649060e0c752b5047ee691120b75df4c16743981e50Dimitris Michailidis err = t4_port_init(adapter, func, func, 0); 3650b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 3651b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_free_dev; 3652b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3653b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3654b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 3655b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * Configure queues and allocate tables now, they can be needed as 3656b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * soon as the first register_netdev completes. 3657b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 3658b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cfg_queues(adapter); 3659b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3660b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->l2t = t4_init_l2t(); 3661b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!adapter->l2t) { 3662b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* We tolerate a lack of L2T, giving up some functionality */ 3663b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_warn(&pdev->dev, "could not allocate L2T, continuing\n"); 3664b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->params.offload = 0; 3665b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3666b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3667b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (is_offload(adapter) && tid_init(&adapter->tids) < 0) { 3668b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_warn(&pdev->dev, "could not allocate TID table, " 3669b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "continuing\n"); 3670b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->params.offload = 0; 3671b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3672b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3673f7cabcdd51480282b58c09e5fe1c4835aaf98a66Dimitris Michailidis /* See what interrupts we'll be using */ 3674f7cabcdd51480282b58c09e5fe1c4835aaf98a66Dimitris Michailidis if (msi > 1 && enable_msix(adapter) == 0) 3675f7cabcdd51480282b58c09e5fe1c4835aaf98a66Dimitris Michailidis adapter->flags |= USING_MSIX; 3676f7cabcdd51480282b58c09e5fe1c4835aaf98a66Dimitris Michailidis else if (msi > 0 && pci_enable_msi(pdev) == 0) 3677f7cabcdd51480282b58c09e5fe1c4835aaf98a66Dimitris Michailidis adapter->flags |= USING_MSI; 3678f7cabcdd51480282b58c09e5fe1c4835aaf98a66Dimitris Michailidis 3679671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis err = init_rss(adapter); 3680671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis if (err) 3681671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis goto out_free_dev; 3682671b0060d82984a566f2e75ffd166a9b61c6da7dDimitris Michailidis 3683b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* 3684b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * The card is now ready to go. If any errors occur during device 3685b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * registration we do not fail the whole card but rather proceed only 3686b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * with the ports we manage to register successfully. However we must 3687b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis * register at least one net device. 3688b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis */ 3689b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adapter, i) { 3690a57cabe09f843a3f71277c485494496b3b9ee84aDimitris Michailidis pi = adap2pinfo(adapter, i); 3691a57cabe09f843a3f71277c485494496b3b9ee84aDimitris Michailidis netif_set_real_num_tx_queues(adapter->port[i], pi->nqsets); 3692a57cabe09f843a3f71277c485494496b3b9ee84aDimitris Michailidis netif_set_real_num_rx_queues(adapter->port[i], pi->nqsets); 3693a57cabe09f843a3f71277c485494496b3b9ee84aDimitris Michailidis 3694b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis err = register_netdev(adapter->port[i]); 3695b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (err) 3696b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis break; 3697b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis adapter->chan_map[pi->tx_chan] = i; 3698b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis print_port_info(adapter->port[i]); 3699b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3700b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis if (i == 0) { 3701b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_err(&pdev->dev, "could not register any net devices\n"); 3702b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis goto out_free_dev; 3703b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3704b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis if (err) { 3705b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis dev_warn(&pdev->dev, "only %d net devices registered\n", i); 3706b1a3c2b698ec333edc86bf8b5a636162ca309870Dimitris Michailidis err = 0; 37076403eab143205a45a5493166ff8bf7e3646f4a77Joe Perches } 3708b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3709b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (cxgb4_debugfs_root) { 3710b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis adapter->debugfs_root = debugfs_create_dir(pci_name(pdev), 3711b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cxgb4_debugfs_root); 3712b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis setup_debugfs(adapter); 3713b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis } 3714b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 37156482aa7c120447858da1869197b48eff66435a31Divy Le Ray /* PCIe EEH recovery on powerpc platforms needs fundamental reset */ 37166482aa7c120447858da1869197b48eff66435a31Divy Le Ray pdev->needs_freset = 1; 37176482aa7c120447858da1869197b48eff66435a31Divy Le Ray 3718b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (is_offload(adapter)) 3719b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis attach_ulds(adapter); 3720b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3721b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidissriov: 3722b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#ifdef CONFIG_PCI_IOV 3723b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (func < ARRAY_SIZE(num_vf) && num_vf[func] > 0) 3724b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (pci_enable_sriov(pdev, num_vf[func]) == 0) 3725b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis dev_info(&pdev->dev, 3726b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis "instantiated %u virtual functions\n", 3727b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis num_vf[func]); 3728b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis#endif 3729b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return 0; 3730b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3731b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis out_free_dev: 3732065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis free_some_resources(adapter); 3733b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis out_unmap_bar: 3734b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis iounmap(adapter->regs); 3735b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis out_free_adapter: 3736b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis kfree(adapter); 3737b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis out_disable_device: 3738b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_disable_pcie_error_reporting(pdev); 3739b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_disable_device(pdev); 3740b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis out_release_regions: 3741b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_release_regions(pdev); 3742b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_set_drvdata(pdev, NULL); 3743b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return err; 3744b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3745b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3746b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void __devexit remove_one(struct pci_dev *pdev) 3747b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3748b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis struct adapter *adapter = pci_get_drvdata(pdev); 3749b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3750b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_disable_sriov(pdev); 3751b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3752b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adapter) { 3753b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int i; 3754b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3755b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (is_offload(adapter)) 3756b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis detach_ulds(adapter); 3757b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3758b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis for_each_port(adapter, i) 37598f3a76769ee50a839282f70d07d5f3429524b68aDimitris Michailidis if (adapter->port[i]->reg_state == NETREG_REGISTERED) 3760b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis unregister_netdev(adapter->port[i]); 3761b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3762b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (adapter->debugfs_root) 3763b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis debugfs_remove_recursive(adapter->debugfs_root); 3764b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3765aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis if (adapter->flags & FULL_INIT_DONE) 3766aaefae9b32b2cba7350a4d524357168119372e51Dimitris Michailidis cxgb_down(adapter); 3767b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3768065463915c3a2a2ce142f64ed3ed591d72ad88b1Dimitris Michailidis free_some_resources(adapter); 3769b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis iounmap(adapter->regs); 3770b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis kfree(adapter); 3771b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_disable_pcie_error_reporting(pdev); 3772b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_disable_device(pdev); 3773b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_release_regions(pdev); 3774b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_set_drvdata(pdev, NULL); 3775a069ec917457e44e214fc34e50acd185110fa81bDimitris Michailidis } else 3776b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_release_regions(pdev); 3777b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3778b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3779b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic struct pci_driver cxgb4_driver = { 3780b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .name = KBUILD_MODNAME, 3781b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .id_table = cxgb4_pci_tbl, 3782b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .probe = init_one, 3783b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis .remove = __devexit_p(remove_one), 3784204dc3c0b1bea10a7d811970fd41ceabaef31267Dimitris Michailidis .err_handler = &cxgb4_eeh, 3785b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis}; 3786b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3787b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic int __init cxgb4_init_module(void) 3788b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3789b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis int ret; 3790b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3791b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis /* Debugfs support is optional, just warn if this fails */ 3792b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); 3793b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (!cxgb4_debugfs_root) 3794b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pr_warning("could not create debugfs entry, continuing\n"); 3795b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3796b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis ret = pci_register_driver(&cxgb4_driver); 3797b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis if (ret < 0) 3798b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis debugfs_remove(cxgb4_debugfs_root); 3799b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis return ret; 3800b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3801b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3802b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidisstatic void __exit cxgb4_cleanup_module(void) 3803b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis{ 3804b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis pci_unregister_driver(&cxgb4_driver); 3805b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis debugfs_remove(cxgb4_debugfs_root); /* NULL ok */ 3806b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis} 3807b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidis 3808b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidismodule_init(cxgb4_init_module); 3809b8ff05a9c3237f694a1c3bf8ceec3bf6c3c14b15Dimitris Michailidismodule_exit(cxgb4_cleanup_module); 3810