16733b39aSJayamohan Kallickal /** 2*c4f39bdaSKetan Mukadam * Copyright (C) 2005 - 2015 Emulex 36733b39aSJayamohan Kallickal * All rights reserved. 46733b39aSJayamohan Kallickal * 56733b39aSJayamohan Kallickal * This program is free software; you can redistribute it and/or 66733b39aSJayamohan Kallickal * modify it under the terms of the GNU General Public License version 2 76733b39aSJayamohan Kallickal * as published by the Free Software Foundation. The full GNU General 86733b39aSJayamohan Kallickal * Public License is included in this distribution in the file called COPYING. 96733b39aSJayamohan Kallickal * 104627de93SMinh Tran * Written by: Jayamohan Kallickal (jayamohan.kallickal@avagotech.com) 116733b39aSJayamohan Kallickal * 126733b39aSJayamohan Kallickal * Contact Information: 134627de93SMinh Tran * linux-drivers@avagotech.com 146733b39aSJayamohan Kallickal * 15*c4f39bdaSKetan Mukadam * Emulex 16255fa9a3SJayamohan Kallickal * 3333 Susan Street 17255fa9a3SJayamohan Kallickal * Costa Mesa, CA 92626 186733b39aSJayamohan Kallickal */ 196733b39aSJayamohan Kallickal 206733b39aSJayamohan Kallickal #include <scsi/libiscsi.h> 216733b39aSJayamohan Kallickal #include <scsi/scsi_transport_iscsi.h> 226733b39aSJayamohan Kallickal #include <scsi/scsi_transport.h> 236733b39aSJayamohan Kallickal #include <scsi/scsi_cmnd.h> 246733b39aSJayamohan Kallickal #include <scsi/scsi_device.h> 256733b39aSJayamohan Kallickal #include <scsi/scsi_host.h> 260e43895eSMike Christie #include <scsi/scsi_netlink.h> 270e43895eSMike Christie #include <net/netlink.h> 286733b39aSJayamohan Kallickal #include <scsi/scsi.h> 296733b39aSJayamohan Kallickal 306733b39aSJayamohan Kallickal #include "be_iscsi.h" 316733b39aSJayamohan Kallickal 326733b39aSJayamohan Kallickal extern struct iscsi_transport beiscsi_iscsi_transport; 336733b39aSJayamohan Kallickal 346733b39aSJayamohan Kallickal /** 356733b39aSJayamohan Kallickal * beiscsi_session_create - creates a new iscsi session 366733b39aSJayamohan Kallickal * @cmds_max: max commands supported 376733b39aSJayamohan Kallickal * @qdepth: max queue depth supported 386733b39aSJayamohan Kallickal * @initial_cmdsn: initial iscsi CMDSN 396733b39aSJayamohan Kallickal */ 406733b39aSJayamohan Kallickal struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep, 416733b39aSJayamohan Kallickal u16 cmds_max, 426733b39aSJayamohan Kallickal u16 qdepth, 436733b39aSJayamohan Kallickal u32 initial_cmdsn) 446733b39aSJayamohan Kallickal { 456733b39aSJayamohan Kallickal struct Scsi_Host *shost; 466733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep; 476733b39aSJayamohan Kallickal struct iscsi_cls_session *cls_session; 486733b39aSJayamohan Kallickal struct beiscsi_hba *phba; 49b8b9e1b8SJayamohan Kallickal struct iscsi_session *sess; 50b8b9e1b8SJayamohan Kallickal struct beiscsi_session *beiscsi_sess; 516733b39aSJayamohan Kallickal struct beiscsi_io_task *io_task; 526733b39aSJayamohan Kallickal 536733b39aSJayamohan Kallickal 546733b39aSJayamohan Kallickal if (!ep) { 5599bc5d55SJohn Soni Jose printk(KERN_ERR 5699bc5d55SJohn Soni Jose "beiscsi_session_create: invalid ep\n"); 576733b39aSJayamohan Kallickal return NULL; 586733b39aSJayamohan Kallickal } 596733b39aSJayamohan Kallickal beiscsi_ep = ep->dd_data; 606733b39aSJayamohan Kallickal phba = beiscsi_ep->phba; 6199bc5d55SJohn Soni Jose 623567f36aSJayamohan Kallickal if (phba->state & BE_ADAPTER_PCI_ERR) { 633567f36aSJayamohan Kallickal beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 643567f36aSJayamohan Kallickal "BS_%d : PCI_ERROR Recovery\n"); 653567f36aSJayamohan Kallickal return NULL; 663567f36aSJayamohan Kallickal } else { 6799bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 6899bc5d55SJohn Soni Jose "BS_%d : In beiscsi_session_create\n"); 693567f36aSJayamohan Kallickal } 7099bc5d55SJohn Soni Jose 716733b39aSJayamohan Kallickal if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) { 7299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 7399bc5d55SJohn Soni Jose "BS_%d : Cannot handle %d cmds." 746733b39aSJayamohan Kallickal "Max cmds per session supported is %d. Using %d." 756733b39aSJayamohan Kallickal "\n", cmds_max, 766733b39aSJayamohan Kallickal beiscsi_ep->phba->params.wrbs_per_cxn, 776733b39aSJayamohan Kallickal beiscsi_ep->phba->params.wrbs_per_cxn); 7899bc5d55SJohn Soni Jose 796733b39aSJayamohan Kallickal cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn; 806733b39aSJayamohan Kallickal } 816733b39aSJayamohan Kallickal 823567f36aSJayamohan Kallickal shost = phba->shost; 836733b39aSJayamohan Kallickal cls_session = iscsi_session_setup(&beiscsi_iscsi_transport, 846733b39aSJayamohan Kallickal shost, cmds_max, 85b8b9e1b8SJayamohan Kallickal sizeof(*beiscsi_sess), 86b8b9e1b8SJayamohan Kallickal sizeof(*io_task), 876733b39aSJayamohan Kallickal initial_cmdsn, ISCSI_MAX_TARGET); 886733b39aSJayamohan Kallickal if (!cls_session) 896733b39aSJayamohan Kallickal return NULL; 906733b39aSJayamohan Kallickal sess = cls_session->dd_data; 912afc95bfSJayamohan Kallickal beiscsi_sess = sess->dd_data; 922afc95bfSJayamohan Kallickal beiscsi_sess->bhs_pool = pci_pool_create("beiscsi_bhs_pool", 932afc95bfSJayamohan Kallickal phba->pcidev, 942afc95bfSJayamohan Kallickal sizeof(struct be_cmd_bhs), 952afc95bfSJayamohan Kallickal 64, 0); 962afc95bfSJayamohan Kallickal if (!beiscsi_sess->bhs_pool) 972afc95bfSJayamohan Kallickal goto destroy_sess; 986733b39aSJayamohan Kallickal 996733b39aSJayamohan Kallickal return cls_session; 1002afc95bfSJayamohan Kallickal destroy_sess: 1012afc95bfSJayamohan Kallickal iscsi_session_teardown(cls_session); 1022afc95bfSJayamohan Kallickal return NULL; 1036733b39aSJayamohan Kallickal } 1046733b39aSJayamohan Kallickal 1056733b39aSJayamohan Kallickal /** 1066733b39aSJayamohan Kallickal * beiscsi_session_destroy - destroys iscsi session 1076733b39aSJayamohan Kallickal * @cls_session: pointer to iscsi cls session 1086733b39aSJayamohan Kallickal * 1096733b39aSJayamohan Kallickal * Destroys iSCSI session instance and releases 1106733b39aSJayamohan Kallickal * resources allocated for it. 1116733b39aSJayamohan Kallickal */ 1126733b39aSJayamohan Kallickal void beiscsi_session_destroy(struct iscsi_cls_session *cls_session) 1136733b39aSJayamohan Kallickal { 1146733b39aSJayamohan Kallickal struct iscsi_session *sess = cls_session->dd_data; 1152afc95bfSJayamohan Kallickal struct beiscsi_session *beiscsi_sess = sess->dd_data; 1166733b39aSJayamohan Kallickal 11799bc5d55SJohn Soni Jose printk(KERN_INFO "In beiscsi_session_destroy\n"); 1182afc95bfSJayamohan Kallickal pci_pool_destroy(beiscsi_sess->bhs_pool); 1196733b39aSJayamohan Kallickal iscsi_session_teardown(cls_session); 1206733b39aSJayamohan Kallickal } 1216733b39aSJayamohan Kallickal 1226733b39aSJayamohan Kallickal /** 1236733b39aSJayamohan Kallickal * beiscsi_conn_create - create an instance of iscsi connection 1246733b39aSJayamohan Kallickal * @cls_session: ptr to iscsi_cls_session 1256733b39aSJayamohan Kallickal * @cid: iscsi cid 1266733b39aSJayamohan Kallickal */ 1276733b39aSJayamohan Kallickal struct iscsi_cls_conn * 1286733b39aSJayamohan Kallickal beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid) 1296733b39aSJayamohan Kallickal { 1306733b39aSJayamohan Kallickal struct beiscsi_hba *phba; 1316733b39aSJayamohan Kallickal struct Scsi_Host *shost; 1326733b39aSJayamohan Kallickal struct iscsi_cls_conn *cls_conn; 1336733b39aSJayamohan Kallickal struct beiscsi_conn *beiscsi_conn; 1346733b39aSJayamohan Kallickal struct iscsi_conn *conn; 1352afc95bfSJayamohan Kallickal struct iscsi_session *sess; 1362afc95bfSJayamohan Kallickal struct beiscsi_session *beiscsi_sess; 1376733b39aSJayamohan Kallickal 1386733b39aSJayamohan Kallickal shost = iscsi_session_to_shost(cls_session); 1396733b39aSJayamohan Kallickal phba = iscsi_host_priv(shost); 1406733b39aSJayamohan Kallickal 14199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 14299bc5d55SJohn Soni Jose "BS_%d : In beiscsi_conn_create ,cid" 14399bc5d55SJohn Soni Jose "from iscsi layer=%d\n", cid); 14499bc5d55SJohn Soni Jose 1456733b39aSJayamohan Kallickal cls_conn = iscsi_conn_setup(cls_session, sizeof(*beiscsi_conn), cid); 1466733b39aSJayamohan Kallickal if (!cls_conn) 1476733b39aSJayamohan Kallickal return NULL; 1486733b39aSJayamohan Kallickal 1496733b39aSJayamohan Kallickal conn = cls_conn->dd_data; 1506733b39aSJayamohan Kallickal beiscsi_conn = conn->dd_data; 1516733b39aSJayamohan Kallickal beiscsi_conn->ep = NULL; 1526733b39aSJayamohan Kallickal beiscsi_conn->phba = phba; 1536733b39aSJayamohan Kallickal beiscsi_conn->conn = conn; 1542afc95bfSJayamohan Kallickal sess = cls_session->dd_data; 1552afc95bfSJayamohan Kallickal beiscsi_sess = sess->dd_data; 1562afc95bfSJayamohan Kallickal beiscsi_conn->beiscsi_sess = beiscsi_sess; 1576733b39aSJayamohan Kallickal return cls_conn; 1586733b39aSJayamohan Kallickal } 1596733b39aSJayamohan Kallickal 1606733b39aSJayamohan Kallickal /** 1616733b39aSJayamohan Kallickal * beiscsi_bindconn_cid - Bind the beiscsi_conn with phba connection table 1626733b39aSJayamohan Kallickal * @beiscsi_conn: The pointer to beiscsi_conn structure 1636733b39aSJayamohan Kallickal * @phba: The phba instance 1646733b39aSJayamohan Kallickal * @cid: The cid to free 1656733b39aSJayamohan Kallickal */ 1666733b39aSJayamohan Kallickal static int beiscsi_bindconn_cid(struct beiscsi_hba *phba, 1676733b39aSJayamohan Kallickal struct beiscsi_conn *beiscsi_conn, 1686733b39aSJayamohan Kallickal unsigned int cid) 1696733b39aSJayamohan Kallickal { 170a7909b39SJayamohan Kallickal uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 171a7909b39SJayamohan Kallickal 172a7909b39SJayamohan Kallickal if (phba->conn_table[cri_index]) { 17399bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 17499bc5d55SJohn Soni Jose "BS_%d : Connection table already occupied. Detected clash\n"); 17599bc5d55SJohn Soni Jose 1766733b39aSJayamohan Kallickal return -EINVAL; 1776733b39aSJayamohan Kallickal } else { 17899bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 17999bc5d55SJohn Soni Jose "BS_%d : phba->conn_table[%d]=%p(beiscsi_conn)\n", 180a7909b39SJayamohan Kallickal cri_index, beiscsi_conn); 18199bc5d55SJohn Soni Jose 182a7909b39SJayamohan Kallickal phba->conn_table[cri_index] = beiscsi_conn; 1836733b39aSJayamohan Kallickal } 1846733b39aSJayamohan Kallickal return 0; 1856733b39aSJayamohan Kallickal } 1866733b39aSJayamohan Kallickal 1876733b39aSJayamohan Kallickal /** 1886733b39aSJayamohan Kallickal * beiscsi_conn_bind - Binds iscsi session/connection with TCP connection 1896733b39aSJayamohan Kallickal * @cls_session: pointer to iscsi cls session 1906733b39aSJayamohan Kallickal * @cls_conn: pointer to iscsi cls conn 1916733b39aSJayamohan Kallickal * @transport_fd: EP handle(64 bit) 1926733b39aSJayamohan Kallickal * 1936733b39aSJayamohan Kallickal * This function binds the TCP Conn with iSCSI Connection and Session. 1946733b39aSJayamohan Kallickal */ 1956733b39aSJayamohan Kallickal int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, 1966733b39aSJayamohan Kallickal struct iscsi_cls_conn *cls_conn, 1976733b39aSJayamohan Kallickal u64 transport_fd, int is_leading) 1986733b39aSJayamohan Kallickal { 1996733b39aSJayamohan Kallickal struct iscsi_conn *conn = cls_conn->dd_data; 2006733b39aSJayamohan Kallickal struct beiscsi_conn *beiscsi_conn = conn->dd_data; 2013093b048SMike Christie struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 2023093b048SMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 2031e4be6ffSJayamohan Kallickal struct hwi_controller *phwi_ctrlr = phba->phwi_ctrlr; 2041e4be6ffSJayamohan Kallickal struct hwi_wrb_context *pwrb_context; 2056733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep; 2066733b39aSJayamohan Kallickal struct iscsi_endpoint *ep; 2076733b39aSJayamohan Kallickal 2086733b39aSJayamohan Kallickal ep = iscsi_lookup_endpoint(transport_fd); 2096733b39aSJayamohan Kallickal if (!ep) 2106733b39aSJayamohan Kallickal return -EINVAL; 2116733b39aSJayamohan Kallickal 2126733b39aSJayamohan Kallickal beiscsi_ep = ep->dd_data; 2136733b39aSJayamohan Kallickal 2146733b39aSJayamohan Kallickal if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) 2156733b39aSJayamohan Kallickal return -EINVAL; 2166733b39aSJayamohan Kallickal 2176733b39aSJayamohan Kallickal if (beiscsi_ep->phba != phba) { 21899bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 21999bc5d55SJohn Soni Jose "BS_%d : beiscsi_ep->hba=%p not equal to phba=%p\n", 2206733b39aSJayamohan Kallickal beiscsi_ep->phba, phba); 22199bc5d55SJohn Soni Jose 2226733b39aSJayamohan Kallickal return -EEXIST; 2236733b39aSJayamohan Kallickal } 2246733b39aSJayamohan Kallickal 2251e4be6ffSJayamohan Kallickal pwrb_context = &phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID( 2261e4be6ffSJayamohan Kallickal beiscsi_ep->ep_cid)]; 2271e4be6ffSJayamohan Kallickal 2286733b39aSJayamohan Kallickal beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid; 2296733b39aSJayamohan Kallickal beiscsi_conn->ep = beiscsi_ep; 2306733b39aSJayamohan Kallickal beiscsi_ep->conn = beiscsi_conn; 2311e4be6ffSJayamohan Kallickal beiscsi_conn->doorbell_offset = pwrb_context->doorbell_offset; 23299bc5d55SJohn Soni Jose 23399bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 23499bc5d55SJohn Soni Jose "BS_%d : beiscsi_conn=%p conn=%p ep_cid=%d\n", 2356733b39aSJayamohan Kallickal beiscsi_conn, conn, beiscsi_ep->ep_cid); 23699bc5d55SJohn Soni Jose 2376733b39aSJayamohan Kallickal return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid); 2386733b39aSJayamohan Kallickal } 2396733b39aSJayamohan Kallickal 2400e43895eSMike Christie static int beiscsi_create_ipv4_iface(struct beiscsi_hba *phba) 2410e43895eSMike Christie { 2420e43895eSMike Christie if (phba->ipv4_iface) 2430e43895eSMike Christie return 0; 2440e43895eSMike Christie 2450e43895eSMike Christie phba->ipv4_iface = iscsi_create_iface(phba->shost, 2460e43895eSMike Christie &beiscsi_iscsi_transport, 2470e43895eSMike Christie ISCSI_IFACE_TYPE_IPV4, 2480e43895eSMike Christie 0, 0); 2490e43895eSMike Christie if (!phba->ipv4_iface) { 25099bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 25199bc5d55SJohn Soni Jose "BS_%d : Could not " 2520e43895eSMike Christie "create default IPv4 address.\n"); 2530e43895eSMike Christie return -ENODEV; 2540e43895eSMike Christie } 2550e43895eSMike Christie 2560e43895eSMike Christie return 0; 2570e43895eSMike Christie } 2580e43895eSMike Christie 2590e43895eSMike Christie static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba) 2600e43895eSMike Christie { 2610e43895eSMike Christie if (phba->ipv6_iface) 2620e43895eSMike Christie return 0; 2630e43895eSMike Christie 2640e43895eSMike Christie phba->ipv6_iface = iscsi_create_iface(phba->shost, 2650e43895eSMike Christie &beiscsi_iscsi_transport, 2660e43895eSMike Christie ISCSI_IFACE_TYPE_IPV6, 2670e43895eSMike Christie 0, 0); 2680e43895eSMike Christie if (!phba->ipv6_iface) { 26999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 27099bc5d55SJohn Soni Jose "BS_%d : Could not " 2710e43895eSMike Christie "create default IPv6 address.\n"); 2720e43895eSMike Christie return -ENODEV; 2730e43895eSMike Christie } 2740e43895eSMike Christie 2750e43895eSMike Christie return 0; 2760e43895eSMike Christie } 2770e43895eSMike Christie 2780e43895eSMike Christie void beiscsi_create_def_ifaces(struct beiscsi_hba *phba) 2790e43895eSMike Christie { 2801f536d49SJayamohan Kallickal struct be_cmd_get_if_info_resp *if_info; 2810e43895eSMike Christie 2821f536d49SJayamohan Kallickal if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info)) { 2830e43895eSMike Christie beiscsi_create_ipv4_iface(phba); 2841f536d49SJayamohan Kallickal kfree(if_info); 2851f536d49SJayamohan Kallickal } 2860e43895eSMike Christie 2871f536d49SJayamohan Kallickal if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info)) { 2880e43895eSMike Christie beiscsi_create_ipv6_iface(phba); 2891f536d49SJayamohan Kallickal kfree(if_info); 2901f536d49SJayamohan Kallickal } 2910e43895eSMike Christie } 2920e43895eSMike Christie 2930e43895eSMike Christie void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba) 2940e43895eSMike Christie { 2950e43895eSMike Christie if (phba->ipv6_iface) 2960e43895eSMike Christie iscsi_destroy_iface(phba->ipv6_iface); 2970e43895eSMike Christie if (phba->ipv4_iface) 2980e43895eSMike Christie iscsi_destroy_iface(phba->ipv4_iface); 2990e43895eSMike Christie } 3000e43895eSMike Christie 3010e43895eSMike Christie static int 3020e43895eSMike Christie beiscsi_set_static_ip(struct Scsi_Host *shost, 3030e43895eSMike Christie struct iscsi_iface_param_info *iface_param, 3040e43895eSMike Christie void *data, uint32_t dt_len) 3050e43895eSMike Christie { 3060e43895eSMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 3070e43895eSMike Christie struct iscsi_iface_param_info *iface_ip = NULL; 3080e43895eSMike Christie struct iscsi_iface_param_info *iface_subnet = NULL; 3090e43895eSMike Christie struct nlattr *nla; 3100e43895eSMike Christie int ret; 3110e43895eSMike Christie 3120e43895eSMike Christie 3130e43895eSMike Christie switch (iface_param->param) { 3140e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 3150e43895eSMike Christie nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR); 3160e43895eSMike Christie if (nla) 3170e43895eSMike Christie iface_ip = nla_data(nla); 3180e43895eSMike Christie 3190e43895eSMike Christie nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET); 3200e43895eSMike Christie if (nla) 3210e43895eSMike Christie iface_subnet = nla_data(nla); 3220e43895eSMike Christie break; 3230e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_ADDR: 3240e43895eSMike Christie iface_ip = iface_param; 3250e43895eSMike Christie nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET); 3260e43895eSMike Christie if (nla) 3270e43895eSMike Christie iface_subnet = nla_data(nla); 3280e43895eSMike Christie break; 3290e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_SUBNET: 3300e43895eSMike Christie iface_subnet = iface_param; 3310e43895eSMike Christie nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR); 3320e43895eSMike Christie if (nla) 3330e43895eSMike Christie iface_ip = nla_data(nla); 3340e43895eSMike Christie break; 3350e43895eSMike Christie default: 33699bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 33799bc5d55SJohn Soni Jose "BS_%d : Unsupported param %d\n", 3380e43895eSMike Christie iface_param->param); 3390e43895eSMike Christie } 3400e43895eSMike Christie 3410e43895eSMike Christie if (!iface_ip || !iface_subnet) { 34299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 34399bc5d55SJohn Soni Jose "BS_%d : IP and Subnet Mask required\n"); 3440e43895eSMike Christie return -EINVAL; 3450e43895eSMike Christie } 3460e43895eSMike Christie 3470e43895eSMike Christie ret = mgmt_set_ip(phba, iface_ip, iface_subnet, 3480e43895eSMike Christie ISCSI_BOOTPROTO_STATIC); 3490e43895eSMike Christie 3500e43895eSMike Christie return ret; 3510e43895eSMike Christie } 3520e43895eSMike Christie 3536f72238eSJohn Soni Jose /** 3546f72238eSJohn Soni Jose * beiscsi_set_vlan_tag()- Set the VLAN TAG 3556f72238eSJohn Soni Jose * @shost: Scsi Host for the driver instance 3566f72238eSJohn Soni Jose * @iface_param: Interface paramters 3576f72238eSJohn Soni Jose * 3586f72238eSJohn Soni Jose * Set the VLAN TAG for the adapter or disable 3596f72238eSJohn Soni Jose * the VLAN config 3606f72238eSJohn Soni Jose * 3616f72238eSJohn Soni Jose * returns 3626f72238eSJohn Soni Jose * Success: 0 3636f72238eSJohn Soni Jose * Failure: Non-Zero Value 3646f72238eSJohn Soni Jose **/ 3656f72238eSJohn Soni Jose static int 3666f72238eSJohn Soni Jose beiscsi_set_vlan_tag(struct Scsi_Host *shost, 3676f72238eSJohn Soni Jose struct iscsi_iface_param_info *iface_param) 3686f72238eSJohn Soni Jose { 3696f72238eSJohn Soni Jose struct beiscsi_hba *phba = iscsi_host_priv(shost); 3706f72238eSJohn Soni Jose int ret = 0; 3716f72238eSJohn Soni Jose 3726f72238eSJohn Soni Jose /* Get the Interface Handle */ 3736f72238eSJohn Soni Jose if (mgmt_get_all_if_id(phba)) { 3746f72238eSJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 3756f72238eSJohn Soni Jose "BS_%d : Getting Interface Handle Failed\n"); 3766f72238eSJohn Soni Jose return -EIO; 3776f72238eSJohn Soni Jose } 3786f72238eSJohn Soni Jose 3796f72238eSJohn Soni Jose switch (iface_param->param) { 3806f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ENABLED: 3816f72238eSJohn Soni Jose if (iface_param->value[0] != ISCSI_VLAN_ENABLE) 3826f72238eSJohn Soni Jose ret = mgmt_set_vlan(phba, BEISCSI_VLAN_DISABLE); 3836f72238eSJohn Soni Jose break; 3846f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_TAG: 3856f72238eSJohn Soni Jose ret = mgmt_set_vlan(phba, 3866f72238eSJohn Soni Jose *((uint16_t *)iface_param->value)); 3876f72238eSJohn Soni Jose break; 3886f72238eSJohn Soni Jose default: 3896f72238eSJohn Soni Jose beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 390b23f7a09SMasanari Iida "BS_%d : Unknown Param Type : %d\n", 3916f72238eSJohn Soni Jose iface_param->param); 3926f72238eSJohn Soni Jose return -ENOSYS; 3936f72238eSJohn Soni Jose } 3946f72238eSJohn Soni Jose return ret; 3956f72238eSJohn Soni Jose } 3966f72238eSJohn Soni Jose 3976f72238eSJohn Soni Jose 3980e43895eSMike Christie static int 3990e43895eSMike Christie beiscsi_set_ipv4(struct Scsi_Host *shost, 4000e43895eSMike Christie struct iscsi_iface_param_info *iface_param, 4010e43895eSMike Christie void *data, uint32_t dt_len) 4020e43895eSMike Christie { 4030e43895eSMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 4040e43895eSMike Christie int ret = 0; 4050e43895eSMike Christie 4060e43895eSMike Christie /* Check the param */ 4070e43895eSMike Christie switch (iface_param->param) { 4080e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_GW: 4090e43895eSMike Christie ret = mgmt_set_gateway(phba, iface_param); 4100e43895eSMike Christie break; 4110e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 4120e43895eSMike Christie if (iface_param->value[0] == ISCSI_BOOTPROTO_DHCP) 4130e43895eSMike Christie ret = mgmt_set_ip(phba, iface_param, 4140e43895eSMike Christie NULL, ISCSI_BOOTPROTO_DHCP); 4150e43895eSMike Christie else if (iface_param->value[0] == ISCSI_BOOTPROTO_STATIC) 4160e43895eSMike Christie ret = beiscsi_set_static_ip(shost, iface_param, 4170e43895eSMike Christie data, dt_len); 4180e43895eSMike Christie else 41999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 42099bc5d55SJohn Soni Jose "BS_%d : Invalid BOOTPROTO: %d\n", 4210e43895eSMike Christie iface_param->value[0]); 4220e43895eSMike Christie break; 4230e43895eSMike Christie case ISCSI_NET_PARAM_IFACE_ENABLE: 4240e43895eSMike Christie if (iface_param->value[0] == ISCSI_IFACE_ENABLE) 4250e43895eSMike Christie ret = beiscsi_create_ipv4_iface(phba); 4260e43895eSMike Christie else 4270e43895eSMike Christie iscsi_destroy_iface(phba->ipv4_iface); 4280e43895eSMike Christie break; 4290e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_SUBNET: 4300e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_ADDR: 4310e43895eSMike Christie ret = beiscsi_set_static_ip(shost, iface_param, 4320e43895eSMike Christie data, dt_len); 4330e43895eSMike Christie break; 4346f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ENABLED: 4356f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_TAG: 4366f72238eSJohn Soni Jose ret = beiscsi_set_vlan_tag(shost, iface_param); 4376f72238eSJohn Soni Jose break; 4380e43895eSMike Christie default: 43999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 44099bc5d55SJohn Soni Jose "BS_%d : Param %d not supported\n", 4410e43895eSMike Christie iface_param->param); 4420e43895eSMike Christie } 4430e43895eSMike Christie 4440e43895eSMike Christie return ret; 4450e43895eSMike Christie } 4460e43895eSMike Christie 4470e43895eSMike Christie static int 4480e43895eSMike Christie beiscsi_set_ipv6(struct Scsi_Host *shost, 4490e43895eSMike Christie struct iscsi_iface_param_info *iface_param, 4500e43895eSMike Christie void *data, uint32_t dt_len) 4510e43895eSMike Christie { 4520e43895eSMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 4530e43895eSMike Christie int ret = 0; 4540e43895eSMike Christie 4550e43895eSMike Christie switch (iface_param->param) { 4560e43895eSMike Christie case ISCSI_NET_PARAM_IFACE_ENABLE: 4570e43895eSMike Christie if (iface_param->value[0] == ISCSI_IFACE_ENABLE) 4580e43895eSMike Christie ret = beiscsi_create_ipv6_iface(phba); 4590e43895eSMike Christie else { 4600e43895eSMike Christie iscsi_destroy_iface(phba->ipv6_iface); 4610e43895eSMike Christie ret = 0; 4620e43895eSMike Christie } 4630e43895eSMike Christie break; 4640e43895eSMike Christie case ISCSI_NET_PARAM_IPV6_ADDR: 4650e43895eSMike Christie ret = mgmt_set_ip(phba, iface_param, NULL, 4660e43895eSMike Christie ISCSI_BOOTPROTO_STATIC); 4670e43895eSMike Christie break; 4680e43895eSMike Christie default: 46999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 47099bc5d55SJohn Soni Jose "BS_%d : Param %d not supported\n", 4710e43895eSMike Christie iface_param->param); 4720e43895eSMike Christie } 4730e43895eSMike Christie 4740e43895eSMike Christie return ret; 4750e43895eSMike Christie } 4760e43895eSMike Christie 4770e43895eSMike Christie int be2iscsi_iface_set_param(struct Scsi_Host *shost, 4780e43895eSMike Christie void *data, uint32_t dt_len) 4790e43895eSMike Christie { 4800e43895eSMike Christie struct iscsi_iface_param_info *iface_param = NULL; 48199bc5d55SJohn Soni Jose struct beiscsi_hba *phba = iscsi_host_priv(shost); 4820e43895eSMike Christie struct nlattr *attrib; 4830e43895eSMike Christie uint32_t rm_len = dt_len; 4840e43895eSMike Christie int ret = 0 ; 4850e43895eSMike Christie 4863567f36aSJayamohan Kallickal if (phba->state & BE_ADAPTER_PCI_ERR) { 4873567f36aSJayamohan Kallickal beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 4883567f36aSJayamohan Kallickal "BS_%d : In PCI_ERROR Recovery\n"); 4893567f36aSJayamohan Kallickal return -EBUSY; 4903567f36aSJayamohan Kallickal } 4913567f36aSJayamohan Kallickal 4920e43895eSMike Christie nla_for_each_attr(attrib, data, dt_len, rm_len) { 4930e43895eSMike Christie iface_param = nla_data(attrib); 4940e43895eSMike Christie 4950e43895eSMike Christie if (iface_param->param_type != ISCSI_NET_PARAM) 4960e43895eSMike Christie continue; 4970e43895eSMike Christie 4980e43895eSMike Christie /* 4990e43895eSMike Christie * BE2ISCSI only supports 1 interface 5000e43895eSMike Christie */ 5010e43895eSMike Christie if (iface_param->iface_num) { 50299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 50399bc5d55SJohn Soni Jose "BS_%d : Invalid iface_num %d." 5040e43895eSMike Christie "Only iface_num 0 is supported.\n", 5050e43895eSMike Christie iface_param->iface_num); 50699bc5d55SJohn Soni Jose 5070e43895eSMike Christie return -EINVAL; 5080e43895eSMike Christie } 5090e43895eSMike Christie 5100e43895eSMike Christie switch (iface_param->iface_type) { 5110e43895eSMike Christie case ISCSI_IFACE_TYPE_IPV4: 5120e43895eSMike Christie ret = beiscsi_set_ipv4(shost, iface_param, 5130e43895eSMike Christie data, dt_len); 5140e43895eSMike Christie break; 5150e43895eSMike Christie case ISCSI_IFACE_TYPE_IPV6: 5160e43895eSMike Christie ret = beiscsi_set_ipv6(shost, iface_param, 5170e43895eSMike Christie data, dt_len); 5180e43895eSMike Christie break; 5190e43895eSMike Christie default: 52099bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 52199bc5d55SJohn Soni Jose "BS_%d : Invalid iface type :%d passed\n", 5220e43895eSMike Christie iface_param->iface_type); 5230e43895eSMike Christie break; 5240e43895eSMike Christie } 5250e43895eSMike Christie 5260e43895eSMike Christie if (ret) 5270e43895eSMike Christie return ret; 5280e43895eSMike Christie } 5290e43895eSMike Christie 5300e43895eSMike Christie return ret; 5310e43895eSMike Christie } 5320e43895eSMike Christie 5330e43895eSMike Christie static int be2iscsi_get_if_param(struct beiscsi_hba *phba, 5340e43895eSMike Christie struct iscsi_iface *iface, int param, 5350e43895eSMike Christie char *buf) 5360e43895eSMike Christie { 5371f536d49SJayamohan Kallickal struct be_cmd_get_if_info_resp *if_info; 5380e43895eSMike Christie int len, ip_type = BE2_IPV4; 5390e43895eSMike Christie 5400e43895eSMike Christie if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) 5410e43895eSMike Christie ip_type = BE2_IPV6; 5420e43895eSMike Christie 5430e43895eSMike Christie len = mgmt_get_if_info(phba, ip_type, &if_info); 5440e7c60cbSGeyslan G. Bem if (len) 5450e43895eSMike Christie return len; 5460e43895eSMike Christie 5470e43895eSMike Christie switch (param) { 5480e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_ADDR: 5491f536d49SJayamohan Kallickal len = sprintf(buf, "%pI4\n", if_info->ip_addr.addr); 5500e43895eSMike Christie break; 5510e43895eSMike Christie case ISCSI_NET_PARAM_IPV6_ADDR: 5521f536d49SJayamohan Kallickal len = sprintf(buf, "%pI6\n", if_info->ip_addr.addr); 5530e43895eSMike Christie break; 5540e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 5551f536d49SJayamohan Kallickal if (!if_info->dhcp_state) 5568359c79bSJohn Soni Jose len = sprintf(buf, "static\n"); 5570e43895eSMike Christie else 5588359c79bSJohn Soni Jose len = sprintf(buf, "dhcp\n"); 5590e43895eSMike Christie break; 5600e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_SUBNET: 5611f536d49SJayamohan Kallickal len = sprintf(buf, "%pI4\n", if_info->ip_addr.subnet_mask); 5620e43895eSMike Christie break; 5636f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ENABLED: 5646f72238eSJohn Soni Jose len = sprintf(buf, "%s\n", 5651f536d49SJayamohan Kallickal (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 5668359c79bSJohn Soni Jose ? "Disabled\n" : "Enabled\n"); 5676f72238eSJohn Soni Jose break; 5686f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ID: 5691f536d49SJayamohan Kallickal if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 5700e7c60cbSGeyslan G. Bem len = -EINVAL; 5716f72238eSJohn Soni Jose else 5726f72238eSJohn Soni Jose len = sprintf(buf, "%d\n", 5731f536d49SJayamohan Kallickal (if_info->vlan_priority & 5746f72238eSJohn Soni Jose ISCSI_MAX_VLAN_ID)); 5756f72238eSJohn Soni Jose break; 5766f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_PRIORITY: 5771f536d49SJayamohan Kallickal if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 5780e7c60cbSGeyslan G. Bem len = -EINVAL; 5796f72238eSJohn Soni Jose else 5806f72238eSJohn Soni Jose len = sprintf(buf, "%d\n", 5811f536d49SJayamohan Kallickal ((if_info->vlan_priority >> 13) & 5826f72238eSJohn Soni Jose ISCSI_MAX_VLAN_PRIORITY)); 5836f72238eSJohn Soni Jose break; 5840e43895eSMike Christie default: 5850e43895eSMike Christie WARN_ON(1); 5860e43895eSMike Christie } 5870e43895eSMike Christie 5881f536d49SJayamohan Kallickal kfree(if_info); 5890e43895eSMike Christie return len; 5900e43895eSMike Christie } 5910e43895eSMike Christie 5920e43895eSMike Christie int be2iscsi_iface_get_param(struct iscsi_iface *iface, 5930e43895eSMike Christie enum iscsi_param_type param_type, 5940e43895eSMike Christie int param, char *buf) 5950e43895eSMike Christie { 5960e43895eSMike Christie struct Scsi_Host *shost = iscsi_iface_to_shost(iface); 5970e43895eSMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 5980e43895eSMike Christie struct be_cmd_get_def_gateway_resp gateway; 5990e43895eSMike Christie int len = -ENOSYS; 6000e43895eSMike Christie 6013567f36aSJayamohan Kallickal if (phba->state & BE_ADAPTER_PCI_ERR) { 6023567f36aSJayamohan Kallickal beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 6033567f36aSJayamohan Kallickal "BS_%d : In PCI_ERROR Recovery\n"); 6043567f36aSJayamohan Kallickal return -EBUSY; 6053567f36aSJayamohan Kallickal } 6063567f36aSJayamohan Kallickal 6070e43895eSMike Christie switch (param) { 6080e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_ADDR: 6090e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_SUBNET: 6100e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 6110e43895eSMike Christie case ISCSI_NET_PARAM_IPV6_ADDR: 6126f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ENABLED: 6136f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ID: 6146f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_PRIORITY: 6150e43895eSMike Christie len = be2iscsi_get_if_param(phba, iface, param, buf); 6160e43895eSMike Christie break; 6170e43895eSMike Christie case ISCSI_NET_PARAM_IFACE_ENABLE: 6188359c79bSJohn Soni Jose len = sprintf(buf, "enabled\n"); 6190e43895eSMike Christie break; 6200e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_GW: 6210e43895eSMike Christie memset(&gateway, 0, sizeof(gateway)); 6220e43895eSMike Christie len = mgmt_get_gateway(phba, BE2_IPV4, &gateway); 6230e43895eSMike Christie if (!len) 6240e43895eSMike Christie len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr); 6250e43895eSMike Christie break; 6260e43895eSMike Christie default: 6270e43895eSMike Christie len = -ENOSYS; 6280e43895eSMike Christie } 6290e43895eSMike Christie 6300e43895eSMike Christie return len; 6310e43895eSMike Christie } 6320e43895eSMike Christie 6336733b39aSJayamohan Kallickal /** 634c7f7fd5bSMike Christie * beiscsi_ep_get_param - get the iscsi parameter 635c7f7fd5bSMike Christie * @ep: pointer to iscsi ep 6366733b39aSJayamohan Kallickal * @param: parameter type identifier 6376733b39aSJayamohan Kallickal * @buf: buffer pointer 6386733b39aSJayamohan Kallickal * 6396733b39aSJayamohan Kallickal * returns iscsi parameter 6406733b39aSJayamohan Kallickal */ 641c7f7fd5bSMike Christie int beiscsi_ep_get_param(struct iscsi_endpoint *ep, 6426733b39aSJayamohan Kallickal enum iscsi_param param, char *buf) 6436733b39aSJayamohan Kallickal { 644c7f7fd5bSMike Christie struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 6456733b39aSJayamohan Kallickal int len = 0; 6466733b39aSJayamohan Kallickal 64799bc5d55SJohn Soni Jose beiscsi_log(beiscsi_ep->phba, KERN_INFO, 64899bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG, 64999bc5d55SJohn Soni Jose "BS_%d : In beiscsi_ep_get_param," 65099bc5d55SJohn Soni Jose " param= %d\n", param); 6516733b39aSJayamohan Kallickal 6526733b39aSJayamohan Kallickal switch (param) { 6536733b39aSJayamohan Kallickal case ISCSI_PARAM_CONN_PORT: 6546733b39aSJayamohan Kallickal len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport); 6556733b39aSJayamohan Kallickal break; 6566733b39aSJayamohan Kallickal case ISCSI_PARAM_CONN_ADDRESS: 6576733b39aSJayamohan Kallickal if (beiscsi_ep->ip_type == BE2_IPV4) 6586733b39aSJayamohan Kallickal len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr); 6596733b39aSJayamohan Kallickal else 6606733b39aSJayamohan Kallickal len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr); 6616733b39aSJayamohan Kallickal break; 6626733b39aSJayamohan Kallickal default: 663c7f7fd5bSMike Christie return -ENOSYS; 6646733b39aSJayamohan Kallickal } 6656733b39aSJayamohan Kallickal return len; 6666733b39aSJayamohan Kallickal } 6676733b39aSJayamohan Kallickal 6686733b39aSJayamohan Kallickal int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, 6696733b39aSJayamohan Kallickal enum iscsi_param param, char *buf, int buflen) 6706733b39aSJayamohan Kallickal { 6716733b39aSJayamohan Kallickal struct iscsi_conn *conn = cls_conn->dd_data; 6726733b39aSJayamohan Kallickal struct iscsi_session *session = conn->session; 67399bc5d55SJohn Soni Jose struct beiscsi_hba *phba = NULL; 6746733b39aSJayamohan Kallickal int ret; 6756733b39aSJayamohan Kallickal 67699bc5d55SJohn Soni Jose phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 67799bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 67899bc5d55SJohn Soni Jose "BS_%d : In beiscsi_conn_set_param," 67999bc5d55SJohn Soni Jose " param= %d\n", param); 68099bc5d55SJohn Soni Jose 6816733b39aSJayamohan Kallickal ret = iscsi_set_param(cls_conn, param, buf, buflen); 6826733b39aSJayamohan Kallickal if (ret) 6836733b39aSJayamohan Kallickal return ret; 6846733b39aSJayamohan Kallickal /* 6856733b39aSJayamohan Kallickal * If userspace tried to set the value to higher than we can 6866733b39aSJayamohan Kallickal * support override here. 6876733b39aSJayamohan Kallickal */ 6886733b39aSJayamohan Kallickal switch (param) { 6896733b39aSJayamohan Kallickal case ISCSI_PARAM_FIRST_BURST: 6906733b39aSJayamohan Kallickal if (session->first_burst > 8192) 6916733b39aSJayamohan Kallickal session->first_burst = 8192; 6926733b39aSJayamohan Kallickal break; 6936733b39aSJayamohan Kallickal case ISCSI_PARAM_MAX_RECV_DLENGTH: 6946733b39aSJayamohan Kallickal if (conn->max_recv_dlength > 65536) 6956733b39aSJayamohan Kallickal conn->max_recv_dlength = 65536; 6966733b39aSJayamohan Kallickal break; 6976733b39aSJayamohan Kallickal case ISCSI_PARAM_MAX_BURST: 698230dceb4SJayamohan Kallickal if (session->max_burst > 262144) 699230dceb4SJayamohan Kallickal session->max_burst = 262144; 7006733b39aSJayamohan Kallickal break; 70142f43c41SJayamohan Kallickal case ISCSI_PARAM_MAX_XMIT_DLENGTH: 7027331613eSJayamohan Kallickal if (conn->max_xmit_dlength > 65536) 70342f43c41SJayamohan Kallickal conn->max_xmit_dlength = 65536; 7046733b39aSJayamohan Kallickal default: 7056733b39aSJayamohan Kallickal return 0; 7066733b39aSJayamohan Kallickal } 7076733b39aSJayamohan Kallickal 7086733b39aSJayamohan Kallickal return 0; 7096733b39aSJayamohan Kallickal } 7106733b39aSJayamohan Kallickal 7116733b39aSJayamohan Kallickal /** 7122177199dSJohn Soni Jose * beiscsi_get_initname - Read Initiator Name from flash 7132177199dSJohn Soni Jose * @buf: buffer bointer 7142177199dSJohn Soni Jose * @phba: The device priv structure instance 7152177199dSJohn Soni Jose * 7162177199dSJohn Soni Jose * returns number of bytes 7172177199dSJohn Soni Jose */ 7182177199dSJohn Soni Jose static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba) 7192177199dSJohn Soni Jose { 7202177199dSJohn Soni Jose int rc; 721e175defeSJohn Soni Jose unsigned int tag; 7222177199dSJohn Soni Jose struct be_mcc_wrb *wrb; 7232177199dSJohn Soni Jose struct be_cmd_hba_name *resp; 7242177199dSJohn Soni Jose 7252177199dSJohn Soni Jose tag = be_cmd_get_initname(phba); 7262177199dSJohn Soni Jose if (!tag) { 72799bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 72899bc5d55SJohn Soni Jose "BS_%d : Getting Initiator Name Failed\n"); 72999bc5d55SJohn Soni Jose 7302177199dSJohn Soni Jose return -EBUSY; 731e175defeSJohn Soni Jose } 7322177199dSJohn Soni Jose 733e175defeSJohn Soni Jose rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL); 734e175defeSJohn Soni Jose if (rc) { 73599bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, 73699bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 737e175defeSJohn Soni Jose "BS_%d : Initiator Name MBX Failed\n"); 738e175defeSJohn Soni Jose return rc; 7392177199dSJohn Soni Jose } 740e175defeSJohn Soni Jose 7412177199dSJohn Soni Jose resp = embedded_payload(wrb); 7422177199dSJohn Soni Jose rc = sprintf(buf, "%s\n", resp->initiator_name); 7432177199dSJohn Soni Jose return rc; 7442177199dSJohn Soni Jose } 7452177199dSJohn Soni Jose 7462177199dSJohn Soni Jose /** 747c62eef0dSJohn Soni Jose * beiscsi_get_port_state - Get the Port State 748c62eef0dSJohn Soni Jose * @shost : pointer to scsi_host structure 749c62eef0dSJohn Soni Jose * 750c62eef0dSJohn Soni Jose */ 751c62eef0dSJohn Soni Jose static void beiscsi_get_port_state(struct Scsi_Host *shost) 752c62eef0dSJohn Soni Jose { 753c62eef0dSJohn Soni Jose struct beiscsi_hba *phba = iscsi_host_priv(shost); 754c62eef0dSJohn Soni Jose struct iscsi_cls_host *ihost = shost->shost_data; 755c62eef0dSJohn Soni Jose 7563567f36aSJayamohan Kallickal ihost->port_state = (phba->state == BE_ADAPTER_LINK_UP) ? 757c62eef0dSJohn Soni Jose ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; 758c62eef0dSJohn Soni Jose } 759c62eef0dSJohn Soni Jose 760c62eef0dSJohn Soni Jose /** 761c62eef0dSJohn Soni Jose * beiscsi_get_port_speed - Get the Port Speed from Adapter 762c62eef0dSJohn Soni Jose * @shost : pointer to scsi_host structure 763c62eef0dSJohn Soni Jose * 764c62eef0dSJohn Soni Jose * returns Success/Failure 765c62eef0dSJohn Soni Jose */ 766c62eef0dSJohn Soni Jose static int beiscsi_get_port_speed(struct Scsi_Host *shost) 767c62eef0dSJohn Soni Jose { 768e175defeSJohn Soni Jose int rc; 769e175defeSJohn Soni Jose unsigned int tag; 770c62eef0dSJohn Soni Jose struct be_mcc_wrb *wrb; 771c62eef0dSJohn Soni Jose struct be_cmd_ntwk_link_status_resp *resp; 772c62eef0dSJohn Soni Jose struct beiscsi_hba *phba = iscsi_host_priv(shost); 773c62eef0dSJohn Soni Jose struct iscsi_cls_host *ihost = shost->shost_data; 774c62eef0dSJohn Soni Jose 775c62eef0dSJohn Soni Jose tag = be_cmd_get_port_speed(phba); 776c62eef0dSJohn Soni Jose if (!tag) { 77799bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 77899bc5d55SJohn Soni Jose "BS_%d : Getting Port Speed Failed\n"); 77999bc5d55SJohn Soni Jose 780c62eef0dSJohn Soni Jose return -EBUSY; 781e175defeSJohn Soni Jose } 782e175defeSJohn Soni Jose rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL); 783e175defeSJohn Soni Jose if (rc) { 78499bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, 78599bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 786e175defeSJohn Soni Jose "BS_%d : Port Speed MBX Failed\n"); 787e175defeSJohn Soni Jose return rc; 788c62eef0dSJohn Soni Jose } 789c62eef0dSJohn Soni Jose resp = embedded_payload(wrb); 790c62eef0dSJohn Soni Jose 791c62eef0dSJohn Soni Jose switch (resp->mac_speed) { 792c62eef0dSJohn Soni Jose case BE2ISCSI_LINK_SPEED_10MBPS: 793c62eef0dSJohn Soni Jose ihost->port_speed = ISCSI_PORT_SPEED_10MBPS; 794c62eef0dSJohn Soni Jose break; 795c62eef0dSJohn Soni Jose case BE2ISCSI_LINK_SPEED_100MBPS: 7963e393172SJayamohan Kallickal ihost->port_speed = ISCSI_PORT_SPEED_100MBPS; 797c62eef0dSJohn Soni Jose break; 798c62eef0dSJohn Soni Jose case BE2ISCSI_LINK_SPEED_1GBPS: 799c62eef0dSJohn Soni Jose ihost->port_speed = ISCSI_PORT_SPEED_1GBPS; 800c62eef0dSJohn Soni Jose break; 801c62eef0dSJohn Soni Jose case BE2ISCSI_LINK_SPEED_10GBPS: 802c62eef0dSJohn Soni Jose ihost->port_speed = ISCSI_PORT_SPEED_10GBPS; 803c62eef0dSJohn Soni Jose break; 804c62eef0dSJohn Soni Jose default: 805c62eef0dSJohn Soni Jose ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN; 806c62eef0dSJohn Soni Jose } 807c62eef0dSJohn Soni Jose return 0; 808c62eef0dSJohn Soni Jose } 809c62eef0dSJohn Soni Jose 810c62eef0dSJohn Soni Jose /** 8116733b39aSJayamohan Kallickal * beiscsi_get_host_param - get the iscsi parameter 8126733b39aSJayamohan Kallickal * @shost: pointer to scsi_host structure 8136733b39aSJayamohan Kallickal * @param: parameter type identifier 8146733b39aSJayamohan Kallickal * @buf: buffer pointer 8156733b39aSJayamohan Kallickal * 8166733b39aSJayamohan Kallickal * returns host parameter 8176733b39aSJayamohan Kallickal */ 8186733b39aSJayamohan Kallickal int beiscsi_get_host_param(struct Scsi_Host *shost, 8196733b39aSJayamohan Kallickal enum iscsi_host_param param, char *buf) 8206733b39aSJayamohan Kallickal { 8213093b048SMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 822b15d05b0SJayamohan Kallickal int status = 0; 8236733b39aSJayamohan Kallickal 8243567f36aSJayamohan Kallickal 8253567f36aSJayamohan Kallickal if (phba->state & BE_ADAPTER_PCI_ERR) { 8263567f36aSJayamohan Kallickal beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 8273567f36aSJayamohan Kallickal "BS_%d : In PCI_ERROR Recovery\n"); 8283567f36aSJayamohan Kallickal return -EBUSY; 8293567f36aSJayamohan Kallickal } else { 83099bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 83199bc5d55SJohn Soni Jose "BS_%d : In beiscsi_get_host_param," 83299bc5d55SJohn Soni Jose " param = %d\n", param); 8333567f36aSJayamohan Kallickal } 83499bc5d55SJohn Soni Jose 8356733b39aSJayamohan Kallickal switch (param) { 8366733b39aSJayamohan Kallickal case ISCSI_HOST_PARAM_HWADDRESS: 837c7acc5b8SJayamohan Kallickal status = beiscsi_get_macaddr(buf, phba); 838c7acc5b8SJayamohan Kallickal if (status < 0) { 83999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 84099bc5d55SJohn Soni Jose "BS_%d : beiscsi_get_macaddr Failed\n"); 841c7acc5b8SJayamohan Kallickal return status; 842c7acc5b8SJayamohan Kallickal } 843c7acc5b8SJayamohan Kallickal break; 8442177199dSJohn Soni Jose case ISCSI_HOST_PARAM_INITIATOR_NAME: 8452177199dSJohn Soni Jose status = beiscsi_get_initname(buf, phba); 8462177199dSJohn Soni Jose if (status < 0) { 84799bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 84899bc5d55SJohn Soni Jose "BS_%d : Retreiving Initiator Name Failed\n"); 8492177199dSJohn Soni Jose return status; 8502177199dSJohn Soni Jose } 8512177199dSJohn Soni Jose break; 852c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_PORT_STATE: 853c62eef0dSJohn Soni Jose beiscsi_get_port_state(shost); 854c62eef0dSJohn Soni Jose status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost)); 855c62eef0dSJohn Soni Jose break; 856c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_PORT_SPEED: 857c62eef0dSJohn Soni Jose status = beiscsi_get_port_speed(shost); 858c62eef0dSJohn Soni Jose if (status) { 85999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 86099bc5d55SJohn Soni Jose "BS_%d : Retreiving Port Speed Failed\n"); 861c62eef0dSJohn Soni Jose return status; 862c62eef0dSJohn Soni Jose } 863c62eef0dSJohn Soni Jose status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost)); 864c62eef0dSJohn Soni Jose break; 865c7acc5b8SJayamohan Kallickal default: 866c7acc5b8SJayamohan Kallickal return iscsi_host_get_param(shost, param, buf); 867c7acc5b8SJayamohan Kallickal } 868b15d05b0SJayamohan Kallickal return status; 869c7acc5b8SJayamohan Kallickal } 870c7acc5b8SJayamohan Kallickal 871c7acc5b8SJayamohan Kallickal int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) 872c7acc5b8SJayamohan Kallickal { 8730e43895eSMike Christie struct be_cmd_get_nic_conf_resp resp; 874c7acc5b8SJayamohan Kallickal int rc; 875c7acc5b8SJayamohan Kallickal 8766c83185aSJayamohan Kallickal if (phba->mac_addr_set) 877df5d0e6eSJohn Soni Jose return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 878c7acc5b8SJayamohan Kallickal 8790e43895eSMike Christie memset(&resp, 0, sizeof(resp)); 8800e43895eSMike Christie rc = mgmt_get_nic_conf(phba, &resp); 8810e43895eSMike Christie if (rc) 882c7acc5b8SJayamohan Kallickal return rc; 883c7acc5b8SJayamohan Kallickal 8846c83185aSJayamohan Kallickal phba->mac_addr_set = true; 8850e43895eSMike Christie memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); 8860e43895eSMike Christie return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 8870e43895eSMike Christie } 8886733b39aSJayamohan Kallickal 8896733b39aSJayamohan Kallickal /** 8906733b39aSJayamohan Kallickal * beiscsi_conn_get_stats - get the iscsi stats 8916733b39aSJayamohan Kallickal * @cls_conn: pointer to iscsi cls conn 8926733b39aSJayamohan Kallickal * @stats: pointer to iscsi_stats structure 8936733b39aSJayamohan Kallickal * 8946733b39aSJayamohan Kallickal * returns iscsi stats 8956733b39aSJayamohan Kallickal */ 8966733b39aSJayamohan Kallickal void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, 8976733b39aSJayamohan Kallickal struct iscsi_stats *stats) 8986733b39aSJayamohan Kallickal { 8996733b39aSJayamohan Kallickal struct iscsi_conn *conn = cls_conn->dd_data; 90099bc5d55SJohn Soni Jose struct beiscsi_hba *phba = NULL; 9016733b39aSJayamohan Kallickal 90299bc5d55SJohn Soni Jose phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 90399bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 90499bc5d55SJohn Soni Jose "BS_%d : In beiscsi_conn_get_stats\n"); 90599bc5d55SJohn Soni Jose 9066733b39aSJayamohan Kallickal stats->txdata_octets = conn->txdata_octets; 9076733b39aSJayamohan Kallickal stats->rxdata_octets = conn->rxdata_octets; 9086733b39aSJayamohan Kallickal stats->dataout_pdus = conn->dataout_pdus_cnt; 9096733b39aSJayamohan Kallickal stats->scsirsp_pdus = conn->scsirsp_pdus_cnt; 9106733b39aSJayamohan Kallickal stats->scsicmd_pdus = conn->scsicmd_pdus_cnt; 9116733b39aSJayamohan Kallickal stats->datain_pdus = conn->datain_pdus_cnt; 9126733b39aSJayamohan Kallickal stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; 9136733b39aSJayamohan Kallickal stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; 9146733b39aSJayamohan Kallickal stats->r2t_pdus = conn->r2t_pdus_cnt; 9156733b39aSJayamohan Kallickal stats->digest_err = 0; 9166733b39aSJayamohan Kallickal stats->timeout_err = 0; 917915aafd8SMike Christie stats->custom_length = 1; 9186733b39aSJayamohan Kallickal strcpy(stats->custom[0].desc, "eh_abort_cnt"); 9196733b39aSJayamohan Kallickal stats->custom[0].value = conn->eh_abort_cnt; 9206733b39aSJayamohan Kallickal } 9216733b39aSJayamohan Kallickal 9226733b39aSJayamohan Kallickal /** 9236733b39aSJayamohan Kallickal * beiscsi_set_params_for_offld - get the parameters for offload 9246733b39aSJayamohan Kallickal * @beiscsi_conn: pointer to beiscsi_conn 9256733b39aSJayamohan Kallickal * @params: pointer to offload_params structure 9266733b39aSJayamohan Kallickal */ 9276733b39aSJayamohan Kallickal static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn, 9286733b39aSJayamohan Kallickal struct beiscsi_offload_params *params) 9296733b39aSJayamohan Kallickal { 9306733b39aSJayamohan Kallickal struct iscsi_conn *conn = beiscsi_conn->conn; 9316733b39aSJayamohan Kallickal struct iscsi_session *session = conn->session; 9326733b39aSJayamohan Kallickal 9336733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length, 9346733b39aSJayamohan Kallickal params, session->max_burst); 9356733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, 9366733b39aSJayamohan Kallickal max_send_data_segment_length, params, 9376733b39aSJayamohan Kallickal conn->max_xmit_dlength); 9386733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length, 9396733b39aSJayamohan Kallickal params, session->first_burst); 9406733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params, 9416733b39aSJayamohan Kallickal session->erl); 9426733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params, 9436733b39aSJayamohan Kallickal conn->datadgst_en); 9446733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params, 9456733b39aSJayamohan Kallickal conn->hdrdgst_en); 9466733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params, 9476733b39aSJayamohan Kallickal session->initial_r2t_en); 9486733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params, 9496733b39aSJayamohan Kallickal session->imm_data_en); 950acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_beiscsi_offload_params, 951acb9693cSJohn Soni Jose data_seq_inorder, params, 952acb9693cSJohn Soni Jose session->dataseq_inorder_en); 953acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_beiscsi_offload_params, 954acb9693cSJohn Soni Jose pdu_seq_inorder, params, 955acb9693cSJohn Soni Jose session->pdu_inorder_en); 956acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_r2t, params, 957acb9693cSJohn Soni Jose session->max_r2t); 9586733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params, 9596733b39aSJayamohan Kallickal (conn->exp_statsn - 1)); 9607331613eSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, 9617331613eSJayamohan Kallickal max_recv_data_segment_length, params, 9627331613eSJayamohan Kallickal conn->max_recv_dlength); 9637331613eSJayamohan Kallickal 9646733b39aSJayamohan Kallickal } 9656733b39aSJayamohan Kallickal 9666733b39aSJayamohan Kallickal /** 9676733b39aSJayamohan Kallickal * beiscsi_conn_start - offload of session to chip 9686733b39aSJayamohan Kallickal * @cls_conn: pointer to beiscsi_conn 9696733b39aSJayamohan Kallickal */ 9706733b39aSJayamohan Kallickal int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) 9716733b39aSJayamohan Kallickal { 9726733b39aSJayamohan Kallickal struct iscsi_conn *conn = cls_conn->dd_data; 9736733b39aSJayamohan Kallickal struct beiscsi_conn *beiscsi_conn = conn->dd_data; 9746733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep; 9756733b39aSJayamohan Kallickal struct beiscsi_offload_params params; 9763567f36aSJayamohan Kallickal struct beiscsi_hba *phba; 9776733b39aSJayamohan Kallickal 9783567f36aSJayamohan Kallickal phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 9793567f36aSJayamohan Kallickal 9803567f36aSJayamohan Kallickal if (phba->state & BE_ADAPTER_PCI_ERR) { 9813567f36aSJayamohan Kallickal beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 9823567f36aSJayamohan Kallickal "BS_%d : In PCI_ERROR Recovery\n"); 9833567f36aSJayamohan Kallickal return -EBUSY; 9843567f36aSJayamohan Kallickal } else { 98599bc5d55SJohn Soni Jose beiscsi_log(beiscsi_conn->phba, KERN_INFO, 98699bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG, 98799bc5d55SJohn Soni Jose "BS_%d : In beiscsi_conn_start\n"); 9883567f36aSJayamohan Kallickal } 98999bc5d55SJohn Soni Jose 9906733b39aSJayamohan Kallickal memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); 9916733b39aSJayamohan Kallickal beiscsi_ep = beiscsi_conn->ep; 9926733b39aSJayamohan Kallickal if (!beiscsi_ep) 99399bc5d55SJohn Soni Jose beiscsi_log(beiscsi_conn->phba, KERN_ERR, 99499bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG, 99599bc5d55SJohn Soni Jose "BS_%d : In beiscsi_conn_start , no beiscsi_ep\n"); 9966733b39aSJayamohan Kallickal 9976733b39aSJayamohan Kallickal beiscsi_conn->login_in_progress = 0; 9986733b39aSJayamohan Kallickal beiscsi_set_params_for_offld(beiscsi_conn, ¶ms); 9996733b39aSJayamohan Kallickal beiscsi_offload_connection(beiscsi_conn, ¶ms); 10006733b39aSJayamohan Kallickal iscsi_conn_start(cls_conn); 10016733b39aSJayamohan Kallickal return 0; 10026733b39aSJayamohan Kallickal } 10036733b39aSJayamohan Kallickal 10046733b39aSJayamohan Kallickal /** 10056733b39aSJayamohan Kallickal * beiscsi_get_cid - Allocate a cid 10066733b39aSJayamohan Kallickal * @phba: The phba instance 10076733b39aSJayamohan Kallickal */ 10086733b39aSJayamohan Kallickal static int beiscsi_get_cid(struct beiscsi_hba *phba) 10096733b39aSJayamohan Kallickal { 10100a3db7c0SJayamohan Kallickal unsigned short cid = 0xFFFF, cid_from_ulp; 10110a3db7c0SJayamohan Kallickal struct ulp_cid_info *cid_info = NULL; 10120a3db7c0SJayamohan Kallickal uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1; 10136733b39aSJayamohan Kallickal 10140a3db7c0SJayamohan Kallickal /* Find the ULP which has more CID available */ 10150a3db7c0SJayamohan Kallickal cid_avlbl_ulp0 = (phba->cid_array_info[BEISCSI_ULP0]) ? 10160a3db7c0SJayamohan Kallickal BEISCSI_ULP0_AVLBL_CID(phba) : 0; 10170a3db7c0SJayamohan Kallickal cid_avlbl_ulp1 = (phba->cid_array_info[BEISCSI_ULP1]) ? 10180a3db7c0SJayamohan Kallickal BEISCSI_ULP1_AVLBL_CID(phba) : 0; 10190a3db7c0SJayamohan Kallickal cid_from_ulp = (cid_avlbl_ulp0 > cid_avlbl_ulp1) ? 10200a3db7c0SJayamohan Kallickal BEISCSI_ULP0 : BEISCSI_ULP1; 10210a3db7c0SJayamohan Kallickal 10220a3db7c0SJayamohan Kallickal if (test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported)) { 10230a3db7c0SJayamohan Kallickal cid_info = phba->cid_array_info[cid_from_ulp]; 10240a3db7c0SJayamohan Kallickal if (!cid_info->avlbl_cids) 10256733b39aSJayamohan Kallickal return cid; 10266733b39aSJayamohan Kallickal 10270a3db7c0SJayamohan Kallickal cid = cid_info->cid_array[cid_info->cid_alloc++]; 10280a3db7c0SJayamohan Kallickal 10290a3db7c0SJayamohan Kallickal if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT( 10300a3db7c0SJayamohan Kallickal phba, cid_from_ulp)) 10310a3db7c0SJayamohan Kallickal cid_info->cid_alloc = 0; 10320a3db7c0SJayamohan Kallickal 10330a3db7c0SJayamohan Kallickal cid_info->avlbl_cids--; 10340a3db7c0SJayamohan Kallickal } 10356733b39aSJayamohan Kallickal return cid; 10366733b39aSJayamohan Kallickal } 10376733b39aSJayamohan Kallickal 10386733b39aSJayamohan Kallickal /** 1039fa95d206SMike Christie * beiscsi_put_cid - Free the cid 1040fa95d206SMike Christie * @phba: The phba for which the cid is being freed 1041fa95d206SMike Christie * @cid: The cid to free 1042fa95d206SMike Christie */ 1043fa95d206SMike Christie static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) 1044fa95d206SMike Christie { 10450a3db7c0SJayamohan Kallickal uint16_t cid_post_ulp; 10460a3db7c0SJayamohan Kallickal struct hwi_controller *phwi_ctrlr; 10470a3db7c0SJayamohan Kallickal struct hwi_wrb_context *pwrb_context; 10480a3db7c0SJayamohan Kallickal struct ulp_cid_info *cid_info = NULL; 10490a3db7c0SJayamohan Kallickal uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 10500a3db7c0SJayamohan Kallickal 10510a3db7c0SJayamohan Kallickal phwi_ctrlr = phba->phwi_ctrlr; 10520a3db7c0SJayamohan Kallickal pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; 10530a3db7c0SJayamohan Kallickal cid_post_ulp = pwrb_context->ulp_num; 10540a3db7c0SJayamohan Kallickal 10550a3db7c0SJayamohan Kallickal cid_info = phba->cid_array_info[cid_post_ulp]; 10560a3db7c0SJayamohan Kallickal cid_info->avlbl_cids++; 10570a3db7c0SJayamohan Kallickal 10580a3db7c0SJayamohan Kallickal cid_info->cid_array[cid_info->cid_free++] = cid; 10590a3db7c0SJayamohan Kallickal if (cid_info->cid_free == BEISCSI_GET_CID_COUNT(phba, cid_post_ulp)) 10600a3db7c0SJayamohan Kallickal cid_info->cid_free = 0; 1061fa95d206SMike Christie } 1062fa95d206SMike Christie 1063fa95d206SMike Christie /** 1064fa95d206SMike Christie * beiscsi_free_ep - free endpoint 1065fa95d206SMike Christie * @ep: pointer to iscsi endpoint structure 1066fa95d206SMike Christie */ 1067fa95d206SMike Christie static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) 1068fa95d206SMike Christie { 1069fa95d206SMike Christie struct beiscsi_hba *phba = beiscsi_ep->phba; 107043f388b0SJayamohan Kallickal struct beiscsi_conn *beiscsi_conn; 1071fa95d206SMike Christie 1072fa95d206SMike Christie beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 1073fa95d206SMike Christie beiscsi_ep->phba = NULL; 1074a7909b39SJayamohan Kallickal phba->ep_array[BE_GET_CRI_FROM_CID 1075a7909b39SJayamohan Kallickal (beiscsi_ep->ep_cid)] = NULL; 107643f388b0SJayamohan Kallickal 107743f388b0SJayamohan Kallickal /** 107843f388b0SJayamohan Kallickal * Check if any connection resource allocated by driver 107943f388b0SJayamohan Kallickal * is to be freed.This case occurs when target redirection 108043f388b0SJayamohan Kallickal * or connection retry is done. 108143f388b0SJayamohan Kallickal **/ 108243f388b0SJayamohan Kallickal if (!beiscsi_ep->conn) 108343f388b0SJayamohan Kallickal return; 108443f388b0SJayamohan Kallickal 108543f388b0SJayamohan Kallickal beiscsi_conn = beiscsi_ep->conn; 108643f388b0SJayamohan Kallickal if (beiscsi_conn->login_in_progress) { 10874a4a11b9SJayamohan Kallickal beiscsi_free_mgmt_task_handles(beiscsi_conn, 10884a4a11b9SJayamohan Kallickal beiscsi_conn->task); 108943f388b0SJayamohan Kallickal beiscsi_conn->login_in_progress = 0; 109043f388b0SJayamohan Kallickal } 1091fa95d206SMike Christie } 1092fa95d206SMike Christie 1093fa95d206SMike Christie /** 10946733b39aSJayamohan Kallickal * beiscsi_open_conn - Ask FW to open a TCP connection 10956733b39aSJayamohan Kallickal * @ep: endpoint to be used 10966733b39aSJayamohan Kallickal * @src_addr: The source IP address 10976733b39aSJayamohan Kallickal * @dst_addr: The Destination IP address 10986733b39aSJayamohan Kallickal * 10996733b39aSJayamohan Kallickal * Asks the FW to open a TCP connection 11006733b39aSJayamohan Kallickal */ 11016733b39aSJayamohan Kallickal static int beiscsi_open_conn(struct iscsi_endpoint *ep, 11026733b39aSJayamohan Kallickal struct sockaddr *src_addr, 11036733b39aSJayamohan Kallickal struct sockaddr *dst_addr, int non_blocking) 11046733b39aSJayamohan Kallickal { 11056733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 11066733b39aSJayamohan Kallickal struct beiscsi_hba *phba = beiscsi_ep->phba; 1107756d29c8SJayamohan Kallickal struct tcp_connect_and_offload_out *ptcpcnct_out; 11083cbb7a74SJayamohan Kallickal struct be_dma_mem nonemb_cmd; 1109b3c202dcSJayamohan Kallickal unsigned int tag, req_memsize; 1110d3ad2bb3SJayamohan Kallickal int ret = -ENOMEM; 11116733b39aSJayamohan Kallickal 111299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 111399bc5d55SJohn Soni Jose "BS_%d : In beiscsi_open_conn\n"); 111499bc5d55SJohn Soni Jose 11156733b39aSJayamohan Kallickal beiscsi_ep->ep_cid = beiscsi_get_cid(phba); 11166733b39aSJayamohan Kallickal if (beiscsi_ep->ep_cid == 0xFFFF) { 111799bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 111899bc5d55SJohn Soni Jose "BS_%d : No free cid available\n"); 11196733b39aSJayamohan Kallickal return ret; 11206733b39aSJayamohan Kallickal } 112199bc5d55SJohn Soni Jose 112299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 112399bc5d55SJohn Soni Jose "BS_%d : In beiscsi_open_conn, ep_cid=%d\n", 11246733b39aSJayamohan Kallickal beiscsi_ep->ep_cid); 112599bc5d55SJohn Soni Jose 1126a7909b39SJayamohan Kallickal phba->ep_array[BE_GET_CRI_FROM_CID 1127a7909b39SJayamohan Kallickal (beiscsi_ep->ep_cid)] = ep; 11286733b39aSJayamohan Kallickal 11296733b39aSJayamohan Kallickal beiscsi_ep->cid_vld = 0; 1130b3c202dcSJayamohan Kallickal 1131b3c202dcSJayamohan Kallickal if (is_chip_be2_be3r(phba)) 1132b3c202dcSJayamohan Kallickal req_memsize = sizeof(struct tcp_connect_and_offload_in); 1133b3c202dcSJayamohan Kallickal else 1134b3c202dcSJayamohan Kallickal req_memsize = sizeof(struct tcp_connect_and_offload_in_v1); 1135b3c202dcSJayamohan Kallickal 11363cbb7a74SJayamohan Kallickal nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, 1137b3c202dcSJayamohan Kallickal req_memsize, 11383cbb7a74SJayamohan Kallickal &nonemb_cmd.dma); 11393cbb7a74SJayamohan Kallickal if (nonemb_cmd.va == NULL) { 114099bc5d55SJohn Soni Jose 114199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 114299bc5d55SJohn Soni Jose "BS_%d : Failed to allocate memory for" 114399bc5d55SJohn Soni Jose " mgmt_open_connection\n"); 114499bc5d55SJohn Soni Jose 1145a7909b39SJayamohan Kallickal beiscsi_free_ep(beiscsi_ep); 11463cbb7a74SJayamohan Kallickal return -ENOMEM; 11473cbb7a74SJayamohan Kallickal } 1148b3c202dcSJayamohan Kallickal nonemb_cmd.size = req_memsize; 11493cbb7a74SJayamohan Kallickal memset(nonemb_cmd.va, 0, nonemb_cmd.size); 11503cbb7a74SJayamohan Kallickal tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd); 11511e234bbbSJayamohan Kallickal if (tag <= 0) { 115299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 115399bc5d55SJohn Soni Jose "BS_%d : mgmt_open_connection Failed for cid=%d\n", 1154756d29c8SJayamohan Kallickal beiscsi_ep->ep_cid); 115599bc5d55SJohn Soni Jose 11563cbb7a74SJayamohan Kallickal pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 11573cbb7a74SJayamohan Kallickal nonemb_cmd.va, nonemb_cmd.dma); 1158a7909b39SJayamohan Kallickal beiscsi_free_ep(beiscsi_ep); 11591f92638fSJayamohan Kallickal return -EAGAIN; 1160756d29c8SJayamohan Kallickal } 1161e175defeSJohn Soni Jose 11621957aa7fSJayamohan Kallickal ret = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd); 1163e175defeSJohn Soni Jose if (ret) { 116499bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, 116599bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 1166e175defeSJohn Soni Jose "BS_%d : mgmt_open_connection Failed"); 116799bc5d55SJohn Soni Jose 11681957aa7fSJayamohan Kallickal if (ret != -EBUSY) 11693cbb7a74SJayamohan Kallickal pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 11703cbb7a74SJayamohan Kallickal nonemb_cmd.va, nonemb_cmd.dma); 11711957aa7fSJayamohan Kallickal 1172a7909b39SJayamohan Kallickal beiscsi_free_ep(beiscsi_ep); 11731957aa7fSJayamohan Kallickal return ret; 1174e175defeSJohn Soni Jose } 1175756d29c8SJayamohan Kallickal 11761e234bbbSJayamohan Kallickal ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va; 1177756d29c8SJayamohan Kallickal beiscsi_ep = ep->dd_data; 1178756d29c8SJayamohan Kallickal beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; 1179756d29c8SJayamohan Kallickal beiscsi_ep->cid_vld = 1; 118099bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 118199bc5d55SJohn Soni Jose "BS_%d : mgmt_open_connection Success\n"); 1182e175defeSJohn Soni Jose 11833cbb7a74SJayamohan Kallickal pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 11843cbb7a74SJayamohan Kallickal nonemb_cmd.va, nonemb_cmd.dma); 1185756d29c8SJayamohan Kallickal return 0; 11866733b39aSJayamohan Kallickal } 11876733b39aSJayamohan Kallickal 11886733b39aSJayamohan Kallickal /** 11896733b39aSJayamohan Kallickal * beiscsi_ep_connect - Ask chip to create TCP Conn 11906733b39aSJayamohan Kallickal * @scsi_host: Pointer to scsi_host structure 11916733b39aSJayamohan Kallickal * @dst_addr: The IP address of Target 11926733b39aSJayamohan Kallickal * @non_blocking: blocking or non-blocking call 11936733b39aSJayamohan Kallickal * 11946733b39aSJayamohan Kallickal * This routines first asks chip to create a connection and then allocates an EP 11956733b39aSJayamohan Kallickal */ 11966733b39aSJayamohan Kallickal struct iscsi_endpoint * 11976733b39aSJayamohan Kallickal beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, 11986733b39aSJayamohan Kallickal int non_blocking) 11996733b39aSJayamohan Kallickal { 12006733b39aSJayamohan Kallickal struct beiscsi_hba *phba; 12016733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep; 12026733b39aSJayamohan Kallickal struct iscsi_endpoint *ep; 12036733b39aSJayamohan Kallickal int ret; 12046733b39aSJayamohan Kallickal 12056733b39aSJayamohan Kallickal if (shost) 12066733b39aSJayamohan Kallickal phba = iscsi_host_priv(shost); 12076733b39aSJayamohan Kallickal else { 12086733b39aSJayamohan Kallickal ret = -ENXIO; 120999bc5d55SJohn Soni Jose printk(KERN_ERR 121099bc5d55SJohn Soni Jose "beiscsi_ep_connect shost is NULL\n"); 12116733b39aSJayamohan Kallickal return ERR_PTR(ret); 12126733b39aSJayamohan Kallickal } 1213bfead3b2SJayamohan Kallickal 1214cf6e3c64SJayamohan Kallickal if (beiscsi_error(phba)) { 1215cf6e3c64SJayamohan Kallickal ret = -EIO; 1216cf6e3c64SJayamohan Kallickal beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 1217cf6e3c64SJayamohan Kallickal "BS_%d : The FW state Not Stable!!!\n"); 1218cf6e3c64SJayamohan Kallickal return ERR_PTR(ret); 1219cf6e3c64SJayamohan Kallickal } 1220cf6e3c64SJayamohan Kallickal 12213567f36aSJayamohan Kallickal if (phba->state & BE_ADAPTER_PCI_ERR) { 12223567f36aSJayamohan Kallickal ret = -EBUSY; 12233567f36aSJayamohan Kallickal beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 12243567f36aSJayamohan Kallickal "BS_%d : In PCI_ERROR Recovery\n"); 12253567f36aSJayamohan Kallickal return ERR_PTR(ret); 12263567f36aSJayamohan Kallickal } else if (phba->state & BE_ADAPTER_LINK_DOWN) { 1227bfead3b2SJayamohan Kallickal ret = -EBUSY; 12288359c79bSJohn Soni Jose beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 12298359c79bSJohn Soni Jose "BS_%d : The Adapter Port state is Down!!!\n"); 1230bfead3b2SJayamohan Kallickal return ERR_PTR(ret); 1231bfead3b2SJayamohan Kallickal } 1232bfead3b2SJayamohan Kallickal 12336733b39aSJayamohan Kallickal ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint)); 12346733b39aSJayamohan Kallickal if (!ep) { 12356733b39aSJayamohan Kallickal ret = -ENOMEM; 12366733b39aSJayamohan Kallickal return ERR_PTR(ret); 12376733b39aSJayamohan Kallickal } 12386733b39aSJayamohan Kallickal 12396733b39aSJayamohan Kallickal beiscsi_ep = ep->dd_data; 12406733b39aSJayamohan Kallickal beiscsi_ep->phba = phba; 1241c2462288SJayamohan Kallickal beiscsi_ep->openiscsi_ep = ep; 1242f5ed7bd4SJayamohan Kallickal ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking); 1243f5ed7bd4SJayamohan Kallickal if (ret) { 124499bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 124599bc5d55SJohn Soni Jose "BS_%d : Failed in beiscsi_open_conn\n"); 12466733b39aSJayamohan Kallickal goto free_ep; 12476733b39aSJayamohan Kallickal } 12486733b39aSJayamohan Kallickal 12496733b39aSJayamohan Kallickal return ep; 12506733b39aSJayamohan Kallickal 12516733b39aSJayamohan Kallickal free_ep: 1252fa95d206SMike Christie iscsi_destroy_endpoint(ep); 12536733b39aSJayamohan Kallickal return ERR_PTR(ret); 12546733b39aSJayamohan Kallickal } 12556733b39aSJayamohan Kallickal 12566733b39aSJayamohan Kallickal /** 12576733b39aSJayamohan Kallickal * beiscsi_ep_poll - Poll to see if connection is established 12586733b39aSJayamohan Kallickal * @ep: endpoint to be used 12596733b39aSJayamohan Kallickal * @timeout_ms: timeout specified in millisecs 12606733b39aSJayamohan Kallickal * 12616733b39aSJayamohan Kallickal * Poll to see if TCP connection established 12626733b39aSJayamohan Kallickal */ 12636733b39aSJayamohan Kallickal int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) 12646733b39aSJayamohan Kallickal { 12656733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 12666733b39aSJayamohan Kallickal 126799bc5d55SJohn Soni Jose beiscsi_log(beiscsi_ep->phba, KERN_INFO, BEISCSI_LOG_CONFIG, 126899bc5d55SJohn Soni Jose "BS_%d : In beiscsi_ep_poll\n"); 126999bc5d55SJohn Soni Jose 12706733b39aSJayamohan Kallickal if (beiscsi_ep->cid_vld == 1) 12716733b39aSJayamohan Kallickal return 1; 12726733b39aSJayamohan Kallickal else 12736733b39aSJayamohan Kallickal return 0; 12746733b39aSJayamohan Kallickal } 12756733b39aSJayamohan Kallickal 12766733b39aSJayamohan Kallickal /** 1277b7ab35b1SJayamohan Kallickal * beiscsi_flush_cq()- Flush the CQ created. 1278b7ab35b1SJayamohan Kallickal * @phba: ptr device priv structure. 1279b7ab35b1SJayamohan Kallickal * 1280b7ab35b1SJayamohan Kallickal * Before the connection resource are freed flush 1281b7ab35b1SJayamohan Kallickal * all the CQ enteries 1282b7ab35b1SJayamohan Kallickal **/ 1283b7ab35b1SJayamohan Kallickal static void beiscsi_flush_cq(struct beiscsi_hba *phba) 1284b7ab35b1SJayamohan Kallickal { 1285b7ab35b1SJayamohan Kallickal uint16_t i; 1286b7ab35b1SJayamohan Kallickal struct be_eq_obj *pbe_eq; 1287b7ab35b1SJayamohan Kallickal struct hwi_controller *phwi_ctrlr; 1288b7ab35b1SJayamohan Kallickal struct hwi_context_memory *phwi_context; 1289b7ab35b1SJayamohan Kallickal 1290b7ab35b1SJayamohan Kallickal phwi_ctrlr = phba->phwi_ctrlr; 1291b7ab35b1SJayamohan Kallickal phwi_context = phwi_ctrlr->phwi_ctxt; 1292b7ab35b1SJayamohan Kallickal 1293b7ab35b1SJayamohan Kallickal for (i = 0; i < phba->num_cpus; i++) { 1294b7ab35b1SJayamohan Kallickal pbe_eq = &phwi_context->be_eq[i]; 1295b7ab35b1SJayamohan Kallickal blk_iopoll_disable(&pbe_eq->iopoll); 1296b7ab35b1SJayamohan Kallickal beiscsi_process_cq(pbe_eq); 1297b7ab35b1SJayamohan Kallickal blk_iopoll_enable(&pbe_eq->iopoll); 1298b7ab35b1SJayamohan Kallickal } 1299b7ab35b1SJayamohan Kallickal } 1300b7ab35b1SJayamohan Kallickal 1301b7ab35b1SJayamohan Kallickal /** 13026733b39aSJayamohan Kallickal * beiscsi_close_conn - Upload the connection 13036733b39aSJayamohan Kallickal * @ep: The iscsi endpoint 13046733b39aSJayamohan Kallickal * @flag: The type of connection closure 13056733b39aSJayamohan Kallickal */ 1306c2462288SJayamohan Kallickal static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) 13076733b39aSJayamohan Kallickal { 13086733b39aSJayamohan Kallickal int ret = 0; 1309756d29c8SJayamohan Kallickal unsigned int tag; 13106733b39aSJayamohan Kallickal struct beiscsi_hba *phba = beiscsi_ep->phba; 13116733b39aSJayamohan Kallickal 1312756d29c8SJayamohan Kallickal tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag); 1313756d29c8SJayamohan Kallickal if (!tag) { 131499bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 131599bc5d55SJohn Soni Jose "BS_%d : upload failed for cid 0x%x\n", 13166733b39aSJayamohan Kallickal beiscsi_ep->ep_cid); 131799bc5d55SJohn Soni Jose 1318d3ad2bb3SJayamohan Kallickal ret = -EAGAIN; 13196733b39aSJayamohan Kallickal } 1320e175defeSJohn Soni Jose 1321e175defeSJohn Soni Jose ret = beiscsi_mccq_compl(phba, tag, NULL, NULL); 1322b7ab35b1SJayamohan Kallickal 1323b7ab35b1SJayamohan Kallickal /* Flush the CQ entries */ 1324b7ab35b1SJayamohan Kallickal beiscsi_flush_cq(phba); 1325b7ab35b1SJayamohan Kallickal 13266733b39aSJayamohan Kallickal return ret; 13276733b39aSJayamohan Kallickal } 13286733b39aSJayamohan Kallickal 13296733b39aSJayamohan Kallickal /** 13306733b39aSJayamohan Kallickal * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table 13316733b39aSJayamohan Kallickal * @phba: The phba instance 13326733b39aSJayamohan Kallickal * @cid: The cid to free 13336733b39aSJayamohan Kallickal */ 13346733b39aSJayamohan Kallickal static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, 13356733b39aSJayamohan Kallickal unsigned int cid) 13366733b39aSJayamohan Kallickal { 1337a7909b39SJayamohan Kallickal uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 1338a7909b39SJayamohan Kallickal 1339a7909b39SJayamohan Kallickal if (phba->conn_table[cri_index]) 1340a7909b39SJayamohan Kallickal phba->conn_table[cri_index] = NULL; 13416733b39aSJayamohan Kallickal else { 134299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 134399bc5d55SJohn Soni Jose "BS_%d : Connection table Not occupied.\n"); 13446733b39aSJayamohan Kallickal return -EINVAL; 13456733b39aSJayamohan Kallickal } 13466733b39aSJayamohan Kallickal return 0; 13476733b39aSJayamohan Kallickal } 13486733b39aSJayamohan Kallickal 13496733b39aSJayamohan Kallickal /** 1350fa95d206SMike Christie * beiscsi_ep_disconnect - Tears down the TCP connection 1351fa95d206SMike Christie * @ep: endpoint to be used 1352fa95d206SMike Christie * 1353fa95d206SMike Christie * Tears down the TCP connection 13546733b39aSJayamohan Kallickal */ 1355fa95d206SMike Christie void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) 13566733b39aSJayamohan Kallickal { 1357fa95d206SMike Christie struct beiscsi_conn *beiscsi_conn; 13586733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep; 1359fa95d206SMike Christie struct beiscsi_hba *phba; 1360756d29c8SJayamohan Kallickal unsigned int tag; 13610a513dd8SJohn Soni Jose uint8_t mgmt_invalidate_flag, tcp_upload_flag; 13626733b39aSJayamohan Kallickal unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; 13636733b39aSJayamohan Kallickal 1364fa95d206SMike Christie beiscsi_ep = ep->dd_data; 1365fa95d206SMike Christie phba = beiscsi_ep->phba; 136699bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 136799bc5d55SJohn Soni Jose "BS_%d : In beiscsi_ep_disconnect for ep_cid = %d\n", 1368fa95d206SMike Christie beiscsi_ep->ep_cid); 1369fa95d206SMike Christie 13700a513dd8SJohn Soni Jose if (beiscsi_ep->conn) { 1371fa95d206SMike Christie beiscsi_conn = beiscsi_ep->conn; 1372fa95d206SMike Christie iscsi_suspend_queue(beiscsi_conn->conn); 13730a513dd8SJohn Soni Jose mgmt_invalidate_flag = ~BEISCSI_NO_RST_ISSUE; 13740a513dd8SJohn Soni Jose tcp_upload_flag = CONNECTION_UPLOAD_GRACEFUL; 13750a513dd8SJohn Soni Jose } else { 13760a513dd8SJohn Soni Jose mgmt_invalidate_flag = BEISCSI_NO_RST_ISSUE; 13770a513dd8SJohn Soni Jose tcp_upload_flag = CONNECTION_UPLOAD_ABORT; 13780a513dd8SJohn Soni Jose } 1379fa95d206SMike Christie 13803567f36aSJayamohan Kallickal if (phba->state & BE_ADAPTER_PCI_ERR) { 13813567f36aSJayamohan Kallickal beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 13823567f36aSJayamohan Kallickal "BS_%d : PCI_ERROR Recovery\n"); 13833567f36aSJayamohan Kallickal goto free_ep; 13843567f36aSJayamohan Kallickal } 13853567f36aSJayamohan Kallickal 1386756d29c8SJayamohan Kallickal tag = mgmt_invalidate_connection(phba, beiscsi_ep, 13870a513dd8SJohn Soni Jose beiscsi_ep->ep_cid, 13880a513dd8SJohn Soni Jose mgmt_invalidate_flag, 13896733b39aSJayamohan Kallickal savecfg_flag); 1390756d29c8SJayamohan Kallickal if (!tag) { 139199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 13920a513dd8SJohn Soni Jose "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n", 13936733b39aSJayamohan Kallickal beiscsi_ep->ep_cid); 13946733b39aSJayamohan Kallickal } 1395fa95d206SMike Christie 1396e175defeSJohn Soni Jose beiscsi_mccq_compl(phba, tag, NULL, NULL); 13970a513dd8SJohn Soni Jose beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); 13983567f36aSJayamohan Kallickal free_ep: 13999343be74SJayamohan Kallickal msleep(BEISCSI_LOGOUT_SYNC_DELAY); 1400c2462288SJayamohan Kallickal beiscsi_free_ep(beiscsi_ep); 14016733b39aSJayamohan Kallickal beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); 1402fa95d206SMike Christie iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); 14036733b39aSJayamohan Kallickal } 14043128c6c7SMike Christie 1405587a1f16SAl Viro umode_t be2iscsi_attr_is_visible(int param_type, int param) 14063128c6c7SMike Christie { 14073128c6c7SMike Christie switch (param_type) { 14080e43895eSMike Christie case ISCSI_NET_PARAM: 14090e43895eSMike Christie switch (param) { 14100e43895eSMike Christie case ISCSI_NET_PARAM_IFACE_ENABLE: 14110e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_ADDR: 14120e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_SUBNET: 14130e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 14140e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_GW: 14150e43895eSMike Christie case ISCSI_NET_PARAM_IPV6_ADDR: 14166f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ID: 14176f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_PRIORITY: 14186f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ENABLED: 14190e43895eSMike Christie return S_IRUGO; 14200e43895eSMike Christie default: 14210e43895eSMike Christie return 0; 14220e43895eSMike Christie } 1423f27fb2efSMike Christie case ISCSI_HOST_PARAM: 1424f27fb2efSMike Christie switch (param) { 1425f27fb2efSMike Christie case ISCSI_HOST_PARAM_HWADDRESS: 1426c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_INITIATOR_NAME: 1427c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_PORT_STATE: 1428c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_PORT_SPEED: 1429f27fb2efSMike Christie return S_IRUGO; 1430f27fb2efSMike Christie default: 1431f27fb2efSMike Christie return 0; 1432f27fb2efSMike Christie } 14333128c6c7SMike Christie case ISCSI_PARAM: 14343128c6c7SMike Christie switch (param) { 14353128c6c7SMike Christie case ISCSI_PARAM_MAX_RECV_DLENGTH: 14363128c6c7SMike Christie case ISCSI_PARAM_MAX_XMIT_DLENGTH: 14373128c6c7SMike Christie case ISCSI_PARAM_HDRDGST_EN: 14383128c6c7SMike Christie case ISCSI_PARAM_DATADGST_EN: 14393128c6c7SMike Christie case ISCSI_PARAM_CONN_ADDRESS: 14403128c6c7SMike Christie case ISCSI_PARAM_CONN_PORT: 14413128c6c7SMike Christie case ISCSI_PARAM_EXP_STATSN: 14423128c6c7SMike Christie case ISCSI_PARAM_PERSISTENT_ADDRESS: 14433128c6c7SMike Christie case ISCSI_PARAM_PERSISTENT_PORT: 14443128c6c7SMike Christie case ISCSI_PARAM_PING_TMO: 14453128c6c7SMike Christie case ISCSI_PARAM_RECV_TMO: 14461d063c17SMike Christie case ISCSI_PARAM_INITIAL_R2T_EN: 14471d063c17SMike Christie case ISCSI_PARAM_MAX_R2T: 14481d063c17SMike Christie case ISCSI_PARAM_IMM_DATA_EN: 14491d063c17SMike Christie case ISCSI_PARAM_FIRST_BURST: 14501d063c17SMike Christie case ISCSI_PARAM_MAX_BURST: 14511d063c17SMike Christie case ISCSI_PARAM_PDU_INORDER_EN: 14521d063c17SMike Christie case ISCSI_PARAM_DATASEQ_INORDER_EN: 14531d063c17SMike Christie case ISCSI_PARAM_ERL: 14541d063c17SMike Christie case ISCSI_PARAM_TARGET_NAME: 14551d063c17SMike Christie case ISCSI_PARAM_TPGT: 14561d063c17SMike Christie case ISCSI_PARAM_USERNAME: 14571d063c17SMike Christie case ISCSI_PARAM_PASSWORD: 14581d063c17SMike Christie case ISCSI_PARAM_USERNAME_IN: 14591d063c17SMike Christie case ISCSI_PARAM_PASSWORD_IN: 14601d063c17SMike Christie case ISCSI_PARAM_FAST_ABORT: 14611d063c17SMike Christie case ISCSI_PARAM_ABORT_TMO: 14621d063c17SMike Christie case ISCSI_PARAM_LU_RESET_TMO: 14631d063c17SMike Christie case ISCSI_PARAM_IFACE_NAME: 14641d063c17SMike Christie case ISCSI_PARAM_INITIATOR_NAME: 14653128c6c7SMike Christie return S_IRUGO; 14663128c6c7SMike Christie default: 14673128c6c7SMike Christie return 0; 14683128c6c7SMike Christie } 14693128c6c7SMike Christie } 14703128c6c7SMike Christie 14713128c6c7SMike Christie return 0; 14723128c6c7SMike Christie } 1473