14d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 2a02d44a02bd2b3f3848f30e335adc3c076b3f905Divy Le Ray * Copyright (c) 2006-2008 Chelsio, Inc. All rights reserved. 34d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * 44d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * This software is available to you under a choice of one of two 54d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * licenses. You may choose to be licensed under the terms of the GNU 64d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * General Public License (GPL) Version 2, available from the file 74d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * COPYING in the main directory of this source tree, or the 84d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * OpenIB.org BSD license below: 94d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * 104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Redistribution and use in source and binary forms, with or 114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * without modification, are permitted provided that the following 124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * conditions are met: 134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * 144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * - Redistributions of source code must retain the above 154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * copyright notice, this list of conditions and the following 164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * disclaimer. 174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * 184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * - Redistributions in binary form must reproduce the above 194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * copyright notice, this list of conditions and the following 204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * disclaimer in the documentation and/or other materials 214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * provided with the distribution. 224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * 234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * SOFTWARE. 314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include <linux/list.h> 345a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include <net/neighbour.h> 364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include <linux/notifier.h> 3760063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h> 384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include <linux/proc_fs.h> 394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include <linux/if_vlan.h> 404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include <net/netevent.h> 414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include <linux/highmem.h> 424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include <linux/vmalloc.h> 43ee40fa0656a730491765545ff7550f3c1ceb0fbcPaul Gortmaker#include <linux/export.h> 444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "common.h" 464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "regs.h" 474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "cxgb3_ioctl.h" 484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "cxgb3_ctl_defs.h" 494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "cxgb3_defs.h" 504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "l2t.h" 514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "firmware_exports.h" 524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "cxgb3_offload.h" 534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic LIST_HEAD(client_list); 554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic LIST_HEAD(ofld_dev_list); 564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic DEFINE_MUTEX(cxgb3_db_lock); 574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic DEFINE_RWLOCK(adapter_list_lock); 594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic LIST_HEAD(adapter_list); 604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic const unsigned int MAX_ATIDS = 64 * 1024; 62c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Raystatic const unsigned int ATID_BASE = 0x10000; 634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 64a5190b4eea1f1c53ee26b3d1176441cafa8e7f79stephen hemmingerstatic void cxgb_neigh_update(struct neighbour *neigh); 65a5190b4eea1f1c53ee26b3d1176441cafa8e7f79stephen hemmingerstatic void cxgb_redirect(struct dst_entry *old, struct dst_entry *new); 66a5190b4eea1f1c53ee26b3d1176441cafa8e7f79stephen hemminger 674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline int offload_activated(struct t3cdev *tdev) 684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray const struct adapter *adapter = tdev2adap(tdev); 704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 71807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet return test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map); 724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/** 754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * cxgb3_register_client - register an offload client 764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * @client: the client 774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * 784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Add the client to the client list, 794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * and call backs the client for each activated offload device 804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_register_client(struct cxgb3_client *client) 824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3cdev *tdev; 844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_lock(&cxgb3_db_lock); 864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_add_tail(&client->client_list, &client_list); 874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (client->add) { 894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_for_each_entry(tdev, &ofld_dev_list, ofld_dev_list) { 904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (offload_activated(tdev)) 914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray client->add(tdev); 924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_unlock(&cxgb3_db_lock); 954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_register_client); 984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/** 1004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * cxgb3_unregister_client - unregister an offload client 1014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * @client: the client 1024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * 1034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Remove the client to the client list, 1044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * and call backs the client for each activated offload device. 1054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 1064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_unregister_client(struct cxgb3_client *client) 1074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 1084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3cdev *tdev; 1094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_lock(&cxgb3_db_lock); 1114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_del(&client->client_list); 1124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (client->remove) { 1144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_for_each_entry(tdev, &ofld_dev_list, ofld_dev_list) { 1154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (offload_activated(tdev)) 1164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray client->remove(tdev); 1174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 1184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 1194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_unlock(&cxgb3_db_lock); 1204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 1214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_unregister_client); 1234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/** 1254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * cxgb3_add_clients - activate registered clients for an offload device 1264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * @tdev: the offload device 1274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * 1284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Call backs all registered clients once a offload device is activated 1294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 1304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_add_clients(struct t3cdev *tdev) 1314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 1324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cxgb3_client *client; 1334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_lock(&cxgb3_db_lock); 1354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_for_each_entry(client, &client_list, client_list) { 1364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (client->add) 1374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray client->add(tdev); 1384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 1394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_unlock(&cxgb3_db_lock); 1404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 1414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/** 1434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * cxgb3_remove_clients - deactivates registered clients 1444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * for an offload device 1454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * @tdev: the offload device 1464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * 1474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Call backs all registered clients once a offload device is deactivated 1484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 1494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_remove_clients(struct t3cdev *tdev) 1504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 1514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cxgb3_client *client; 1524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_lock(&cxgb3_db_lock); 1544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_for_each_entry(client, &client_list, client_list) { 1554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (client->remove) 1564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray client->remove(tdev); 1574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 1584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_unlock(&cxgb3_db_lock); 1594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 1604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 161fa0d4c11c4b6eb49708b82b638ceb0761152f46aSteve Wisevoid cxgb3_event_notify(struct t3cdev *tdev, u32 event, u32 port) 162cb0bc205959bf8c60acae9c71f3da0597e756f8eDivy Le Ray{ 163cb0bc205959bf8c60acae9c71f3da0597e756f8eDivy Le Ray struct cxgb3_client *client; 164cb0bc205959bf8c60acae9c71f3da0597e756f8eDivy Le Ray 165cb0bc205959bf8c60acae9c71f3da0597e756f8eDivy Le Ray mutex_lock(&cxgb3_db_lock); 166cb0bc205959bf8c60acae9c71f3da0597e756f8eDivy Le Ray list_for_each_entry(client, &client_list, client_list) { 167fa0d4c11c4b6eb49708b82b638ceb0761152f46aSteve Wise if (client->event_handler) 168fa0d4c11c4b6eb49708b82b638ceb0761152f46aSteve Wise client->event_handler(tdev, event, port); 169cb0bc205959bf8c60acae9c71f3da0597e756f8eDivy Le Ray } 170cb0bc205959bf8c60acae9c71f3da0597e756f8eDivy Le Ray mutex_unlock(&cxgb3_db_lock); 171cb0bc205959bf8c60acae9c71f3da0597e756f8eDivy Le Ray} 172cb0bc205959bf8c60acae9c71f3da0597e756f8eDivy Le Ray 1734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic struct net_device *get_iff_from_mac(struct adapter *adapter, 1744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray const unsigned char *mac, 1754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int vlan) 1764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 1774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int i; 1784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray for_each_port(adapter, i) { 1804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct net_device *dev = adapter->port[i]; 1814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!memcmp(dev->dev_addr, mac, ETH_ALEN)) { 1834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (vlan && vlan != VLAN_VID_MASK) { 184892ef5d85259e193505d553c10237fd5dc9a3d0dJiri Pirko rcu_read_lock(); 185892ef5d85259e193505d553c10237fd5dc9a3d0dJiri Pirko dev = __vlan_find_dev_deep(dev, vlan); 186892ef5d85259e193505d553c10237fd5dc9a3d0dJiri Pirko rcu_read_unlock(); 1871765a575334f1a232c1478accdee5c7d19f4b3e3Jiri Pirko } else if (netif_is_bond_slave(dev)) { 1884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray while (dev->master) 1894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev = dev->master; 1901765a575334f1a232c1478accdee5c7d19f4b3e3Jiri Pirko } 1914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return dev; 1924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 1934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 1944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return NULL; 1954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 1964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req, 1984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray void *data) 1994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 200a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie int i; 2014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int ret = 0; 202a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie unsigned int val = 0; 2034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct ulp_iscsi_info *uiip = data; 2044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 2054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray switch (req) { 2064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case ULP_ISCSI_GET_PARAMS: 2074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray uiip->pdev = adapter->pdev; 2084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray uiip->llimit = t3_read_reg(adapter, A_ULPRX_ISCSI_LLIMIT); 2094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray uiip->ulimit = t3_read_reg(adapter, A_ULPRX_ISCSI_ULIMIT); 2104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray uiip->tagmask = t3_read_reg(adapter, A_ULPRX_ISCSI_TAGMASK); 211a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie 212a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie val = t3_read_reg(adapter, A_ULPRX_ISCSI_PSZ); 213a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie for (i = 0; i < 4; i++, val >>= 8) 214a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie uiip->pgsz_factor[i] = val & 0xFF; 215a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie 216a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie val = t3_read_reg(adapter, A_TP_PARA_REG7); 217a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie uiip->max_txsz = 218a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie uiip->max_rxsz = min((val >> S_PMMAXXFERLEN0)&M_PMMAXXFERLEN0, 219a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie (val >> S_PMMAXXFERLEN1)&M_PMMAXXFERLEN1); 2204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray /* 2214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * On tx, the iscsi pdu has to be <= tx page size and has to 2224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * fit into the Tx PM FIFO. 2234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 224a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie val = min(adapter->params.tp.tx_pg_size, 225a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie t3_read_reg(adapter, A_PM1_TX_CFG) >> 17); 226a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie uiip->max_txsz = min(val, uiip->max_txsz); 227a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie 228a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie /* set MaxRxData to 16224 */ 229a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie val = t3_read_reg(adapter, A_TP_PARA_REG2); 230a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie if ((val >> S_MAXRXDATA) != 0x3f60) { 231a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie val &= (M_RXCOALESCESIZE << S_RXCOALESCESIZE); 232a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie val |= V_MAXRXDATA(0x3f60); 233a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie printk(KERN_INFO 234a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie "%s, iscsi set MaxRxData to 16224 (0x%x).\n", 235a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie adapter->name, val); 236a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie t3_write_reg(adapter, A_TP_PARA_REG2, val); 237a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie } 238a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie 239a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie /* 240a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie * on rx, the iscsi pdu has to be < rx page size and the 241a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie * the max rx data length programmed in TP 242a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie */ 243a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie val = min(adapter->params.tp.rx_pg_size, 244a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie ((t3_read_reg(adapter, A_TP_PARA_REG2)) >> 245a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie S_MAXRXDATA) & M_MAXRXDATA); 246a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie uiip->max_rxsz = min(val, uiip->max_rxsz); 2474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 2484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case ULP_ISCSI_SET_PARAMS: 2494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_write_reg(adapter, A_ULPRX_ISCSI_TAGMASK, uiip->tagmask); 2509439f749441f3a7c2c8ef9e32b698cfe9ed60f48Karen Xie /* program the ddp page sizes */ 251a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie for (i = 0; i < 4; i++) 252a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie val |= (uiip->pgsz_factor[i] & 0xF) << (8 * i); 253a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie if (val && (val != t3_read_reg(adapter, A_ULPRX_ISCSI_PSZ))) { 254a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie printk(KERN_INFO 255a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie "%s, setting iscsi pgsz 0x%x, %u,%u,%u,%u.\n", 256a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie adapter->name, val, uiip->pgsz_factor[0], 257a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie uiip->pgsz_factor[1], uiip->pgsz_factor[2], 258a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie uiip->pgsz_factor[3]); 259a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie t3_write_reg(adapter, A_ULPRX_ISCSI_PSZ, val); 2609439f749441f3a7c2c8ef9e32b698cfe9ed60f48Karen Xie } 2614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 2624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray default: 2634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ret = -EOPNOTSUPP; 2644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 2654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return ret; 2664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 2674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 2684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* Response queue used for RDMA events. */ 2694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define ASYNC_NOTIF_RSPQ 0 2704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 2714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int cxgb_rdma_ctl(struct adapter *adapter, unsigned int req, void *data) 2724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 2734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int ret = 0; 2744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 2754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray switch (req) { 2769265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger case RDMA_GET_PARAMS: { 2779265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger struct rdma_info *rdma = data; 2784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct pci_dev *pdev = adapter->pdev; 2794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 2809265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->udbell_physbase = pci_resource_start(pdev, 2); 2819265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->udbell_len = pci_resource_len(pdev, 2); 2829265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->tpt_base = 2834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_read_reg(adapter, A_ULPTX_TPT_LLIMIT); 2849265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->tpt_top = t3_read_reg(adapter, A_ULPTX_TPT_ULIMIT); 2859265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->pbl_base = 2864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_read_reg(adapter, A_ULPTX_PBL_LLIMIT); 2879265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->pbl_top = t3_read_reg(adapter, A_ULPTX_PBL_ULIMIT); 2889265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->rqt_base = t3_read_reg(adapter, A_ULPRX_RQ_LLIMIT); 2899265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->rqt_top = t3_read_reg(adapter, A_ULPRX_RQ_ULIMIT); 2909265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->kdb_addr = adapter->regs + A_SG_KDOORBELL; 2919265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->pdev = pdev; 2924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 2934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 2944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_CQ_OP:{ 2954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned long flags; 2969265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger struct rdma_cq_op *rdma = data; 2974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 2984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray /* may be called in any context */ 2994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_irqsave(&adapter->sge.reg_lock, flags); 3009265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger ret = t3_sge_cqcntxt_op(adapter, rdma->id, rdma->op, 3019265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->credits); 3024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_irqrestore(&adapter->sge.reg_lock, flags); 3034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 3044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 3054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_GET_MEM:{ 3064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct ch_mem_range *t = data; 3074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct mc7 *mem; 3084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 3094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if ((t->addr & 7) || (t->len & 7)) 3104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return -EINVAL; 3114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (t->mem_id == MEM_CM) 3124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mem = &adapter->cm; 3134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray else if (t->mem_id == MEM_PMRX) 3144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mem = &adapter->pmrx; 3154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray else if (t->mem_id == MEM_PMTX) 3164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mem = &adapter->pmtx; 3174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray else 3184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return -EINVAL; 3194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 3204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ret = 3214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_mc7_bd_read(mem, t->addr / 8, t->len / 8, 3224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray (u64 *) t->buf); 3234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (ret) 3244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return ret; 3254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 3264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 3274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_CQ_SETUP:{ 3289265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger struct rdma_cq_setup *rdma = data; 3294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 3304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_irq(&adapter->sge.reg_lock); 3314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ret = 3329265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger t3_sge_init_cqcntxt(adapter, rdma->id, 3339265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->base_addr, rdma->size, 3344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ASYNC_NOTIF_RSPQ, 3359265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->ovfl_mode, rdma->credits, 3369265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->credit_thres); 3374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_irq(&adapter->sge.reg_lock); 3384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 3394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 3404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_CQ_DISABLE: 3414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_irq(&adapter->sge.reg_lock); 3424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ret = t3_sge_disable_cqcntxt(adapter, *(unsigned int *)data); 3434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_irq(&adapter->sge.reg_lock); 3444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 3454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_CTRL_QP_SETUP:{ 3469265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger struct rdma_ctrlqp_setup *rdma = data; 3474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 3484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_irq(&adapter->sge.reg_lock); 3494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ret = t3_sge_init_ecntxt(adapter, FW_RI_SGEEC_START, 0, 3504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray SGE_CNTXT_RDMA, 3514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ASYNC_NOTIF_RSPQ, 3529265fabf0d4c3d0a52e169d4b9149d52fd91db69Stephen Hemminger rdma->base_addr, rdma->size, 3534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray FW_RI_TID_START, 1, 0); 3544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_irq(&adapter->sge.reg_lock); 3554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 3564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 35714cc180f7b032f8484c1a3d0533b1129ffe307fdSteve Wise case RDMA_GET_MIB: { 35814cc180f7b032f8484c1a3d0533b1129ffe307fdSteve Wise spin_lock(&adapter->stats_lock); 35914cc180f7b032f8484c1a3d0533b1129ffe307fdSteve Wise t3_tp_get_mib_stats(adapter, (struct tp_mib_stats *)data); 36014cc180f7b032f8484c1a3d0533b1129ffe307fdSteve Wise spin_unlock(&adapter->stats_lock); 36114cc180f7b032f8484c1a3d0533b1129ffe307fdSteve Wise break; 36214cc180f7b032f8484c1a3d0533b1129ffe307fdSteve Wise } 3634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray default: 3644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ret = -EOPNOTSUPP; 3654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 3664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return ret; 3674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 3684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 3694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data) 3704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 3714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct adapter *adapter = tdev2adap(tdev); 3724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct tid_range *tid; 3734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct mtutab *mtup; 3744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct iff_mac *iffmacp; 3754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct ddp_params *ddpp; 3764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct adap_ports *ports; 377e22bb45d772b5e5c850a6223c2a3245f520de641Divy Le Ray struct ofld_page_info *rx_page_info; 378e22bb45d772b5e5c850a6223c2a3245f520de641Divy Le Ray struct tp_params *tp = &adapter->params.tp; 3794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int i; 3804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 3814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray switch (req) { 3824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_MAX_OUTSTANDING_WR: 3834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray *(unsigned int *)data = FW_WR_NUM; 3844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 3854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_WR_LEN: 3864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray *(unsigned int *)data = WR_FLITS; 3874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 3884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_TX_MAX_CHUNK: 3894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray *(unsigned int *)data = 1 << 20; /* 1MB */ 3904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 3914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_TID_RANGE: 3924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tid = data; 3934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tid->num = t3_mc5_size(&adapter->mc5) - 3944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray adapter->params.mc5.nroutes - 3954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray adapter->params.mc5.nfilters - adapter->params.mc5.nservers; 3964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tid->base = 0; 3974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 3984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_STID_RANGE: 3994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tid = data; 4004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tid->num = adapter->params.mc5.nservers; 4014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tid->base = t3_mc5_size(&adapter->mc5) - tid->num - 4024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray adapter->params.mc5.nfilters - adapter->params.mc5.nroutes; 4034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 4044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_L2T_CAPACITY: 4054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray *(unsigned int *)data = 2048; 4064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 4074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_MTUS: 4084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mtup = data; 4094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mtup->size = NMTUS; 4104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mtup->mtus = adapter->params.mtus; 4114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 4124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_IFF_FROM_MAC: 4134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray iffmacp = data; 4144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray iffmacp->dev = get_iff_from_mac(adapter, iffmacp->mac_addr, 4154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray iffmacp->vlan_tag & 4164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray VLAN_VID_MASK); 4174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 4184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_DDP_PARAMS: 4194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ddpp = data; 4204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ddpp->llimit = t3_read_reg(adapter, A_ULPRX_TDDP_LLIMIT); 4214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ddpp->ulimit = t3_read_reg(adapter, A_ULPRX_TDDP_ULIMIT); 4224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ddpp->tag_mask = t3_read_reg(adapter, A_ULPRX_TDDP_TAGMASK); 4234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 4244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case GET_PORTS: 4254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ports = data; 4264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ports->nports = adapter->params.nports; 4274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray for_each_port(adapter, i) 4284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ports->lldevs[i] = adapter->port[i]; 4294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 4304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case ULP_ISCSI_GET_PARAMS: 4314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case ULP_ISCSI_SET_PARAMS: 4324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!offload_running(adapter)) 4334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return -EAGAIN; 4344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return cxgb_ulp_iscsi_ctl(adapter, req, data); 4354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_GET_PARAMS: 4364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_CQ_OP: 4374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_CQ_SETUP: 4384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_CQ_DISABLE: 4394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_CTRL_QP_SETUP: 4404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case RDMA_GET_MEM: 44114cc180f7b032f8484c1a3d0533b1129ffe307fdSteve Wise case RDMA_GET_MIB: 4424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!offload_running(adapter)) 4434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return -EAGAIN; 4444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return cxgb_rdma_ctl(adapter, req, data); 445e22bb45d772b5e5c850a6223c2a3245f520de641Divy Le Ray case GET_RX_PAGE_INFO: 446e22bb45d772b5e5c850a6223c2a3245f520de641Divy Le Ray rx_page_info = data; 447e22bb45d772b5e5c850a6223c2a3245f520de641Divy Le Ray rx_page_info->page_size = tp->rx_pg_size; 448e22bb45d772b5e5c850a6223c2a3245f520de641Divy Le Ray rx_page_info->num = tp->rx_num_pgs; 449e22bb45d772b5e5c850a6223c2a3245f520de641Divy Le Ray break; 450a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie case GET_ISCSI_IPV4ADDR: { 451a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie struct iscsi_ipv4addr *p = data; 452a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie struct port_info *pi = netdev_priv(p->dev); 453a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie p->ipv4addr = pi->iscsi_ipv4addr; 454a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie break; 455a109a5b916bc180e14fad0d1e9c37a08c85652c0Karen Xie } 4564d8cd002602987ddc9507b5390800343f820ac92Divy Le Ray case GET_EMBEDDED_INFO: { 4574d8cd002602987ddc9507b5390800343f820ac92Divy Le Ray struct ch_embedded_info *e = data; 4584d8cd002602987ddc9507b5390800343f820ac92Divy Le Ray 4594d8cd002602987ddc9507b5390800343f820ac92Divy Le Ray spin_lock(&adapter->stats_lock); 4604d8cd002602987ddc9507b5390800343f820ac92Divy Le Ray t3_get_fw_version(adapter, &e->fw_vers); 4614d8cd002602987ddc9507b5390800343f820ac92Divy Le Ray t3_get_tp_version(adapter, &e->tp_vers); 4624d8cd002602987ddc9507b5390800343f820ac92Divy Le Ray spin_unlock(&adapter->stats_lock); 4634d8cd002602987ddc9507b5390800343f820ac92Divy Le Ray break; 4644d8cd002602987ddc9507b5390800343f820ac92Divy Le Ray } 4654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray default: 4664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return -EOPNOTSUPP; 4674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 4684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return 0; 4694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 4704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 4714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 4724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Dummy handler for Rx offload packets in case we get an offload packet before 4734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * proper processing is setup. This complains and drops the packet as it isn't 4744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * normal to get offload packets at this stage. 4754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 4764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int rx_offload_blackhole(struct t3cdev *dev, struct sk_buff **skbs, 4774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int n) 4784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 4794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray while (n--) 4804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev_kfree_skb_any(skbs[n]); 4814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return 0; 4824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 4834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 4844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic void dummy_neigh_update(struct t3cdev *dev, struct neighbour *neigh) 4854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 4864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 4874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 4884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_set_dummy_ops(struct t3cdev *dev) 4894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 4904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->recv = rx_offload_blackhole; 4914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->neigh_update = dummy_neigh_update; 4924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 4934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 4944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 4954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Free an active-open TID. 4964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 4974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid *cxgb3_free_atid(struct t3cdev *tdev, int atid) 4984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 4994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; 5004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray union active_open_entry *p = atid2entry(t, atid); 5014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray void *ctx = p->t3c_tid.ctx; 5024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_bh(&t->atid_lock); 5044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray p->next = t->afree; 5054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->afree = p; 5064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->atids_in_use--; 5074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_bh(&t->atid_lock); 5084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return ctx; 5104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 5114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_free_atid); 5134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 5154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Free a server TID and return it to the free pool. 5164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 5174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_free_stid(struct t3cdev *tdev, int stid) 5184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 5194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; 5204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray union listen_entry *p = stid2entry(t, stid); 5214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_bh(&t->stid_lock); 5234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray p->next = t->sfree; 5244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->sfree = p; 5254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->stids_in_use--; 5264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_bh(&t->stid_lock); 5274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 5284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_free_stid); 5304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_insert_tid(struct t3cdev *tdev, struct cxgb3_client *client, 5324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray void *ctx, unsigned int tid) 5334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 5344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; 5354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->tid_tab[tid].client = client; 5374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->tid_tab[tid].ctx = ctx; 5384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray atomic_inc(&t->tids_in_use); 5394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 5404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_insert_tid); 5424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 5444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Populate a TID_RELEASE WR. The skb must be already propely sized. 5454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 5464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline void mk_tid_release(struct sk_buff *skb, unsigned int tid) 5474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 5484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_tid_release *req; 5494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray skb->priority = CPL_PRIORITY_SETUP; 5514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray req = (struct cpl_tid_release *)__skb_put(skb, sizeof(*req)); 5524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); 5534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid)); 5544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 5554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic void t3_process_tid_release_list(struct work_struct *work) 5574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 5584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_data *td = container_of(work, struct t3c_data, 5594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tid_release_task); 5604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct sk_buff *skb; 5614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3cdev *tdev = td->dev; 5622eab17ab880ad8d570d27517e6c9d9fe74adc214Jeff Garzik 5634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_bh(&td->tid_release_lock); 5654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray while (td->tid_release_list) { 5664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *p = td->tid_release_list; 5674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 56843d620c82985b19008d87a437b4cf83f356264f7Joe Perches td->tid_release_list = p->ctx; 5694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_bh(&td->tid_release_lock); 5704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray skb = alloc_skb(sizeof(struct cpl_tid_release), 57274b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray GFP_KERNEL); 57374b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray if (!skb) 57474b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray skb = td->nofail_skb; 57574b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray if (!skb) { 57674b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray spin_lock_bh(&td->tid_release_lock); 57774b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray p->ctx = (void *)td->tid_release_list; 57874b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray td->tid_release_list = (struct t3c_tid_entry *)p; 57974b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray break; 58074b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray } 5814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mk_tid_release(skb, p - td->tid_maps.tid_tab); 5824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray cxgb3_ofld_send(tdev, skb); 5834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray p->ctx = NULL; 58474b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray if (skb == td->nofail_skb) 58574b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray td->nofail_skb = 58674b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray alloc_skb(sizeof(struct cpl_tid_release), 58774b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray GFP_KERNEL); 5884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_bh(&td->tid_release_lock); 5894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 59074b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1; 5914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_bh(&td->tid_release_lock); 59274b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray 59374b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray if (!td->nofail_skb) 59474b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray td->nofail_skb = 59574b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray alloc_skb(sizeof(struct cpl_tid_release), 59674b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray GFP_KERNEL); 5974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 5984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 5994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* use ctx as a next pointer in the tid release list */ 6004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid) 6014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 6024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_data *td = T3C_DATA(tdev); 6034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *p = &td->tid_maps.tid_tab[tid]; 6044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_bh(&td->tid_release_lock); 6064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray p->ctx = (void *)td->tid_release_list; 607606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray p->client = NULL; 6084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray td->tid_release_list = p; 60974b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray if (!p->ctx || td->release_list_incomplete) 6104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray schedule_work(&td->tid_release_task); 6114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_bh(&td->tid_release_lock); 6124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 6134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_queue_tid_release); 6154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 6174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Remove a tid from the TID table. A client may defer processing its last 6184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * CPL message if it is locked at the time it arrives, and while the message 6194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * sits in the client's backlog the TID may be reused for another connection. 6204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * To handle this we atomically switch the TID association if it still points 6214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * to the original client context. 6224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 6234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_remove_tid(struct t3cdev *tdev, void *ctx, unsigned int tid) 6244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 6254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; 6264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray BUG_ON(tid >= t->ntids); 6284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (tdev->type == T3A) 6294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray (void)cmpxchg(&t->tid_tab[tid].ctx, ctx, NULL); 6304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray else { 6314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct sk_buff *skb; 6324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_ATOMIC); 6344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (likely(skb)) { 6354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mk_tid_release(skb, tid); 6364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray cxgb3_ofld_send(tdev, skb); 6374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->tid_tab[tid].ctx = NULL; 6384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } else 6394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray cxgb3_queue_tid_release(tdev, tid); 6404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 6414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray atomic_dec(&t->tids_in_use); 6424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 6434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_remove_tid); 6454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayint cxgb3_alloc_atid(struct t3cdev *tdev, struct cxgb3_client *client, 6474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray void *ctx) 6484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 6494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int atid = -1; 6504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; 6514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_bh(&t->atid_lock); 6539f238486f5438b2e44f760b11fa3a08714c1ddb6Divy Le Ray if (t->afree && 6549f238486f5438b2e44f760b11fa3a08714c1ddb6Divy Le Ray t->atids_in_use + atomic_read(&t->tids_in_use) + MC5_MIN_TIDS <= 6559f238486f5438b2e44f760b11fa3a08714c1ddb6Divy Le Ray t->ntids) { 6564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray union active_open_entry *p = t->afree; 6574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray atid = (p - t->atid_tab) + t->atid_base; 6594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->afree = p->next; 6604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray p->t3c_tid.ctx = ctx; 6614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray p->t3c_tid.client = client; 6624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->atids_in_use++; 6634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 6644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_bh(&t->atid_lock); 6654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return atid; 6664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 6674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_alloc_atid); 6694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayint cxgb3_alloc_stid(struct t3cdev *tdev, struct cxgb3_client *client, 6714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray void *ctx) 6724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 6734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int stid = -1; 6744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct tid_info *t = &(T3C_DATA(tdev))->tid_maps; 6754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_bh(&t->stid_lock); 6774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (t->sfree) { 6784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray union listen_entry *p = t->sfree; 6794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray stid = (p - t->stid_tab) + t->stid_base; 6814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->sfree = p->next; 6824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray p->t3c_tid.ctx = ctx; 6834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray p->t3c_tid.client = client; 6844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->stids_in_use++; 6854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 6864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_unlock_bh(&t->stid_lock); 6874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return stid; 6884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 6894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_alloc_stid); 6914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 6925fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray/* Get the t3cdev associated with a net_device */ 6935fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Raystruct t3cdev *dev2t3cdev(struct net_device *dev) 6945fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray{ 6955fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray const struct port_info *pi = netdev_priv(dev); 6965fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray 6975fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray return (struct t3cdev *)pi->adapter; 6985fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray} 6995fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray 7005fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le RayEXPORT_SYMBOL(dev2t3cdev); 7015fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray 7024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_smt_write_rpl(struct t3cdev *dev, struct sk_buff *skb) 7034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 7044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_smt_write_rpl *rpl = cplhdr(skb); 7054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (rpl->status != CPL_ERR_NONE) 7074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR 7084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray "Unexpected SMT_WRITE_RPL status %u for entry %u\n", 7094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray rpl->status, GET_TID(rpl)); 7104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE; 7124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 7134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_l2t_write_rpl(struct t3cdev *dev, struct sk_buff *skb) 7154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 7164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_l2t_write_rpl *rpl = cplhdr(skb); 7174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (rpl->status != CPL_ERR_NONE) 7194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR 7204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray "Unexpected L2T_WRITE_RPL status %u for entry %u\n", 7214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray rpl->status, GET_TID(rpl)); 7224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE; 7244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 7254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 726b881955b7d045e7486e9af08398242aeb7199f67Divy Le Raystatic int do_rte_write_rpl(struct t3cdev *dev, struct sk_buff *skb) 727b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray{ 728b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray struct cpl_rte_write_rpl *rpl = cplhdr(skb); 729b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray 730b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray if (rpl->status != CPL_ERR_NONE) 731b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray printk(KERN_ERR 732b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray "Unexpected RTE_WRITE_RPL status %u for entry %u\n", 733b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray rpl->status, GET_TID(rpl)); 734b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray 735b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray return CPL_RET_BUF_DONE; 736b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray} 737b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray 7384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_act_open_rpl(struct t3cdev *dev, struct sk_buff *skb) 7394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 7404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_act_open_rpl *rpl = cplhdr(skb); 7414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int atid = G_TID(ntohl(rpl->atid)); 7424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *t3c_tid; 7434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid = lookup_atid(&(T3C_DATA(dev))->tid_maps, atid); 745606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (t3c_tid && t3c_tid->ctx && t3c_tid->client && 746606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray t3c_tid->client->handlers && 7474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid->client->handlers[CPL_ACT_OPEN_RPL]) { 7484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return t3c_tid->client->handlers[CPL_ACT_OPEN_RPL] (dev, skb, 7494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid-> 7504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ctx); 7514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } else { 7524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", 7534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->name, CPL_ACT_OPEN_RPL); 7544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; 7554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 7564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 7574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_stid_rpl(struct t3cdev *dev, struct sk_buff *skb) 7594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 7604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray union opcode_tid *p = cplhdr(skb); 7614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int stid = G_TID(ntohl(p->opcode_tid)); 7624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *t3c_tid; 7634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid = lookup_stid(&(T3C_DATA(dev))->tid_maps, stid); 765606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers && 7664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid->client->handlers[p->opcode]) { 7674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return t3c_tid->client->handlers[p->opcode] (dev, skb, 7684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid->ctx); 7694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } else { 7704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", 7714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->name, p->opcode); 7724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; 7734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 7744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 7754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_hwtid_rpl(struct t3cdev *dev, struct sk_buff *skb) 7774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 7784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray union opcode_tid *p = cplhdr(skb); 7794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int hwtid = G_TID(ntohl(p->opcode_tid)); 7804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *t3c_tid; 7814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid = lookup_tid(&(T3C_DATA(dev))->tid_maps, hwtid); 783606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers && 7844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid->client->handlers[p->opcode]) { 7854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return t3c_tid->client->handlers[p->opcode] 7864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray (dev, skb, t3c_tid->ctx); 7874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } else { 7884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", 7894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->name, p->opcode); 7904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; 7914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 7924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 7934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 7944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_cr(struct t3cdev *dev, struct sk_buff *skb) 7954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 7964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_pass_accept_req *req = cplhdr(skb); 7974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int stid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); 798c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray struct tid_info *t = &(T3C_DATA(dev))->tid_maps; 7994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *t3c_tid; 800c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray unsigned int tid = GET_TID(req); 8014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 802c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray if (unlikely(tid >= t->ntids)) { 803c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray printk("%s: passive open TID %u too large\n", 804c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray dev->name, tid); 805c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray t3_fatal_err(tdev2adap(dev)); 806c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray return CPL_RET_BUF_DONE; 807c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray } 808c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray 809c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray t3c_tid = lookup_stid(t, stid); 810c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers && 8114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ]) { 8124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return t3c_tid->client->handlers[CPL_PASS_ACCEPT_REQ] 8134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray (dev, skb, t3c_tid->ctx); 8144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } else { 8154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", 8164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->name, CPL_PASS_ACCEPT_REQ); 8174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; 8184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 8194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 8204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 821606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray/* 822606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray * Returns an sk_buff for a reply CPL message of size len. If the input 823606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray * sk_buff has no other users it is trimmed and reused, otherwise a new buffer 824606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray * is allocated. The input skb must be of size at least len. Note that this 825606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray * operation does not destroy the original skb data even if it decides to reuse 826606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray * the buffer. 827606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray */ 828606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Raystatic struct sk_buff *cxgb3_get_cpl_reply_skb(struct sk_buff *skb, size_t len, 8291f41bb3a5a24c82900b33071edcedec679b99de7Al Viro gfp_t gfp) 830606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray{ 831606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (likely(!skb_cloned(skb))) { 832606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray BUG_ON(skb->len < len); 833606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray __skb_trim(skb, len); 834606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray skb_get(skb); 835606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray } else { 836606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray skb = alloc_skb(len, gfp); 837606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (skb) 838606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray __skb_put(skb, len); 839606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray } 840606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray return skb; 841606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray} 842606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray 8434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_abort_req_rss(struct t3cdev *dev, struct sk_buff *skb) 8444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 8454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray union opcode_tid *p = cplhdr(skb); 8464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int hwtid = G_TID(ntohl(p->opcode_tid)); 8474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *t3c_tid; 8484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 8494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid = lookup_tid(&(T3C_DATA(dev))->tid_maps, hwtid); 850606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers && 8514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid->client->handlers[p->opcode]) { 8524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return t3c_tid->client->handlers[p->opcode] 8534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray (dev, skb, t3c_tid->ctx); 8544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } else { 8554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_abort_req_rss *req = cplhdr(skb); 8564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_abort_rpl *rpl; 857606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray struct sk_buff *reply_skb; 858606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray unsigned int tid = GET_TID(req); 859606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray u8 cmd = req->status; 860606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray 861606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (req->status == CPL_ERR_RTX_NEG_ADVICE || 862606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray req->status == CPL_ERR_PERSIST_NEG_ADVICE) 863606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray goto out; 8644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 865606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray reply_skb = cxgb3_get_cpl_reply_skb(skb, 866606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray sizeof(struct 867606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray cpl_abort_rpl), 868606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray GFP_ATOMIC); 869606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray 870606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (!reply_skb) { 8714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk("do_abort_req_rss: couldn't get skb!\n"); 8724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray goto out; 8734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 874606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray reply_skb->priority = CPL_PRIORITY_DATA; 875606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray __skb_put(reply_skb, sizeof(struct cpl_abort_rpl)); 876606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray rpl = cplhdr(reply_skb); 8774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray rpl->wr.wr_hi = 8784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL)); 879606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray rpl->wr.wr_lo = htonl(V_WR_TID(tid)); 880606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, tid)); 881606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray rpl->cmd = cmd; 882606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray cxgb3_ofld_send(dev, reply_skb); 8834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayout: 8844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE; 8854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 8864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 8874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 8884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_act_establish(struct t3cdev *dev, struct sk_buff *skb) 8894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 8904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_act_establish *req = cplhdr(skb); 8914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); 892c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray struct tid_info *t = &(T3C_DATA(dev))->tid_maps; 8934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *t3c_tid; 894c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray unsigned int tid = GET_TID(req); 8954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 896c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray if (unlikely(tid >= t->ntids)) { 897c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray printk("%s: active establish TID %u too large\n", 898c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray dev->name, tid); 899c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray t3_fatal_err(tdev2adap(dev)); 900c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray return CPL_RET_BUF_DONE; 901c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray } 902c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray 903c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray t3c_tid = lookup_atid(t, atid); 904606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers && 9054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid->client->handlers[CPL_ACT_ESTABLISH]) { 9064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return t3c_tid->client->handlers[CPL_ACT_ESTABLISH] 9074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray (dev, skb, t3c_tid->ctx); 9084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } else { 9094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", 910c9a6ce500d78932c43361eae28c3de81b3660c77Divy Le Ray dev->name, CPL_ACT_ESTABLISH); 9114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; 9124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 9134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 9144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 9154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_trace(struct t3cdev *dev, struct sk_buff *skb) 9164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 9174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_trace_pkt *p = cplhdr(skb); 9184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 919b53449725a9a436fb9cc2f2ef8579368a704db03Al Viro skb->protocol = htons(0xffff); 9204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray skb->dev = dev->lldev; 9214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray skb_pull(skb, sizeof(*p)); 922459a98ed881802dee55897441bc7f77af614368eArnaldo Carvalho de Melo skb_reset_mac_header(skb); 9234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray netif_receive_skb(skb); 9244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return 0; 9254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 9264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 927fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro/* 928fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro * That skb would better have come from process_responses() where we abuse 929fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro * ->priority and ->csum to carry our data. NB: if we get to per-arch 930fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro * ->csum, the things might get really interesting here. 931fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro */ 932fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro 933fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Virostatic inline u32 get_hwtid(struct sk_buff *skb) 934fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro{ 935fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro return ntohl((__force __be32)skb->priority) >> 8 & 0xfffff; 936fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro} 937fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro 938fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Virostatic inline u32 get_opcode(struct sk_buff *skb) 939fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro{ 940fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro return G_OPCODE(ntohl((__force __be32)skb->csum)); 941fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro} 942fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro 9434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_term(struct t3cdev *dev, struct sk_buff *skb) 9444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 945fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro unsigned int hwtid = get_hwtid(skb); 946fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro unsigned int opcode = get_opcode(skb); 9474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *t3c_tid; 9484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 9494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid = lookup_tid(&(T3C_DATA(dev))->tid_maps, hwtid); 950606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (t3c_tid && t3c_tid->ctx && t3c_tid->client->handlers && 9514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid->client->handlers[opcode]) { 9524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return t3c_tid->client->handlers[opcode] (dev, skb, 9534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3c_tid->ctx); 9544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } else { 9554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "%s: received clientless CPL command 0x%x\n", 9564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->name, opcode); 9574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; 9584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 9594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 9604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 9614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int nb_callback(struct notifier_block *self, unsigned long event, 9624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray void *ctx) 9634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 9644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray switch (event) { 9654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case (NETEVENT_NEIGH_UPDATE):{ 9664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray cxgb_neigh_update((struct neighbour *)ctx); 9674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 9684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 9694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray case (NETEVENT_REDIRECT):{ 9704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct netevent_redirect *nr = ctx; 9714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray cxgb_redirect(nr->old, nr->new); 9722721745501a26d0dc3b88c0d2f3aa11471891388David Miller cxgb_neigh_update(dst_get_neighbour_noref(nr->new)); 9734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 9744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 9754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray default: 9764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray break; 9774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 9784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return 0; 9794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 9804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 9814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic struct notifier_block nb = { 9824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray .notifier_call = nb_callback 9834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}; 9844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 9854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 9864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Process a received packet with an unknown/unexpected CPL opcode. 9874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 9884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int do_bad_cpl(struct t3cdev *dev, struct sk_buff *skb) 9894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 9904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "%s: received bad CPL command 0x%x\n", dev->name, 9914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray *skb->data); 9924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return CPL_RET_BUF_DONE | CPL_RET_BAD_MSG; 9934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 9944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 9954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 9964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Handlers for each CPL opcode 9974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 9984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic cpl_handler_func cpl_handlers[NUM_CPL_CMDS]; 9994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 10014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Add a new handler to the CPL dispatch table. A NULL handler may be supplied 10024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * to unregister an existing handler. 10034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 10044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h) 10054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 10064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (opcode < NUM_CPL_CMDS) 10074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray cpl_handlers[opcode] = h ? h : do_bad_cpl; 10084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray else 10094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "T3C: handler registration for " 10104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray "opcode %x failed\n", opcode); 10114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 10124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(t3_register_cpl_handler); 10144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 10164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * T3CDEV's receive method. 10174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 1018a5190b4eea1f1c53ee26b3d1176441cafa8e7f79stephen hemmingerstatic int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n) 10194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 10204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray while (n--) { 10214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct sk_buff *skb = *skbs++; 1022fa3a6cb4a6feacd712ca58fd1c6e99b33fde5d5dAl Viro unsigned int opcode = get_opcode(skb); 10234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int ret = cpl_handlers[opcode] (dev, skb); 10244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#if VALIDATE_TID 10264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (ret & CPL_RET_UNKNOWN_TID) { 10274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray union opcode_tid *p = cplhdr(skb); 10284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "%s: CPL message (opcode %u) had " 10304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray "unknown TID %u\n", dev->name, opcode, 10314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray G_TID(ntohl(p->opcode_tid))); 10324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 10334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#endif 10344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (ret & CPL_RET_BUF_DONE) 10354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray kfree_skb(skb); 10364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 10374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return 0; 10384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 10394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 10414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Sends an sk_buff to a T3C driver after dealing with any active network taps. 10424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 10434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayint cxgb3_ofld_send(struct t3cdev *dev, struct sk_buff *skb) 10444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 10454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int r; 10464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray local_bh_disable(); 10484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray r = dev->send(dev, skb); 10494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray local_bh_enable(); 10504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return r; 10514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 10524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le RayEXPORT_SYMBOL(cxgb3_ofld_send); 10544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int is_offloading(struct net_device *dev) 10564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 10574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct adapter *adapter; 10584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int i; 10594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray read_lock_bh(&adapter_list_lock); 10614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_for_each_entry(adapter, &adapter_list, adapter_list) { 10624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray for_each_port(adapter, i) { 10634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (dev == adapter->port[i]) { 10644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray read_unlock_bh(&adapter_list_lock); 10654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return 1; 10664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 10674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 10684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 10694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray read_unlock_bh(&adapter_list_lock); 10704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return 0; 10714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 10724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1073a5190b4eea1f1c53ee26b3d1176441cafa8e7f79stephen hemmingerstatic void cxgb_neigh_update(struct neighbour *neigh) 10744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 1075c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller struct net_device *dev; 10764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1077c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller if (!neigh) 1078c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller return; 1079c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller dev = neigh->dev; 10804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (dev && (is_offloading(dev))) { 10815fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray struct t3cdev *tdev = dev2t3cdev(dev); 10824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray BUG_ON(!tdev); 10844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_l2t_update(tdev, neigh); 10854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 10864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 10874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e) 10894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 10904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct sk_buff *skb; 10914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct cpl_set_tcb_field *req; 10924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 10934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray skb = alloc_skb(sizeof(*req), GFP_ATOMIC); 10944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!skb) { 1095b39d66a81fb4f5ab555f86a2e49f3714f8369a3dHarvey Harrison printk(KERN_ERR "%s: cannot allocate skb!\n", __func__); 10964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return; 10974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 10984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray skb->priority = CPL_PRIORITY_CONTROL; 10994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray req = (struct cpl_set_tcb_field *)skb_put(skb, sizeof(*req)); 11004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); 11014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid)); 11024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray req->reply = 0; 11034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray req->cpu_idx = 0; 11044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray req->word = htons(W_TCB_L2T_IX); 11054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray req->mask = cpu_to_be64(V_TCB_L2T_IX(M_TCB_L2T_IX)); 11064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray req->val = cpu_to_be64(V_TCB_L2T_IX(e->idx)); 11074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tdev->send(tdev, skb); 11084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 11094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1110a5190b4eea1f1c53ee26b3d1176441cafa8e7f79stephen hemmingerstatic void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) 11114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 11124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct net_device *olddev, *newdev; 1113c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller struct neighbour *n; 11144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct tid_info *ti; 11154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3cdev *tdev; 11164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray u32 tid; 11174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int update_tcb; 11184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct l2t_entry *e; 11194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_tid_entry *te; 11204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1121c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller n = dst_get_neighbour_noref(old); 1122c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller if (!n) 1123c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller return; 1124c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller olddev = n->dev; 1125c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller 1126c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller n = dst_get_neighbour_noref(new); 1127c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller if (!n) 1128c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller return; 1129c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller newdev = n->dev; 1130c4be62a4d27cf4170c2e0eca5a4f8d6fa84d85e4David Miller 11314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!is_offloading(olddev)) 11324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return; 11334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!is_offloading(newdev)) { 1134f07b2e403b563d42693e02fd17956c31d3aeff1dJoe Perches printk(KERN_WARNING "%s: Redirect to non-offload " 1135b39d66a81fb4f5ab555f86a2e49f3714f8369a3dHarvey Harrison "device ignored.\n", __func__); 11364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return; 11374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 11385fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray tdev = dev2t3cdev(olddev); 11394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray BUG_ON(!tdev); 11405fbf816fe7d72bfdbf22bfec05b4ec3aa6849f72Divy Le Ray if (tdev != dev2t3cdev(newdev)) { 11414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_WARNING "%s: Redirect to different " 1142b39d66a81fb4f5ab555f86a2e49f3714f8369a3dHarvey Harrison "offload device ignored.\n", __func__); 11434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return; 11444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 11454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 11464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray /* Add new L2T entry */ 1147a4757123aeadf450b5b3c5f51f214660e20477f3David Miller e = t3_l2t_get(tdev, new, newdev); 11484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!e) { 11494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n", 1150b39d66a81fb4f5ab555f86a2e49f3714f8369a3dHarvey Harrison __func__); 11514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return; 11524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 11534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 11544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray /* Walk tid table and notify clients of dst change. */ 11554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray ti = &(T3C_DATA(tdev))->tid_maps; 11564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray for (tid = 0; tid < ti->ntids; tid++) { 11574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray te = lookup_tid(ti, tid); 11584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray BUG_ON(!te); 1159606fcd0b94f7531f52a9b07008a4461213cbcd27Divy Le Ray if (te && te->ctx && te->client && te->client->redirect) { 11604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray update_tcb = te->client->redirect(te->ctx, old, new, e); 11614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (update_tcb) { 1162e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman rcu_read_lock(); 11634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray l2t_hold(L2DATA(tdev), e); 1164e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman rcu_read_unlock(); 11654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray set_l2t_ix(tdev, tid, e); 11664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 11674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 11684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 1169e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman l2t_release(tdev, e); 11704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 11714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 11724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 11734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Allocate a chunk of memory using kmalloc or, if that fails, vmalloc. 11744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * The allocated memory is cleared. 11754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 11764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid *cxgb_alloc_mem(unsigned long size) 11774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 117889bf67f1f080c947c92f8773482d9e57767ca292Eric Dumazet void *p = kzalloc(size, GFP_KERNEL); 11794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 11804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!p) 118189bf67f1f080c947c92f8773482d9e57767ca292Eric Dumazet p = vzalloc(size); 11824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return p; 11834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 11844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 11854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 11864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Free memory allocated through t3_alloc_mem(). 11874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 11884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb_free_mem(void *addr) 11894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 11909e2779fa281cfda13ac060753d674bbcaa23367eChristoph Lameter if (is_vmalloc_addr(addr)) 11914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray vfree(addr); 11924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray else 11934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray kfree(addr); 11944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 11954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 11964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* 11974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Allocate and initialize the TID tables. Returns 0 on success. 11984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 11994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int init_tid_tabs(struct tid_info *t, unsigned int ntids, 12004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int natids, unsigned int nstids, 12014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int atid_base, unsigned int stid_base) 12024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 12034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned long size = ntids * sizeof(*t->tid_tab) + 12044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray natids * sizeof(*t->atid_tab) + nstids * sizeof(*t->stid_tab); 12054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->tid_tab = cxgb_alloc_mem(size); 12074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!t->tid_tab) 12084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return -ENOMEM; 12094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->stid_tab = (union listen_entry *)&t->tid_tab[ntids]; 12114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->atid_tab = (union active_open_entry *)&t->stid_tab[nstids]; 12124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->ntids = ntids; 12134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->nstids = nstids; 12144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->stid_base = stid_base; 12154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->sfree = NULL; 12164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->natids = natids; 12174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->atid_base = atid_base; 12184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->afree = NULL; 12194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->stids_in_use = t->atids_in_use = 0; 12204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray atomic_set(&t->tids_in_use, 0); 12214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_init(&t->stid_lock); 12224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_init(&t->atid_lock); 12234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray /* 12254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Setup the free lists for stid_tab and atid_tab. 12264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */ 12274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (nstids) { 12284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray while (--nstids) 12294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->stid_tab[nstids - 1].next = &t->stid_tab[nstids]; 12304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->sfree = t->stid_tab; 12314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 12324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (natids) { 12334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray while (--natids) 12344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->atid_tab[natids - 1].next = &t->atid_tab[natids]; 12354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->afree = t->atid_tab; 12364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray } 12374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return 0; 12384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 12394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic void free_tid_maps(struct tid_info *t) 12414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 12424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray cxgb_free_mem(t->tid_tab); 12434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 12444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline void add_adapter(struct adapter *adap) 12464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 12474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray write_lock_bh(&adapter_list_lock); 12484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_add_tail(&adap->adapter_list, &adapter_list); 12494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray write_unlock_bh(&adapter_list_lock); 12504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 12514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline void remove_adapter(struct adapter *adap) 12534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 12544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray write_lock_bh(&adapter_list_lock); 12554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_del(&adap->adapter_list); 12564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray write_unlock_bh(&adapter_list_lock); 12574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 12584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayint cxgb3_offload_activate(struct adapter *adapter) 12604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 12614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3cdev *dev = &adapter->tdev; 12624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int natids, err; 12634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_data *t; 12644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct tid_range stid_range, tid_range; 12654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct mtutab mtutab; 12664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unsigned int l2t_capacity; 12674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 126875ed0a897208c3273fd8dc0f71e1417dba5a049bJulia Lawall t = kzalloc(sizeof(*t), GFP_KERNEL); 12694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!t) 12704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return -ENOMEM; 12714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray err = -EOPNOTSUPP; 12734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (dev->ctl(dev, GET_TX_MAX_CHUNK, &t->tx_max_chunk) < 0 || 12744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->ctl(dev, GET_MAX_OUTSTANDING_WR, &t->max_wrs) < 0 || 12754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->ctl(dev, GET_L2T_CAPACITY, &l2t_capacity) < 0 || 12764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->ctl(dev, GET_MTUS, &mtutab) < 0 || 12774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->ctl(dev, GET_TID_RANGE, &tid_range) < 0 || 12784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->ctl(dev, GET_STID_RANGE, &stid_range) < 0) 12794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray goto out_free; 12804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray err = -ENOMEM; 1282e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman RCU_INIT_POINTER(dev->l2opt, t3_init_l2t(l2t_capacity)); 12834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (!L2DATA(dev)) 12844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray goto out_free; 12854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray natids = min(tid_range.num / 2, MAX_ATIDS); 12874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray err = init_tid_tabs(&t->tid_maps, tid_range.num, natids, 12884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray stid_range.num, ATID_BASE, stid_range.base); 12894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (err) 12904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray goto out_free_l2t; 12914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->mtus = mtutab.mtus; 12934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->nmtus = mtutab.size; 12944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 12954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray INIT_WORK(&t->tid_release_task, t3_process_tid_release_list); 12964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray spin_lock_init(&t->tid_release_lock); 12974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray INIT_LIST_HEAD(&t->list_node); 12984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t->dev = dev; 12994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray T3C_DATA(dev) = t; 13014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->recv = process_rx; 13024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray dev->neigh_update = t3_l2t_update; 13034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray /* Register netevent handler once */ 13054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (list_empty(&adapter_list)) 13064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray register_netevent_notifier(&nb); 13074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 130874b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL); 130974b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray t->release_list_incomplete = 0; 131074b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray 13114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray add_adapter(adapter); 13124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return 0; 13134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayout_free_l2t: 13154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_free_l2t(L2DATA(dev)); 13162cfa5a0471fef43fda0b7bd87e3a5e4dbadb7809Eric Dumazet RCU_INIT_POINTER(dev->l2opt, NULL); 13174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayout_free: 13184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray kfree(t); 13194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray return err; 13204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 13214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 1322e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Hormanstatic void clean_l2_data(struct rcu_head *head) 1323e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman{ 1324e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman struct l2t_data *d = container_of(head, struct l2t_data, rcu_head); 1325e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman t3_free_l2t(d); 1326e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman} 1327e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman 1328e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman 13294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid cxgb3_offload_deactivate(struct adapter *adapter) 13304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 13314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3cdev *tdev = &adapter->tdev; 13324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3c_data *t = T3C_DATA(tdev); 1333e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman struct l2t_data *d; 13344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray remove_adapter(adapter); 13364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray if (list_empty(&adapter_list)) 13374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unregister_netevent_notifier(&nb); 13384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray free_tid_maps(&t->tid_maps); 13404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray T3C_DATA(tdev) = NULL; 1341e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman rcu_read_lock(); 1342e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman d = L2DATA(tdev); 1343e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman rcu_read_unlock(); 13442cfa5a0471fef43fda0b7bd87e3a5e4dbadb7809Eric Dumazet RCU_INIT_POINTER(tdev->l2opt, NULL); 1345e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman call_rcu(&d->rcu_head, clean_l2_data); 134674b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray if (t->nofail_skb) 134774b793e1ef79edc49bc031a88d62f1e93fc6b30fDivy Le Ray kfree_skb(t->nofail_skb); 13484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray kfree(t); 13494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 13504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline void register_tdev(struct t3cdev *tdev) 13524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 13534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray static int unit; 13544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_lock(&cxgb3_db_lock); 13564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray snprintf(tdev->name, sizeof(tdev->name), "ofld_dev%d", unit++); 13574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_add_tail(&tdev->ofld_dev_list, &ofld_dev_list); 13584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_unlock(&cxgb3_db_lock); 13594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 13604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline void unregister_tdev(struct t3cdev *tdev) 13624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 13634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_lock(&cxgb3_db_lock); 13644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray list_del(&tdev->ofld_dev_list); 13654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray mutex_unlock(&cxgb3_db_lock); 13664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 13674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13688f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Raystatic inline int adap2type(struct adapter *adapter) 13698f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray{ 13708f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray int type = 0; 13718f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray 13728f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray switch (adapter->params.rev) { 13738f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray case T3_REV_A: 13748f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray type = T3A; 13758f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray break; 13768f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray case T3_REV_B: 13778f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray case T3_REV_B2: 13788f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray type = T3B; 13798f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray break; 13808f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray case T3_REV_C: 13818f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray type = T3C; 13828f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray break; 13838f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray } 13848f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray return type; 13858f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray} 13868f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray 13874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid __devinit cxgb3_adapter_ofld(struct adapter *adapter) 13884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 13894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3cdev *tdev = &adapter->tdev; 13904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray INIT_LIST_HEAD(&tdev->ofld_dev_list); 13924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray cxgb3_set_dummy_ops(tdev); 13944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tdev->send = t3_offload_tx; 13954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tdev->ctl = cxgb_offload_ctl; 13968f85cd7fefa3d01c4e05aac1cb198733336cf44bDivy Le Ray tdev->type = adap2type(adapter); 13974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 13984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray register_tdev(tdev); 13994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 14004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 14014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid __devexit cxgb3_adapter_unofld(struct adapter *adapter) 14024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 14034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray struct t3cdev *tdev = &adapter->tdev; 14044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 14054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tdev->recv = NULL; 14064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray tdev->neigh_update = NULL; 14074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 14084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray unregister_tdev(tdev); 14094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 14104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 14114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid __init cxgb3_offload_init(void) 14124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{ 14134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray int i; 14144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 14154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray for (i = 0; i < NUM_CPL_CMDS; ++i) 14164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray cpl_handlers[i] = do_bad_cpl; 14174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray 14184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_SMT_WRITE_RPL, do_smt_write_rpl); 14194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_L2T_WRITE_RPL, do_l2t_write_rpl); 1420b881955b7d045e7486e9af08398242aeb7199f67Divy Le Ray t3_register_cpl_handler(CPL_RTE_WRITE_RPL, do_rte_write_rpl); 14214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_PASS_OPEN_RPL, do_stid_rpl); 14224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, do_stid_rpl); 14234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_PASS_ACCEPT_REQ, do_cr); 14244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_PASS_ESTABLISH, do_hwtid_rpl); 14254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_ABORT_RPL_RSS, do_hwtid_rpl); 14264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_ABORT_RPL, do_hwtid_rpl); 14274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_RX_URG_NOTIFY, do_hwtid_rpl); 14284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_RX_DATA, do_hwtid_rpl); 14294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_TX_DATA_ACK, do_hwtid_rpl); 14304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_TX_DMA_ACK, do_hwtid_rpl); 14314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_ACT_OPEN_RPL, do_act_open_rpl); 14324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_PEER_CLOSE, do_hwtid_rpl); 14334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_CLOSE_CON_RPL, do_hwtid_rpl); 14344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_ABORT_REQ_RSS, do_abort_req_rss); 14354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_ACT_ESTABLISH, do_act_establish); 14366cdbd77e8883aac2e24f8b19b91e5b1c839213a0Divy Le Ray t3_register_cpl_handler(CPL_SET_TCB_RPL, do_hwtid_rpl); 14376cdbd77e8883aac2e24f8b19b91e5b1c839213a0Divy Le Ray t3_register_cpl_handler(CPL_GET_TCB_RPL, do_hwtid_rpl); 14384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_RDMA_TERMINATE, do_term); 14394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_RDMA_EC_STATUS, do_hwtid_rpl); 14404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_TRACE_PKT, do_trace); 14414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_RX_DATA_DDP, do_hwtid_rpl); 14424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_RX_DDP_COMPLETE, do_hwtid_rpl); 14434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray t3_register_cpl_handler(CPL_ISCSI_HDR, do_hwtid_rpl); 14444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray} 1445