17a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann/* 27a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * linux/drivers/net/ehea/ehea_main.c 37a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * 47a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * eHEA ethernet device driver for IBM eServer System p 57a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * 67a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * (C) Copyright IBM Corp. 2006 77a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * 87a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * Authors: 9508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey * Christoph Raisch <raisch@de.ibm.com> 10508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey * Jan-Bernd Themann <themann@de.ibm.com> 11508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey * Thomas Klein <tklein@de.ibm.com> 127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * 137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * 147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * This program is free software; you can redistribute it and/or modify 157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * it under the terms of the GNU General Public License as published by 167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * the Free Software Foundation; either version 2, or (at your option) 177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * any later version. 187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * 197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * This program is distributed in the hope that it will be useful, 207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * but WITHOUT ANY WARRANTY; without even the implied warranty of 217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * GNU General Public License for more details. 237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * 247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * You should have received a copy of the GNU General Public License 257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * along with this program; if not, write to the Free Software 267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann */ 287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 298c4877a4128e7931077b024a891a4b284d8756a3Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 308c4877a4128e7931077b024a891a4b284d8756a3Joe Perches 317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include <linux/in.h> 327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include <linux/ip.h> 337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include <linux/tcp.h> 347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include <linux/udp.h> 357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include <linux/if.h> 367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include <linux/list.h> 375a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include <linux/if_ether.h> 392a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann#include <linux/notifier.h> 402a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann#include <linux/reboot.h> 4148cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering#include <linux/memory.h> 4221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein#include <asm/kexec.h> 4306f89edf89f254346c95d0c569cecd606459d83eDaniel Walker#include <linux/mutex.h> 44268bb0ce3e87872cb9290c322b0d35bce230d88fLinus Torvalds#include <linux/prefetch.h> 452a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann 467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include <net/ip.h> 477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include "ehea.h" 497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include "ehea_qmr.h" 507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann#include "ehea_phyp.h" 517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd ThemannMODULE_LICENSE("GPL"); 547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd ThemannMODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); 557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd ThemannMODULE_DESCRIPTION("IBM eServer HEA Driver"); 567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd ThemannMODULE_VERSION(DRV_VERSION); 577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int msg_level = -1; 607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int rq1_entries = EHEA_DEF_ENTRIES_RQ1; 617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int rq2_entries = EHEA_DEF_ENTRIES_RQ2; 627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int rq3_entries = EHEA_DEF_ENTRIES_RQ3; 637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int sq_entries = EHEA_DEF_ENTRIES_SQ; 64b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchardstatic int use_mcs = 1; 65508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxeystatic int prop_carrier_state; 667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannmodule_param(msg_level, int, 0); 687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannmodule_param(rq1_entries, int, 0); 697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannmodule_param(rq2_entries, int, 0); 707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannmodule_param(rq3_entries, int, 0); 717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannmodule_param(sq_entries, int, 0); 728759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd Themannmodule_param(prop_carrier_state, int, 0); 7318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themannmodule_param(use_mcs, int, 0); 747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd ThemannMODULE_PARM_DESC(msg_level, "msg_level"); 768759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd ThemannMODULE_PARM_DESC(prop_carrier_state, "Propagate carrier state of physical " 778759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd Themann "port to stack. 1:yes, 0:no. Default = 0 "); 787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd ThemannMODULE_PARM_DESC(rq3_entries, "Number of entries for Receive Queue 3 " 797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann "[2^x - 1], x = [6..14]. Default = " 807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann __MODULE_STRING(EHEA_DEF_ENTRIES_RQ3) ")"); 817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd ThemannMODULE_PARM_DESC(rq2_entries, "Number of entries for Receive Queue 2 " 827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann "[2^x - 1], x = [6..14]. Default = " 837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann __MODULE_STRING(EHEA_DEF_ENTRIES_RQ2) ")"); 847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd ThemannMODULE_PARM_DESC(rq1_entries, "Number of entries for Receive Queue 1 " 857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann "[2^x - 1], x = [6..14]. Default = " 867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann __MODULE_STRING(EHEA_DEF_ENTRIES_RQ1) ")"); 877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd ThemannMODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue " 887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann "[2^x - 1], x = [6..14]. Default = " 897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann __MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")"); 90b95644685d530de5e9f9658bd8087e50840b831dAnton BlanchardMODULE_PARM_DESC(use_mcs, " Multiple receive queues, 1: enable, 0: disable, " 91b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard "Default = 1"); 927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 93508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxeystatic int port_name_cnt; 9444c821525778c5d2e81da293195d5d589e8ad845Thomas Kleinstatic LIST_HEAD(adapter_list); 9548e4cc777c091b037acaf39036a77ece43fe1ab9Stephen Rothwellstatic unsigned long ehea_driver_flags; 9606f89edf89f254346c95d0c569cecd606459d83eDaniel Walkerstatic DEFINE_MUTEX(dlpar_mem_lock); 971886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic struct ehea_fw_handle_array ehea_fw_handles; 981886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic struct ehea_bcmc_reg_array ehea_bcmc_regs; 9921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 100d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein 1012dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devinit ehea_probe_adapter(struct platform_device *dev, 102d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann const struct of_device_id *id); 103d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein 1042dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devexit ehea_remove(struct platform_device *dev); 105d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein 106d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Kleinstatic struct of_device_id ehea_device_table[] = { 107d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein { 108d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein .name = "lhea", 109d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein .compatible = "IBM,lhea", 110d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein }, 111d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein {}, 112d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein}; 113b0afffe89be619f42ae4215554ed66e67de7bb0eJan-Bernd ThemannMODULE_DEVICE_TABLE(of, ehea_device_table); 114d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein 1156b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkesstatic struct of_platform_driver ehea_driver = { 1164018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .driver = { 1174018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .name = "ehea", 1184018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .owner = THIS_MODULE, 1194018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .of_match_table = ehea_device_table, 1204018294b53d1dae026880e45f174c1cc63b5d435Grant Likely }, 121d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein .probe = ehea_probe_adapter, 122d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein .remove = ehea_remove, 123d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein}; 124d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein 125508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxeyvoid ehea_dump(void *adr, int len, char *msg) 126508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey{ 1277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int x; 1287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann unsigned char *deb = adr; 1297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann for (x = 0; x < len; x += 16) { 1308c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("%s adr=%p ofs=%04x %016llx %016llx\n", 1318c4877a4128e7931077b024a891a4b284d8756a3Joe Perches msg, deb, x, *((u64 *)&deb[0]), *((u64 *)&deb[8])); 1327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann deb += 16; 1337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 1347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 1357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1361886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic void ehea_schedule_port_reset(struct ehea_port *port) 1372f69ae01c83a94af5dc3c20e8135b974687ed004Jan-Bernd Themann{ 1382f69ae01c83a94af5dc3c20e8135b974687ed004Jan-Bernd Themann if (!test_bit(__EHEA_DISABLE_PORT_RESET, &port->flags)) 1392f69ae01c83a94af5dc3c20e8135b974687ed004Jan-Bernd Themann schedule_work(&port->reset_task); 1402f69ae01c83a94af5dc3c20e8135b974687ed004Jan-Bernd Themann} 1412f69ae01c83a94af5dc3c20e8135b974687ed004Jan-Bernd Themann 14221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Kleinstatic void ehea_update_firmware_handles(void) 14321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein{ 14421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_fw_handle_entry *arr = NULL; 14521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_adapter *adapter; 14621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int num_adapters = 0; 14721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int num_ports = 0; 14821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int num_portres = 0; 14921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int i = 0; 15021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int num_fw_handles, k, l; 15121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 15221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein /* Determine number of handles */ 15352e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann mutex_lock(&ehea_fw_handles.lock); 15452e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann 15521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein list_for_each_entry(adapter, &adapter_list, list) { 15621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein num_adapters++; 15721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 15821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein for (k = 0; k < EHEA_MAX_PORTS; k++) { 15921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_port *port = adapter->port[k]; 16021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 16121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (!port || (port->state != EHEA_PORT_UP)) 16221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein continue; 16321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 16421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein num_ports++; 165723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard num_portres += port->num_def_qps; 16621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 16721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 16821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 16921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein num_fw_handles = num_adapters * EHEA_NUM_ADAPTER_FW_HANDLES + 17021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein num_ports * EHEA_NUM_PORT_FW_HANDLES + 17121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein num_portres * EHEA_NUM_PORTRES_FW_HANDLES; 17221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 17321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (num_fw_handles) { 174baeb2ffab4e67bb9174e6166e070a9a8ec94b0f6Joe Perches arr = kcalloc(num_fw_handles, sizeof(*arr), GFP_KERNEL); 17521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (!arr) 17652e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann goto out; /* Keep the existing array */ 17721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } else 17821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein goto out_update; 17921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 18021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein list_for_each_entry(adapter, &adapter_list, list) { 18152e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann if (num_adapters == 0) 18252e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann break; 18352e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann 18421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein for (k = 0; k < EHEA_MAX_PORTS; k++) { 18521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_port *port = adapter->port[k]; 18621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 1878e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if (!port || (port->state != EHEA_PORT_UP) || 1888e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (num_ports == 0)) 18921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein continue; 19021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 191723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (l = 0; l < port->num_def_qps; l++) { 19221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_port_res *pr = &port->port_res[l]; 19321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 19421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 19521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].fwh = pr->qp->fw_handle; 19621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 19721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].fwh = pr->send_cq->fw_handle; 19821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 19921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].fwh = pr->recv_cq->fw_handle; 20021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 20121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].fwh = pr->eq->fw_handle; 20221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 20321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].fwh = pr->send_mr.handle; 20421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 20521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].fwh = pr->recv_mr.handle; 20621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 20721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 20821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].fwh = port->qp_eq->fw_handle; 20952e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann num_ports--; 21021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 21121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 21221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 21321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].fwh = adapter->neq->fw_handle; 21421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 21521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (adapter->mr.handle) { 21621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 21721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].fwh = adapter->mr.handle; 21821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 21952e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann num_adapters--; 22021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 22121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 22221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Kleinout_update: 22321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein kfree(ehea_fw_handles.arr); 22421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_fw_handles.arr = arr; 22521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_fw_handles.num_entries = i; 22652e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themannout: 22752e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann mutex_unlock(&ehea_fw_handles.lock); 22821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein} 22921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 23021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Kleinstatic void ehea_update_bcmc_registrations(void) 23121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein{ 23252e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann unsigned long flags; 23321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_bcmc_reg_entry *arr = NULL; 23421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_adapter *adapter; 23521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_mc_list *mc_entry; 23621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int num_registrations = 0; 23721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int i = 0; 23821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int k; 23921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 24052e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann spin_lock_irqsave(&ehea_bcmc_regs.lock, flags); 24152e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann 24221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein /* Determine number of registrations */ 24321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein list_for_each_entry(adapter, &adapter_list, list) 24421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein for (k = 0; k < EHEA_MAX_PORTS; k++) { 24521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_port *port = adapter->port[k]; 24621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 24721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (!port || (port->state != EHEA_PORT_UP)) 24821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein continue; 24921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 25021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein num_registrations += 2; /* Broadcast registrations */ 25121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 25221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein list_for_each_entry(mc_entry, &port->mc_list->list,list) 25321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein num_registrations += 2; 25421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 25521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 25621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (num_registrations) { 257baeb2ffab4e67bb9174e6166e070a9a8ec94b0f6Joe Perches arr = kcalloc(num_registrations, sizeof(*arr), GFP_ATOMIC); 25821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (!arr) 25952e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann goto out; /* Keep the existing array */ 26021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } else 26121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein goto out_update; 26221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 26321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein list_for_each_entry(adapter, &adapter_list, list) { 26421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein for (k = 0; k < EHEA_MAX_PORTS; k++) { 26521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein struct ehea_port *port = adapter->port[k]; 26621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 26721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (!port || (port->state != EHEA_PORT_UP)) 26821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein continue; 26921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 27052e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann if (num_registrations == 0) 27152e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann goto out_update; 27252e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann 27321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 27421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].port_id = port->logical_port_id; 27521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].reg_type = EHEA_BCMC_BROADCAST | 27621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein EHEA_BCMC_UNTAGGED; 27721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].macaddr = port->mac_addr; 27821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 27921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 28021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].port_id = port->logical_port_id; 28121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].reg_type = EHEA_BCMC_BROADCAST | 28221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein EHEA_BCMC_VLANID_ALL; 28321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].macaddr = port->mac_addr; 28452e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann num_registrations -= 2; 28521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 28621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein list_for_each_entry(mc_entry, 28721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein &port->mc_list->list, list) { 28852e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann if (num_registrations == 0) 28952e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann goto out_update; 29052e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann 29121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 29221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].port_id = port->logical_port_id; 29321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | 29421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein EHEA_BCMC_MULTICAST | 29521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein EHEA_BCMC_UNTAGGED; 29621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].macaddr = mc_entry->macaddr; 29721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 29821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].adh = adapter->handle; 29921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].port_id = port->logical_port_id; 30021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | 30121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein EHEA_BCMC_MULTICAST | 30221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein EHEA_BCMC_VLANID_ALL; 30321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein arr[i++].macaddr = mc_entry->macaddr; 30452e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann num_registrations -= 2; 30521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 30621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 30721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 30821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 30921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Kleinout_update: 31021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein kfree(ehea_bcmc_regs.arr); 31121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_bcmc_regs.arr = arr; 31221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_bcmc_regs.num_entries = i; 31352e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themannout: 31452e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann spin_unlock_irqrestore(&ehea_bcmc_regs.lock, flags); 31521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein} 31621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 317239c562c94dcdd2aeb3d0c0e604627dec043183eAnton Blanchardstatic struct rtnl_link_stats64 *ehea_get_stats64(struct net_device *dev, 318239c562c94dcdd2aeb3d0c0e604627dec043183eAnton Blanchard struct rtnl_link_stats64 *stats) 3197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 3207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 3212aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com u64 rx_packets = 0, tx_packets = 0, rx_bytes = 0, tx_bytes = 0; 3227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int i; 3237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3242aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com for (i = 0; i < port->num_def_qps; i++) { 3252aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com rx_packets += port->port_res[i].rx_packets; 3262aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com rx_bytes += port->port_res[i].rx_bytes; 3272aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com } 3282aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com 329723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) { 3302aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com tx_packets += port->port_res[i].tx_packets; 3312aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com tx_bytes += port->port_res[i].tx_bytes; 3322aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com } 3332aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com 3342aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com stats->tx_packets = tx_packets; 3352aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com stats->rx_bytes = rx_bytes; 3362aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com stats->tx_bytes = tx_bytes; 3372aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com stats->rx_packets = rx_packets; 3382aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com 3392aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com return &port->stats; 3402aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com} 3412aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com 3422aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.comstatic void ehea_update_stats(struct work_struct *work) 3432aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com{ 3442aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com struct ehea_port *port = 3452aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com container_of(work, struct ehea_port, stats_work.work); 3462aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com struct net_device *dev = port->netdev; 347239c562c94dcdd2aeb3d0c0e604627dec043183eAnton Blanchard struct rtnl_link_stats64 *stats = &port->stats; 3482aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com struct hcp_ehea_port_cb2 *cb2; 3492aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com u64 hret; 3507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3513d8009c780ee90fccb5c171caf30aff839f13547Brian King cb2 = (void *)get_zeroed_page(GFP_KERNEL); 3527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb2) { 3532aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com netdev_err(dev, "No mem for cb2. Some interface statistics were not updated\n"); 3542aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com goto resched; 3557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 3567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea_port(port->adapter->handle, 3587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, 3597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_PORT_CB2, H_PORT_CB2_ALL, cb2); 3607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 3618c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "query_ehea_port failed\n"); 3627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_herr; 3637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 3647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (netif_msg_hw(port)) 3667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_dump(cb2, sizeof(*cb2), "net_device_stats"); 3677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann stats->multicast = cb2->rxmcp; 3697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann stats->rx_errors = cb2->rxuerr; 3707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_herr: 3723faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb2); 3732aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.comresched: 37467c170a24fc6669f8f7c0864d75caadef0a8e5e6Anton Blanchard schedule_delayed_work(&port->stats_work, 37567c170a24fc6669f8f7c0864d75caadef0a8e5e6Anton Blanchard round_jiffies_relative(msecs_to_jiffies(1000))); 3767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 3777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes) 3797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 3807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff **skb_arr_rq1 = pr->rq1_skba.arr; 3817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct net_device *dev = pr->port->netdev; 3827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int max_index_mask = pr->rq1_skba.len - 1; 3832c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int fill_wqes = pr->rq1_skba.os_skbs + nr_of_wqes; 3842c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int adder = 0; 3857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int i; 3867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3872c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann pr->rq1_skba.os_skbs = 0; 3882c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 3892c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) { 39044fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein if (nr_of_wqes > 0) 39144fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein pr->rq1_skba.index = index; 3922c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann pr->rq1_skba.os_skbs = fill_wqes; 3937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return; 3942c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 3957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3962c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann for (i = 0; i < fill_wqes; i++) { 3977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!skb_arr_rq1[index]) { 3987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_arr_rq1[index] = netdev_alloc_skb(dev, 3997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_L_PKT_SIZE); 4007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!skb_arr_rq1[index]) { 4018c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(dev, "Unable to allocate enough skb in the array\n"); 4022c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann pr->rq1_skba.os_skbs = fill_wqes - i; 4037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 4047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 4057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 4067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann index--; 4077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann index &= max_index_mask; 4082c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann adder++; 4097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 4102c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 4112c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (adder == 0) 4122c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann return; 4132c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 4147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Ring doorbell */ 4152c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ehea_update_rq1a(pr->qp, adder); 4167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 4177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 418e2878806227d223467f84f900ef4c6733ee166dfThomas Kleinstatic void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a) 4197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 4207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff **skb_arr_rq1 = pr->rq1_skba.arr; 4217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct net_device *dev = pr->port->netdev; 4227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int i; 4237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 4245c7e57f7cddb83d81d83fefa5822dfe80891130eBreno Leitao if (nr_rq1a > pr->rq1_skba.len) { 4258c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "NR_RQ1A bigger than skb array len\n"); 4265c7e57f7cddb83d81d83fefa5822dfe80891130eBreno Leitao return; 4275c7e57f7cddb83d81d83fefa5822dfe80891130eBreno Leitao } 4285c7e57f7cddb83d81d83fefa5822dfe80891130eBreno Leitao 4295c7e57f7cddb83d81d83fefa5822dfe80891130eBreno Leitao for (i = 0; i < nr_rq1a; i++) { 4307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE); 4315c7e57f7cddb83d81d83fefa5822dfe80891130eBreno Leitao if (!skb_arr_rq1[i]) { 4328c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(dev, "Not enough memory to allocate skb array\n"); 433e2878806227d223467f84f900ef4c6733ee166dfThomas Klein break; 4345c7e57f7cddb83d81d83fefa5822dfe80891130eBreno Leitao } 4357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 4367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Ring doorbell */ 437f76957fc8fc4fa9735f01e59653b2792b077de06Breno Leitao ehea_update_rq1a(pr->qp, i - 1); 4387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 4397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 4407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_refill_rq_def(struct ehea_port_res *pr, 4417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_q_skb_arr *q_skba, int rq_nr, 4427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int num_wqes, int wqe_type, int packet_size) 4437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 4447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct net_device *dev = pr->port->netdev; 4457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_qp *qp = pr->qp; 4467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff **skb_arr = q_skba->arr; 4477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_rwqe *rwqe; 4487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int i, index, max_index_mask, fill_wqes; 4492c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int adder = 0; 4507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret = 0; 4517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 4527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann fill_wqes = q_skba->os_skbs + num_wqes; 4532c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann q_skba->os_skbs = 0; 4547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 4552c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) { 4562c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann q_skba->os_skbs = fill_wqes; 4577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 4582c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 4597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 4607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann index = q_skba->index; 4617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann max_index_mask = q_skba->len - 1; 4627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann for (i = 0; i < fill_wqes; i++) { 4632c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann u64 tmp_addr; 46489d71a66c40d629e3b1285def543ab1425558cd5Eric Dumazet struct sk_buff *skb; 46589d71a66c40d629e3b1285def543ab1425558cd5Eric Dumazet 46689d71a66c40d629e3b1285def543ab1425558cd5Eric Dumazet skb = netdev_alloc_skb_ip_align(dev, packet_size); 4677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!skb) { 4687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann q_skba->os_skbs = fill_wqes - i; 469e2878806227d223467f84f900ef4c6733ee166dfThomas Klein if (q_skba->os_skbs == q_skba->len - 2) { 4708c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(pr->port->netdev, 4718c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "rq%i ran dry - no mem for skb\n", 4728c4877a4128e7931077b024a891a4b284d8756a3Joe Perches rq_nr); 473e2878806227d223467f84f900ef4c6733ee166dfThomas Klein ret = -ENOMEM; 474e2878806227d223467f84f900ef4c6733ee166dfThomas Klein } 4757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 4767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 4777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 4787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_arr[index] = skb; 4792c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann tmp_addr = ehea_map_vaddr(skb->data); 4802c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (tmp_addr == -1) { 4812c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann dev_kfree_skb(skb); 4822c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann q_skba->os_skbs = fill_wqes - i; 4832c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ret = 0; 4842c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann break; 4852c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 4867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 4877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann rwqe = ehea_get_next_rwqe(qp, rq_nr); 4887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type) 489d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index); 4907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann rwqe->sg_list[0].l_key = pr->recv_mr.lkey; 4912c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann rwqe->sg_list[0].vaddr = tmp_addr; 4927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann rwqe->sg_list[0].len = packet_size; 4937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann rwqe->data_segments = 1; 4947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 4957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann index++; 4967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann index &= max_index_mask; 4972c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann adder++; 4987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 49944c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 5007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann q_skba->index = index; 5012c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (adder == 0) 5022c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 5037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Ring doorbell */ 5057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann iosync(); 5067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (rq_nr == 2) 5072c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ehea_update_rq2a(pr->qp, adder); 5087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann else 5092c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ehea_update_rq3a(pr->qp, adder); 51044c821525778c5d2e81da293195d5d589e8ad845Thomas Kleinout: 5117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 5127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 5137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_refill_rq2(struct ehea_port_res *pr, int nr_of_wqes) 5167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 5177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ehea_refill_rq_def(pr, &pr->rq2_skba, 2, 5187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann nr_of_wqes, EHEA_RWQE2_TYPE, 51989d71a66c40d629e3b1285def543ab1425558cd5Eric Dumazet EHEA_RQ2_PKT_SIZE); 5207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 5217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_refill_rq3(struct ehea_port_res *pr, int nr_of_wqes) 5247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 5257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ehea_refill_rq_def(pr, &pr->rq3_skba, 3, 5267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann nr_of_wqes, EHEA_RWQE3_TYPE, 52789d71a66c40d629e3b1285def543ab1425558cd5Eric Dumazet EHEA_MAX_PACKET_SIZE); 5287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 5297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic inline int ehea_check_cqe(struct ehea_cqe *cqe, int *rq_num) 5317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 5327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann *rq_num = (cqe->type & EHEA_CQE_TYPE_RQ) >> 5; 5337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if ((cqe->status & EHEA_CQE_STAT_ERR_MASK) == 0) 5347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 5357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (((cqe->status & EHEA_CQE_STAT_ERR_TCP) != 0) && 5367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann (cqe->header_length == 0)) 5377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 5387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return -EINVAL; 5397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 5407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic inline void ehea_fill_skb(struct net_device *dev, 542b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard struct sk_buff *skb, struct ehea_cqe *cqe, 543b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard struct ehea_port_res *pr) 5447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 5457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int length = cqe->num_bytes_transfered - 4; /*remove CRC */ 5467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_put(skb, length); 5487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb->protocol = eth_type_trans(skb, dev); 54971085ce8285dc5f3011694f6ba7259201135c6d6Breno Leitao 55071085ce8285dc5f3011694f6ba7259201135c6d6Breno Leitao /* The packet was not an IPV4 packet so a complemented checksum was 55171085ce8285dc5f3011694f6ba7259201135c6d6Breno Leitao calculated. The value is found in the Internet Checksum field. */ 55271085ce8285dc5f3011694f6ba7259201135c6d6Breno Leitao if (cqe->status & EHEA_CQE_BLIND_CKSUM) { 55371085ce8285dc5f3011694f6ba7259201135c6d6Breno Leitao skb->ip_summed = CHECKSUM_COMPLETE; 55471085ce8285dc5f3011694f6ba7259201135c6d6Breno Leitao skb->csum = csum_unfold(~cqe->inet_checksum_value); 55571085ce8285dc5f3011694f6ba7259201135c6d6Breno Leitao } else 55671085ce8285dc5f3011694f6ba7259201135c6d6Breno Leitao skb->ip_summed = CHECKSUM_UNNECESSARY; 557b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard 558b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard skb_record_rx_queue(skb, pr - &pr->port->port_res[0]); 5597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 5607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic inline struct sk_buff *get_skb_by_index(struct sk_buff **skb_array, 5627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int arr_len, 5637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_cqe *cqe) 5647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 5657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int skb_index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, cqe->wr_id); 5667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff *skb; 5677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann void *pref; 5687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int x; 5697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann x = skb_index + 1; 5717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann x &= (arr_len - 1); 5727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pref = skb_array[x]; 5740b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering if (pref) { 5750b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetchw(pref); 5760b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetchw(pref + EHEA_CACHE_LINE); 5770b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering 5780b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering pref = (skb_array[x]->data); 5790b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetch(pref); 5800b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetch(pref + EHEA_CACHE_LINE); 5810b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetch(pref + EHEA_CACHE_LINE * 2); 5820b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetch(pref + EHEA_CACHE_LINE * 3); 5830b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering } 5840b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering 5857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb = skb_array[skb_index]; 5867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_array[skb_index] = NULL; 5877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return skb; 5887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 5897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic inline struct sk_buff *get_skb_by_index_ll(struct sk_buff **skb_array, 5917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int arr_len, int wqe_index) 5927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 5937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff *skb; 5947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann void *pref; 5957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int x; 5967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 5977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann x = wqe_index + 1; 5987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann x &= (arr_len - 1); 5997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 6007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pref = skb_array[x]; 6010b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering if (pref) { 6020b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetchw(pref); 6030b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetchw(pref + EHEA_CACHE_LINE); 6047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 6050b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering pref = (skb_array[x]->data); 6060b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetchw(pref); 6070b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering prefetchw(pref + EHEA_CACHE_LINE); 6080b2febf38a33d7c40fb7bb4a58c113a1fa33c412Hannes Hering } 6097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 6107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb = skb_array[wqe_index]; 6117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_array[wqe_index] = NULL; 6127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return skb; 6137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 6147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 6157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_treat_poll_error(struct ehea_port_res *pr, int rq, 6167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_cqe *cqe, int *processed_rq2, 6177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int *processed_rq3) 6187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 6197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff *skb; 6207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 621acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann if (cqe->status & EHEA_CQE_STAT_ERR_TCP) 622acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann pr->p_stats.err_tcp_cksum++; 623acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann if (cqe->status & EHEA_CQE_STAT_ERR_IP) 624acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann pr->p_stats.err_ip_cksum++; 625acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann if (cqe->status & EHEA_CQE_STAT_ERR_CRC) 626acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann pr->p_stats.err_frame_crc++; 627acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann 6287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (rq == 2) { 6297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann *processed_rq2 += 1; 6307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb = get_skb_by_index(pr->rq2_skba.arr, pr->rq2_skba.len, cqe); 6317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev_kfree_skb(skb); 6327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else if (rq == 3) { 6337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann *processed_rq3 += 1; 6347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb = get_skb_by_index(pr->rq3_skba.arr, pr->rq3_skba.len, cqe); 6357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev_kfree_skb(skb); 6367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 6377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 6387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (cqe->status & EHEA_CQE_STAT_FAT_ERR_MASK) { 63958dd8258fccbb68e0d0e1898038442822cb833c0Thomas Klein if (netif_msg_rx_err(pr->port)) { 6408c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("Critical receive error for QP %d. Resetting port.\n", 6418c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr->qp->init_attr.qp_nr); 64258dd8258fccbb68e0d0e1898038442822cb833c0Thomas Klein ehea_dump(cqe, sizeof(*cqe), "CQE"); 64358dd8258fccbb68e0d0e1898038442822cb833c0Thomas Klein } 6442f69ae01c83a94af5dc3c20e8135b974687ed004Jan-Bernd Themann ehea_schedule_port_reset(pr->port); 6457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 1; 6467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 6477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 6487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 6497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 6507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 651bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemmingerstatic int ehea_proc_rwqes(struct net_device *dev, 652bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger struct ehea_port_res *pr, 653bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger int budget) 6547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 65518604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann struct ehea_port *port = pr->port; 6567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_qp *qp = pr->qp; 6577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_cqe *cqe; 6587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff *skb; 6597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff **skb_arr_rq1 = pr->rq1_skba.arr; 6607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff **skb_arr_rq2 = pr->rq2_skba.arr; 6617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sk_buff **skb_arr_rq3 = pr->rq3_skba.arr; 6627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int skb_arr_rq1_len = pr->rq1_skba.len; 6637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int skb_arr_rq2_len = pr->rq2_skba.len; 6647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int skb_arr_rq3_len = pr->rq3_skba.len; 6657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int processed, processed_rq1, processed_rq2, processed_rq3; 666ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao u64 processed_bytes = 0; 667bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger int wqe_index, last_wqe_index, rq, port_reset; 6687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 6697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann processed = processed_rq1 = processed_rq2 = processed_rq3 = 0; 6707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann last_wqe_index = 0; 6717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 6727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cqe = ehea_poll_rq1(qp, &wqe_index); 673bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger while ((processed < budget) && cqe) { 6747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_inc_rq1(qp); 6757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann processed_rq1++; 6767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann processed++; 6777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (netif_msg_rx_status(port)) 6787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_dump(cqe, sizeof(*cqe), "CQE"); 6797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 6807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann last_wqe_index = wqe_index; 6817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann rmb(); 6827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!ehea_check_cqe(cqe, &rq)) { 683508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey if (rq == 1) { 684508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey /* LL RQ1 */ 6857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb = get_skb_by_index_ll(skb_arr_rq1, 6867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_arr_rq1_len, 6877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann wqe_index); 6887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (unlikely(!skb)) { 689782615aea84e57dc7f2f922cea823df3de635a78Breno Leitao netif_info(port, rx_err, dev, 6908c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "LL rq1: skb=NULL\n"); 69118604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 692bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger skb = netdev_alloc_skb(dev, 6937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_L_PKT_SIZE); 6945c7e57f7cddb83d81d83fefa5822dfe80891130eBreno Leitao if (!skb) { 695782615aea84e57dc7f2f922cea823df3de635a78Breno Leitao netdev_err(dev, "Not enough memory to allocate skb\n"); 6967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 6975c7e57f7cddb83d81d83fefa5822dfe80891130eBreno Leitao } 6987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 699508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey skb_copy_to_linear_data(skb, ((char *)cqe) + 64, 700d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann cqe->num_bytes_transfered - 4); 701b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard ehea_fill_skb(dev, skb, cqe, pr); 702508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey } else if (rq == 2) { 703508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey /* RQ2 */ 7047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb = get_skb_by_index(skb_arr_rq2, 7057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_arr_rq2_len, cqe); 7067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (unlikely(!skb)) { 7078c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_err(port, rx_err, dev, 7088c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "rq2: skb=NULL\n"); 7097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 7107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 711b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard ehea_fill_skb(dev, skb, cqe, pr); 7127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann processed_rq2++; 713508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey } else { 714508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey /* RQ3 */ 7157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb = get_skb_by_index(skb_arr_rq3, 7167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_arr_rq3_len, cqe); 7177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (unlikely(!skb)) { 7188c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_err(port, rx_err, dev, 7198c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "rq3: skb=NULL\n"); 7207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 7217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 722b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard ehea_fill_skb(dev, skb, cqe, pr); 7237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann processed_rq3++; 7247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 7257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 726ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao processed_bytes += skb->len; 7273428414f71e12f8111dfa16e4d958e6ed055268aAnton Blanchard 7283428414f71e12f8111dfa16e4d958e6ed055268aAnton Blanchard if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) 7293428414f71e12f8111dfa16e4d958e6ed055268aAnton Blanchard __vlan_hwaccel_put_tag(skb, cqe->vlan_tag); 7303428414f71e12f8111dfa16e4d958e6ed055268aAnton Blanchard 7313428414f71e12f8111dfa16e4d958e6ed055268aAnton Blanchard napi_gro_receive(&pr->napi, skb); 73218604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann } else { 733acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann pr->p_stats.poll_receive_errors++; 7347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port_reset = ehea_treat_poll_error(pr, rq, cqe, 7357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann &processed_rq2, 7367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann &processed_rq3); 7377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (port_reset) 7387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 7397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 7407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cqe = ehea_poll_rq1(qp, &wqe_index); 7417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 7427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 7437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->rx_packets += processed; 744ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao pr->rx_bytes += processed_bytes; 7457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 7467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_refill_rq1(pr, last_wqe_index, processed_rq1); 7477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_refill_rq2(pr, processed_rq2); 7487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_refill_rq3(pr, processed_rq3); 7497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 750bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger return processed; 7517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 7527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 7532928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch#define SWQE_RESTART_CHECK 0xdeadbeaff00d0000ull 7542928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 7552928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detschstatic void reset_sq_restart_flag(struct ehea_port *port) 7562928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch{ 7572928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch int i; 7582928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 759723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) { 7602928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch struct ehea_port_res *pr = &port->port_res[i]; 7612928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch pr->sq_restart_flag = 0; 7622928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch } 763a8bb69f78194dc483f6c4a4bf8860c1ede35fa25Breno Leitao wake_up(&port->restart_wq); 7642928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch} 7652928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 7662928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detschstatic void check_sqs(struct ehea_port *port) 7672928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch{ 7682928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch struct ehea_swqe *swqe; 7692928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch int swqe_index; 7702928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch int i, k; 7712928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 772723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) { 7732928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch struct ehea_port_res *pr = &port->port_res[i]; 774a8bb69f78194dc483f6c4a4bf8860c1ede35fa25Breno Leitao int ret; 7752928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch k = 0; 7762928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch swqe = ehea_get_swqe(pr->qp, &swqe_index); 7772928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch memset(swqe, 0, SWQE_HEADER_SIZE); 7782928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch atomic_dec(&pr->swqe_avail); 7792928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 7802928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch swqe->tx_control |= EHEA_SWQE_PURGE; 7812928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch swqe->wr_id = SWQE_RESTART_CHECK; 7822928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION; 7832928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch swqe->tx_control |= EHEA_SWQE_IMM_DATA_PRESENT; 7842928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch swqe->immediate_data_length = 80; 7852928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 7862928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch ehea_post_swqe(pr->qp, swqe); 7872928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 788a8bb69f78194dc483f6c4a4bf8860c1ede35fa25Breno Leitao ret = wait_event_timeout(port->restart_wq, 789a8bb69f78194dc483f6c4a4bf8860c1ede35fa25Breno Leitao pr->sq_restart_flag == 0, 790a8bb69f78194dc483f6c4a4bf8860c1ede35fa25Breno Leitao msecs_to_jiffies(100)); 791a8bb69f78194dc483f6c4a4bf8860c1ede35fa25Breno Leitao 792a8bb69f78194dc483f6c4a4bf8860c1ede35fa25Breno Leitao if (!ret) { 7938c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("HW/SW queues out of sync\n"); 794a8bb69f78194dc483f6c4a4bf8860c1ede35fa25Breno Leitao ehea_schedule_port_reset(pr->port); 795a8bb69f78194dc483f6c4a4bf8860c1ede35fa25Breno Leitao return; 7962928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch } 7972928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch } 7982928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch} 7992928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 8002928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 80118604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themannstatic struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) 8027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 803acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann struct sk_buff *skb; 8047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_cq *send_cq = pr->send_cq; 8057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_cqe *cqe; 80618604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann int quota = my_quota; 8077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int cqe_counter = 0; 8087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int swqe_av = 0; 809acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann int index; 810b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard struct netdev_queue *txq = netdev_get_tx_queue(pr->port->netdev, 811b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard pr - &pr->port->port_res[0]); 8127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 81318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann cqe = ehea_poll_cq(send_cq); 814508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey while (cqe && (quota > 0)) { 81518604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann ehea_inc_cq(send_cq); 81618604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 8177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cqe_counter++; 8187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann rmb(); 8192928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 8202928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch if (cqe->wr_id == SWQE_RESTART_CHECK) { 8212928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch pr->sq_restart_flag = 1; 8222928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch swqe_av++; 8232928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch break; 8242928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch } 8252928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch 8267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { 8278c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("Bad send completion status=0x%04X\n", 8288c4877a4128e7931077b024a891a4b284d8756a3Joe Perches cqe->status); 829ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein 8307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (netif_msg_tx_err(pr->port)) 8317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_dump(cqe, sizeof(*cqe), "Send CQE"); 832ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein 833ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein if (cqe->status & EHEA_CQE_STAT_RESET_MASK) { 8348c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("Resetting port\n"); 835ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein ehea_schedule_port_reset(pr->port); 836ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein break; 837ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein } 8387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 8397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 8407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (netif_msg_tx_done(pr->port)) 8417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_dump(cqe, sizeof(*cqe), "CQE"); 8427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 8437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (likely(EHEA_BMASK_GET(EHEA_WR_ID_TYPE, cqe->wr_id) 844acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann == EHEA_SWQE2_TYPE)) { 845acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann 846acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, cqe->wr_id); 847acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann skb = pr->sq_skba.arr[index]; 848acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann dev_kfree_skb(skb); 849acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann pr->sq_skba.arr[index] = NULL; 850acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann } 8517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 8527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe_av += EHEA_BMASK_GET(EHEA_WR_ID_REFILL, cqe->wr_id); 8537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann quota--; 85418604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 85518604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann cqe = ehea_poll_cq(send_cq); 856ee289b6440c3b0ccb9459495783e8c299bec6604Joe Perches } 8577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 8587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_update_feca(send_cq, cqe_counter); 8597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann atomic_add(swqe_av, &pr->swqe_avail); 8607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 861b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard if (unlikely(netif_tx_queue_stopped(txq) && 862b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard (atomic_read(&pr->swqe_avail) >= pr->swqe_refill_th))) { 863b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard __netif_tx_lock(txq, smp_processor_id()); 864b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard if (netif_tx_queue_stopped(txq) && 865b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard (atomic_read(&pr->swqe_avail) >= pr->swqe_refill_th)) 866b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_wake_queue(txq); 867b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard __netif_tx_unlock(txq); 8687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 869b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard 8705b27d42755fa6536a89f32b107fb2a53267696c2Breno Leitao wake_up(&pr->port->swqe_avail_wq); 8717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 87218604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann return cqe; 8737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 8747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 875bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger#define EHEA_POLL_MAX_CQES 65535 87618604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 877bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemmingerstatic int ehea_poll(struct napi_struct *napi, int budget) 8787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 879508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey struct ehea_port_res *pr = container_of(napi, struct ehea_port_res, 880508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey napi); 881bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger struct net_device *dev = pr->port->netdev; 88218604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann struct ehea_cqe *cqe; 88318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann struct ehea_cqe *cqe_skb = NULL; 884222ca96b69ae8afb2ad13b99070b09309e7d9657Anton Blanchard int wqe_index; 885bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger int rx = 0; 88618604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 887bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger cqe_skb = ehea_proc_cqes(pr, EHEA_POLL_MAX_CQES); 888222ca96b69ae8afb2ad13b99070b09309e7d9657Anton Blanchard rx += ehea_proc_rwqes(dev, pr, budget - rx); 889bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger 890222ca96b69ae8afb2ad13b99070b09309e7d9657Anton Blanchard while (rx != budget) { 891288379f050284087578b77e04f040b57db3db3f8Ben Hutchings napi_complete(napi); 89218604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann ehea_reset_cq_ep(pr->recv_cq); 89318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann ehea_reset_cq_ep(pr->send_cq); 89418604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann ehea_reset_cq_n1(pr->recv_cq); 89518604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann ehea_reset_cq_n1(pr->send_cq); 896a91fb143de61dce847e319ca79b9937a665ad622Jan-Bernd Themann rmb(); 89718604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann cqe = ehea_poll_rq1(pr->qp, &wqe_index); 89818604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann cqe_skb = ehea_poll_cq(pr->send_cq); 89918604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 900e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann if (!cqe && !cqe_skb) 901bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger return rx; 90218604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 903288379f050284087578b77e04f040b57db3db3f8Ben Hutchings if (!napi_reschedule(napi)) 904bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger return rx; 90518604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 906bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger cqe_skb = ehea_proc_cqes(pr, EHEA_POLL_MAX_CQES); 907bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger rx += ehea_proc_rwqes(dev, pr, budget - rx); 908bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger } 909e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann 910bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger return rx; 9117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 9127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 9138d22c9711aa5e704fc5f89027f5cf64838767c98Jan-Bernd Themann#ifdef CONFIG_NET_POLL_CONTROLLER 9148d22c9711aa5e704fc5f89027f5cf64838767c98Jan-Bernd Themannstatic void ehea_netpoll(struct net_device *dev) 9158d22c9711aa5e704fc5f89027f5cf64838767c98Jan-Bernd Themann{ 9168d22c9711aa5e704fc5f89027f5cf64838767c98Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 917bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger int i; 9188d22c9711aa5e704fc5f89027f5cf64838767c98Jan-Bernd Themann 919bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger for (i = 0; i < port->num_def_qps; i++) 920288379f050284087578b77e04f040b57db3db3f8Ben Hutchings napi_schedule(&port->port_res[i].napi); 9218d22c9711aa5e704fc5f89027f5cf64838767c98Jan-Bernd Themann} 9228d22c9711aa5e704fc5f89027f5cf64838767c98Jan-Bernd Themann#endif 9238d22c9711aa5e704fc5f89027f5cf64838767c98Jan-Bernd Themann 9247d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t ehea_recv_irq_handler(int irq, void *param) 9257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 9267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port_res *pr = param; 92718604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 928288379f050284087578b77e04f040b57db3db3f8Ben Hutchings napi_schedule(&pr->napi); 92918604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 9307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return IRQ_HANDLED; 9317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 9327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 9337d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) 9347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 9357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = param; 9367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_eqe *eqe; 937d2db9eea7901d83e494340c93d131fc1fd463e4cJan-Bernd Themann struct ehea_qp *qp; 9387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u32 qp_token; 939ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein u64 resource_type, aer, aerr; 940ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein int reset_port = 0; 9417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 9427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann eqe = ehea_poll_eq(port->qp_eq); 943bb3a6449c18f6203e59195a98d633f5b5b57c133Thomas Klein 9447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann while (eqe) { 9457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); 9468c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("QP aff_err: entry=0x%llx, token=0x%x\n", 9478c4877a4128e7931077b024a891a4b284d8756a3Joe Perches eqe->entry, qp_token); 948d2db9eea7901d83e494340c93d131fc1fd463e4cJan-Bernd Themann 949d2db9eea7901d83e494340c93d131fc1fd463e4cJan-Bernd Themann qp = port->port_res[qp_token].qp; 950ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein 951ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein resource_type = ehea_error_data(port->adapter, qp->fw_handle, 952ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein &aer, &aerr); 953ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein 954ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein if (resource_type == EHEA_AER_RESTYPE_QP) { 955ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein if ((aer & EHEA_AER_RESET_MASK) || 956ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein (aerr & EHEA_AERR_RESET_MASK)) 957ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein reset_port = 1; 958ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein } else 959ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein reset_port = 1; /* Reset in case of CQ or EQ error */ 960ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein 961bb3a6449c18f6203e59195a98d633f5b5b57c133Thomas Klein eqe = ehea_poll_eq(port->qp_eq); 9627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 9637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 964ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein if (reset_port) { 9658c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("Resetting port\n"); 966ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein ehea_schedule_port_reset(port); 967ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0aThomas Klein } 968d2db9eea7901d83e494340c93d131fc1fd463e4cJan-Bernd Themann 9697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return IRQ_HANDLED; 9707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 9717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 9727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic struct ehea_port *ehea_get_port(struct ehea_adapter *adapter, 9737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int logical_port) 9747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 9757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int i; 9767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 9771acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann for (i = 0; i < EHEA_MAX_PORTS; i++) 97841b69c705152e93b3c6c872678dffd8a19b14d61Thomas Klein if (adapter->port[i]) 979d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann if (adapter->port[i]->logical_port_id == logical_port) 98041b69c705152e93b3c6c872678dffd8a19b14d61Thomas Klein return adapter->port[i]; 9817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return NULL; 9827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 9837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 9847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannint ehea_sense_port_attr(struct ehea_port *port) 9857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 9867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 9877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 9887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct hcp_ehea_port_cb0 *cb0; 9897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 990508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey /* may be called via ehea_neq_tasklet() */ 9913faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb0 = (void *)get_zeroed_page(GFP_ATOMIC); 992508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey if (!cb0) { 9938c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for cb0\n"); 9947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -ENOMEM; 9957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 9967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 9977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 9987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea_port(port->adapter->handle, 9997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, H_PORT_CB0, 10007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(H_PORT_CB0_ALL, 0xFFFF), 10017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cb0); 10027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 10037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 10047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 10057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 10067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* MAC address */ 10087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->mac_addr = cb0->port_mac_addr << 16; 10097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1010508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey if (!is_valid_ether_addr((u8 *)&port->mac_addr)) { 10117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EADDRNOTAVAIL; 10127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 10137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 10147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Port speed */ 10167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann switch (cb0->port_speed) { 10177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_10M_H: 10187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_10M; 10197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 0; 10207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 10217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_10M_F: 10227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_10M; 10237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 1; 10247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 10257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_100M_H: 10267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_100M; 10277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 0; 10287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 10297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_100M_F: 10307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_100M; 10317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 1; 10327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 10337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_1G_F: 10347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_1G; 10357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 1; 10367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 10377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_10G_F: 10387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_10G; 10397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 1; 10407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 10417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann default: 10427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = 0; 10437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 0; 10447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 10457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 10467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1047e919b5938b11e1d48a6dcdcb2860e890a954f10dThomas Klein port->autoneg = 1; 104818604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann port->num_mcs = cb0->num_default_qps; 1049e919b5938b11e1d48a6dcdcb2860e890a954f10dThomas Klein 10507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Number of default QPs */ 105118604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann if (use_mcs) 105218604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann port->num_def_qps = cb0->num_default_qps; 105318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann else 105418604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann port->num_def_qps = 1; 10557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!port->num_def_qps) { 10577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EINVAL; 10587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 10597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 10607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = 0; 10627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_free: 10637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret || netif_msg_probe(port)) 10647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_dump(cb0, sizeof(*cb0), "ehea_sense_port_attr"); 10653faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb0); 10667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 10677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 10687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 10697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannint ehea_set_portspeed(struct ehea_port *port, u32 port_speed) 10717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 10727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct hcp_ehea_port_cb4 *cb4; 10737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 10747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret = 0; 10757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10763faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb4 = (void *)get_zeroed_page(GFP_KERNEL); 10777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb4) { 10788c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for cb4\n"); 10797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -ENOMEM; 10807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 10817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 10827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cb4->port_speed = port_speed; 10847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann netif_carrier_off(port->netdev); 10867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_modify_ehea_port(port->adapter->handle, 10887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, 10897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_PORT_CB4, H_PORT_CB4_SPEED, cb4); 10907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret == H_SUCCESS) { 10917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->autoneg = port_speed == EHEA_SPEED_AUTONEG ? 1 : 0; 10927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 10937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea_port(port->adapter->handle, 10947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, 10957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_PORT_CB4, H_PORT_CB4_SPEED, 10967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cb4); 10977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret == H_SUCCESS) { 10987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann switch (cb4->port_speed) { 10997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_10M_H: 11007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_10M; 11017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 0; 11027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 11037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_10M_F: 11047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_10M; 11057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 1; 11067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 11077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_100M_H: 11087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_100M; 11097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 0; 11107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 11117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_100M_F: 11127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_100M; 11137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 1; 11147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 11157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_1G_F: 11167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_1G; 11177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 1; 11187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 11197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case H_SPEED_10G_F: 11207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = EHEA_SPEED_10G; 11217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 1; 11227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 11237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann default: 11247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->port_speed = 0; 11257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->full_duplex = 0; 11267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 11277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 11287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else { 11298c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("Failed sensing port speed\n"); 11307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 11317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 11327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else { 11337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret == H_AUTHORITY) { 11348c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("Hypervisor denied setting port speed\n"); 11357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EPERM; 11367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else { 11377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 11388c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("Failed setting port speed\n"); 11397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 11407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 11418759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd Themann if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP)) 11428759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd Themann netif_carrier_on(port->netdev); 11438759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd Themann 11443faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb4); 11457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 11467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 11477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 11487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 11497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe) 11507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 11517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 11527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u8 ec; 11537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u8 portnum; 11547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port; 11558c4877a4128e7931077b024a891a4b284d8756a3Joe Perches struct net_device *dev; 11567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 11577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ec = EHEA_BMASK_GET(NEQE_EVENT_CODE, eqe); 11587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann portnum = EHEA_BMASK_GET(NEQE_PORTNUM, eqe); 11597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port = ehea_get_port(adapter, portnum); 11608c4877a4128e7931077b024a891a4b284d8756a3Joe Perches dev = port->netdev; 11617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 11627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann switch (ec) { 11637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case EHEA_EC_PORTSTATE_CHG: /* port state change */ 11647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 11657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!port) { 11668c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "unknown portnum %x\n", portnum); 11677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 11687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 11697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 11707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) { 11718c4877a4128e7931077b024a891a4b284d8756a3Joe Perches if (!netif_carrier_ok(dev)) { 11721e1675ccf758cbb4303ab052d58405cda6c745a7Jan-Bernd Themann ret = ehea_sense_port_attr(port); 11737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 11748c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "failed resensing port attributes\n"); 11757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 11767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 11777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 11788c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, link, dev, 11798c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "Logical port up: %dMbps %s Duplex\n", 11808c4877a4128e7931077b024a891a4b284d8756a3Joe Perches port->port_speed, 11818c4877a4128e7931077b024a891a4b284d8756a3Joe Perches port->full_duplex == 1 ? 11828c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "Full" : "Half"); 11837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 11848c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_carrier_on(dev); 11858c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_wake_queue(dev); 11867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 11877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else 11888c4877a4128e7931077b024a891a4b284d8756a3Joe Perches if (netif_carrier_ok(dev)) { 11898c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, link, dev, 11908c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "Logical port down\n"); 11918c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_carrier_off(dev); 1192b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_disable(dev); 11937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 11947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 11957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PORT_UP, eqe)) { 11968759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd Themann port->phy_link = EHEA_PHY_LINK_UP; 11978c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, link, dev, 11988c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "Physical port up\n"); 11998759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd Themann if (prop_carrier_state) 12008c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_carrier_on(dev); 12017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else { 12028759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd Themann port->phy_link = EHEA_PHY_LINK_DOWN; 12038c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, link, dev, 12048c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "Physical port down\n"); 12058759cf76e9a6322fc68dcbfaa1cbad00c74b199eJan-Bernd Themann if (prop_carrier_state) 12068c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_carrier_off(dev); 12077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 12087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (EHEA_BMASK_GET(NEQE_EXTSWITCH_PRIMARY, eqe)) 12108c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(dev, 12118c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "External switch port is primary port\n"); 12127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann else 12138c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(dev, 12148c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "External switch port is backup port\n"); 12157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 12177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case EHEA_EC_ADAPTER_MALFUNC: 12188c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "Adapter malfunction\n"); 12197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 12207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann case EHEA_EC_PORT_MALFUNC: 12218c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(dev, "Port malfunction\n"); 12228c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_carrier_off(dev); 1223b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_disable(dev); 12247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 12257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann default: 12268c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "unknown event code %x, eqe=0x%llX\n", ec, eqe); 12277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann break; 12287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 12297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 12307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_neq_tasklet(unsigned long data) 12327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 1233508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey struct ehea_adapter *adapter = (struct ehea_adapter *)data; 12347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_eqe *eqe; 12357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 event_mask; 12367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann eqe = ehea_poll_eq(adapter->neq); 12388c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_debug("eqe=%p\n", eqe); 12397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann while (eqe) { 12418c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_debug("*eqe=%lx\n", (unsigned long) eqe->entry); 12427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_parse_eqe(adapter, eqe->entry); 12437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann eqe = ehea_poll_eq(adapter->neq); 12448c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_debug("next eqe=%p\n", eqe); 12457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 12467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann event_mask = EHEA_BMASK_SET(NELR_PORTSTATE_CHG, 1) 12487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(NELR_ADAPTER_MALFUNC, 1) 12497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(NELR_PORT_MALFUNC, 1); 12507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_h_reset_events(adapter->handle, 12527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann adapter->neq->fw_handle, event_mask); 12537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 12547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12557d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t ehea_interrupt_neq(int irq, void *param) 12567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 12577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_adapter *adapter = param; 12587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann tasklet_hi_schedule(&adapter->neq_tasklet); 12597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return IRQ_HANDLED; 12607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 12617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_fill_port_res(struct ehea_port_res *pr) 12647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 12657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 12667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_qp_init_attr *init_attr = &pr->qp->init_attr; 12677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1268f76957fc8fc4fa9735f01e59653b2792b077de06Breno Leitao ehea_init_fill_rq1(pr, pr->rq1_skba.len); 12697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1270e2878806227d223467f84f900ef4c6733ee166dfThomas Klein ret = ehea_refill_rq2(pr, init_attr->act_nr_rwqes_rq2 - 1); 12717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret |= ehea_refill_rq3(pr, init_attr->act_nr_rwqes_rq3 - 1); 12737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 12757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 12767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_reg_interrupts(struct net_device *dev) 12787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 12797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 12807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port_res *pr; 12817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int i, ret; 12827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann snprintf(port->int_aff_name, EHEA_IRQ_NAME_SIZE - 1, "%s-aff", 12857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev->name); 12867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12876b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ret = ibmebus_request_irq(port->qp_eq->attr.ist1, 12887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_qp_aff_irq_handler, 128938515e908ba3a9c467ad3bf347b9bce69216df94Thomas Gleixner IRQF_DISABLED, port->int_aff_name, port); 12907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 12918c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "failed registering irq for qp_aff_irq_handler:ist=%X\n", 12928c4877a4128e7931077b024a891a4b284d8756a3Joe Perches port->qp_eq->attr.ist1); 12937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free_qpeq; 12947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 12957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 12968c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, ifup, dev, 12978c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "irq_handle 0x%X for function qp_aff_irq_handler registered\n", 12988c4877a4128e7931077b024a891a4b284d8756a3Joe Perches port->qp_eq->attr.ist1); 12997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 130018604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 1301723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) { 13027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr = &port->port_res[i]; 13037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann snprintf(pr->int_send_name, EHEA_IRQ_NAME_SIZE - 1, 130418604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann "%s-queue%d", dev->name, i); 13056b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ret = ibmebus_request_irq(pr->eq->attr.ist1, 130618604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann ehea_recv_irq_handler, 130738515e908ba3a9c467ad3bf347b9bce69216df94Thomas Gleixner IRQF_DISABLED, pr->int_send_name, 13087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr); 13097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 13108c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "failed registering irq for ehea_queue port_res_nr:%d, ist=%X\n", 13118c4877a4128e7931077b024a891a4b284d8756a3Joe Perches i, pr->eq->attr.ist1); 13127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free_req; 13137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 13148c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, ifup, dev, 13158c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "irq_handle 0x%X for function ehea_queue_int %d registered\n", 13168c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr->eq->attr.ist1, i); 13177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 13187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 13197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 13207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 132118604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 13227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_free_req: 13237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann while (--i >= 0) { 132418604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann u32 ist = port->port_res[i].eq->attr.ist1; 13256b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ibmebus_free_irq(ist, &port->port_res[i]); 13267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 132718604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 13287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_free_qpeq: 13296b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ibmebus_free_irq(port->qp_eq->attr.ist1, port); 13307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann i = port->num_def_qps; 133118604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 13327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 133318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 13347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 13357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 13367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_free_interrupts(struct net_device *dev) 13377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 13387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 13397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port_res *pr; 13407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int i; 13417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 13427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* send */ 134318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 1344723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) { 13457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr = &port->port_res[i]; 13466b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ibmebus_free_irq(pr->eq->attr.ist1, pr); 13478c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, intr, dev, 13488c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "free send irq for res %d with handle 0x%X\n", 13498c4877a4128e7931077b024a891a4b284d8756a3Joe Perches i, pr->eq->attr.ist1); 13507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 13517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 13527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* associated events */ 13536b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ibmebus_free_irq(port->qp_eq->attr.ist1, port); 13548c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, intr, dev, 13558c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "associated event interrupt for handle 0x%X freed\n", 13568c4877a4128e7931077b024a891a4b284d8756a3Joe Perches port->qp_eq->attr.ist1); 13577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 13587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 13597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_configure_port(struct ehea_port *port) 13607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 13617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret, i; 13627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret, mask; 13637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct hcp_ehea_port_cb0 *cb0; 13647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 13657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -ENOMEM; 13663faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb0 = (void *)get_zeroed_page(GFP_KERNEL); 13677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb0) 13687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 13697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 13707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cb0->port_rc = EHEA_BMASK_SET(PXLY_RC_VALID, 1) 13717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(PXLY_RC_IP_CHKSUM, 1) 13727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(PXLY_RC_TCP_UDP_CHKSUM, 1) 13737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(PXLY_RC_VLAN_XTRACT, 1) 13747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(PXLY_RC_VLAN_TAG_FILTER, 13757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann PXLY_RC_VLAN_FILTER) 13767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(PXLY_RC_JUMBO_FRAME, 1); 13777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 137818604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann for (i = 0; i < port->num_mcs; i++) 137918604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann if (use_mcs) 138018604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann cb0->default_qpn_arr[i] = 138118604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann port->port_res[i].qp->init_attr.qp_nr; 138218604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann else 138318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann cb0->default_qpn_arr[i] = 138418604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann port->port_res[0].qp->init_attr.qp_nr; 1385e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann 13867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (netif_msg_ifup(port)) 13877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port"); 13887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 13897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann mask = EHEA_BMASK_SET(H_PORT_CB0_PRC, 1) 13907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(H_PORT_CB0_DEFQPNARRAY, 1); 13917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 13927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_modify_ehea_port(port->adapter->handle, 13937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, 13947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_PORT_CB0, mask, cb0); 13957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 13967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) 13977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 13987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 13997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = 0; 14007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_free: 14023faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb0); 14037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 14047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 14057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 14067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14071886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic int ehea_gen_smrs(struct ehea_port_res *pr) 14087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 1409e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann int ret; 14107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_adapter *adapter = pr->port->adapter; 14117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1412e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann ret = ehea_gen_smr(adapter, &adapter->mr, &pr->send_mr); 1413e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann if (ret) 14147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 14157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1416e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann ret = ehea_gen_smr(adapter, &adapter->mr, &pr->recv_mr); 1417e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann if (ret) 1418e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann goto out_free; 14197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 14217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1422e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themannout_free: 1423e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann ehea_rem_mr(&pr->send_mr); 14247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 14258c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("Generating SMRS failed\n"); 14267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return -EIO; 14277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 14287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14291886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic int ehea_rem_smrs(struct ehea_port_res *pr) 14307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 14318e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if ((ehea_rem_mr(&pr->send_mr)) || 14328e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches (ehea_rem_mr(&pr->recv_mr))) 1433e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann return -EIO; 1434e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann else 1435e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann return 0; 14367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 14377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries) 14397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 1440508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey int arr_size = sizeof(void *) * max_q_entries; 14417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 144289bf67f1f080c947c92f8773482d9e57767ca292Eric Dumazet q_skba->arr = vzalloc(arr_size); 14437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!q_skba->arr) 14447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return -ENOMEM; 14457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann q_skba->len = max_q_entries; 14477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann q_skba->index = 0; 14487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann q_skba->os_skbs = 0; 14497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 14517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 14527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, 14547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct port_res_cfg *pr_cfg, int queue_token) 14557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 14567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_adapter *adapter = port->adapter; 14577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann enum ehea_eq_type eq_type = EHEA_EQ; 14587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_qp_init_attr *init_attr = NULL; 14597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret = -EIO; 1460ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao u64 tx_bytes, rx_bytes, tx_packets, rx_packets; 1461ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao 1462ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao tx_bytes = pr->tx_bytes; 1463ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao tx_packets = pr->tx_packets; 1464ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao rx_bytes = pr->rx_bytes; 1465ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao rx_packets = pr->rx_packets; 14667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann memset(pr, 0, sizeof(struct ehea_port_res)); 14687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1469ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao pr->tx_bytes = rx_bytes; 1470ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao pr->tx_packets = tx_packets; 1471ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao pr->rx_bytes = rx_bytes; 1472ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao pr->rx_packets = rx_packets; 1473ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao 14747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->port = port; 14757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 147618604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann pr->eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0); 147718604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann if (!pr->eq) { 14788c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("create_eq failed (eq)\n"); 14797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 14807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 14817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->recv_cq = ehea_create_cq(adapter, pr_cfg->max_entries_rcq, 148318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann pr->eq->fw_handle, 14847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id); 14857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!pr->recv_cq) { 14868c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("create_cq failed (cq_recv)\n"); 14877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 14887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 14897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->send_cq = ehea_create_cq(adapter, pr_cfg->max_entries_scq, 149118604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann pr->eq->fw_handle, 14927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id); 14937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!pr->send_cq) { 14948c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("create_cq failed (cq_send)\n"); 14957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 14967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 14977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 14987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (netif_msg_ifup(port)) 14998c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("Send CQ: act_nr_cqes=%d, Recv CQ: act_nr_cqes=%d\n", 15008c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr->send_cq->attr.act_nr_of_cqes, 15018c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr->recv_cq->attr.act_nr_of_cqes); 15027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr = kzalloc(sizeof(*init_attr), GFP_KERNEL); 15047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!init_attr) { 15057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -ENOMEM; 15068c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for ehea_qp_init_attr\n"); 15077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 15087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 15097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->low_lat_rq1 = 1; 15117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->signalingtype = 1; /* generate CQE if specified in WQE */ 15127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->rq_count = 3; 15137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->qp_token = queue_token; 15147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->max_nr_send_wqes = pr_cfg->max_entries_sq; 15157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->max_nr_rwqes_rq1 = pr_cfg->max_entries_rq1; 15167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->max_nr_rwqes_rq2 = pr_cfg->max_entries_rq2; 15177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->max_nr_rwqes_rq3 = pr_cfg->max_entries_rq3; 15187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->wqe_size_enc_sq = EHEA_SG_SQ; 15197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->wqe_size_enc_rq1 = EHEA_SG_RQ1; 15207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->wqe_size_enc_rq2 = EHEA_SG_RQ2; 15217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->wqe_size_enc_rq3 = EHEA_SG_RQ3; 15227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->rq2_threshold = EHEA_RQ2_THRESHOLD; 15237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->rq3_threshold = EHEA_RQ3_THRESHOLD; 15247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->port_nr = port->logical_port_id; 15257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->send_cq_handle = pr->send_cq->fw_handle; 15267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->recv_cq_handle = pr->recv_cq->fw_handle; 15277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann init_attr->aff_eq_handle = port->qp_eq->fw_handle; 15287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->qp = ehea_create_qp(adapter, adapter->pd, init_attr); 15307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!pr->qp) { 15318c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("create_qp failed\n"); 15327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 15337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 15347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 15357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (netif_msg_ifup(port)) 15378c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("QP: qp_nr=%d\n act_nr_snd_wqe=%d\n nr_rwqe_rq1=%d\n nr_rwqe_rq2=%d\n nr_rwqe_rq3=%d\n", 15388c4877a4128e7931077b024a891a4b284d8756a3Joe Perches init_attr->qp_nr, 15398c4877a4128e7931077b024a891a4b284d8756a3Joe Perches init_attr->act_nr_send_wqes, 15408c4877a4128e7931077b024a891a4b284d8756a3Joe Perches init_attr->act_nr_rwqes_rq1, 15418c4877a4128e7931077b024a891a4b284d8756a3Joe Perches init_attr->act_nr_rwqes_rq2, 15428c4877a4128e7931077b024a891a4b284d8756a3Joe Perches init_attr->act_nr_rwqes_rq3); 15437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 154444fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein pr->sq_skba_size = init_attr->act_nr_send_wqes + 1; 154544fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein 154644fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein ret = ehea_init_q_skba(&pr->sq_skba, pr->sq_skba_size); 15477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret |= ehea_init_q_skba(&pr->rq1_skba, init_attr->act_nr_rwqes_rq1 + 1); 15487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret |= ehea_init_q_skba(&pr->rq2_skba, init_attr->act_nr_rwqes_rq2 + 1); 15497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret |= ehea_init_q_skba(&pr->rq3_skba, init_attr->act_nr_rwqes_rq3 + 1); 15507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) 15517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 15527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->swqe_refill_th = init_attr->act_nr_send_wqes / 10; 15547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ehea_gen_smrs(pr) != 0) { 15557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 15567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 15577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 155818604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 15597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann atomic_set(&pr->swqe_avail, init_attr->act_nr_send_wqes - 1); 15607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann kfree(init_attr); 156218604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 1563bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger netif_napi_add(pr->port->netdev, &pr->napi, ehea_poll, 64); 156418604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 15657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = 0; 15667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 15677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_free: 15697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann kfree(init_attr); 15707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann vfree(pr->sq_skba.arr); 15717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann vfree(pr->rq1_skba.arr); 15727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann vfree(pr->rq2_skba.arr); 15737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann vfree(pr->rq3_skba.arr); 15747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_destroy_qp(pr->qp); 15757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_destroy_cq(pr->send_cq); 15767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_destroy_cq(pr->recv_cq); 157718604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann ehea_destroy_eq(pr->eq); 15787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 15797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 15807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 15817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_clean_portres(struct ehea_port *port, struct ehea_port_res *pr) 15837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 15847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret, i; 15857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1586357eb46d8f275b4e8484541234ea3ba06065e258Hannes Hering if (pr->qp) 1587357eb46d8f275b4e8484541234ea3ba06065e258Hannes Hering netif_napi_del(&pr->napi); 1588357eb46d8f275b4e8484541234ea3ba06065e258Hannes Hering 15897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_destroy_qp(pr->qp); 15907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!ret) { 15927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_destroy_cq(pr->send_cq); 15937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_destroy_cq(pr->recv_cq); 159418604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann ehea_destroy_eq(pr->eq); 15957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 15967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann for (i = 0; i < pr->rq1_skba.len; i++) 15977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (pr->rq1_skba.arr[i]) 15987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev_kfree_skb(pr->rq1_skba.arr[i]); 15997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann for (i = 0; i < pr->rq2_skba.len; i++) 16017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (pr->rq2_skba.arr[i]) 16027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev_kfree_skb(pr->rq2_skba.arr[i]); 16037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann for (i = 0; i < pr->rq3_skba.len; i++) 16057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (pr->rq3_skba.arr[i]) 16067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev_kfree_skb(pr->rq3_skba.arr[i]); 16077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann for (i = 0; i < pr->sq_skba.len; i++) 16097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (pr->sq_skba.arr[i]) 16107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev_kfree_skb(pr->sq_skba.arr[i]); 16117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann vfree(pr->rq1_skba.arr); 16137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann vfree(pr->rq2_skba.arr); 16147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann vfree(pr->rq3_skba.arr); 16157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann vfree(pr->sq_skba.arr); 16167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_rem_smrs(pr); 16177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 16187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 16197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 16207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 162113946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchardstatic void write_swqe2_immediate(struct sk_buff *skb, struct ehea_swqe *swqe, 162213946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard u32 lkey) 16237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 1624e743d31312d00932391b123dfac3324d2b9e8c81Eric Dumazet int skb_data_size = skb_headlen(skb); 16257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u8 *imm_data = &swqe->u.immdata_desc.immediate_data[0]; 16267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_vsgentry *sg1entry = &swqe->u.immdata_desc.sg_entry; 162713946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard unsigned int immediate_len = SWQE2_MAX_IMM; 162813946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard 162913946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard swqe->descriptors = 0; 16307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 163113946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard if (skb_is_gso(skb)) { 163213946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard swqe->tx_control |= EHEA_SWQE_TSO; 163313946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard swqe->mss = skb_shinfo(skb)->gso_size; 163413946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard /* 163513946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard * For TSO packets we only copy the headers into the 163613946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard * immediate area. 163713946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard */ 163813946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard immediate_len = ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); 163913946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard } 16407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 164113946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard if (skb_is_gso(skb) || skb_data_size >= SWQE2_MAX_IMM) { 164213946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard skb_copy_from_linear_data(skb, imm_data, immediate_len); 164313946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard swqe->immediate_data_length = immediate_len; 16447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 164513946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard if (skb_data_size > immediate_len) { 16467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann sg1entry->l_key = lkey; 164713946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard sg1entry->len = skb_data_size - immediate_len; 164844a5b3d539893988dc6b63054c59d031df1fd7bcThomas Klein sg1entry->vaddr = 164913946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard ehea_map_vaddr(skb->data + immediate_len); 16507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe->descriptors++; 16517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 16527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else { 1653d626f62b11e00c16e81e4308ab93d3f13551812aArnaldo Carvalho de Melo skb_copy_from_linear_data(skb, imm_data, skb_data_size); 16547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe->immediate_data_length = skb_data_size; 16557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 16567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 16577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev, 16597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_swqe *swqe, u32 lkey) 16607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 16617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_vsgentry *sg_list, *sg1entry, *sgentry; 16627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann skb_frag_t *frag; 16637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int nfrags, sg1entry_contains_frag_data, i; 16647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann nfrags = skb_shinfo(skb)->nr_frags; 16667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann sg1entry = &swqe->u.immdata_desc.sg_entry; 1667508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey sg_list = (struct ehea_vsgentry *)&swqe->u.immdata_desc.sg_list; 16687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann sg1entry_contains_frag_data = 0; 16697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 167013946f5e4eefd5162733a75c03bb9f52c9c69614Anton Blanchard write_swqe2_immediate(skb, swqe, lkey); 16717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* write descriptors */ 16737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (nfrags > 0) { 16747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (swqe->descriptors == 0) { 16757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* sg1entry not yet used */ 16767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann frag = &skb_shinfo(skb)->frags[0]; 16777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* copy sg1entry data */ 16797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann sg1entry->l_key = lkey; 16809e903e085262ffbf1fc44a17ac06058aca03524aEric Dumazet sg1entry->len = skb_frag_size(frag); 168144a5b3d539893988dc6b63054c59d031df1fd7bcThomas Klein sg1entry->vaddr = 1682618c4a0ad41a42edd4f06259623f78f2e8da66e8Ian Campbell ehea_map_vaddr(skb_frag_address(frag)); 16837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe->descriptors++; 16847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann sg1entry_contains_frag_data = 1; 16857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 16867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann for (i = sg1entry_contains_frag_data; i < nfrags; i++) { 16887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann frag = &skb_shinfo(skb)->frags[i]; 16907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann sgentry = &sg_list[i - sg1entry_contains_frag_data]; 16917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 16927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann sgentry->l_key = lkey; 16930110bba5e7731524940f9e02ce3d4aae75087f68Eric Dumazet sgentry->len = skb_frag_size(frag); 1694618c4a0ad41a42edd4f06259623f78f2e8da66e8Ian Campbell sgentry->vaddr = ehea_map_vaddr(skb_frag_address(frag)); 16957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe->descriptors++; 16967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 16977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 16987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 16997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid) 17017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 17027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret = 0; 17037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 17047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u8 reg_type; 17057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* De/Register untagged packets */ 17077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann reg_type = EHEA_BCMC_BROADCAST | EHEA_BCMC_UNTAGGED; 17087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, 17097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, 17107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann reg_type, port->mac_addr, 0, hcallid); 17117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 17128c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("%sregistering bc address failed (tagged)\n", 17138c4877a4128e7931077b024a891a4b284d8756a3Joe Perches hcallid == H_REG_BCMC ? "" : "de"); 17147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 17157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_herr; 17167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 17177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* De/Register VLAN packets */ 17197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann reg_type = EHEA_BCMC_BROADCAST | EHEA_BCMC_VLANID_ALL; 17207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, 17217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, 17227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann reg_type, port->mac_addr, 0, hcallid); 17237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 17248c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("%sregistering bc address failed (vlan)\n", 17258c4877a4128e7931077b024a891a4b284d8756a3Joe Perches hcallid == H_REG_BCMC ? "" : "de"); 17267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 17277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 17287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_herr: 17297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 17307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 17317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_set_mac_addr(struct net_device *dev, void *sa) 17337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 17347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 17357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct sockaddr *mac_addr = sa; 17367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct hcp_ehea_port_cb0 *cb0; 17377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 17387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 17397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!is_valid_ether_addr(mac_addr->sa_data)) { 17417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EADDRNOTAVAIL; 17427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 17437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 17447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17453faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb0 = (void *)get_zeroed_page(GFP_KERNEL); 17467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb0) { 17478c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for cb0\n"); 17487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -ENOMEM; 17497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 17507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 17517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann memcpy(&(cb0->port_mac_addr), &(mac_addr->sa_data[0]), ETH_ALEN); 17537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cb0->port_mac_addr = cb0->port_mac_addr >> 16; 17557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_modify_ehea_port(port->adapter->handle, 17577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, H_PORT_CB0, 17587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(H_PORT_CB0_MAC, 1), cb0); 17597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 17607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 17617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free; 17627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 17637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len); 17657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Deregister old MAC in pHYP */ 176700aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann if (port->state == EHEA_PORT_UP) { 176800aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); 176900aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann if (ret) 177000aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann goto out_upregs; 177100aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann } 17727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->mac_addr = cb0->port_mac_addr << 16; 17747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Register new MAC in pHYP */ 177600aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann if (port->state == EHEA_PORT_UP) { 177700aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); 177800aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann if (ret) 177900aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann goto out_upregs; 178000aaea2f95d73d4e2b5e45cf77c3cbb16c59e87fJan-Bernd Themann } 17817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = 0; 178321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 178421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Kleinout_upregs: 178521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_update_bcmc_registrations(); 17867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_free: 17873faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb0); 17887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 17897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 17907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 17917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 17927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_promiscuous_error(u64 hret, int enable) 17937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 17947674a588e93c6fa1fde8e452a4c025c49037cb96Thomas Klein if (hret == H_AUTHORITY) 17958c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("Hypervisor denied %sabling promiscuous mode\n", 17968c4877a4128e7931077b024a891a4b284d8756a3Joe Perches enable == 1 ? "en" : "dis"); 17977674a588e93c6fa1fde8e452a4c025c49037cb96Thomas Klein else 17988c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("failed %sabling promiscuous mode\n", 17998c4877a4128e7931077b024a891a4b284d8756a3Joe Perches enable == 1 ? "en" : "dis"); 18007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 18017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_promiscuous(struct net_device *dev, int enable) 18037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 18047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 18057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct hcp_ehea_port_cb7 *cb7; 18067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 18077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1808aa3bc6c68e3c1064969f5f2962be84491ffb69a0Nicolas Kaiser if (enable == port->promisc) 18097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return; 18107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18113faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb7 = (void *)get_zeroed_page(GFP_ATOMIC); 18127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb7) { 18138c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for cb7\n"); 18147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 18157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 18167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Modify Pxs_DUCQPN in CB7 */ 18187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cb7->def_uc_qpn = enable == 1 ? port->port_res[0].qp->fw_handle : 0; 18197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_modify_ehea_port(port->adapter->handle, 18217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, 18227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_PORT_CB7, H_PORT_CB7_DUCQPN, cb7); 18237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret) { 18247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_promiscuous_error(hret, enable); 18257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 18267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 18277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->promisc = enable; 18297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 18303faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb7); 18317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 18327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr, 18347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u32 hcallid) 18357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 18367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 18377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u8 reg_type; 18387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST 18407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BCMC_UNTAGGED; 18417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, 18437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, 18447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann reg_type, mc_mac_addr, 0, hcallid); 18457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret) 18467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 18477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST 18497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BCMC_VLANID_ALL; 18507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, 18527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->logical_port_id, 18537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann reg_type, mc_mac_addr, 0, hcallid); 18547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 18557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return hret; 18567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 18577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_drop_multicast_list(struct net_device *dev) 18597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 18607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 18617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_mc_list *mc_entry = port->mc_list; 18627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct list_head *pos; 18637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct list_head *temp; 18647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret = 0; 18657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 18667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann list_for_each_safe(pos, temp, &(port->mc_list->list)) { 18687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann mc_entry = list_entry(pos, struct ehea_mc_list, list); 18697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_multicast_reg_helper(port, mc_entry->macaddr, 18717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_DEREG_BCMC); 18727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret) { 18738c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("failed deregistering mcast MAC\n"); 18747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 18757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 18767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann list_del(pos); 18787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann kfree(mc_entry); 18797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 18807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 18817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 18827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_allmulti(struct net_device *dev, int enable) 18847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 18857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 18867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 18877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 18887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!port->allmulti) { 18897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (enable) { 18907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Enable ALLMULTI */ 18917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_drop_multicast_list(dev); 18927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_multicast_reg_helper(port, 0, H_REG_BCMC); 18937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!hret) 18947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->allmulti = 1; 18957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann else 18968c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, 18978c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "failed enabling IFF_ALLMULTI\n"); 18987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 18997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else 19007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!enable) { 19017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Disable ALLMULTI */ 19027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC); 19037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!hret) 19047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->allmulti = 0; 19057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann else 19068c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, 19078c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "failed disabling IFF_ALLMULTI\n"); 19087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 19097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 19107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1911508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxeystatic void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) 19127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 19137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_mc_list *ehea_mcl_entry; 19147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 19157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 19161e1675ccf758cbb4303ab052d58405cda6c745a7Jan-Bernd Themann ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC); 19177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!ehea_mcl_entry) { 19188c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for mcl_entry\n"); 19197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return; 19207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 19217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 19227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann INIT_LIST_HEAD(&ehea_mcl_entry->list); 19237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 19247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann memcpy(&ehea_mcl_entry->macaddr, mc_mac_addr, ETH_ALEN); 19257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 19267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_multicast_reg_helper(port, ehea_mcl_entry->macaddr, 19277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_REG_BCMC); 19287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!hret) 19297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann list_add(&ehea_mcl_entry->list, &port->mc_list->list); 19307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann else { 19318c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("failed registering mcast MAC\n"); 19327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann kfree(ehea_mcl_entry); 19337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 19347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 19357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 19367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_set_multicast_list(struct net_device *dev) 19377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 19387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 193922bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko struct netdev_hw_addr *ha; 194048e2f183cb1709600012265a2e723f45a350d5feJiri Pirko int ret; 19417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1942a4910b744486254cfa61995954c118fb2283c4fdBreno Leitao if (port->promisc) { 19437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_promiscuous(dev, 1); 19447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return; 19457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 19467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_promiscuous(dev, 0); 19477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 19487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (dev->flags & IFF_ALLMULTI) { 19497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_allmulti(dev, 1); 195021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein goto out; 19517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 19527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_allmulti(dev, 0); 19537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 19544cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko if (!netdev_mc_empty(dev)) { 19557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_drop_multicast_list(dev); 19567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 19577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Dropping the current multicast list failed. 19587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann * Enabling ALL_MULTI is the best we can do. 19597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann */ 19607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_allmulti(dev, 1); 19617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 19627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 19634cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko if (netdev_mc_count(dev) > port->adapter->max_mc_mac) { 19648c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("Mcast registration limit reached (0x%llx). Use ALLMULTI!\n", 19658c4877a4128e7931077b024a891a4b284d8756a3Joe Perches port->adapter->max_mc_mac); 19667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 19677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 19687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 196922bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko netdev_for_each_mc_addr(ha, dev) 197022bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko ehea_add_multicast_entry(port, ha->addr); 1971508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey 19727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 19737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 197421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_update_bcmc_registrations(); 19757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 19767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 19777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_change_mtu(struct net_device *dev, int new_mtu) 19787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 19797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if ((new_mtu < 68) || (new_mtu > EHEA_MAX_PACKET_SIZE)) 19807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return -EINVAL; 19817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev->mtu = new_mtu; 19827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 19837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 19847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1985d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchardstatic void xmit_common(struct sk_buff *skb, struct ehea_swqe *swqe) 19867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 1987d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard swqe->tx_control |= EHEA_SWQE_IMM_DATA_PRESENT | EHEA_SWQE_CRC; 1988d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann 1989d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard if (skb->protocol != htons(ETH_P_IP)) 1990d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard return; 19917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1992d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard if (skb->ip_summed == CHECKSUM_PARTIAL) 1993d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard swqe->tx_control |= EHEA_SWQE_IP_CHECKSUM; 19947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1995d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard swqe->ip_start = skb_network_offset(skb); 1996d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard swqe->ip_end = swqe->ip_start + ip_hdrlen(skb) - 1; 19977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 1998d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard switch (ip_hdr(skb)->protocol) { 1999d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard case IPPROTO_UDP: 2000d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard if (skb->ip_summed == CHECKSUM_PARTIAL) 2001d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard swqe->tx_control |= EHEA_SWQE_TCP_CHECKSUM; 20027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2003d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard swqe->tcp_offset = swqe->ip_end + 1 + 2004d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard offsetof(struct udphdr, check); 2005d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard break; 2006d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard 2007d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard case IPPROTO_TCP: 2008d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard if (skb->ip_summed == CHECKSUM_PARTIAL) 2009d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard swqe->tx_control |= EHEA_SWQE_TCP_CHECKSUM; 2010d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard 2011d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard swqe->tcp_offset = swqe->ip_end + 1 + 2012d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard offsetof(struct tcphdr, check); 2013d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard break; 20147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 2015d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard} 2016d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard 2017d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchardstatic void ehea_xmit2(struct sk_buff *skb, struct net_device *dev, 2018d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard struct ehea_swqe *swqe, u32 lkey) 2019d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard{ 2020d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard swqe->tx_control |= EHEA_SWQE_DESCRIPTORS_PRESENT; 2021d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard 2022d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard xmit_common(skb, swqe); 20237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 20247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann write_swqe2_data(skb, dev, swqe, lkey); 20257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 20267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 20277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_xmit3(struct sk_buff *skb, struct net_device *dev, 20287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_swqe *swqe) 20297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 20307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u8 *imm_data = &swqe->u.immdata_nodesc.immediate_data[0]; 20317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2032d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard xmit_common(skb, swqe); 2033d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann 203430e2e90b4de735769c8c9dc2397388fdf305e5caAnton Blanchard if (!skb->data_len) 2035d626f62b11e00c16e81e4308ab93d3f13551812aArnaldo Carvalho de Melo skb_copy_from_linear_data(skb, imm_data, skb->len); 203630e2e90b4de735769c8c9dc2397388fdf305e5caAnton Blanchard else 203730e2e90b4de735769c8c9dc2397388fdf305e5caAnton Blanchard skb_copy_bits(skb, 0, imm_data, skb->len); 2038d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard 20397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe->immediate_data_length = skb->len; 20407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev_kfree_skb(skb); 20417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 20427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 20437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) 20447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 20457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 20467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_swqe *swqe; 20477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u32 lkey; 20487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int swqe_index; 204918604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann struct ehea_port_res *pr; 2050b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard struct netdev_queue *txq; 205118604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 2052b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard pr = &port->port_res[skb_get_queue_mapping(skb)]; 2053b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); 205418604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann 20557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe = ehea_get_swqe(pr->qp, &swqe_index); 20567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann memset(swqe, 0, SWQE_HEADER_SIZE); 20577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann atomic_dec(&pr->swqe_avail); 20587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2059e5ccd96110d5ac0f73b695ba606feb6d69472f26Eric Dumazet if (vlan_tx_tag_present(skb)) { 2060e5ccd96110d5ac0f73b695ba606feb6d69472f26Eric Dumazet swqe->tx_control |= EHEA_SWQE_VLAN_INSERT; 2061e5ccd96110d5ac0f73b695ba606feb6d69472f26Eric Dumazet swqe->vlan_tag = vlan_tx_tag_get(skb); 2062e5ccd96110d5ac0f73b695ba606feb6d69472f26Eric Dumazet } 2063e5ccd96110d5ac0f73b695ba606feb6d69472f26Eric Dumazet 2064ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao pr->tx_packets++; 2065ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao pr->tx_bytes += skb->len; 2066ce45b873028fdf94a24f0850cd554e6fda593e16Breno Leitao 20677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (skb->len <= SWQE3_MAX_IMM) { 20687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u32 sig_iv = port->sig_comp_iv; 20697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u32 swqe_num = pr->swqe_id_counter; 20707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_xmit3(skb, dev, swqe); 20717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, EHEA_SWQE3_TYPE) 20727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(EHEA_WR_ID_COUNT, swqe_num); 20737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (pr->swqe_ll_count >= (sig_iv - 1)) { 20747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe->wr_id |= EHEA_BMASK_SET(EHEA_WR_ID_REFILL, 20757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann sig_iv); 20767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION; 20777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->swqe_ll_count = 0; 20787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else 20797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->swqe_ll_count += 1; 20807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else { 20817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann swqe->wr_id = 20827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(EHEA_WR_ID_TYPE, EHEA_SWQE2_TYPE) 20837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(EHEA_WR_ID_COUNT, pr->swqe_id_counter) 2084acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann | EHEA_BMASK_SET(EHEA_WR_ID_REFILL, 1) 20857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, pr->sq_skba.index); 20867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->sq_skba.arr[pr->sq_skba.index] = skb; 20877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 20887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->sq_skba.index++; 20897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->sq_skba.index &= (pr->sq_skba.len - 1); 20907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 20917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann lkey = pr->send_mr.lkey; 20927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_xmit2(skb, dev, swqe, lkey); 2093acbddb591ba76bb20204fd6a407cb87d3f5f751eJan-Bernd Themann swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION; 20947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 20957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr->swqe_id_counter += 1; 20967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 20978c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, tx_queued, dev, 20988c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "post swqe on QP %d\n", pr->qp->init_attr.qp_nr); 20998c4877a4128e7931077b024a891a4b284d8756a3Joe Perches if (netif_msg_tx_queued(port)) 2100bff0a55f34e62970203c4af9c8ef4dc7d73e2f96Jan-Bernd Themann ehea_dump(swqe, 512, "swqe"); 21017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21022c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) { 2103b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_stop_queue(txq); 21042c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann swqe->tx_control |= EHEA_SWQE_PURGE; 21052c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 210644c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 21077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_post_swqe(pr->qp, swqe); 21087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) { 2110b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard pr->p_stats.queue_stopped++; 2111b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_stop_queue(txq); 21127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 21132c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 21147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return NETDEV_TX_OK; 21157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 21167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21178e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirkostatic int ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) 21187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 21197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 21207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_adapter *adapter = port->adapter; 21217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct hcp_ehea_port_cb1 *cb1; 21227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int index; 21237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 21248e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko int err = 0; 21257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21263faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb1 = (void *)get_zeroed_page(GFP_KERNEL); 21277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb1) { 21288c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for cb1\n"); 21298e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko err = -ENOMEM; 21307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 21317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 21327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id, 21347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_PORT_CB1, H_PORT_CB1_ALL, cb1); 21357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 21368c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("query_ehea_port failed\n"); 21378e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko err = -EINVAL; 21387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 21397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 21407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann index = (vid / 64); 2142dec590c1bb05c1553b68cab7aa3ea36d77e7f9a3Thomas Klein cb1->vlan_filter[index] |= ((u64)(0x8000000000000000 >> (vid & 0x3F))); 21437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, 21457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_PORT_CB1, H_PORT_CB1_ALL, cb1); 21468e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko if (hret != H_SUCCESS) { 21478c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("modify_ehea_port failed\n"); 21488e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko err = -EINVAL; 21498e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko } 21507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 21513faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb1); 21528e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko return err; 21537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 21547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21558e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirkostatic int ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) 21567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 21577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 21587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_adapter *adapter = port->adapter; 21597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct hcp_ehea_port_cb1 *cb1; 21607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int index; 21617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 21628e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko int err = 0; 21637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21643faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb1 = (void *)get_zeroed_page(GFP_KERNEL); 21657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb1) { 21668c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for cb1\n"); 21678e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko err = -ENOMEM; 21687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 21697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 21707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea_port(adapter->handle, port->logical_port_id, 21727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_PORT_CB1, H_PORT_CB1_ALL, cb1); 21737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 21748c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("query_ehea_port failed\n"); 21758e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko err = -EINVAL; 21767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 21777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 21787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann index = (vid / 64); 2180dec590c1bb05c1553b68cab7aa3ea36d77e7f9a3Thomas Klein cb1->vlan_filter[index] &= ~((u64)(0x8000000000000000 >> (vid & 0x3F))); 21817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, 21837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann H_PORT_CB1, H_PORT_CB1_ALL, cb1); 21848e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko if (hret != H_SUCCESS) { 21858c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("modify_ehea_port failed\n"); 21868e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko err = -EINVAL; 21878e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko } 21887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 21893faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb1); 21908e586137e6b63af1e881b328466ab5ffbe562510Jiri Pirko return err; 21917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 21927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 21931886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp) 21947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 21957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret = -EIO; 21967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 21977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u16 dummy16 = 0; 21987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 dummy64 = 0; 2199508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey struct hcp_modify_qp_cb0 *cb0; 22007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22013faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb0 = (void *)get_zeroed_page(GFP_KERNEL); 22027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb0) { 22037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -ENOMEM; 22047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 22057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 22067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, 22087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); 22097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 22108c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("query_ehea_qp failed (1)\n"); 22117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 22127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 22137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cb0->qp_ctl_reg = H_QP_CR_STATE_INITIALIZED; 22157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_modify_ehea_qp(adapter->handle, 0, qp->fw_handle, 22167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, 22177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann &dummy64, &dummy64, &dummy16, &dummy16); 22187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 22198c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("modify_ehea_qp failed (1)\n"); 22207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 22217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 22227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, 22247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); 22257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 22268c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("query_ehea_qp failed (2)\n"); 22277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 22287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 22297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cb0->qp_ctl_reg = H_QP_CR_ENABLED | H_QP_CR_STATE_INITIALIZED; 22317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_modify_ehea_qp(adapter->handle, 0, qp->fw_handle, 22327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, 22337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann &dummy64, &dummy64, &dummy16, &dummy16); 22347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 22358c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("modify_ehea_qp failed (2)\n"); 22367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 22377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 22387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, 22407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); 22417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 22428c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("query_ehea_qp failed (3)\n"); 22437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 22447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 22457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann cb0->qp_ctl_reg = H_QP_CR_ENABLED | H_QP_CR_STATE_RDY2SND; 22477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_modify_ehea_qp(adapter->handle, 0, qp->fw_handle, 22487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 1), cb0, 22497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann &dummy64, &dummy64, &dummy16, &dummy16); 22507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 22518c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("modify_ehea_qp failed (3)\n"); 22527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 22537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 22547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, 22567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), cb0); 22577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 22588c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("query_ehea_qp failed (4)\n"); 22597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 22607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 22617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = 0; 22637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 22643faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb0); 22657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 22667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 22677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2268723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchardstatic int ehea_port_res_setup(struct ehea_port *port, int def_qps) 22697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 22707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret, i; 22717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct port_res_cfg pr_cfg, pr_cfg_small_rx; 22727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann enum ehea_eq_type eq_type = EHEA_EQ; 22737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->qp_eq = ehea_create_eq(port->adapter, eq_type, 22757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_MAX_ENTRIES_EQ, 1); 22767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!port->qp_eq) { 22777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EINVAL; 22788c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("ehea_create_eq failed (qp_eq)\n"); 22797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_kill_eq; 22807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 22817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg.max_entries_rcq = rq1_entries + rq2_entries + rq3_entries; 228318604c54854549ee0ad65e27ca9cb91c96af784cJan-Bernd Themann pr_cfg.max_entries_scq = sq_entries * 2; 22847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg.max_entries_sq = sq_entries; 22857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg.max_entries_rq1 = rq1_entries; 22867a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg.max_entries_rq2 = rq2_entries; 22877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg.max_entries_rq3 = rq3_entries; 22887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg_small_rx.max_entries_rcq = 1; 22907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg_small_rx.max_entries_scq = sq_entries; 22917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg_small_rx.max_entries_sq = sq_entries; 22927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg_small_rx.max_entries_rq1 = 1; 22937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg_small_rx.max_entries_rq2 = 1; 22947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann pr_cfg_small_rx.max_entries_rq3 = 1; 22957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 22967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann for (i = 0; i < def_qps; i++) { 22977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_init_port_res(port, &port->port_res[i], &pr_cfg, i); 22987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) 22997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_clean_pr; 23007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 2301723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = def_qps; i < def_qps; i++) { 23027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_init_port_res(port, &port->port_res[i], 23037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann &pr_cfg_small_rx, i); 23047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) 23057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_clean_pr; 23067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 23077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 23087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 23097a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 23107a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_clean_pr: 23117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann while (--i >= 0) 23127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_clean_portres(port, &port->port_res[i]); 23137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 23147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_kill_eq: 23157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_destroy_eq(port->qp_eq); 23167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 23177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 23187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 23197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_clean_all_portres(struct ehea_port *port) 23207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 23217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret = 0; 23227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int i; 23237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2324723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) 23257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret |= ehea_clean_portres(port, &port->port_res[i]); 23267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 23277a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret |= ehea_destroy_eq(port->qp_eq); 23287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 23297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 23307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 23317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 233235cf2e2e3b96c070a615d699bf514ffec6afd19eThomas Kleinstatic void ehea_remove_adapter_mr(struct ehea_adapter *adapter) 23331211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein{ 233435cf2e2e3b96c070a615d699bf514ffec6afd19eThomas Klein if (adapter->active_ports) 233535cf2e2e3b96c070a615d699bf514ffec6afd19eThomas Klein return; 23361211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein 23371211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein ehea_rem_mr(&adapter->mr); 23381211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein} 23391211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein 234035cf2e2e3b96c070a615d699bf514ffec6afd19eThomas Kleinstatic int ehea_add_adapter_mr(struct ehea_adapter *adapter) 23411211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein{ 234235cf2e2e3b96c070a615d699bf514ffec6afd19eThomas Klein if (adapter->active_ports) 234335cf2e2e3b96c070a615d699bf514ffec6afd19eThomas Klein return 0; 23441211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein 23451211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein return ehea_reg_kernel_mr(adapter, &adapter->mr); 23461211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein} 23471211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein 23487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_up(struct net_device *dev) 23497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 23507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret, i; 23517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 23527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 23537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (port->state == EHEA_PORT_UP) 23547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 23557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2356723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard ret = ehea_port_res_setup(port, port->num_def_qps); 23577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 23588c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "port_res_failed\n"); 23597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 23607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 23617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 23627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* Set default QP for this port */ 23637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_configure_port(port); 23647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 23658c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "ehea_configure_port failed. ret:%d\n", ret); 23667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_clean_pr; 23677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 23687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 23697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_reg_interrupts(dev); 23707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 23718c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "reg_interrupts failed. ret:%d\n", ret); 2372f9e29228e6f2058e7b086115ecb7008630ebd832Thomas Klein goto out_clean_pr; 23737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 23747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2375723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) { 23767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_activate_qp(port->adapter, port->port_res[i].qp); 23777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 23788c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "activate_qp failed\n"); 23797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free_irqs; 23807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 23817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 23827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2383508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey for (i = 0; i < port->num_def_qps; i++) { 23847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_fill_port_res(&port->port_res[i]); 23857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 23868c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "out_free_irqs\n"); 23877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free_irqs; 23887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 23897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 23907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 239121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); 239221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (ret) { 239321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ret = -EIO; 239421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein goto out_free_irqs; 239521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein } 239621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 23977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->state = EHEA_PORT_UP; 239821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 239921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ret = 0; 24007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 24017a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24027a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_free_irqs: 24037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_free_interrupts(dev); 24047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_clean_pr: 24067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_clean_all_portres(port); 24077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 240844c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (ret) 24098c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(dev, "Failed starting. ret=%i\n", ret); 241044c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 241121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_update_bcmc_registrations(); 241221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_update_firmware_handles(); 241321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 24147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 24157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 24167a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2417bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemmingerstatic void port_napi_disable(struct ehea_port *port) 2418bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger{ 2419bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger int i; 2420bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger 2421723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) 2422bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger napi_disable(&port->port_res[i].napi); 2423bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger} 2424bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger 2425bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemmingerstatic void port_napi_enable(struct ehea_port *port) 2426bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger{ 2427bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger int i; 2428bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger 2429723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) 2430bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger napi_enable(&port->port_res[i].napi); 2431bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger} 2432bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger 24337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_open(struct net_device *dev) 24347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 24357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 24367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 24377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2438a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_lock(&port->port_lock); 24397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24408c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, ifup, dev, "enabling port\n"); 24417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_up(dev); 2443bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger if (!ret) { 2444bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger port_napi_enable(port); 2445b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_start_all_queues(dev); 2446bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger } 24477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2448a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_unlock(&port->port_lock); 244967c170a24fc6669f8f7c0864d75caadef0a8e5e6Anton Blanchard schedule_delayed_work(&port->stats_work, 245067c170a24fc6669f8f7c0864d75caadef0a8e5e6Anton Blanchard round_jiffies_relative(msecs_to_jiffies(1000))); 24517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 24537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 24547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_down(struct net_device *dev) 24567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 2457bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger int ret; 24587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 24597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (port->state == EHEA_PORT_DOWN) 24617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 24627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_drop_multicast_list(dev); 246421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_broadcast_reg_helper(port, H_DEREG_BCMC); 246521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 24667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_free_interrupts(dev); 24677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->state = EHEA_PORT_DOWN; 246944c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 247021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_update_bcmc_registrations(); 247121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 247244c821525778c5d2e81da293195d5d589e8ad845Thomas Klein ret = ehea_clean_all_portres(port); 247344c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (ret) 24748c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(dev, "Failed freeing resources. ret=%i\n", ret); 247544c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 247621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_update_firmware_handles(); 247721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 24787a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 24797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 24807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_stop(struct net_device *dev) 24827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 24837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 24847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 24857a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24868c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, ifdown, dev, "disabling port\n"); 24877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 24882f69ae01c83a94af5dc3c20e8135b974687ed004Jan-Bernd Themann set_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); 24894bb073c0e32a0862bdb5215d11af19f6c0180c98David S. Miller cancel_work_sync(&port->reset_task); 24902aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com cancel_delayed_work_sync(&port->stats_work); 2491a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_lock(&port->port_lock); 2492b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_stop_all_queues(dev); 24930173b793ca477aa2ca516ebf0a35e137b678d466Jan-Bernd Themann port_napi_disable(port); 24947a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_down(dev); 2495a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_unlock(&port->port_lock); 24962f69ae01c83a94af5dc3c20e8135b974687ed004Jan-Bernd Themann clear_bit(__EHEA_DISABLE_PORT_RESET, &port->flags); 24977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 24987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 24997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 250022559c5d7488fe21f5f46117a4d275fc72066aa6Andrew Mortonstatic void ehea_purge_sq(struct ehea_qp *orig_qp) 25012c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann{ 25022c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_qp qp = *orig_qp; 25032c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_qp_init_attr *init_attr = &qp.init_attr; 25042c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_swqe *swqe; 25052c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int wqe_index; 25062c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int i; 25072c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 25082c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann for (i = 0; i < init_attr->act_nr_send_wqes; i++) { 25092c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann swqe = ehea_get_swqe(&qp, &wqe_index); 25102c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann swqe->tx_control |= EHEA_SWQE_PURGE; 25112c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 25122c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann} 25132c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 251422559c5d7488fe21f5f46117a4d275fc72066aa6Andrew Mortonstatic void ehea_flush_sq(struct ehea_port *port) 251544fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein{ 251644fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein int i; 251744fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein 2518723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < port->num_def_qps; i++) { 251944fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein struct ehea_port_res *pr = &port->port_res[i]; 252044fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein int swqe_max = pr->sq_skba_size - 2 - pr->swqe_ll_count; 25215b27d42755fa6536a89f32b107fb2a53267696c2Breno Leitao int ret; 25225b27d42755fa6536a89f32b107fb2a53267696c2Breno Leitao 25235b27d42755fa6536a89f32b107fb2a53267696c2Breno Leitao ret = wait_event_timeout(port->swqe_avail_wq, 25245b27d42755fa6536a89f32b107fb2a53267696c2Breno Leitao atomic_read(&pr->swqe_avail) >= swqe_max, 25255b27d42755fa6536a89f32b107fb2a53267696c2Breno Leitao msecs_to_jiffies(100)); 25265b27d42755fa6536a89f32b107fb2a53267696c2Breno Leitao 25275b27d42755fa6536a89f32b107fb2a53267696c2Breno Leitao if (!ret) { 25288c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("WARNING: sq not flushed completely\n"); 25295b27d42755fa6536a89f32b107fb2a53267696c2Breno Leitao break; 253044fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein } 253144fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein } 253244fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein} 253344fb3126d7e6fb411775551b4653643f1d28ebe9Thomas Klein 25341886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic int ehea_stop_qps(struct net_device *dev) 25352c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann{ 25362c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 25372c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_adapter *adapter = port->adapter; 2538508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey struct hcp_modify_qp_cb0 *cb0; 25392c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int ret = -EIO; 25402c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int dret; 25412c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int i; 25422c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann u64 hret; 25432c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann u64 dummy64 = 0; 25442c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann u16 dummy16 = 0; 25452c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 25463faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb0 = (void *)get_zeroed_page(GFP_KERNEL); 25472c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (!cb0) { 25482c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ret = -ENOMEM; 25492c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 25502c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 25512c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 2552723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < (port->num_def_qps); i++) { 25532c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_port_res *pr = &port->port_res[i]; 25542c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_qp *qp = pr->qp; 25552c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 25562c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann /* Purge send queue */ 25572c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ehea_purge_sq(qp); 25582c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 25592c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann /* Disable queue pair */ 25602c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, 25612c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), 25622c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann cb0); 25632c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (hret != H_SUCCESS) { 25648c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("query_ehea_qp failed (1)\n"); 25652c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 25662c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 25672c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 25682c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann cb0->qp_ctl_reg = (cb0->qp_ctl_reg & H_QP_CR_RES_STATE) << 8; 25692c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann cb0->qp_ctl_reg &= ~H_QP_CR_ENABLED; 25702c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 25712c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann hret = ehea_h_modify_ehea_qp(adapter->handle, 0, qp->fw_handle, 25722c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 25732c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 1), cb0, &dummy64, 25742c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann &dummy64, &dummy16, &dummy16); 25752c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (hret != H_SUCCESS) { 25768c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("modify_ehea_qp failed (1)\n"); 25772c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 25782c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 25792c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 25802c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, 25812c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), 25822c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann cb0); 25832c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (hret != H_SUCCESS) { 25848c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("query_ehea_qp failed (2)\n"); 25852c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 25862c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 25872c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 25882c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann /* deregister shared memory regions */ 25892c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann dret = ehea_rem_smrs(pr); 25902c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (dret) { 25918c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("unreg shared memory region failed\n"); 25922c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 25932c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 25942c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 25952c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 25962c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ret = 0; 25972c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themannout: 25983faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb0); 25992c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26002c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann return ret; 26012c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann} 26022c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26031886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic void ehea_update_rqs(struct ehea_qp *orig_qp, struct ehea_port_res *pr) 26042c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann{ 26052c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_qp qp = *orig_qp; 26062c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_qp_init_attr *init_attr = &qp.init_attr; 26072c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_rwqe *rwqe; 26082c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct sk_buff **skba_rq2 = pr->rq2_skba.arr; 26092c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct sk_buff **skba_rq3 = pr->rq3_skba.arr; 26102c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct sk_buff *skb; 26112c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann u32 lkey = pr->recv_mr.lkey; 26122c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26132c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26142c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int i; 26152c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int index; 26162c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26172c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann for (i = 0; i < init_attr->act_nr_rwqes_rq2 + 1; i++) { 26182c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann rwqe = ehea_get_next_rwqe(&qp, 2); 26192c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann rwqe->sg_list[0].l_key = lkey; 26202c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, rwqe->wr_id); 26212c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann skb = skba_rq2[index]; 26222c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (skb) 26232c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann rwqe->sg_list[0].vaddr = ehea_map_vaddr(skb->data); 26242c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 26252c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26262c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann for (i = 0; i < init_attr->act_nr_rwqes_rq3 + 1; i++) { 26272c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann rwqe = ehea_get_next_rwqe(&qp, 3); 26282c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann rwqe->sg_list[0].l_key = lkey; 26292c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, rwqe->wr_id); 26302c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann skb = skba_rq3[index]; 26312c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (skb) 26322c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann rwqe->sg_list[0].vaddr = ehea_map_vaddr(skb->data); 26332c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 26342c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann} 26352c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26361886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic int ehea_restart_qps(struct net_device *dev) 26372c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann{ 26382c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 26392c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_adapter *adapter = port->adapter; 26402c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int ret = 0; 26412c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann int i; 26422c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 2643508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey struct hcp_modify_qp_cb0 *cb0; 26442c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann u64 hret; 26452c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann u64 dummy64 = 0; 26462c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann u16 dummy16 = 0; 26472c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26483faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb0 = (void *)get_zeroed_page(GFP_KERNEL); 26492c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (!cb0) { 26502c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ret = -ENOMEM; 26512c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 26522c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 26532c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 2654723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard for (i = 0; i < (port->num_def_qps); i++) { 26552c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_port_res *pr = &port->port_res[i]; 26562c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann struct ehea_qp *qp = pr->qp; 26572c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26582c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ret = ehea_gen_smrs(pr); 26592c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (ret) { 26608c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "creation of shared memory regions failed\n"); 26612c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 26622c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 26632c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26642c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ehea_update_rqs(qp, pr); 26652c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26662c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann /* Enable queue pair */ 26672c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, 26682c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), 26692c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann cb0); 26702c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (hret != H_SUCCESS) { 26718c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "query_ehea_qp failed (1)\n"); 26722c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 26732c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 26742c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26752c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann cb0->qp_ctl_reg = (cb0->qp_ctl_reg & H_QP_CR_RES_STATE) << 8; 26762c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann cb0->qp_ctl_reg |= H_QP_CR_ENABLED; 26772c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26782c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann hret = ehea_h_modify_ehea_qp(adapter->handle, 0, qp->fw_handle, 26792c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG, 26802c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 1), cb0, &dummy64, 26812c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann &dummy64, &dummy16, &dummy16); 26822c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (hret != H_SUCCESS) { 26838c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "modify_ehea_qp failed (1)\n"); 26842c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 26852c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 26862c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26872c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle, 26882c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF), 26892c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann cb0); 26902c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (hret != H_SUCCESS) { 26918c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "query_ehea_qp failed (2)\n"); 26922c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann goto out; 26932c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 26942c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 26952c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann /* refill entire queue */ 26962c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ehea_refill_rq1(pr, pr->rq1_skba.index, 0); 26972c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ehea_refill_rq2(pr, 0); 26982c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ehea_refill_rq3(pr, 0); 26992c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann } 27002c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themannout: 27013faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb0); 27022c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 27032c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann return ret; 27042c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann} 27052c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 2706c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howellsstatic void ehea_reset_port(struct work_struct *work) 27077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 27087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 2709c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells struct ehea_port *port = 2710c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells container_of(work, struct ehea_port, reset_task); 2711c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells struct net_device *dev = port->netdev; 27127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2713099473c16bac7b936994bc95b5fd96f36397e1adJan-Bernd Themann mutex_lock(&dlpar_mem_lock); 27147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann port->resets++; 2715a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_lock(&port->port_lock); 2716b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_disable(dev); 2717bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger 2718bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger port_napi_disable(port); 27197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 272044c821525778c5d2e81da293195d5d589e8ad845Thomas Klein ehea_down(dev); 27217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 27227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_up(dev); 272344c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (ret) 27247a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 27257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 27262c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ehea_set_multicast_list(dev); 27272c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann 27288c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netif_info(port, timer, dev, "reset successful\n"); 27297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 2730bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger port_napi_enable(port); 2731bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger 2732b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_wake_all_queues(dev); 27337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 2734a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_unlock(&port->port_lock); 2735099473c16bac7b936994bc95b5fd96f36397e1adJan-Bernd Themann mutex_unlock(&dlpar_mem_lock); 27367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 27377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 27383d6b892bcc4c810071e36d8aff25aa171f55f93dTejun Heostatic void ehea_rereg_mrs(void) 273944c821525778c5d2e81da293195d5d589e8ad845Thomas Klein{ 274044c821525778c5d2e81da293195d5d589e8ad845Thomas Klein int ret, i; 274144c821525778c5d2e81da293195d5d589e8ad845Thomas Klein struct ehea_adapter *adapter; 274244c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 27438c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("LPAR memory changed - re-initializing driver\n"); 274444c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 274544c821525778c5d2e81da293195d5d589e8ad845Thomas Klein list_for_each_entry(adapter, &adapter_list, list) 274644c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (adapter->active_ports) { 274744c821525778c5d2e81da293195d5d589e8ad845Thomas Klein /* Shutdown all ports */ 274844c821525778c5d2e81da293195d5d589e8ad845Thomas Klein for (i = 0; i < EHEA_MAX_PORTS; i++) { 274944c821525778c5d2e81da293195d5d589e8ad845Thomas Klein struct ehea_port *port = adapter->port[i]; 2750a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker struct net_device *dev; 275144c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 2752a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker if (!port) 2753a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker continue; 275444c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 2755a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker dev = port->netdev; 2756a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker 2757a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker if (dev->flags & IFF_UP) { 2758a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_lock(&port->port_lock); 2759b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_disable(dev); 2760df39e8ba56a788733d369068c7319e04b1da3cd5David S. Miller ehea_flush_sq(port); 2761a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker ret = ehea_stop_qps(dev); 2762a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker if (ret) { 2763a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_unlock(&port->port_lock); 2764a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker goto out; 276544c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 2766a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker port_napi_disable(port); 2767a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_unlock(&port->port_lock); 276844c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 27692928db4c3c62552d3caf9ab53ccc6f7ae9865a23Andre Detsch reset_sq_restart_flag(port); 277044c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 277144c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 277244c821525778c5d2e81da293195d5d589e8ad845Thomas Klein /* Unregister old memory region */ 277344c821525778c5d2e81da293195d5d589e8ad845Thomas Klein ret = ehea_rem_mr(&adapter->mr); 277444c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (ret) { 27758c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("unregister MR failed - driver inoperable!\n"); 277644c821525778c5d2e81da293195d5d589e8ad845Thomas Klein goto out; 277744c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 277844c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 277944c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 278044c821525778c5d2e81da293195d5d589e8ad845Thomas Klein clear_bit(__EHEA_STOP_XFER, &ehea_driver_flags); 278144c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 278244c821525778c5d2e81da293195d5d589e8ad845Thomas Klein list_for_each_entry(adapter, &adapter_list, list) 278344c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (adapter->active_ports) { 278444c821525778c5d2e81da293195d5d589e8ad845Thomas Klein /* Register new memory region */ 278544c821525778c5d2e81da293195d5d589e8ad845Thomas Klein ret = ehea_reg_kernel_mr(adapter, &adapter->mr); 278644c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (ret) { 27878c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("register MR failed - driver inoperable!\n"); 278844c821525778c5d2e81da293195d5d589e8ad845Thomas Klein goto out; 278944c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 279044c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 279144c821525778c5d2e81da293195d5d589e8ad845Thomas Klein /* Restart all ports */ 279244c821525778c5d2e81da293195d5d589e8ad845Thomas Klein for (i = 0; i < EHEA_MAX_PORTS; i++) { 279344c821525778c5d2e81da293195d5d589e8ad845Thomas Klein struct ehea_port *port = adapter->port[i]; 279444c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 279544c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (port) { 279644c821525778c5d2e81da293195d5d589e8ad845Thomas Klein struct net_device *dev = port->netdev; 279744c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 279844c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (dev->flags & IFF_UP) { 2799a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_lock(&port->port_lock); 28002c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann ret = ehea_restart_qps(dev); 28016f4d6dc167a001267eeff18bdea0ce3e9108c662Breno Leitao if (!ret) { 28026f4d6dc167a001267eeff18bdea0ce3e9108c662Breno Leitao check_sqs(port); 28036f4d6dc167a001267eeff18bdea0ce3e9108c662Breno Leitao port_napi_enable(port); 2804b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_tx_wake_all_queues(dev); 28056f4d6dc167a001267eeff18bdea0ce3e9108c662Breno Leitao } else { 28066f4d6dc167a001267eeff18bdea0ce3e9108c662Breno Leitao netdev_err(dev, "Unable to restart QPS\n"); 28076f4d6dc167a001267eeff18bdea0ce3e9108c662Breno Leitao } 2808a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_unlock(&port->port_lock); 280944c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 281044c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 281144c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 281244c821525778c5d2e81da293195d5d589e8ad845Thomas Klein } 28138c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("re-initializing driver complete\n"); 281444c821525778c5d2e81da293195d5d589e8ad845Thomas Kleinout: 281544c821525778c5d2e81da293195d5d589e8ad845Thomas Klein return; 281644c821525778c5d2e81da293195d5d589e8ad845Thomas Klein} 281744c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 28187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void ehea_tx_watchdog(struct net_device *dev) 28197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 28207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_port *port = netdev_priv(dev); 28217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28222c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann if (netif_carrier_ok(dev) && 28232c69448bbcedebeb8409ddb05fbc7d3fe1cfbda7Jan-Bernd Themann !test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)) 28242f69ae01c83a94af5dc3c20e8135b974687ed004Jan-Bernd Themann ehea_schedule_port_reset(port); 28257a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 28267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28271886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic int ehea_sense_adapter_attr(struct ehea_adapter *adapter) 28287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 28297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct hcp_query_ehea *cb; 28307a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann u64 hret; 28317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 28327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28333faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb = (void *)get_zeroed_page(GFP_KERNEL); 28347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb) { 28357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -ENOMEM; 28367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 28377a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 28387a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann hret = ehea_h_query_ehea(adapter->handle, cb); 28407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28417a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (hret != H_SUCCESS) { 28427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EIO; 28437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_herr; 28447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 28457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann adapter->max_mc_mac = cb->max_mc_mac - 1; 28477a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = 0; 28487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_herr: 28503faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb); 28517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 28527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 28537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 28547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28551886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo) 28567a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 28577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct hcp_ehea_port_cb4 *cb4; 28581acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann u64 hret; 28591acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann int ret = 0; 28607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28611acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann *jumbo = 0; 28627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 28631acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann /* (Try to) enable *jumbo frames */ 28643faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein cb4 = (void *)get_zeroed_page(GFP_KERNEL); 28657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!cb4) { 28668c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for cb4\n"); 28671acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ret = -ENOMEM; 28681acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann goto out; 28697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } else { 28701acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann hret = ehea_h_query_ehea_port(port->adapter->handle, 28719c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein port->logical_port_id, 28729c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein H_PORT_CB4, 28739c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein H_PORT_CB4_JUMBO, cb4); 28749c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein if (hret == H_SUCCESS) { 28759c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein if (cb4->jumbo_frame) 28761acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann *jumbo = 1; 28779c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein else { 28789c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein cb4->jumbo_frame = 1; 28791acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann hret = ehea_h_modify_ehea_port(port->adapter-> 28801acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann handle, 28819c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein port-> 28821acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann logical_port_id, 28839c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein H_PORT_CB4, 28849c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein H_PORT_CB4_JUMBO, 28859c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein cb4); 28869c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein if (hret == H_SUCCESS) 28871acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann *jumbo = 1; 28889c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein } 28891acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } else 28901acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ret = -EINVAL; 28911acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 28923faf2693bd6800c2521799f6a9ae174d9f080ed2Thomas Klein free_page((unsigned long)cb4); 28937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 28941acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannout: 28951acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return ret; 28961acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 28971acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 28981acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic ssize_t ehea_show_port_id(struct device *dev, 28991acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_attribute *attr, char *buf) 29001acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 29011acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev); 2902a8e34fda798861d0f3f12c2739c1bec258be8bedJan-Bernd Themann return sprintf(buf, "%d", port->logical_port_id); 29031acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 29041acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29051acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id, 29061acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann NULL); 29071acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29081acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic void __devinit logical_port_release(struct device *dev) 29091acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 29101acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev); 291161c7a080a5a061c976988fd4b844dfb468dda255Grant Likely of_node_put(port->ofdev.dev.of_node); 29121acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 29131acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29141acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic struct device *ehea_register_port(struct ehea_port *port, 29151acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_node *dn) 29161acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 29171acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann int ret; 29181acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 291961c7a080a5a061c976988fd4b844dfb468dda255Grant Likely port->ofdev.dev.of_node = of_node_get(dn); 29206b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes port->ofdev.dev.parent = &port->adapter->ofdev->dev; 2921d1dea38d54311f6b3dd37ce485e794bd133e3593Thomas Klein port->ofdev.dev.bus = &ibmebus_bus_type; 29221acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 2923db1d7bf70f42124f73675fca62fe32f3ab1111b4Kay Sievers dev_set_name(&port->ofdev.dev, "port%d", port_name_cnt++); 29241acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port->ofdev.dev.release = logical_port_release; 29251acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29261acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ret = of_device_register(&port->ofdev); 29271acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (ret) { 29288c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("failed to register device. ret=%d\n", ret); 29291acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann goto out; 29301acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } 29311acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29321acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id); 2933d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann if (ret) { 29348c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("failed to register attributes, ret=%d\n", ret); 29351acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann goto out_unreg_of_dev; 29361acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } 2937e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann 29381acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return &port->ofdev.dev; 29391acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29401acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannout_unreg_of_dev: 29411acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann of_device_unregister(&port->ofdev); 29421acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannout: 29431acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return NULL; 29441acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 29451acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29461acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic void ehea_unregister_port(struct ehea_port *port) 29471acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 29481acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann device_remove_file(&port->ofdev.dev, &dev_attr_log_port_id); 29491acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann of_device_unregister(&port->ofdev); 29501acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 29511acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 2952086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Kleinstatic const struct net_device_ops ehea_netdev_ops = { 2953086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein .ndo_open = ehea_open, 2954086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein .ndo_stop = ehea_stop, 2955086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein .ndo_start_xmit = ehea_start_xmit, 2956086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein#ifdef CONFIG_NET_POLL_CONTROLLER 2957086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein .ndo_poll_controller = ehea_netpoll, 2958086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein#endif 2959239c562c94dcdd2aeb3d0c0e604627dec043183eAnton Blanchard .ndo_get_stats64 = ehea_get_stats64, 2960086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein .ndo_set_mac_address = ehea_set_mac_addr, 2961240c102d9c54fee7fdc87a4ef2fabc7eb539e00aBen Hutchings .ndo_validate_addr = eth_validate_addr, 2962afc4b13df143122f99a0eb10bfefb216c2806de0Jiri Pirko .ndo_set_rx_mode = ehea_set_multicast_list, 2963086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein .ndo_change_mtu = ehea_change_mtu, 2964086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein .ndo_vlan_rx_add_vid = ehea_vlan_rx_add_vid, 296532e8f9a8d9bd52b59b512f8e5177b08e8edfd58bAlexander Beregalov .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid, 296632e8f9a8d9bd52b59b512f8e5177b08e8edfd58bAlexander Beregalov .ndo_tx_timeout = ehea_tx_watchdog, 2967086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein}; 2968086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein 29691886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, 29701acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann u32 logical_port_id, 29711acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_node *dn) 29721acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 29731acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann int ret; 29741acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct net_device *dev; 29751acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct ehea_port *port; 29761acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device *port_dev; 29771acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann int jumbo; 29781acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29791acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann /* allocate memory for the port structures */ 2980b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard dev = alloc_etherdev_mq(sizeof(struct ehea_port), EHEA_MAX_PORT_RES); 29811acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29821acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (!dev) { 29838c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("no mem for net_device\n"); 29841acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ret = -ENOMEM; 29851acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann goto out_err; 29861acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } 29871acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29881acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port = netdev_priv(dev); 29891acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 2990a5af6ad3a0d4f5c6d0a3535d46fc1b26eeff0816Daniel Walker mutex_init(&port->port_lock); 29911acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port->state = EHEA_PORT_DOWN; 29921acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port->sig_comp_iv = sq_entries / 10; 29931acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29941acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port->adapter = adapter; 29951acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port->netdev = dev; 29961acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port->logical_port_id = logical_port_id; 29971acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 29981acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port->msg_enable = netif_msg_init(msg_level, EHEA_MSG_DEFAULT); 29991acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 30001acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port->mc_list = kzalloc(sizeof(struct ehea_mc_list), GFP_KERNEL); 30011acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (!port->mc_list) { 30021acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ret = -ENOMEM; 30031acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann goto out_free_ethdev; 30041acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } 30051acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 30061acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann INIT_LIST_HEAD(&port->mc_list->list); 30071acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 30081acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ret = ehea_sense_port_attr(port); 30091acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (ret) 30101acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann goto out_free_mc_list; 30111acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 3012b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard netif_set_real_num_rx_queues(dev, port->num_def_qps); 3013723f28e49c9f8578b418dfd1ec8c7b9cc13e2b63Anton Blanchard netif_set_real_num_tx_queues(dev, port->num_def_qps); 3014b95644685d530de5e9f9658bd8087e50840b831dAnton Blanchard 30151acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port_dev = ehea_register_port(port, dn); 30161acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (!port_dev) 30171acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann goto out_free_mc_list; 30181acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 30191acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann SET_NETDEV_DEV(dev, port_dev); 30207a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 30217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* initialize net_device structure */ 30227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann memcpy(dev->dev_addr, &port->mac_addr, ETH_ALEN); 30237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3024086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein dev->netdev_ops = &ehea_netdev_ops; 3025086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein ehea_set_ethtool_ops(dev); 3026086c1b2c52f03d128d1a6db47f8736c56e915043Thomas Klein 3027d695c335f9165cb73f9389479cce755e8207b5f4Anton Blanchard dev->hw_features = NETIF_F_SG | NETIF_F_TSO 3028f4786a96252b97f6f05cd42ea7fe6e967048bfa3Michał Mirosław | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_LRO; 30297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO 3030dc01c447123b489af7b4d0c58a15abcec36a40e6Thomas Klein | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX 30317a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER 30323f7947b9f069c125ffdedc75ac9c4e3101fc2c6aAnton Blanchard | NETIF_F_RXCSUM; 3033076f203258c5b8f07226ba41c4643d958785bb07Anton Blanchard dev->vlan_features = NETIF_F_SG | NETIF_F_TSO | NETIF_F_HIGHDMA | 3034076f203258c5b8f07226ba41c4643d958785bb07Anton Blanchard NETIF_F_IP_CSUM; 30357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; 30367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3037c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells INIT_WORK(&port->reset_task, ehea_reset_port); 30382aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com INIT_DELAYED_WORK(&port->stats_work, ehea_update_stats); 30397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 304021ccc7936dac5ca9b3e2838bbc112a60f34e18b3Anton Blanchard init_waitqueue_head(&port->swqe_avail_wq); 304121ccc7936dac5ca9b3e2838bbc112a60f34e18b3Anton Blanchard init_waitqueue_head(&port->restart_wq); 304221ccc7936dac5ca9b3e2838bbc112a60f34e18b3Anton Blanchard 30432aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com memset(&port->stats, 0, sizeof(struct net_device_stats)); 30447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = register_netdev(dev); 30457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 30468c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("register_netdev failed. ret=%d\n", ret); 304721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein goto out_unreg_port; 30487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 30497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 30501acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ret = ehea_get_jumboframe_status(port, &jumbo); 3051e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann if (ret) 30528c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_err(dev, "failed determining jumbo frame status\n"); 30531acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 30548c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(dev, "Jumbo frames are %sabled\n", 30558c4877a4128e7931077b024a891a4b284d8756a3Joe Perches jumbo == 1 ? "en" : "dis"); 30569c750b7d14301b710c13247f7cc28abd614d9f5cThomas Klein 305744c821525778c5d2e81da293195d5d589e8ad845Thomas Klein adapter->active_ports++; 305844c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 30591acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return port; 30607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 30611acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannout_unreg_port: 30621acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ehea_unregister_port(port); 30631acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 30641acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannout_free_mc_list: 30657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann kfree(port->mc_list); 30661acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 30671acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannout_free_ethdev: 30681acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann free_netdev(dev); 30691acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 30701acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannout_err: 30718c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("setting up logical port with id=%d failed, ret=%d\n", 30728c4877a4128e7931077b024a891a4b284d8756a3Joe Perches logical_port_id, ret); 30731acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return NULL; 30741acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 30751acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 30761acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic void ehea_shutdown_single_port(struct ehea_port *port) 30771acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 30787fb1c2ac8ecaf0883f2fcb38dfc9ec2d15cee11dBrian King struct ehea_adapter *adapter = port->adapter; 3079f5c35cc191afd08d660e6db0fecc9f431dc8f273Tejun Heo 3080f5c35cc191afd08d660e6db0fecc9f431dc8f273Tejun Heo cancel_work_sync(&port->reset_task); 30812aefcad8666e0c7c1aff51c0dacc164a1b681895brenohl@br.ibm.com cancel_delayed_work_sync(&port->stats_work); 30821acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann unregister_netdev(port->netdev); 30831acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ehea_unregister_port(port); 30841acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann kfree(port->mc_list); 30851acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann free_netdev(port->netdev); 30867fb1c2ac8ecaf0883f2fcb38dfc9ec2d15cee11dBrian King adapter->active_ports--; 30877a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 30887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 30897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int ehea_setup_ports(struct ehea_adapter *adapter) 30907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 30911acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_node *lhea_dn; 30921acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_node *eth_dn = NULL; 3093d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann 30949f9a3b8a06b7965335bfe5162c1a50e4d9c3859bStephen Rothwell const u32 *dn_log_port_id; 30951acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann int i = 0; 30961acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 309761c7a080a5a061c976988fd4b844dfb468dda255Grant Likely lhea_dn = adapter->ofdev->dev.of_node; 30981eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { 3099e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann 310040cd3a4564ed6b7bc0279430120ca0e9b83cf486Stephen Rothwell dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", 3101d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann NULL); 31021acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (!dn_log_port_id) { 31038c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("bad device node: eth_dn name=%s\n", 31048c4877a4128e7931077b024a891a4b284d8756a3Joe Perches eth_dn->full_name); 31051acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann continue; 31061acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } 31077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 31081211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein if (ehea_add_adapter_mr(adapter)) { 31098c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("creating MR failed\n"); 31101211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein of_node_put(eth_dn); 31111211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein return -EIO; 31121211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein } 31131211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein 31141acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann adapter->port[i] = ehea_setup_single_port(adapter, 31151acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann *dn_log_port_id, 31161acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann eth_dn); 31177a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (adapter->port[i]) 31188c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(adapter->port[i]->netdev, 31198c4877a4128e7931077b024a891a4b284d8756a3Joe Perches "logical port id #%d\n", *dn_log_port_id); 31201211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein else 31211211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein ehea_remove_adapter_mr(adapter); 31221211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein 31231acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann i++; 3124ee289b6440c3b0ccb9459495783e8c299bec6604Joe Perches } 31251211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein return 0; 31261acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 31271acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 3128e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themannstatic struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, 3129e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann u32 logical_port_id) 31301acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 31311acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_node *lhea_dn; 31321acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_node *eth_dn = NULL; 31339f9a3b8a06b7965335bfe5162c1a50e4d9c3859bStephen Rothwell const u32 *dn_log_port_id; 31341acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 313561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely lhea_dn = adapter->ofdev->dev.of_node; 31361eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { 3137e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann 313840cd3a4564ed6b7bc0279430120ca0e9b83cf486Stephen Rothwell dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", 3139d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann NULL); 31401acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (dn_log_port_id) 31411acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (*dn_log_port_id == logical_port_id) 31421acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return eth_dn; 3143ee289b6440c3b0ccb9459495783e8c299bec6604Joe Perches } 31441acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 31451acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return NULL; 31461acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 31471acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 31481acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic ssize_t ehea_probe_port(struct device *dev, 31491acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_attribute *attr, 31501acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann const char *buf, size_t count) 31511acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 3152c7ae011dc8306d982c25fb4f679752e790a08dc4Greg Kroah-Hartman struct ehea_adapter *adapter = dev_get_drvdata(dev); 31531acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct ehea_port *port; 31541acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_node *eth_dn = NULL; 31551acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann int i; 31561acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 31571acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann u32 logical_port_id; 31581acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 3159a8e34fda798861d0f3f12c2739c1bec258be8bedJan-Bernd Themann sscanf(buf, "%d", &logical_port_id); 31601acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 31611acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port = ehea_get_port(adapter, logical_port_id); 31621acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 31631acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (port) { 31648c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(port->netdev, "adding port with logical port id=%d failed: port already configured\n", 31658c4877a4128e7931077b024a891a4b284d8756a3Joe Perches logical_port_id); 31661acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return -EINVAL; 31677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 3168e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann 31691acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann eth_dn = ehea_get_eth_dn(adapter, logical_port_id); 31707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 31711acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (!eth_dn) { 31728c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("no logical port with id %d found\n", logical_port_id); 31731acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return -EINVAL; 31741acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } 3175e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann 31761211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein if (ehea_add_adapter_mr(adapter)) { 31778c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("creating MR failed\n"); 31781211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein return -EIO; 31791211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein } 31801211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein 31811acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port = ehea_setup_single_port(adapter, logical_port_id, eth_dn); 31827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 31831eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann of_node_put(eth_dn); 31841eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann 31851acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (port) { 3186508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey for (i = 0; i < EHEA_MAX_PORTS; i++) 31871acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (!adapter->port[i]) { 31881acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann adapter->port[i] = port; 31891acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann break; 31901acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } 31917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 31928c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(port->netdev, "added: (logical port id=%d)\n", 31938c4877a4128e7931077b024a891a4b284d8756a3Joe Perches logical_port_id); 31941211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein } else { 31951211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein ehea_remove_adapter_mr(adapter); 3196e542aa6bd50ba163253e60ba8e7e51c0d56162a7Jan-Bernd Themann return -EIO; 31971211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein } 31987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 31991acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return (ssize_t) count; 32001acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 32011acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 32021acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic ssize_t ehea_remove_port(struct device *dev, 32031acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct device_attribute *attr, 32041acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann const char *buf, size_t count) 32051acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 3206c7ae011dc8306d982c25fb4f679752e790a08dc4Greg Kroah-Hartman struct ehea_adapter *adapter = dev_get_drvdata(dev); 32071acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann struct ehea_port *port; 32081acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann int i; 32091acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann u32 logical_port_id; 32101acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 3211a8e34fda798861d0f3f12c2739c1bec258be8bedJan-Bernd Themann sscanf(buf, "%d", &logical_port_id); 32121acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 32131acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann port = ehea_get_port(adapter, logical_port_id); 32141acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 32151acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (port) { 32168c4877a4128e7931077b024a891a4b284d8756a3Joe Perches netdev_info(port->netdev, "removed: (logical port id=%d)\n", 32178c4877a4128e7931077b024a891a4b284d8756a3Joe Perches logical_port_id); 32181acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 32191acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ehea_shutdown_single_port(port); 32201acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 3221508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey for (i = 0; i < EHEA_MAX_PORTS; i++) 32221acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (adapter->port[i] == port) { 32231acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann adapter->port[i] = NULL; 32241acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann break; 32251acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } 32261acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } else { 32278c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("removing port with logical port id=%d failed. port not configured.\n", 32288c4877a4128e7931077b024a891a4b284d8756a3Joe Perches logical_port_id); 32291acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return -EINVAL; 32301acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann } 32311acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 32321211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein ehea_remove_adapter_mr(adapter); 32331211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein 32341acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann return (ssize_t) count; 32351acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 32361acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 32371acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic DEVICE_ATTR(probe_port, S_IWUSR, NULL, ehea_probe_port); 32381acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannstatic DEVICE_ATTR(remove_port, S_IWUSR, NULL, ehea_remove_port); 32391acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 32401886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic int ehea_create_device_sysfs(struct platform_device *dev) 32411acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 32426b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes int ret = device_create_file(&dev->dev, &dev_attr_probe_port); 32431acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann if (ret) 32441acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann goto out; 32451acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 32466b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ret = device_create_file(&dev->dev, &dev_attr_remove_port); 32471acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannout: 32487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 32497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 32507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 32511886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic void ehea_remove_device_sysfs(struct platform_device *dev) 32521acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann{ 32536b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes device_remove_file(&dev->dev, &dev_attr_probe_port); 32546b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes device_remove_file(&dev->dev, &dev_attr_remove_port); 32551acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann} 32561acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 32572dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devinit ehea_probe_adapter(struct platform_device *dev, 32581acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann const struct of_device_id *id) 32597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 32607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann struct ehea_adapter *adapter; 32619f9a3b8a06b7965335bfe5162c1a50e4d9c3859bStephen Rothwell const u64 *adapter_handle; 32627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 32637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 326461c7a080a5a061c976988fd4b844dfb468dda255Grant Likely if (!dev || !dev->dev.of_node) { 32658c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("Invalid ibmebus device probed\n"); 32661eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann return -EINVAL; 32671eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann } 32681eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann 32697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); 32707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!adapter) { 32717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -ENOMEM; 32726b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes dev_err(&dev->dev, "no mem for ehea_adapter\n"); 32737a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 32747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 32757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 327644c821525778c5d2e81da293195d5d589e8ad845Thomas Klein list_add(&adapter->list, &adapter_list); 327744c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 32786b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes adapter->ofdev = dev; 32791acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 328061c7a080a5a061c976988fd4b844dfb468dda255Grant Likely adapter_handle = of_get_property(dev->dev.of_node, "ibm,hea-handle", 3281d1d25aaba85fd24ab18b0a4d22f19be02aac65c9Jan-Bernd Themann NULL); 3282061bf3cdba753ae7b52fba8cc324d81adac77696Thomas Klein if (adapter_handle) 3283061bf3cdba753ae7b52fba8cc324d81adac77696Thomas Klein adapter->handle = *adapter_handle; 3284061bf3cdba753ae7b52fba8cc324d81adac77696Thomas Klein 3285061bf3cdba753ae7b52fba8cc324d81adac77696Thomas Klein if (!adapter->handle) { 32866b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes dev_err(&dev->dev, "failed getting handle for adapter" 328761c7a080a5a061c976988fd4b844dfb468dda255Grant Likely " '%s'\n", dev->dev.of_node->full_name); 32887a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -ENODEV; 32897a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_free_ad; 32907a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 32917a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 32927a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann adapter->pd = EHEA_PD_ID; 32937a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 3294c7ae011dc8306d982c25fb4f679752e790a08dc4Greg Kroah-Hartman dev_set_drvdata(&dev->dev, adapter); 32957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 32967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 32977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* initialize adapter and ports */ 32987a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann /* get adapter properties */ 32997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_sense_adapter_attr(adapter); 33007a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 3301898eb71cb17644964c5895fb190e79e3d0c49679Joe Perches dev_err(&dev->dev, "sense_adapter_attr failed: %d\n", ret); 33021211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein goto out_free_ad; 33037a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 33047a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33057a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann adapter->neq = ehea_create_eq(adapter, 33067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1); 33077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (!adapter->neq) { 33081eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann ret = -EIO; 3309898eb71cb17644964c5895fb190e79e3d0c49679Joe Perches dev_err(&dev->dev, "NEQ creation failed\n"); 33101211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein goto out_free_ad; 33117a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 33127a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33137a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, 33147a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann (unsigned long)adapter); 33157a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33166b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ret = ibmebus_request_irq(adapter->neq->attr.ist1, 331738515e908ba3a9c467ad3bf347b9bce69216df94Thomas Gleixner ehea_interrupt_neq, IRQF_DISABLED, 33187a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann "ehea_neq", adapter); 33197a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 3320898eb71cb17644964c5895fb190e79e3d0c49679Joe Perches dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); 33217a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out_kill_eq; 33227a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 33237a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33241eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann ret = ehea_create_device_sysfs(dev); 33251eef4e04c95fb52a1a3885c8f53a822206fc9aa5Jan-Bernd Themann if (ret) 33263bf76b81608479a10077bd6b55972d40db782067Jan-Bernd Themann goto out_free_irq; 33271acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 33287a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ehea_setup_ports(adapter); 33297a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) { 3330898eb71cb17644964c5895fb190e79e3d0c49679Joe Perches dev_err(&dev->dev, "setup_ports failed\n"); 33311acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann goto out_rem_dev_sysfs; 33327a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 33337a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33347a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = 0; 33357a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 33367a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33371acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themannout_rem_dev_sysfs: 33381acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ehea_remove_device_sysfs(dev); 33391acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 33407a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_free_irq: 33416b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ibmebus_free_irq(adapter->neq->attr.ist1, adapter); 33427a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33437a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_kill_eq: 33447a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_destroy_eq(adapter->neq); 33457a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33467a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout_free_ad: 334751621fbdb1ea8709ab67170b54e71be6d9fa29adHannes Hering list_del(&adapter->list); 33487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann kfree(adapter); 334921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 33507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 335121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_update_firmware_handles(); 335252e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann 33537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 33547a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 33557a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33562dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devexit ehea_remove(struct platform_device *dev) 33577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 3358c7ae011dc8306d982c25fb4f679752e790a08dc4Greg Kroah-Hartman struct ehea_adapter *adapter = dev_get_drvdata(&dev->dev); 33597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int i; 33607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33611acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann for (i = 0; i < EHEA_MAX_PORTS; i++) 33627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (adapter->port[i]) { 33637a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_shutdown_single_port(adapter->port[i]); 33647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann adapter->port[i] = NULL; 33657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 33661acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 33671acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann ehea_remove_device_sysfs(dev); 33681acf2318dd136edfbfa30f1f33b43f69f2e2ec6cJan-Bernd Themann 33696b08f3ae8eec27a9e557468a48540bc64fd4a524Joachim Fenkes ibmebus_free_irq(adapter->neq->attr.ist1, adapter); 3370d4150a2731615de5cd4527a23435aaa7396c63c6Thomas Klein tasklet_kill(&adapter->neq_tasklet); 33717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ehea_destroy_eq(adapter->neq); 33731211bb6dcd935c48e864d4eecbf8a684e982419aThomas Klein ehea_remove_adapter_mr(adapter); 337444c821525778c5d2e81da293195d5d589e8ad845Thomas Klein list_del(&adapter->list); 33757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann kfree(adapter); 337644c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 337721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_update_firmware_handles(); 337821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 33797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return 0; 33807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 33817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 33821886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic void ehea_crash_handler(void) 338321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein{ 338421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int i; 338521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 338621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (ehea_fw_handles.arr) 338721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein for (i = 0; i < ehea_fw_handles.num_entries; i++) 338821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_h_free_resource(ehea_fw_handles.arr[i].adh, 338921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_fw_handles.arr[i].fwh, 339021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein FORCE_FREE); 339121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 339221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (ehea_bcmc_regs.arr) 339321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein for (i = 0; i < ehea_bcmc_regs.num_entries; i++) 339421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_h_reg_dereg_bcmc(ehea_bcmc_regs.arr[i].adh, 339521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_bcmc_regs.arr[i].port_id, 339621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_bcmc_regs.arr[i].reg_type, 339721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ehea_bcmc_regs.arr[i].macaddr, 339821eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 0, H_DEREG_BCMC); 339921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein} 340021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 340148cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Heringstatic int ehea_mem_notifier(struct notifier_block *nb, 340248cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering unsigned long action, void *data) 340348cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering{ 3404a7c561f2e32f98b477f5fe670b3f294be6b1eae2Thomas Klein int ret = NOTIFY_BAD; 3405d4f12daf7ba4efc506c377a9591ecdb692641fe5Hannes Hering struct memory_notify *arg = data; 3406a7c561f2e32f98b477f5fe670b3f294be6b1eae2Thomas Klein 3407099473c16bac7b936994bc95b5fd96f36397e1adJan-Bernd Themann mutex_lock(&dlpar_mem_lock); 3408a7c561f2e32f98b477f5fe670b3f294be6b1eae2Thomas Klein 340948cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering switch (action) { 3410d4f12daf7ba4efc506c377a9591ecdb692641fe5Hannes Hering case MEM_CANCEL_OFFLINE: 34118c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("memory offlining canceled"); 3412d4f12daf7ba4efc506c377a9591ecdb692641fe5Hannes Hering /* Readd canceled memory block */ 3413d4f12daf7ba4efc506c377a9591ecdb692641fe5Hannes Hering case MEM_ONLINE: 34148c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("memory is going online"); 34153876732c12cd2b9896e8c3e86fad142112e93569Thomas Klein set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); 3416d4f12daf7ba4efc506c377a9591ecdb692641fe5Hannes Hering if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) 3417a7c561f2e32f98b477f5fe670b3f294be6b1eae2Thomas Klein goto out_unlock; 34183d6b892bcc4c810071e36d8aff25aa171f55f93dTejun Heo ehea_rereg_mrs(); 3419d4f12daf7ba4efc506c377a9591ecdb692641fe5Hannes Hering break; 3420d4f12daf7ba4efc506c377a9591ecdb692641fe5Hannes Hering case MEM_GOING_OFFLINE: 34218c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("memory is going offline"); 34223876732c12cd2b9896e8c3e86fad142112e93569Thomas Klein set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); 3423d4f12daf7ba4efc506c377a9591ecdb692641fe5Hannes Hering if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) 3424a7c561f2e32f98b477f5fe670b3f294be6b1eae2Thomas Klein goto out_unlock; 34253d6b892bcc4c810071e36d8aff25aa171f55f93dTejun Heo ehea_rereg_mrs(); 342648cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering break; 342748cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering default: 342848cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering break; 342948cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering } 343052e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann 343152e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann ehea_update_firmware_handles(); 3432a7c561f2e32f98b477f5fe670b3f294be6b1eae2Thomas Klein ret = NOTIFY_OK; 343352e21b1bd96444c452f6eab7dc438a8a898aa14aJan-Bernd Themann 3434a7c561f2e32f98b477f5fe670b3f294be6b1eae2Thomas Kleinout_unlock: 3435a7c561f2e32f98b477f5fe670b3f294be6b1eae2Thomas Klein mutex_unlock(&dlpar_mem_lock); 3436a7c561f2e32f98b477f5fe670b3f294be6b1eae2Thomas Klein return ret; 343748cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering} 343848cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering 343948cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Heringstatic struct notifier_block ehea_mem_nb = { 344048cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering .notifier_call = ehea_mem_notifier, 344148cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering}; 344248cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering 34432a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themannstatic int ehea_reboot_notifier(struct notifier_block *nb, 34442a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann unsigned long action, void *unused) 34452a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann{ 34462a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann if (action == SYS_RESTART) { 34478c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("Reboot: freeing all eHEA resources\n"); 34482a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann ibmebus_unregister_driver(&ehea_driver); 34492a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann } 34502a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann return NOTIFY_DONE; 34512a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann} 34522a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann 34532a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themannstatic struct notifier_block ehea_reboot_nb = { 3454508d2b5d261abbd7fb728092c5025c5063060c04Doug Maxey .notifier_call = ehea_reboot_notifier, 34552a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann}; 34562a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann 34577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic int check_module_parm(void) 34587a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 34597a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret = 0; 34607a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 34617a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if ((rq1_entries < EHEA_MIN_ENTRIES_QP) || 34627a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann (rq1_entries > EHEA_MAX_ENTRIES_RQ1)) { 34638c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("Bad parameter: rq1_entries\n"); 34647a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EINVAL; 34657a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 34667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if ((rq2_entries < EHEA_MIN_ENTRIES_QP) || 34677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann (rq2_entries > EHEA_MAX_ENTRIES_RQ2)) { 34688c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("Bad parameter: rq2_entries\n"); 34697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EINVAL; 34707a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 34717a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if ((rq3_entries < EHEA_MIN_ENTRIES_QP) || 34727a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann (rq3_entries > EHEA_MAX_ENTRIES_RQ3)) { 34738c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("Bad parameter: rq3_entries\n"); 34747a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EINVAL; 34757a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 34767a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if ((sq_entries < EHEA_MIN_ENTRIES_QP) || 34777a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann (sq_entries > EHEA_MAX_ENTRIES_SQ)) { 34788c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("Bad parameter: sq_entries\n"); 34797a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = -EINVAL; 34807a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann } 34817a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 34827a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 34837a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 34847a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 34854c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themannstatic ssize_t ehea_show_capabilities(struct device_driver *drv, 34864c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann char *buf) 34874c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann{ 34884c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann return sprintf(buf, "%d", EHEA_CAPABILITIES); 34894c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann} 34904c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann 34914c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themannstatic DRIVER_ATTR(capabilities, S_IRUSR | S_IRGRP | S_IROTH, 34924c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann ehea_show_capabilities, NULL); 34934c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann 34941886e5d2c694e7fb59434c717e704e7fd8475d2eThadeu Lima de Souza Cascardostatic int __init ehea_module_init(void) 34957a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 34967a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann int ret; 34977a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 34988c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("IBM eHEA ethernet device driver (Release %s)\n", DRV_VERSION); 34997a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 350021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles)); 350121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs)); 350221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 35039f71a568f5f1d6c9fb3ca89b6b973475e6475192Daniel Walker mutex_init(&ehea_fw_handles.lock); 35045c2cec143ac54c1960e54bc320fa7d13ac8e0f4aJan-Bernd Themann spin_lock_init(&ehea_bcmc_regs.lock); 350544c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 35067a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = check_module_parm(); 35077a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann if (ret) 35087a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann goto out; 350944c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 351044c821525778c5d2e81da293195d5d589e8ad845Thomas Klein ret = ehea_create_busmap(); 351144c821525778c5d2e81da293195d5d589e8ad845Thomas Klein if (ret) 351244c821525778c5d2e81da293195d5d589e8ad845Thomas Klein goto out; 351344c821525778c5d2e81da293195d5d589e8ad845Thomas Klein 351421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ret = register_reboot_notifier(&ehea_reboot_nb); 351521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (ret) 35168c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("failed registering reboot notifier\n"); 351721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 351848cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering ret = register_memory_notifier(&ehea_mem_nb); 351948cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering if (ret) 35208c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("failed registering memory remove notifier\n"); 352148cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering 3522c061b18df0f1fe3f50fe451dbbdc9ede3c19701aJoe Perches ret = crash_shutdown_register(ehea_crash_handler); 352321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (ret) 35248c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("failed registering crash handler\n"); 35252a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann 35267a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ret = ibmebus_register_driver(&ehea_driver); 35274c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann if (ret) { 35288c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("failed registering eHEA device driver on ebus\n"); 352921eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein goto out2; 35304c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann } 35314c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann 35324c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann ret = driver_create_file(&ehea_driver.driver, 35334c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann &driver_attr_capabilities); 35344c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann if (ret) { 35358c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_err("failed to register capabilities attribute, ret=%d\n", 35368c4877a4128e7931077b024a891a4b284d8756a3Joe Perches ret); 353721eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein goto out3; 35384c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann } 35397a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 354021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein return ret; 354121eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 354221eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Kleinout3: 354321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein ibmebus_unregister_driver(&ehea_driver); 354421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Kleinout2: 354548cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering unregister_memory_notifier(&ehea_mem_nb); 354621eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein unregister_reboot_notifier(&ehea_reboot_nb); 3547c061b18df0f1fe3f50fe451dbbdc9ede3c19701aJoe Perches crash_shutdown_unregister(ehea_crash_handler); 35487a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannout: 35497a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann return ret; 35507a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 35517a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 35527a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannstatic void __exit ehea_module_exit(void) 35537a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann{ 355421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein int ret; 355521eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein 35564c3ca4da8086c3c9fcc81dccc387c34bee6b755eJan-Bernd Themann driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); 35577a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann ibmebus_unregister_driver(&ehea_driver); 35582a6f4e4983918b18fe5d3fb364afe33db7139870Jan-Bernd Themann unregister_reboot_notifier(&ehea_reboot_nb); 3559c061b18df0f1fe3f50fe451dbbdc9ede3c19701aJoe Perches ret = crash_shutdown_unregister(ehea_crash_handler); 356021eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein if (ret) 35618c4877a4128e7931077b024a891a4b284d8756a3Joe Perches pr_info("failed unregistering crash handler\n"); 356248cfb14f8b89d4d5b3df6c16f08b258686fb12adHannes Hering unregister_memory_notifier(&ehea_mem_nb); 356321eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein kfree(ehea_fw_handles.arr); 356421eee2dd1b5702f15924f18f923b2a281f0e72e8Thomas Klein kfree(ehea_bcmc_regs.arr); 356544c821525778c5d2e81da293195d5d589e8ad845Thomas Klein ehea_destroy_busmap(); 35667a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann} 35677a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themann 35687a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannmodule_init(ehea_module_init); 35697a291083225af6e22ffaa46b3d91cfc1a1ccaab4Jan-Bernd Themannmodule_exit(ehea_module_exit); 3570