16f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 26f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * cxgb3i_offload.c: Chelsio S3xx iscsi offloaded tcp connection management 36f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 46f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Copyright (C) 2003-2008 Chelsio Communications. All rights reserved. 56f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 66f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * This program is distributed in the hope that it will be useful, but WITHOUT 76f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 86f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this 96f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * release for licensing terms and conditions. 106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Written by: Dimitris Michailidis (dm@chelsio.com) 126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Karen Xie (kxie@chelsio.com) 136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ 166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include <linux/module.h> 186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include <linux/moduleparam.h> 196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include <scsi/scsi_host.h> 206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include "common.h" 226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include "t3_cpl.h" 236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include "t3cdev.h" 246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include "cxgb3_defs.h" 256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include "cxgb3_ctl_defs.h" 266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include "cxgb3_offload.h" 276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include "firmware_exports.h" 286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include "cxgb3i.h" 296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic unsigned int dbg_level; 316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#include "../libcxgbi.h" 326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#define DRV_MODULE_NAME "cxgb3i" 346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#define DRV_MODULE_DESC "Chelsio T3 iSCSI Driver" 356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#define DRV_MODULE_VERSION "2.0.0" 366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com#define DRV_MODULE_RELDATE "Jun. 2010" 376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic char version[] = 396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com DRV_MODULE_DESC " " DRV_MODULE_NAME 406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; 416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_AUTHOR("Chelsio Communications, Inc."); 436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_DESCRIPTION(DRV_MODULE_DESC); 446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_VERSION(DRV_MODULE_VERSION); 456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_LICENSE("GPL"); 466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.commodule_param(dbg_level, uint, 0644); 486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_PARM_DESC(dbg_level, "debug flag (default=0)"); 496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int cxgb3i_rcv_win = 256 * 1024; 516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.commodule_param(cxgb3i_rcv_win, int, 0644); 526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_PARM_DESC(cxgb3i_rcv_win, "TCP receive window in bytes (default=256KB)"); 536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int cxgb3i_snd_win = 128 * 1024; 556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.commodule_param(cxgb3i_snd_win, int, 0644); 566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_PARM_DESC(cxgb3i_snd_win, "TCP send window in bytes (default=128KB)"); 576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int cxgb3i_rx_credit_thres = 10 * 1024; 596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.commodule_param(cxgb3i_rx_credit_thres, int, 0644); 606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_PARM_DESC(rx_credit_thres, 616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "RX credits return threshold in bytes (default=10KB)"); 626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic unsigned int cxgb3i_max_connect = 8 * 1024; 646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.commodule_param(cxgb3i_max_connect, uint, 0644); 656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_PARM_DESC(cxgb3i_max_connect, "Max. # of connections (default=8092)"); 666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic unsigned int cxgb3i_sport_base = 20000; 686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.commodule_param(cxgb3i_sport_base, uint, 0644); 696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comMODULE_PARM_DESC(cxgb3i_sport_base, "starting port number (default=20000)"); 706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void cxgb3i_dev_open(struct t3cdev *); 726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void cxgb3i_dev_close(struct t3cdev *); 736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void cxgb3i_dev_event_handler(struct t3cdev *, u32, u32); 746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic struct cxgb3_client t3_client = { 766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .name = DRV_MODULE_NAME, 776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .handlers = cxgb3i_cpl_handlers, 786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .add = cxgb3i_dev_open, 796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .remove = cxgb3i_dev_close, 806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .event_handler = cxgb3i_dev_event_handler, 816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com}; 826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic struct scsi_host_template cxgb3i_host_template = { 846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .module = THIS_MODULE, 856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .name = DRV_MODULE_NAME, 866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .proc_name = DRV_MODULE_NAME, 876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .can_queue = CXGB3I_SCSI_HOST_QDEPTH, 886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .queuecommand = iscsi_queuecommand, 896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .change_queue_depth = iscsi_change_queue_depth, 906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .sg_tablesize = SG_ALL, 916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .max_sectors = 0xFFFF, 926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, 936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .eh_abort_handler = iscsi_eh_abort, 946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .eh_device_reset_handler = iscsi_eh_device_reset, 956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .eh_target_reset_handler = iscsi_eh_recover_target, 966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .target_alloc = iscsi_target_alloc, 976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .use_clustering = DISABLE_CLUSTERING, 986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .this_id = -1, 996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com}; 1006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic struct iscsi_transport cxgb3i_iscsi_transport = { 1026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .owner = THIS_MODULE, 1036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .name = DRV_MODULE_NAME, 1046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* owner and name should be set already */ 1056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST 1066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com | CAP_DATADGST | CAP_DIGEST_OFFLOAD | 107fdafd4dfc7bbdd40a4692192b77299b28c8a948fMike Christie CAP_PADDING_OFFLOAD | CAP_TEXT_NEGO, 1083128c6c73cdf3df92c3165bfb785ae50114d18bfMike Christie .attr_is_visible = cxgbi_attr_is_visible, 1096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .get_host_param = cxgbi_get_host_param, 1106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .set_host_param = cxgbi_set_host_param, 1116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* session management */ 1126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .create_session = cxgbi_create_session, 1136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .destroy_session = cxgbi_destroy_session, 1146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .get_session_param = iscsi_session_get_param, 1156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* connection management */ 1166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .create_conn = cxgbi_create_conn, 1176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .bind_conn = cxgbi_bind_conn, 1186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .destroy_conn = iscsi_tcp_conn_teardown, 1196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .start_conn = iscsi_conn_start, 1206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .stop_conn = iscsi_conn_stop, 121c71b9b669e1243623f7ed4332877d3f2beafc6abMike Christie .get_conn_param = iscsi_conn_get_param, 1226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .set_param = cxgbi_set_conn_param, 1236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .get_stats = cxgbi_get_conn_stats, 1246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* pdu xmit req from user space */ 1256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .send_pdu = iscsi_conn_send_pdu, 1266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* task */ 1276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .init_task = iscsi_tcp_task_init, 1286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .xmit_task = iscsi_tcp_task_xmit, 1296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .cleanup_task = cxgbi_cleanup_task, 1306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* pdu */ 1316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .alloc_pdu = cxgbi_conn_alloc_pdu, 1326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .init_pdu = cxgbi_conn_init_pdu, 1336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .xmit_pdu = cxgbi_conn_xmit_pdu, 1346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .parse_pdu_itt = cxgbi_parse_pdu_itt, 1356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* TCP connect/disconnect */ 136c71b9b669e1243623f7ed4332877d3f2beafc6abMike Christie .get_ep_param = cxgbi_get_ep_param, 1376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .ep_connect = cxgbi_ep_connect, 1386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .ep_poll = cxgbi_ep_poll, 1396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .ep_disconnect = cxgbi_ep_disconnect, 1406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* Error recovery timeout call */ 1416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com .session_recovery_timedout = iscsi_session_recovery_timedout, 1426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com}; 1436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic struct scsi_transport_template *cxgb3i_stt; 1456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 1476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * CPL (Chelsio Protocol Language) defines a message passing interface between 1486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * the host driver and Chelsio asic. 1496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * The section below implments CPLs that related to iscsi tcp connection 1506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * open/close/abort and data send/receive. 1516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 1526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int push_tx_frames(struct cxgbi_sock *csk, int req_completion); 1546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb, 1566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com const struct l2t_entry *e) 1576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 1586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int wscale = cxgbi_sock_compute_wscale(cxgb3i_rcv_win); 1596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_act_open_req *req = (struct cpl_act_open_req *)skb->head; 1606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->priority = CPL_PRIORITY_SETUP; 1626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); 1646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ACT_OPEN_REQ, csk->atid)); 1656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->local_port = csk->saddr.sin_port; 1666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->peer_port = csk->daddr.sin_port; 1676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->local_ip = csk->saddr.sin_addr.s_addr; 1686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->peer_ip = csk->daddr.sin_addr.s_addr; 1696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->opt0h = htonl(V_KEEP_ALIVE(1) | F_TCAM_BYPASS | 1716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com V_WND_SCALE(wscale) | V_MSS_IDX(csk->mss_idx) | 1726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com V_L2T_IDX(e->idx) | V_TX_CHANNEL(e->smt_idx)); 1736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->opt0l = htonl(V_ULP_MODE(ULP2_MODE_ISCSI) | 1746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com V_RCV_BUFSIZ(cxgb3i_rcv_win>>10)); 1756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 1776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u, %pI4:%u-%pI4:%u, %u,%u,%u.\n", 1786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->atid, 1796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com &req->local_ip, ntohs(req->local_port), 1806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com &req->peer_ip, ntohs(req->peer_port), 1816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->mss_idx, e->idx, e->smt_idx); 1826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com l2t_send(csk->cdev->lldev, skb, csk->l2t); 1846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 1856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic inline void act_open_arp_failure(struct t3cdev *dev, struct sk_buff *skb) 1876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 1886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_act_open_req_arp_failure(NULL, skb); 1896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 1906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 1926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * CPL connection close request: host -> 1936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 1946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Close a connection by sending a CPL_CLOSE_CON_REQ message and queue it to 1956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * the write queue (i.e., after any unsent txt data). 1966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 1976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void send_close_req(struct cxgbi_sock *csk) 1986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 1996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct sk_buff *skb = csk->cpl_close; 2006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_close_con_req *req = (struct cpl_close_con_req *)skb->head; 2016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int tid = csk->tid; 2026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 2046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u.\n", 2056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid); 2066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->cpl_close = NULL; 2086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON)); 2096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr.wr_lo = htonl(V_WR_TID(tid)); 2106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, tid)); 2116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->rsvd = htonl(csk->write_seq); 2126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_skb_entail(csk, skb); 2146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (csk->state >= CTP_ESTABLISHED) 2156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com push_tx_frames(csk, 1); 2166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 2176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 2196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * CPL connection abort request: host -> 2206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 2216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Send an ABORT_REQ message. Makes sure we do not send multiple ABORT_REQs 2226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * for the same connection and also that we do not try to send a message 2236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * after the connection has closed. 2246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 2256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void abort_arp_failure(struct t3cdev *tdev, struct sk_buff *skb) 2266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 2276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_abort_req *req = cplhdr(skb); 2286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 2306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "t3dev 0x%p, tid %u, skb 0x%p.\n", 2316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com tdev, GET_TID(req), skb); 2326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->cmd = CPL_ABORT_NO_RST; 2336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_ofld_send(tdev, skb); 2346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 2356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void send_abort_req(struct cxgbi_sock *csk) 2376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 2386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct sk_buff *skb = csk->cpl_abort_req; 2396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_abort_req *req; 2406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (unlikely(csk->state == CTP_ABORTING || !skb)) 2426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return; 2436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_set_state(csk, CTP_ABORTING); 2446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_set_flag(csk, CTPF_ABORT_RPL_PENDING); 2456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* Purge the send queue so we don't send anything after an abort. */ 2466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_purge_write_queue(csk); 2476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->cpl_abort_req = NULL; 2496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req = (struct cpl_abort_req *)skb->head; 2506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->priority = CPL_PRIORITY_DATA; 2516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com set_arp_failure_handler(skb, abort_arp_failure); 2526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_REQ)); 2536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr.wr_lo = htonl(V_WR_TID(csk->tid)); 2546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, csk->tid)); 2556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->rsvd0 = htonl(csk->snd_nxt); 2566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->rsvd1 = !cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT); 2576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->cmd = CPL_ABORT_SEND_RST; 2586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 2606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u, snd_nxt %u, 0x%x.\n", 2616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid, csk->snd_nxt, 2626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->rsvd1); 2636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com l2t_send(csk->cdev->lldev, skb, csk->l2t); 2656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 2666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 2686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * CPL connection abort reply: host -> 2696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 2706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Send an ABORT_RPL message in response of the ABORT_REQ received. 2716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 2726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void send_abort_rpl(struct cxgbi_sock *csk, int rst_status) 2736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 2746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct sk_buff *skb = csk->cpl_abort_rpl; 2756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_abort_rpl *rpl = (struct cpl_abort_rpl *)skb->head; 2766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 2786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u, status %d.\n", 2796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid, rst_status); 2806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->cpl_abort_rpl = NULL; 2826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->priority = CPL_PRIORITY_DATA; 2836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com rpl->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_RPL)); 2846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com rpl->wr.wr_lo = htonl(V_WR_TID(csk->tid)); 2856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, csk->tid)); 2866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com rpl->cmd = rst_status; 2876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_ofld_send(csk->cdev->lldev, skb); 2886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 2896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 2906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 2916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * CPL connection rx data ack: host -> 2926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Send RX credits through an RX_DATA_ACK CPL message. Returns the number of 2936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * credits sent. 2946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 2956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic u32 send_rx_credits(struct cxgbi_sock *csk, u32 credits) 2966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 2976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct sk_buff *skb; 2986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_rx_data_ack *req; 2996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com u32 dack = F_RX_DACK_CHANGE | V_RX_DACK_MODE(1); 3006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX, 3026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u, credit %u, dack %u.\n", 3036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid, credits, dack); 3046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 30524d3f95a5b6082ca4aba89071ca6259e15d3e564kxie@chelsio.com skb = alloc_wr(sizeof(*req), 0, GFP_ATOMIC); 3066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!skb) { 3076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("csk 0x%p, credit %u, OOM.\n", csk, credits); 3086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 3096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 3106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req = (struct cpl_rx_data_ack *)skb->head; 3116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); 3126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, csk->tid)); 3136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->credit_dack = htonl(F_RX_DACK_CHANGE | V_RX_DACK_MODE(1) | 3146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com V_RX_CREDITS(credits)); 3156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->priority = CPL_PRIORITY_ACK; 3166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_ofld_send(csk->cdev->lldev, skb); 3176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return credits; 3186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 3196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 3216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * CPL connection tx data: host -> 3226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 3236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Send iscsi PDU via TX_DATA CPL message. Returns the number of 3246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * credits sent. 3256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Each TX_DATA consumes work request credit (wrs), so we need to keep track of 3266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * how many we've used so far and how many are pending (i.e., yet ack'ed by T3). 3276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 3286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic unsigned int wrlen __read_mostly; 3306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic unsigned int skb_wrs[SKB_WR_LIST_SIZE] __read_mostly; 3316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void init_wr_tab(unsigned int wr_len) 3336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 3346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int i; 3356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (skb_wrs[1]) /* already initialized */ 3376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return; 3386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com for (i = 1; i < SKB_WR_LIST_SIZE; i++) { 3396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int sgl_len = (3 * i) / 2 + (i & 1); 3406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com sgl_len += 3; 3426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb_wrs[i] = (sgl_len <= wr_len 3436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com ? 1 : 1 + (sgl_len - 2) / (wr_len - 1)); 3446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 3456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com wrlen = wr_len * 8; 3466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 3476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic inline void make_tx_data_wr(struct cxgbi_sock *csk, struct sk_buff *skb, 3496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int len, int req_completion) 3506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 3516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct tx_data_wr *req; 3526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct l2t_entry *l2t = csk->l2t; 3536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb_reset_transport_header(skb); 3556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req = (struct tx_data_wr *)__skb_push(skb, sizeof(*req)); 3566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_TX_DATA) | 3576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com (req_completion ? F_WR_COMPL : 0)); 3586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr_lo = htonl(V_WR_TID(csk->tid)); 3596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* len includes the length of any HW ULP additions */ 3606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->len = htonl(len); 3616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* V_TX_ULP_SUBMODE sets both the mode and submode */ 3626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->flags = htonl(V_TX_ULP_SUBMODE(cxgbi_skcb_ulp_mode(skb)) | 3636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com V_TX_SHOVE((skb_peek(&csk->write_queue) ? 0 : 1))); 3646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->sndseq = htonl(csk->snd_nxt); 3656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->param = htonl(V_TX_PORT(l2t->smt_idx)); 3666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT)) { 3686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->flags |= htonl(V_TX_ACK_PAGES(2) | F_TX_INIT | 3696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com V_TX_CPU_IDX(csk->rss_qid)); 3706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* sendbuffer is in units of 32KB. */ 3716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->param |= htonl(V_TX_SNDBUF(cxgb3i_snd_win >> 15)); 3726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_set_flag(csk, CTPF_TX_DATA_SENT); 3736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 3746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 3756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/** 3776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * push_tx_frames -- start transmit 3786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @c3cn: the offloaded connection 3796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @req_completion: request wr_ack or not 3806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 3816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Prepends TX_DATA_WR or CPL_CLOSE_CON_REQ headers to buffers waiting in a 3826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * connection's send queue and sends them on to T3. Must be called with the 3836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * connection's lock held. Returns the amount of send buffer space that was 3846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * freed as a result of sending queued data to T3. 3856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 3866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void arp_failure_skb_discard(struct t3cdev *dev, struct sk_buff *skb) 3886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 3896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com kfree_skb(skb); 3906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 3916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int push_tx_frames(struct cxgbi_sock *csk, int req_completion) 3936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 3946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int total_size = 0; 3956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct sk_buff *skb; 3966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 3976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (unlikely(csk->state < CTP_ESTABLISHED || 3986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->state == CTP_CLOSE_WAIT_1 || csk->state >= CTP_ABORTING)) { 3996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_TX, 4006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u, in closing state.\n", 4016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid); 4026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 4036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 4046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com while (csk->wr_cred && (skb = skb_peek(&csk->write_queue)) != NULL) { 4066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int len = skb->len; /* length before skb_push */ 4076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int frags = skb_shinfo(skb)->nr_frags + (len != skb->data_len); 4086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int wrs_needed = skb_wrs[frags]; 4096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (wrs_needed > 1 && len + sizeof(struct tx_data_wr) <= wrlen) 4116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com wrs_needed = 1; 4126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com WARN_ON(frags >= SKB_WR_LIST_SIZE || wrs_needed < 1); 4146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (csk->wr_cred < wrs_needed) { 4166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_PDU_TX, 4176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p, skb len %u/%u, frag %u, wr %d<%u.\n", 4186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, skb->len, skb->data_len, frags, 4196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com wrs_needed, csk->wr_cred); 4206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com break; 4216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 4226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __skb_unlink(skb, &csk->write_queue); 4246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->priority = CPL_PRIORITY_DATA; 4256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->csum = wrs_needed; /* remember this until the WR_ACK */ 4266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->wr_cred -= wrs_needed; 4276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->wr_una_cred += wrs_needed; 4286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_enqueue_wr(csk, skb); 4296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_TX, 4316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p, enqueue, skb len %u/%u, frag %u, wr %d, " 4326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "left %u, unack %u.\n", 4336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, skb->len, skb->data_len, frags, skb->csum, 4346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->wr_cred, csk->wr_una_cred); 4356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (likely(cxgbi_skcb_test_flag(skb, SKCBF_TX_NEED_HDR))) { 4376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if ((req_completion && 4386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->wr_una_cred == wrs_needed) || 4396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->wr_una_cred >= csk->wr_max_cred / 2) { 4406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req_completion = 1; 4416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->wr_una_cred = 0; 4426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 4436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com len += cxgbi_ulp_extra_len(cxgbi_skcb_ulp_mode(skb)); 4446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com make_tx_data_wr(csk, skb, len, req_completion); 4456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->snd_nxt += len; 4466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_clear_flag(skb, SKCBF_TX_NEED_HDR); 4476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 4486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com total_size += skb->truesize; 4496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_TX, 4506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p, tid 0x%x, send skb 0x%p.\n", 4516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->tid, skb); 4526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com set_arp_failure_handler(skb, arp_failure_skb_discard); 4536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com l2t_send(csk->cdev->lldev, skb, csk->l2t); 4546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 4556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return total_size; 4566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 4576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 4596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process a CPL_ACT_ESTABLISH message: -> host 4606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Updates connection state from an active establish CPL message. Runs with 4616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * the connection lock held. 4626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 4636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic inline void free_atid(struct cxgbi_sock *csk) 4656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 4666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (cxgbi_sock_flag(csk, CTPF_HAS_ATID)) { 4676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_free_atid(csk->cdev->lldev, csk->atid); 4686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_clear_flag(csk, CTPF_HAS_ATID); 4696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_put(csk); 4706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 4716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 4726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int do_act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) 4746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 4756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_sock *csk = ctx; 4766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_act_establish *req = cplhdr(skb); 4776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int tid = GET_TID(req); 4786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int atid = G_PASS_OPEN_TID(ntohl(req->tos_tid)); 4796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com u32 rcv_isn = ntohl(req->rcv_isn); /* real RCV_ISN + 1 */ 4806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 4826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "atid 0x%x,tid 0x%x, csk 0x%p,%u,0x%lx, isn %u.\n", 4836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com atid, atid, csk, csk->state, csk->flags, rcv_isn); 4846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_get(csk); 4866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_set_flag(csk, CTPF_HAS_TID); 4876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->tid = tid; 4886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_insert_tid(csk->cdev->lldev, &t3_client, csk, tid); 4896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com free_atid(csk); 4916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->rss_qid = G_QNUM(ntohs(skb->csum)); 4936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 4946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_lock_bh(&csk->lock); 4956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (csk->retry_timer.function) { 4966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com del_timer(&csk->retry_timer); 4976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->retry_timer.function = NULL; 4986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 4996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (unlikely(csk->state != CTP_ACTIVE_OPEN)) 5016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("csk 0x%p,%u,0x%lx,%u, got EST.\n", 5026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid); 5036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->copied_seq = csk->rcv_wup = csk->rcv_nxt = rcv_isn; 5056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (cxgb3i_rcv_win > (M_RCV_BUFSIZ << 10)) 5066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->rcv_wup -= cxgb3i_rcv_win - (M_RCV_BUFSIZ << 10); 5076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_established(csk, ntohl(req->snd_isn), ntohs(req->tcp_opt)); 5096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (unlikely(cxgbi_sock_flag(csk, CTPF_ACTIVE_CLOSE_NEEDED))) 5116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* upper layer has requested closing */ 5126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com send_abort_req(csk); 5136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com else { 5146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (skb_queue_len(&csk->write_queue)) 5156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com push_tx_frames(csk, 1); 5166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_conn_tx_open(csk); 5176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 5186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_unlock_bh(&csk->lock); 5206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __kfree_skb(skb); 5216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 5226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 5236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 5256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process a CPL_ACT_OPEN_RPL message: -> host 5266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Handle active open failures. 5276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 5286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int act_open_rpl_status_to_errno(int status) 5296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 5306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com switch (status) { 5316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_CONN_RESET: 5326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -ECONNREFUSED; 5336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_ARP_MISS: 5346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -EHOSTUNREACH; 5356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_CONN_TIMEDOUT: 5366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -ETIMEDOUT; 5376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_TCAM_FULL: 5386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -ENOMEM; 5396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_CONN_EXIST: 5406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -EADDRINUSE; 5416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com default: 5426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -EIO; 5436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 5446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 5456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void act_open_retry_timer(unsigned long data) 5476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 5486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct sk_buff *skb; 5496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_sock *csk = (struct cxgbi_sock *)data; 5506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 5526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u.\n", 5536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid); 5546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_get(csk); 5566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_lock_bh(&csk->lock); 55724d3f95a5b6082ca4aba89071ca6259e15d3e564kxie@chelsio.com skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_ATOMIC); 5586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!skb) 5596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_fail_act_open(csk, -ENOMEM); 5606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com else { 5616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->sk = (struct sock *)csk; 5626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com set_arp_failure_handler(skb, act_open_arp_failure); 5636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com send_act_open_req(csk, skb, csk->l2t); 5646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 5656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_unlock_bh(&csk->lock); 5666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_put(csk); 5676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 5686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int do_act_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) 5706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 5716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_sock *csk = ctx; 5726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_act_open_rpl *rpl = cplhdr(skb); 5736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5740b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com pr_info("csk 0x%p,%u,0x%lx,%u, status %u, %pI4:%u-%pI4:%u.\n", 5750b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com csk, csk->state, csk->flags, csk->atid, rpl->status, 5760b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com &csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port), 5770b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com &csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port)); 5786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (rpl->status != CPL_ERR_TCAM_FULL && 5806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com rpl->status != CPL_ERR_CONN_EXIST && 5816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com rpl->status != CPL_ERR_ARP_MISS) 5826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_queue_tid_release(tdev, GET_TID(rpl)); 5836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_get(csk); 5856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_lock_bh(&csk->lock); 5866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (rpl->status == CPL_ERR_CONN_EXIST && 5876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->retry_timer.function != act_open_retry_timer) { 5886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->retry_timer.function = act_open_retry_timer; 5896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com mod_timer(&csk->retry_timer, jiffies + HZ / 2); 5906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } else 5916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_fail_act_open(csk, 5926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com act_open_rpl_status_to_errno(rpl->status)); 5936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 5946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_unlock_bh(&csk->lock); 5956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_put(csk); 5966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __kfree_skb(skb); 5976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 5986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 5996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 6016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process PEER_CLOSE CPL messages: -> host 6026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Handle peer FIN. 6036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 6046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int do_peer_close(struct t3cdev *cdev, struct sk_buff *skb, void *ctx) 6056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 6066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_sock *csk = ctx; 6076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 6096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u.\n", 6106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid); 6116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_rcv_peer_close(csk); 6136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __kfree_skb(skb); 6146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 6156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 6166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 6186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process CLOSE_CONN_RPL CPL message: -> host 6196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process a peer ACK to our FIN. 6206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 6216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int do_close_con_rpl(struct t3cdev *cdev, struct sk_buff *skb, 6226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com void *ctx) 6236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 6246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_sock *csk = ctx; 6256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_close_con_rpl *rpl = cplhdr(skb); 6266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 6286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u, snxt %u.\n", 6296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid, ntohl(rpl->snd_nxt)); 6306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_rcv_close_conn_rpl(csk, ntohl(rpl->snd_nxt)); 6326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __kfree_skb(skb); 6336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 6346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 6356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 6376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process ABORT_REQ_RSS CPL message: -> host 6386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process abort requests. If we are waiting for an ABORT_RPL we ignore this 6396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * request except that we need to reply to it. 6406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 6416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int abort_status_to_errno(struct cxgbi_sock *csk, int abort_reason, 6436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int *need_rst) 6446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 6456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com switch (abort_reason) { 6466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_BAD_SYN: /* fall through */ 6476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_CONN_RESET: 6480b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com return csk->state > CTP_ESTABLISHED ? -EPIPE : -ECONNRESET; 6496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_XMIT_TIMEDOUT: 6506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_PERSIST_TIMEDOUT: 6516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_FINWAIT2_TIMEDOUT: 6526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case CPL_ERR_KEEPALIVE_TIMEDOUT: 6536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -ETIMEDOUT; 6546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com default: 6556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -EIO; 6566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 6576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 6586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int do_abort_req(struct t3cdev *cdev, struct sk_buff *skb, void *ctx) 6606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 6616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com const struct cpl_abort_req_rss *req = cplhdr(skb); 6626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_sock *csk = ctx; 6636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int rst_status = CPL_ABORT_NO_RST; 6646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 6666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u.\n", 6676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid); 6686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (req->status == CPL_ERR_RTX_NEG_ADVICE || 6706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->status == CPL_ERR_PERSIST_NEG_ADVICE) { 6716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto done; 6726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 6736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_get(csk); 6756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_lock_bh(&csk->lock); 6766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!cxgbi_sock_flag(csk, CTPF_ABORT_REQ_RCVD)) { 6786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_set_flag(csk, CTPF_ABORT_REQ_RCVD); 6796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_set_state(csk, CTP_ABORTING); 6806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto out; 6816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 6826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_clear_flag(csk, CTPF_ABORT_REQ_RCVD); 6846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com send_abort_rpl(csk, rst_status); 6856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!cxgbi_sock_flag(csk, CTPF_ABORT_RPL_PENDING)) { 6876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->err = abort_status_to_errno(csk, req->status, &rst_status); 6886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_closed(csk); 6896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 6906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comout: 6926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_unlock_bh(&csk->lock); 6936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_put(csk); 6946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comdone: 6956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __kfree_skb(skb); 6966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 6976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 6986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 6996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 7006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process ABORT_RPL_RSS CPL message: -> host 7016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process abort replies. We only process these messages if we anticipate 7026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * them as the coordination between SW and HW in this area is somewhat lacking 7036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * and sometimes we get ABORT_RPLs after we are done with the connection that 7046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * originated the ABORT_REQ. 7056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 7066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int do_abort_rpl(struct t3cdev *cdev, struct sk_buff *skb, void *ctx) 7076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 7086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_abort_rpl_rss *rpl = cplhdr(skb); 7096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_sock *csk = ctx; 7106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 7126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "status 0x%x, csk 0x%p, s %u, 0x%lx.\n", 7136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com rpl->status, csk, csk ? csk->state : 0, 7146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk ? csk->flags : 0UL); 7156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* 7166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Ignore replies to post-close aborts indicating that the abort was 7176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * requested too late. These connections are terminated when we get 7186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * PEER_CLOSE or CLOSE_CON_RPL and by the time the abort_rpl_rss 7196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * arrives the TID is either no longer used or it has been recycled. 7206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 7216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (rpl->status == CPL_ERR_ABORT_FAILED) 7226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto rel_skb; 7236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* 7246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Sometimes we've already closed the connection, e.g., a post-close 7256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * abort races with ABORT_REQ_RSS, the latter frees the connection 7266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * expecting the ABORT_REQ will fail with CPL_ERR_ABORT_FAILED, 7276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * but FW turns the ABORT_REQ into a regular one and so we get 7286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * ABORT_RPL_RSS with status 0 and no connection. 7296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 7306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (csk) 7316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_rcv_abort_rpl(csk); 7326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comrel_skb: 7336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __kfree_skb(skb); 7346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 7356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 7366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 7386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process RX_ISCSI_HDR CPL message: -> host 7396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Handle received PDUs, the payload could be DDP'ed. If not, the payload 7406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * follow after the bhs. 7416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 7426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int do_iscsi_hdr(struct t3cdev *t3dev, struct sk_buff *skb, void *ctx) 7436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 7446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_sock *csk = ctx; 7456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_iscsi_hdr *hdr_cpl = cplhdr(skb); 7466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_iscsi_hdr_norss data_cpl; 7476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_rx_data_ddp_norss ddp_cpl; 7486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int hdr_len, data_len, status; 7496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int len; 7506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int err; 7516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX, 7536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u, skb 0x%p,%u.\n", 7546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid, skb, skb->len); 7556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_lock_bh(&csk->lock); 7576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (unlikely(csk->state >= CTP_PASSIVE_CLOSE)) { 7596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 7606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u, bad state.\n", 7616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid); 7626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (csk->state != CTP_ABORTING) 7636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto abort_conn; 7646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com else 7656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto discard; 7666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 7676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_tcp_seq(skb) = ntohl(hdr_cpl->seq); 7696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_flags(skb) = 0; 7706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb_reset_transport_header(skb); 7726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __skb_pull(skb, sizeof(struct cpl_iscsi_hdr)); 7736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com len = hdr_len = ntohs(hdr_cpl->len); 7756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* msg coalesce is off or not enough data received */ 7766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (skb->len <= hdr_len) { 7776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_err("%s: tid %u, CPL_ISCSI_HDR, skb len %u < %u.\n", 7786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->cdev->ports[csk->port_id]->name, csk->tid, 7796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->len, hdr_len); 7806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto abort_conn; 7816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 7826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_set_flag(skb, SKCBF_RX_COALESCED); 7836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com err = skb_copy_bits(skb, skb->len - sizeof(ddp_cpl), &ddp_cpl, 7856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com sizeof(ddp_cpl)); 7866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (err < 0) { 7876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_err("%s: tid %u, copy cpl_ddp %u-%zu failed %d.\n", 7886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->cdev->ports[csk->port_id]->name, csk->tid, 7896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->len, sizeof(ddp_cpl), err); 7906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto abort_conn; 7916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 7926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_set_flag(skb, SKCBF_RX_STATUS); 7946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_rx_pdulen(skb) = ntohs(ddp_cpl.len); 7956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_rx_ddigest(skb) = ntohl(ddp_cpl.ulp_crc); 7966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com status = ntohl(ddp_cpl.ddp_status); 7976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 7986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX, 7996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p, skb 0x%p,%u, pdulen %u, status 0x%x.\n", 8006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, skb, skb->len, cxgbi_skcb_rx_pdulen(skb), status); 8016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (status & (1 << CPL_RX_DDP_STATUS_HCRC_SHIFT)) 8036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_set_flag(skb, SKCBF_RX_HCRC_ERR); 8046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (status & (1 << CPL_RX_DDP_STATUS_DCRC_SHIFT)) 8056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_set_flag(skb, SKCBF_RX_DCRC_ERR); 8066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (status & (1 << CPL_RX_DDP_STATUS_PAD_SHIFT)) 8076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_set_flag(skb, SKCBF_RX_PAD_ERR); 8086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (skb->len > (hdr_len + sizeof(ddp_cpl))) { 8106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com err = skb_copy_bits(skb, hdr_len, &data_cpl, sizeof(data_cpl)); 8116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (err < 0) { 8126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_err("%s: tid %u, cp %zu/%u failed %d.\n", 8136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->cdev->ports[csk->port_id]->name, 8146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->tid, sizeof(data_cpl), skb->len, err); 8156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto abort_conn; 8166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 8176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com data_len = ntohs(data_cpl.len); 8186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_DDP | 1 << CXGBI_DBG_PDU_RX, 8196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "skb 0x%p, pdu not ddp'ed %u/%u, status 0x%x.\n", 8206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb, data_len, cxgbi_skcb_rx_pdulen(skb), status); 8216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com len += sizeof(data_cpl) + data_len; 8226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } else if (status & (1 << CPL_RX_DDP_STATUS_DDP_SHIFT)) 8236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_skcb_set_flag(skb, SKCBF_RX_DATA_DDPD); 8246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->rcv_nxt = ntohl(ddp_cpl.seq) + cxgbi_skcb_rx_pdulen(skb); 8266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __pskb_trim(skb, len); 8276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __skb_queue_tail(&csk->receive_queue, skb); 8286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_conn_pdu_ready(csk); 8296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_unlock_bh(&csk->lock); 8316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 8326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comabort_conn: 8346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com send_abort_req(csk); 8356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comdiscard: 8366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com spin_unlock_bh(&csk->lock); 8376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __kfree_skb(skb); 8386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 8396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 8406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 8426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process TX_DATA_ACK CPL messages: -> host 8436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Process an acknowledgment of WR completion. Advance snd_una and send the 8446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * next batch of work requests from the write queue. 8456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 8466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int do_wr_ack(struct t3cdev *cdev, struct sk_buff *skb, void *ctx) 8476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 8486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_sock *csk = ctx; 8496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_wr_ack *hdr = cplhdr(skb); 8506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_RX, 8526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u, cr %u.\n", 8536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid, ntohs(hdr->credits)); 8546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_rcv_wr_ack(csk, ntohs(hdr->credits), ntohl(hdr->snd_una), 1); 8566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __kfree_skb(skb); 8576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 8586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 8596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 8616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * for each connection, pre-allocate skbs needed for close/abort requests. So 8626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * that we can service the request right away. 8636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 8646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int alloc_cpls(struct cxgbi_sock *csk) 8656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 86624d3f95a5b6082ca4aba89071ca6259e15d3e564kxie@chelsio.com csk->cpl_close = alloc_wr(sizeof(struct cpl_close_con_req), 0, 8676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com GFP_KERNEL); 8686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!csk->cpl_close) 8696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -ENOMEM; 87024d3f95a5b6082ca4aba89071ca6259e15d3e564kxie@chelsio.com csk->cpl_abort_req = alloc_wr(sizeof(struct cpl_abort_req), 0, 8716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com GFP_KERNEL); 8726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!csk->cpl_abort_req) 8736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto free_cpl_skbs; 8746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 87524d3f95a5b6082ca4aba89071ca6259e15d3e564kxie@chelsio.com csk->cpl_abort_rpl = alloc_wr(sizeof(struct cpl_abort_rpl), 0, 8766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com GFP_KERNEL); 8776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!csk->cpl_abort_rpl) 8786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto free_cpl_skbs; 8796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 8816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comfree_cpl_skbs: 8836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_free_cpl_skbs(csk); 8846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -ENOMEM; 8856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 8866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/** 8886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * release_offload_resources - release offload resource 8896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @c3cn: the offloaded iscsi tcp connection. 8906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * Release resources held by an offload connection (TID, L2T entry, etc.) 8916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 8926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void l2t_put(struct cxgbi_sock *csk) 8936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 8946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct t3cdev *t3dev = (struct t3cdev *)csk->cdev->lldev; 8956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 8966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (csk->l2t) { 897e48f129c2f200dde8899f6ea5c6e7173674fc482Neil Horman l2t_release(t3dev, csk->l2t); 8986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->l2t = NULL; 8996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_put(csk); 9006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 9016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 9026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void release_offload_resources(struct cxgbi_sock *csk) 9046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 9056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct t3cdev *t3dev = (struct t3cdev *)csk->cdev->lldev; 9066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 9086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx,%u.\n", 9096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, csk->state, csk->flags, csk->tid); 9106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->rss_qid = 0; 9126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_free_cpl_skbs(csk); 9136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (csk->wr_cred != csk->wr_max_cred) { 9156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_purge_wr_queue(csk); 9166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_reset_wr_list(csk); 9176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 9186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com l2t_put(csk); 9196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (cxgbi_sock_flag(csk, CTPF_HAS_ATID)) 9206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com free_atid(csk); 9216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com else if (cxgbi_sock_flag(csk, CTPF_HAS_TID)) { 9226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_remove_tid(t3dev, (void *)csk, csk->tid); 9236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_clear_flag(csk, CTPF_HAS_TID); 9246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_put(csk); 9256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 9266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->dst = NULL; 9276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->cdev = NULL; 9286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 9296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9300b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.comstatic void update_address(struct cxgbi_hba *chba) 9310b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com{ 9320b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com if (chba->ipv4addr) { 9330b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com if (chba->vdev && 9340b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com chba->ipv4addr != cxgb3i_get_private_ipv4addr(chba->vdev)) { 9350b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com cxgb3i_set_private_ipv4addr(chba->vdev, chba->ipv4addr); 9360b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com cxgb3i_set_private_ipv4addr(chba->ndev, 0); 9370b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com pr_info("%s set %pI4.\n", 9380b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com chba->vdev->name, &chba->ipv4addr); 9390b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com } else if (chba->ipv4addr != 9400b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com cxgb3i_get_private_ipv4addr(chba->ndev)) { 9410b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com cxgb3i_set_private_ipv4addr(chba->ndev, chba->ipv4addr); 9420b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com pr_info("%s set %pI4.\n", 9430b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com chba->ndev->name, &chba->ipv4addr); 9440b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com } 9450b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com } else if (cxgb3i_get_private_ipv4addr(chba->ndev)) { 9460b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com if (chba->vdev) 9470b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com cxgb3i_set_private_ipv4addr(chba->vdev, 0); 9480b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com cxgb3i_set_private_ipv4addr(chba->ndev, 0); 9490b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com } 9500b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com} 9510b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com 9526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int init_act_open(struct cxgbi_sock *csk) 9536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 9546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct dst_entry *dst = csk->dst; 9556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_device *cdev = csk->cdev; 9566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev; 9576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct net_device *ndev = cdev->ports[csk->port_id]; 9580b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com struct cxgbi_hba *chba = cdev->hbas[csk->port_id]; 9596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct sk_buff *skb = NULL; 9606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 9626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p,%u,0x%lx.\n", csk, csk->state, csk->flags); 9636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9640b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com update_address(chba); 9650b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com if (chba->ipv4addr) 9660b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com csk->saddr.sin_addr.s_addr = chba->ipv4addr; 9670b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com 9686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->rss_qid = 0; 969a4757123aeadf450b5b3c5f51f214660e20477f3David Miller csk->l2t = t3_l2t_get(t3dev, dst, ndev); 9706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!csk->l2t) { 9716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_err("NO l2t available.\n"); 9726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -EINVAL; 9736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 9746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_get(csk); 9756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->atid = cxgb3_alloc_atid(t3dev, &t3_client, csk); 9776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (csk->atid < 0) { 9786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_err("NO atid available.\n"); 9796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto rel_resource; 9806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 9816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_set_flag(csk, CTPF_HAS_ATID); 9826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_get(csk); 9836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 98424d3f95a5b6082ca4aba89071ca6259e15d3e564kxie@chelsio.com skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL); 9856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!skb) 9866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto rel_resource; 9876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->sk = (struct sock *)csk; 9886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com set_arp_failure_handler(skb, act_open_arp_failure); 9896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->wr_max_cred = csk->wr_cred = T3C_DATA(t3dev)->max_wrs - 1; 9916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->wr_una_cred = 0; 9926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->mss_idx = cxgbi_sock_select_mss(csk, dst_mtu(dst)); 9936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_reset_wr_list(csk); 9946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk->err = 0; 9956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 9960b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, 9970b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com "csk 0x%p,%u,0x%lx, %pI4:%u-%pI4:%u.\n", 9980b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com csk, csk->state, csk->flags, 9990b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com &csk->saddr.sin_addr.s_addr, ntohs(csk->saddr.sin_port), 10000b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com &csk->daddr.sin_addr.s_addr, ntohs(csk->daddr.sin_port)); 10010b3d8947972bfd2dd6d55c8009427ad2941ef038kxie@chelsio.com 10026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN); 10036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com send_act_open_req(csk, skb, csk->l2t); 10046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 10056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comrel_resource: 10076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (skb) 10086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com __kfree_skb(skb); 10096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -EINVAL; 10106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 10116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comcxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS] = { 10136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com [CPL_ACT_ESTABLISH] = do_act_establish, 10146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com [CPL_ACT_OPEN_RPL] = do_act_open_rpl, 10156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com [CPL_PEER_CLOSE] = do_peer_close, 10166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com [CPL_ABORT_REQ_RSS] = do_abort_req, 10176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com [CPL_ABORT_RPL_RSS] = do_abort_rpl, 10186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com [CPL_CLOSE_CON_RPL] = do_close_con_rpl, 10196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com [CPL_TX_DMA_ACK] = do_wr_ack, 10206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com [CPL_ISCSI_HDR] = do_iscsi_hdr, 10216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com}; 10226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/** 10246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * cxgb3i_ofld_init - allocate and initialize resources for each adapter found 10256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @cdev: cxgbi adapter 10266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 10276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comint cxgb3i_ofld_init(struct cxgbi_device *cdev) 10286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 10296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct t3cdev *t3dev = (struct t3cdev *)cdev->lldev; 10306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct adap_ports port; 10316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct ofld_page_info rx_page_info; 10326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int wr_len; 10336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int rc; 10346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (t3dev->ctl(t3dev, GET_WR_LEN, &wr_len) < 0 || 10366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com t3dev->ctl(t3dev, GET_PORTS, &port) < 0 || 10376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com t3dev->ctl(t3dev, GET_RX_PAGE_INFO, &rx_page_info) < 0) { 10386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_warn("t3 0x%p, offload up, ioctl failed.\n", t3dev); 10396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -EINVAL; 10406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 10416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (cxgb3i_max_connect > CXGBI_MAX_CONN) 10436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3i_max_connect = CXGBI_MAX_CONN; 10446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com rc = cxgbi_device_portmap_create(cdev, cxgb3i_sport_base, 10466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3i_max_connect); 10476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (rc < 0) 10486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return rc; 10496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com init_wr_tab(wr_len); 10516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_release_offload_resources = release_offload_resources; 10526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_push_tx_frames = push_tx_frames; 10536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_send_abort_req = send_abort_req; 10546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_send_close_req = send_close_req; 10556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_send_rx_credits = send_rx_credits; 10566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_alloc_cpls = alloc_cpls; 10576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_init_act_open = init_act_open; 10586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("cdev 0x%p, offload up, added.\n", cdev); 10606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 10616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 10626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/* 10646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * functions to program the pagepod in h/w 10656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 10666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic inline void ulp_mem_io_set_hdr(struct sk_buff *skb, unsigned int addr) 10676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 10686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct ulp_mem_io *req = (struct ulp_mem_io *)skb->head; 10696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com memset(req, 0, sizeof(*req)); 10716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_BYPASS)); 10736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->cmd_lock_addr = htonl(V_ULP_MEMIO_ADDR(addr >> 5) | 10746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com V_ULPTX_CMD(ULP_MEM_WRITE)); 10756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->len = htonl(V_ULP_MEMIO_DATA_LEN(PPOD_SIZE >> 5) | 10766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com V_ULPTX_NFLITS((PPOD_SIZE >> 3) + 1)); 10776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 10786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int ddp_set_map(struct cxgbi_sock *csk, struct cxgbi_pagepod_hdr *hdr, 10806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int idx, unsigned int npods, 10816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_gather_list *gl) 10826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 10836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_device *cdev = csk->cdev; 10846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_ddp_info *ddp = cdev->ddp; 10856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit; 10866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int i; 10876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_DDP, 10896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p, idx %u, npods %u, gl 0x%p.\n", 10906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com csk, idx, npods, gl); 10916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) { 1093b8ce8b59b8d64ee0d864706b9d3cca2a9b314bf5kxie@chelsio.com struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) + 1094b8ce8b59b8d64ee0d864706b9d3cca2a9b314bf5kxie@chelsio.com PPOD_SIZE, 0, GFP_ATOMIC); 10956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 1096b8ce8b59b8d64ee0d864706b9d3cca2a9b314bf5kxie@chelsio.com if (!skb) 1097b8ce8b59b8d64ee0d864706b9d3cca2a9b314bf5kxie@chelsio.com return -ENOMEM; 10986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 10996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com ulp_mem_io_set_hdr(skb, pm_addr); 11006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_ddp_ppod_set((struct cxgbi_pagepod *)(skb->head + 11016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com sizeof(struct ulp_mem_io)), 11026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com hdr, gl, i * PPOD_PAGES_MAX); 11036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->priority = CPL_PRIORITY_CONTROL; 11046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_ofld_send(cdev->lldev, skb); 11056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 11066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 11076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 11086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void ddp_clear_map(struct cxgbi_hba *chba, unsigned int tag, 11106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int idx, unsigned int npods) 11116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 11126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_device *cdev = chba->cdev; 11136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_ddp_info *ddp = cdev->ddp; 11146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit; 11156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int i; 11166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_DDP, 11186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "cdev 0x%p, idx %u, npods %u, tag 0x%x.\n", 11196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev, idx, npods, tag); 11206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) { 1122b8ce8b59b8d64ee0d864706b9d3cca2a9b314bf5kxie@chelsio.com struct sk_buff *skb = alloc_wr(sizeof(struct ulp_mem_io) + 1123b8ce8b59b8d64ee0d864706b9d3cca2a9b314bf5kxie@chelsio.com PPOD_SIZE, 0, GFP_ATOMIC); 11246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!skb) { 1126b8ce8b59b8d64ee0d864706b9d3cca2a9b314bf5kxie@chelsio.com pr_err("tag 0x%x, 0x%x, %d/%u, skb OOM.\n", 11276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com tag, idx, i, npods); 11286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com continue; 11296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 11306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com ulp_mem_io_set_hdr(skb, pm_addr); 11316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->priority = CPL_PRIORITY_CONTROL; 11326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_ofld_send(cdev->lldev, skb); 11336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 11346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 11356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, 11376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int tid, int pg_idx, bool reply) 11386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 113924d3f95a5b6082ca4aba89071ca6259e15d3e564kxie@chelsio.com struct sk_buff *skb = alloc_wr(sizeof(struct cpl_set_tcb_field), 0, 11406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com GFP_KERNEL); 11416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_set_tcb_field *req; 11426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com u64 val = pg_idx < DDP_PGIDX_MAX ? pg_idx : 0; 11436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_DDP, 11456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p, tid %u, pg_idx %d.\n", csk, tid, pg_idx); 11466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!skb) 11476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -ENOMEM; 11486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* set up ulp submode and page size */ 11506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req = (struct cpl_set_tcb_field *)skb->head; 11516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); 11526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid)); 11536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->reply = V_NO_REPLY(reply ? 0 : 1); 11546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->cpu_idx = 0; 11556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->word = htons(31); 11566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->mask = cpu_to_be64(0xF0000000); 11576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->val = cpu_to_be64(val << 28); 11586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->priority = CPL_PRIORITY_CONTROL; 11596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_ofld_send(csk->cdev->lldev, skb); 11616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 11626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 11636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/** 11656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * cxgb3i_setup_conn_digest - setup conn. digest setting 11666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @csk: cxgb tcp socket 11676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @tid: connection id 11686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @hcrc: header digest enabled 11696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @dcrc: data digest enabled 11706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @reply: request reply from h/w 11716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * set up the iscsi digest settings for a connection identified by tid 11726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 11736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid, 11746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int hcrc, int dcrc, int reply) 11756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 117624d3f95a5b6082ca4aba89071ca6259e15d3e564kxie@chelsio.com struct sk_buff *skb = alloc_wr(sizeof(struct cpl_set_tcb_field), 0, 11776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com GFP_KERNEL); 11786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cpl_set_tcb_field *req; 11796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com u64 val = (hcrc ? 1 : 0) | (dcrc ? 2 : 0); 11806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_DDP, 11826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "csk 0x%p, tid %u, crc %d,%d.\n", csk, tid, hcrc, dcrc); 11836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!skb) 11846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -ENOMEM; 11856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com /* set up ulp submode and page size */ 11876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req = (struct cpl_set_tcb_field *)skb->head; 11886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); 11896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid)); 11906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->reply = V_NO_REPLY(reply ? 0 : 1); 11916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->cpu_idx = 0; 11926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->word = htons(31); 11936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->mask = cpu_to_be64(0x0F000000); 11946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com req->val = cpu_to_be64(val << 24); 11956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com skb->priority = CPL_PRIORITY_CONTROL; 11966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 11976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_ofld_send(csk->cdev->lldev, skb); 11986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 11996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 12006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/** 12026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * t3_ddp_cleanup - release the cxgb3 adapter's ddp resource 12036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @cdev: cxgb3i adapter 12046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * release all the resource held by the ddp pagepod manager for a given 12056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * adapter if needed 12066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 12076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void t3_ddp_cleanup(struct cxgbi_device *cdev) 12096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 12106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct t3cdev *tdev = (struct t3cdev *)cdev->lldev; 12116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (cxgbi_ddp_cleanup(cdev)) { 12136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("t3dev 0x%p, ulp_iscsi no more user.\n", tdev); 12146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com tdev->ulp_iscsi = NULL; 12156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 12166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 12176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/** 12196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * ddp_init - initialize the cxgb3 adapter's ddp resource 12206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @cdev: cxgb3i adapter 12216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * initialize the ddp pagepod manager for a given adapter 12226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 12236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int cxgb3i_ddp_init(struct cxgbi_device *cdev) 12246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 12256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct t3cdev *tdev = (struct t3cdev *)cdev->lldev; 12266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_ddp_info *ddp = tdev->ulp_iscsi; 12276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct ulp_iscsi_info uinfo; 12286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com unsigned int pgsz_factor[4]; 1229c682d602d0f9751c92e07c196be27d8fac6ec3edKaren Xie int i, err; 12306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (ddp) { 12326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com kref_get(&ddp->refcnt); 12336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_warn("t3dev 0x%p, ddp 0x%p already set up.\n", 12346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com tdev, tdev->ulp_iscsi); 12356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->ddp = ddp; 12366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return -EALREADY; 12376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 12386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com err = tdev->ctl(tdev, ULP_ISCSI_GET_PARAMS, &uinfo); 12406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (err < 0) { 12416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_err("%s, failed to get iscsi param err=%d.\n", 12426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com tdev->name, err); 12436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return err; 12446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 12456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com err = cxgbi_ddp_init(cdev, uinfo.llimit, uinfo.ulimit, 12476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com uinfo.max_txsz, uinfo.max_rxsz); 12486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (err < 0) 12496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return err; 12506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com ddp = cdev->ddp; 12526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com uinfo.tagmask = ddp->idx_mask << PPOD_IDX_SHIFT; 12546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_ddp_page_size_factor(pgsz_factor); 1255c682d602d0f9751c92e07c196be27d8fac6ec3edKaren Xie for (i = 0; i < 4; i++) 1256c682d602d0f9751c92e07c196be27d8fac6ec3edKaren Xie uinfo.pgsz_factor[i] = pgsz_factor[i]; 12576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com uinfo.ulimit = uinfo.llimit + (ddp->nppods << PPOD_SIZE_SHIFT); 12586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com err = tdev->ctl(tdev, ULP_ISCSI_SET_PARAMS, &uinfo); 12606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (err < 0) { 12616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_warn("%s unable to set iscsi param err=%d, ddp disabled.\n", 12626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com tdev->name, err); 12636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_ddp_cleanup(cdev); 12646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return err; 12656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 12666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com tdev->ulp_iscsi = ddp; 12676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_ddp_setup_digest = ddp_setup_conn_digest; 12696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_ddp_setup_pgidx = ddp_setup_conn_pgidx; 12706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_ddp_set = ddp_set_map; 12716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->csk_ddp_clear = ddp_clear_map; 12726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("tdev 0x%p, nppods %u, bits %u, mask 0x%x,0x%x pkt %u/%u, " 12746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "%u/%u.\n", 12756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com tdev, ddp->nppods, ddp->idx_bits, ddp->idx_mask, 12766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com ddp->rsvd_tag_mask, ddp->max_txsz, uinfo.max_txsz, 12776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com ddp->max_rxsz, uinfo.max_rxsz); 12786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 12796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 12806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void cxgb3i_dev_close(struct t3cdev *t3dev) 12826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 12836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_device *cdev = cxgbi_device_find_by_lldev(t3dev); 12846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!cdev || cdev->flags & CXGBI_FLAG_ADAPTER_RESET) { 12866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("0x%p close, f 0x%x.\n", cdev, cdev ? cdev->flags : 0); 12876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return; 12886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 12896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_device_unregister(cdev); 12916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 12926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 12936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/** 12946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * cxgb3i_dev_open - init a t3 adapter structure and any h/w settings 12956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * @t3dev: t3cdev adapter 12966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 12976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void cxgb3i_dev_open(struct t3cdev *t3dev) 12986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 12996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_device *cdev = cxgbi_device_find_by_lldev(t3dev); 13006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct adapter *adapter = tdev2adap(t3dev); 13016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int i, err; 13026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (cdev) { 13046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("0x%p, updating.\n", cdev); 13056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return; 13066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 13076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev = cxgbi_device_register(0, adapter->params.nports); 13096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!cdev) { 13106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_warn("device 0x%p register failed.\n", t3dev); 13116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return; 13126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 13136f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13146f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->flags = CXGBI_FLAG_DEV_T3 | CXGBI_FLAG_IPV4_SET; 13156f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->lldev = t3dev; 13166f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->pdev = adapter->pdev; 13176f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->ports = adapter->port; 13186f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->nports = adapter->params.nports; 13196f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->mtus = adapter->params.mtus; 13206f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->nmtus = NMTUS; 13216f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->snd_win = cxgb3i_snd_win; 13226f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->rcv_win = cxgb3i_rcv_win; 13236f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->rx_credit_thres = cxgb3i_rx_credit_thres; 13246f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->skb_tx_rsvd = CXGB3I_TX_HEADER_LEN; 13256f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->skb_rx_extra = sizeof(struct cpl_iscsi_hdr_norss); 13266f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->dev_ddp_cleanup = t3_ddp_cleanup; 13276f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->itp = &cxgb3i_iscsi_transport; 13286f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13296f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com err = cxgb3i_ddp_init(cdev); 13306f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (err) { 13316f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("0x%p ddp init failed\n", cdev); 13326f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto err_out; 13336f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 13346f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13356f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com err = cxgb3i_ofld_init(cdev); 13366f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (err) { 13376f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("0x%p offload init failed\n", cdev); 13386f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto err_out; 13396f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 13406f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13416f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com err = cxgbi_hbas_add(cdev, CXGB3I_MAX_LUN, CXGBI_MAX_CONN, 13426f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com &cxgb3i_host_template, cxgb3i_stt); 13436f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (err) 13446f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com goto err_out; 13456f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13466f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com for (i = 0; i < cdev->nports; i++) 13476f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->hbas[i]->ipv4addr = 13486f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3i_get_private_ipv4addr(cdev->ports[i]); 13496f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13506f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com pr_info("cdev 0x%p, f 0x%x, t3dev 0x%p open, err %d.\n", 13516f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev, cdev ? cdev->flags : 0, t3dev, err); 13526f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return; 13536f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13546f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comerr_out: 13556f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_device_unregister(cdev); 13566f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 13576f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13586f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void cxgb3i_dev_event_handler(struct t3cdev *t3dev, u32 event, u32 port) 13596f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 13606f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com struct cxgbi_device *cdev = cxgbi_device_find_by_lldev(t3dev); 13616f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13626f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com log_debug(1 << CXGBI_DBG_TOE, 13636f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com "0x%p, cdev 0x%p, event 0x%x, port 0x%x.\n", 13646f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com t3dev, cdev, event, port); 13656f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (!cdev) 13666f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return; 13676f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13686f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com switch (event) { 13696f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case OFFLOAD_STATUS_DOWN: 13706f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->flags |= CXGBI_FLAG_ADAPTER_RESET; 13716f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com break; 13726f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com case OFFLOAD_STATUS_UP: 13736f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cdev->flags &= ~CXGBI_FLAG_ADAPTER_RESET; 13746f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com break; 13756f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com } 13766f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 13776f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13786f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/** 13796f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * cxgb3i_init_module - module init entry point 13806f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 13816f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * initialize any driver wide global data structures and register itself 13826f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * with the cxgb3 module 13836f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 13846f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic int __init cxgb3i_init_module(void) 13856f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 13866f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com int rc; 13876f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13886f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com printk(KERN_INFO "%s", version); 13896f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13906f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com rc = cxgbi_iscsi_init(&cxgb3i_iscsi_transport, &cxgb3i_stt); 13916f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com if (rc < 0) 13926f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return rc; 13936f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13946f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_register_client(&t3_client); 13956f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com return 0; 13966f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 13976f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 13986f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com/** 13996f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * cxgb3i_exit_module - module cleanup/exit entry point 14006f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * 14016f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * go through the driver hba list and for each hba, release any resource held. 14026f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com * and unregisters iscsi transport and the cxgb3 module 14036f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com */ 14046f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.comstatic void __exit cxgb3i_exit_module(void) 14056f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com{ 14066f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgb3_unregister_client(&t3_client); 14076f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_device_unregister_all(CXGBI_FLAG_DEV_T3); 14086f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com cxgbi_iscsi_cleanup(&cxgb3i_iscsi_transport, &cxgb3i_stt); 14096f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com} 14106f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.com 14116f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.commodule_init(cxgb3i_init_module); 14126f7efaabefebfbc523ea9776e3663a2d81b86399kxie@chelsio.commodule_exit(cxgb3i_exit_module); 1413