16733b39aSJayamohan Kallickal /** 2c4f39bdaSKetan 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 * 15c4f39bdaSKetan 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) { 559122e991SJitendra Bhivare pr_err("beiscsi_session_create: invalid ep\n"); 566733b39aSJayamohan Kallickal return NULL; 576733b39aSJayamohan Kallickal } 586733b39aSJayamohan Kallickal beiscsi_ep = ep->dd_data; 596733b39aSJayamohan Kallickal phba = beiscsi_ep->phba; 6099bc5d55SJohn Soni Jose 61*d1d5ca88SJitendra Bhivare if (!beiscsi_hba_is_online(phba)) { 6299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 639122e991SJitendra Bhivare "BS_%d : HBA in error 0x%lx\n", phba->state); 649122e991SJitendra Bhivare return NULL; 653567f36aSJayamohan Kallickal } 6699bc5d55SJohn Soni Jose 679122e991SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 689122e991SJitendra Bhivare "BS_%d : In beiscsi_session_create\n"); 696733b39aSJayamohan Kallickal if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) { 7099bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 7199bc5d55SJohn Soni Jose "BS_%d : Cannot handle %d cmds." 726733b39aSJayamohan Kallickal "Max cmds per session supported is %d. Using %d." 736733b39aSJayamohan Kallickal "\n", cmds_max, 746733b39aSJayamohan Kallickal beiscsi_ep->phba->params.wrbs_per_cxn, 756733b39aSJayamohan Kallickal beiscsi_ep->phba->params.wrbs_per_cxn); 7699bc5d55SJohn Soni Jose 776733b39aSJayamohan Kallickal cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn; 786733b39aSJayamohan Kallickal } 796733b39aSJayamohan Kallickal 803567f36aSJayamohan Kallickal shost = phba->shost; 816733b39aSJayamohan Kallickal cls_session = iscsi_session_setup(&beiscsi_iscsi_transport, 826733b39aSJayamohan Kallickal shost, cmds_max, 83b8b9e1b8SJayamohan Kallickal sizeof(*beiscsi_sess), 84b8b9e1b8SJayamohan Kallickal sizeof(*io_task), 856733b39aSJayamohan Kallickal initial_cmdsn, ISCSI_MAX_TARGET); 866733b39aSJayamohan Kallickal if (!cls_session) 876733b39aSJayamohan Kallickal return NULL; 886733b39aSJayamohan Kallickal sess = cls_session->dd_data; 892afc95bfSJayamohan Kallickal beiscsi_sess = sess->dd_data; 902afc95bfSJayamohan Kallickal beiscsi_sess->bhs_pool = pci_pool_create("beiscsi_bhs_pool", 912afc95bfSJayamohan Kallickal phba->pcidev, 922afc95bfSJayamohan Kallickal sizeof(struct be_cmd_bhs), 932afc95bfSJayamohan Kallickal 64, 0); 942afc95bfSJayamohan Kallickal if (!beiscsi_sess->bhs_pool) 952afc95bfSJayamohan Kallickal goto destroy_sess; 966733b39aSJayamohan Kallickal 976733b39aSJayamohan Kallickal return cls_session; 982afc95bfSJayamohan Kallickal destroy_sess: 992afc95bfSJayamohan Kallickal iscsi_session_teardown(cls_session); 1002afc95bfSJayamohan Kallickal return NULL; 1016733b39aSJayamohan Kallickal } 1026733b39aSJayamohan Kallickal 1036733b39aSJayamohan Kallickal /** 1046733b39aSJayamohan Kallickal * beiscsi_session_destroy - destroys iscsi session 1056733b39aSJayamohan Kallickal * @cls_session: pointer to iscsi cls session 1066733b39aSJayamohan Kallickal * 1076733b39aSJayamohan Kallickal * Destroys iSCSI session instance and releases 1086733b39aSJayamohan Kallickal * resources allocated for it. 1096733b39aSJayamohan Kallickal */ 1106733b39aSJayamohan Kallickal void beiscsi_session_destroy(struct iscsi_cls_session *cls_session) 1116733b39aSJayamohan Kallickal { 1126733b39aSJayamohan Kallickal struct iscsi_session *sess = cls_session->dd_data; 1132afc95bfSJayamohan Kallickal struct beiscsi_session *beiscsi_sess = sess->dd_data; 1146733b39aSJayamohan Kallickal 11599bc5d55SJohn Soni Jose printk(KERN_INFO "In beiscsi_session_destroy\n"); 1162afc95bfSJayamohan Kallickal pci_pool_destroy(beiscsi_sess->bhs_pool); 1176733b39aSJayamohan Kallickal iscsi_session_teardown(cls_session); 1186733b39aSJayamohan Kallickal } 1196733b39aSJayamohan Kallickal 1206733b39aSJayamohan Kallickal /** 121480195c2SJitendra Bhivare * beiscsi_session_fail(): Closing session with appropriate error 122480195c2SJitendra Bhivare * @cls_session: ptr to session 123480195c2SJitendra Bhivare **/ 124480195c2SJitendra Bhivare void beiscsi_session_fail(struct iscsi_cls_session *cls_session) 125480195c2SJitendra Bhivare { 126480195c2SJitendra Bhivare iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); 127480195c2SJitendra Bhivare } 128480195c2SJitendra Bhivare 129480195c2SJitendra Bhivare 130480195c2SJitendra Bhivare /** 1316733b39aSJayamohan Kallickal * beiscsi_conn_create - create an instance of iscsi connection 1326733b39aSJayamohan Kallickal * @cls_session: ptr to iscsi_cls_session 1336733b39aSJayamohan Kallickal * @cid: iscsi cid 1346733b39aSJayamohan Kallickal */ 1356733b39aSJayamohan Kallickal struct iscsi_cls_conn * 1366733b39aSJayamohan Kallickal beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid) 1376733b39aSJayamohan Kallickal { 1386733b39aSJayamohan Kallickal struct beiscsi_hba *phba; 1396733b39aSJayamohan Kallickal struct Scsi_Host *shost; 1406733b39aSJayamohan Kallickal struct iscsi_cls_conn *cls_conn; 1416733b39aSJayamohan Kallickal struct beiscsi_conn *beiscsi_conn; 1426733b39aSJayamohan Kallickal struct iscsi_conn *conn; 1432afc95bfSJayamohan Kallickal struct iscsi_session *sess; 1442afc95bfSJayamohan Kallickal struct beiscsi_session *beiscsi_sess; 1456733b39aSJayamohan Kallickal 1466733b39aSJayamohan Kallickal shost = iscsi_session_to_shost(cls_session); 1476733b39aSJayamohan Kallickal phba = iscsi_host_priv(shost); 1486733b39aSJayamohan Kallickal 14999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 15099bc5d55SJohn Soni Jose "BS_%d : In beiscsi_conn_create ,cid" 15199bc5d55SJohn Soni Jose "from iscsi layer=%d\n", cid); 15299bc5d55SJohn Soni Jose 1536733b39aSJayamohan Kallickal cls_conn = iscsi_conn_setup(cls_session, sizeof(*beiscsi_conn), cid); 1546733b39aSJayamohan Kallickal if (!cls_conn) 1556733b39aSJayamohan Kallickal return NULL; 1566733b39aSJayamohan Kallickal 1576733b39aSJayamohan Kallickal conn = cls_conn->dd_data; 1586733b39aSJayamohan Kallickal beiscsi_conn = conn->dd_data; 1596733b39aSJayamohan Kallickal beiscsi_conn->ep = NULL; 1606733b39aSJayamohan Kallickal beiscsi_conn->phba = phba; 1616733b39aSJayamohan Kallickal beiscsi_conn->conn = conn; 1622afc95bfSJayamohan Kallickal sess = cls_session->dd_data; 1632afc95bfSJayamohan Kallickal beiscsi_sess = sess->dd_data; 1642afc95bfSJayamohan Kallickal beiscsi_conn->beiscsi_sess = beiscsi_sess; 1656733b39aSJayamohan Kallickal return cls_conn; 1666733b39aSJayamohan Kallickal } 1676733b39aSJayamohan Kallickal 1686733b39aSJayamohan Kallickal /** 1696733b39aSJayamohan Kallickal * beiscsi_bindconn_cid - Bind the beiscsi_conn with phba connection table 1706733b39aSJayamohan Kallickal * @beiscsi_conn: The pointer to beiscsi_conn structure 1716733b39aSJayamohan Kallickal * @phba: The phba instance 1726733b39aSJayamohan Kallickal * @cid: The cid to free 1736733b39aSJayamohan Kallickal */ 1746733b39aSJayamohan Kallickal static int beiscsi_bindconn_cid(struct beiscsi_hba *phba, 1756733b39aSJayamohan Kallickal struct beiscsi_conn *beiscsi_conn, 1766733b39aSJayamohan Kallickal unsigned int cid) 1776733b39aSJayamohan Kallickal { 178a7909b39SJayamohan Kallickal uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 179a7909b39SJayamohan Kallickal 180a7909b39SJayamohan Kallickal if (phba->conn_table[cri_index]) { 18199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 18299bc5d55SJohn Soni Jose "BS_%d : Connection table already occupied. Detected clash\n"); 18399bc5d55SJohn Soni Jose 1846733b39aSJayamohan Kallickal return -EINVAL; 1856733b39aSJayamohan Kallickal } else { 18699bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 18799bc5d55SJohn Soni Jose "BS_%d : phba->conn_table[%d]=%p(beiscsi_conn)\n", 188a7909b39SJayamohan Kallickal cri_index, beiscsi_conn); 18999bc5d55SJohn Soni Jose 190a7909b39SJayamohan Kallickal phba->conn_table[cri_index] = beiscsi_conn; 1916733b39aSJayamohan Kallickal } 1926733b39aSJayamohan Kallickal return 0; 1936733b39aSJayamohan Kallickal } 1946733b39aSJayamohan Kallickal 1956733b39aSJayamohan Kallickal /** 1966733b39aSJayamohan Kallickal * beiscsi_conn_bind - Binds iscsi session/connection with TCP connection 1976733b39aSJayamohan Kallickal * @cls_session: pointer to iscsi cls session 1986733b39aSJayamohan Kallickal * @cls_conn: pointer to iscsi cls conn 1996733b39aSJayamohan Kallickal * @transport_fd: EP handle(64 bit) 2006733b39aSJayamohan Kallickal * 2016733b39aSJayamohan Kallickal * This function binds the TCP Conn with iSCSI Connection and Session. 2026733b39aSJayamohan Kallickal */ 2036733b39aSJayamohan Kallickal int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, 2046733b39aSJayamohan Kallickal struct iscsi_cls_conn *cls_conn, 2056733b39aSJayamohan Kallickal u64 transport_fd, int is_leading) 2066733b39aSJayamohan Kallickal { 2076733b39aSJayamohan Kallickal struct iscsi_conn *conn = cls_conn->dd_data; 2086733b39aSJayamohan Kallickal struct beiscsi_conn *beiscsi_conn = conn->dd_data; 2093093b048SMike Christie struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 2103093b048SMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 2111e4be6ffSJayamohan Kallickal struct hwi_controller *phwi_ctrlr = phba->phwi_ctrlr; 2121e4be6ffSJayamohan Kallickal struct hwi_wrb_context *pwrb_context; 2136733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep; 2146733b39aSJayamohan Kallickal struct iscsi_endpoint *ep; 2156733b39aSJayamohan Kallickal 2166733b39aSJayamohan Kallickal ep = iscsi_lookup_endpoint(transport_fd); 2176733b39aSJayamohan Kallickal if (!ep) 2186733b39aSJayamohan Kallickal return -EINVAL; 2196733b39aSJayamohan Kallickal 2206733b39aSJayamohan Kallickal beiscsi_ep = ep->dd_data; 2216733b39aSJayamohan Kallickal 2226733b39aSJayamohan Kallickal if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) 2236733b39aSJayamohan Kallickal return -EINVAL; 2246733b39aSJayamohan Kallickal 2256733b39aSJayamohan Kallickal if (beiscsi_ep->phba != phba) { 22699bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 22799bc5d55SJohn Soni Jose "BS_%d : beiscsi_ep->hba=%p not equal to phba=%p\n", 2286733b39aSJayamohan Kallickal beiscsi_ep->phba, phba); 22999bc5d55SJohn Soni Jose 2306733b39aSJayamohan Kallickal return -EEXIST; 2316733b39aSJayamohan Kallickal } 2326733b39aSJayamohan Kallickal 2331e4be6ffSJayamohan Kallickal pwrb_context = &phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID( 2341e4be6ffSJayamohan Kallickal beiscsi_ep->ep_cid)]; 2351e4be6ffSJayamohan Kallickal 2366733b39aSJayamohan Kallickal beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid; 2376733b39aSJayamohan Kallickal beiscsi_conn->ep = beiscsi_ep; 2386733b39aSJayamohan Kallickal beiscsi_ep->conn = beiscsi_conn; 2391e4be6ffSJayamohan Kallickal beiscsi_conn->doorbell_offset = pwrb_context->doorbell_offset; 24099bc5d55SJohn Soni Jose 24199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 24299bc5d55SJohn Soni Jose "BS_%d : beiscsi_conn=%p conn=%p ep_cid=%d\n", 2436733b39aSJayamohan Kallickal beiscsi_conn, conn, beiscsi_ep->ep_cid); 24499bc5d55SJohn Soni Jose 2456733b39aSJayamohan Kallickal return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid); 2466733b39aSJayamohan Kallickal } 2476733b39aSJayamohan Kallickal 24896b48b92SJitendra Bhivare static int beiscsi_iface_create_ipv4(struct beiscsi_hba *phba) 2490e43895eSMike Christie { 2500e43895eSMike Christie if (phba->ipv4_iface) 2510e43895eSMike Christie return 0; 2520e43895eSMike Christie 2530e43895eSMike Christie phba->ipv4_iface = iscsi_create_iface(phba->shost, 2540e43895eSMike Christie &beiscsi_iscsi_transport, 2550e43895eSMike Christie ISCSI_IFACE_TYPE_IPV4, 2560e43895eSMike Christie 0, 0); 2570e43895eSMike Christie if (!phba->ipv4_iface) { 25899bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 25999bc5d55SJohn Soni Jose "BS_%d : Could not " 2600e43895eSMike Christie "create default IPv4 address.\n"); 2610e43895eSMike Christie return -ENODEV; 2620e43895eSMike Christie } 2630e43895eSMike Christie 2640e43895eSMike Christie return 0; 2650e43895eSMike Christie } 2660e43895eSMike Christie 26796b48b92SJitendra Bhivare static int beiscsi_iface_create_ipv6(struct beiscsi_hba *phba) 2680e43895eSMike Christie { 2690e43895eSMike Christie if (phba->ipv6_iface) 2700e43895eSMike Christie return 0; 2710e43895eSMike Christie 2720e43895eSMike Christie phba->ipv6_iface = iscsi_create_iface(phba->shost, 2730e43895eSMike Christie &beiscsi_iscsi_transport, 2740e43895eSMike Christie ISCSI_IFACE_TYPE_IPV6, 2750e43895eSMike Christie 0, 0); 2760e43895eSMike Christie if (!phba->ipv6_iface) { 27799bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 27899bc5d55SJohn Soni Jose "BS_%d : Could not " 2790e43895eSMike Christie "create default IPv6 address.\n"); 2800e43895eSMike Christie return -ENODEV; 2810e43895eSMike Christie } 2820e43895eSMike Christie 2830e43895eSMike Christie return 0; 2840e43895eSMike Christie } 2850e43895eSMike Christie 28696b48b92SJitendra Bhivare void beiscsi_iface_create_default(struct beiscsi_hba *phba) 2870e43895eSMike Christie { 2881f536d49SJayamohan Kallickal struct be_cmd_get_if_info_resp *if_info; 2890e43895eSMike Christie 290290aa376SJitendra Bhivare if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V4, &if_info)) { 29196b48b92SJitendra Bhivare beiscsi_iface_create_ipv4(phba); 2921f536d49SJayamohan Kallickal kfree(if_info); 2931f536d49SJayamohan Kallickal } 2940e43895eSMike Christie 295290aa376SJitendra Bhivare if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V6, &if_info)) { 29696b48b92SJitendra Bhivare beiscsi_iface_create_ipv6(phba); 2971f536d49SJayamohan Kallickal kfree(if_info); 2981f536d49SJayamohan Kallickal } 2990e43895eSMike Christie } 3000e43895eSMike Christie 30196b48b92SJitendra Bhivare void beiscsi_iface_destroy_default(struct beiscsi_hba *phba) 3020e43895eSMike Christie { 303f7dd017eSJitendra Bhivare if (phba->ipv6_iface) { 3040e43895eSMike Christie iscsi_destroy_iface(phba->ipv6_iface); 305f7dd017eSJitendra Bhivare phba->ipv6_iface = NULL; 306f7dd017eSJitendra Bhivare } 307f7dd017eSJitendra Bhivare if (phba->ipv4_iface) { 3080e43895eSMike Christie iscsi_destroy_iface(phba->ipv4_iface); 309f7dd017eSJitendra Bhivare phba->ipv4_iface = NULL; 310f7dd017eSJitendra Bhivare } 3110e43895eSMike Christie } 3120e43895eSMike Christie 3136f72238eSJohn Soni Jose /** 3146f72238eSJohn Soni Jose * beiscsi_set_vlan_tag()- Set the VLAN TAG 3156f72238eSJohn Soni Jose * @shost: Scsi Host for the driver instance 3166f72238eSJohn Soni Jose * @iface_param: Interface paramters 3176f72238eSJohn Soni Jose * 3186f72238eSJohn Soni Jose * Set the VLAN TAG for the adapter or disable 3196f72238eSJohn Soni Jose * the VLAN config 3206f72238eSJohn Soni Jose * 3216f72238eSJohn Soni Jose * returns 3226f72238eSJohn Soni Jose * Success: 0 3236f72238eSJohn Soni Jose * Failure: Non-Zero Value 3246f72238eSJohn Soni Jose **/ 3256f72238eSJohn Soni Jose static int 326db02aea9SJitendra Bhivare beiscsi_iface_config_vlan(struct Scsi_Host *shost, 3276f72238eSJohn Soni Jose struct iscsi_iface_param_info *iface_param) 3286f72238eSJohn Soni Jose { 3296f72238eSJohn Soni Jose struct beiscsi_hba *phba = iscsi_host_priv(shost); 330c5bf8889SJitendra Bhivare int ret = -EPERM; 3316f72238eSJohn Soni Jose 3326f72238eSJohn Soni Jose switch (iface_param->param) { 3336f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ENABLED: 334db02aea9SJitendra Bhivare ret = 0; 3356f72238eSJohn Soni Jose if (iface_param->value[0] != ISCSI_VLAN_ENABLE) 336db02aea9SJitendra Bhivare ret = beiscsi_if_set_vlan(phba, BEISCSI_VLAN_DISABLE); 3376f72238eSJohn Soni Jose break; 3386f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_TAG: 339db02aea9SJitendra Bhivare ret = beiscsi_if_set_vlan(phba, 3406f72238eSJohn Soni Jose *((uint16_t *)iface_param->value)); 3416f72238eSJohn Soni Jose break; 3426f72238eSJohn Soni Jose } 3436f72238eSJohn Soni Jose return ret; 3446f72238eSJohn Soni Jose } 3456f72238eSJohn Soni Jose 3466f72238eSJohn Soni Jose 3470e43895eSMike Christie static int 3480152a7e9SJitendra Bhivare beiscsi_iface_config_ipv4(struct Scsi_Host *shost, 3490152a7e9SJitendra Bhivare struct iscsi_iface_param_info *info, 3500e43895eSMike Christie void *data, uint32_t dt_len) 3510e43895eSMike Christie { 3520e43895eSMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 3530152a7e9SJitendra Bhivare u8 *ip = NULL, *subnet = NULL, *gw; 3540152a7e9SJitendra Bhivare struct nlattr *nla; 355db02aea9SJitendra Bhivare int ret = -EPERM; 3560e43895eSMike Christie 3570e43895eSMike Christie /* Check the param */ 3580152a7e9SJitendra Bhivare switch (info->param) { 359f7dd017eSJitendra Bhivare case ISCSI_NET_PARAM_IFACE_ENABLE: 3600152a7e9SJitendra Bhivare if (info->value[0] == ISCSI_IFACE_ENABLE) 36196b48b92SJitendra Bhivare ret = beiscsi_iface_create_ipv4(phba); 362f7dd017eSJitendra Bhivare else { 363f7dd017eSJitendra Bhivare iscsi_destroy_iface(phba->ipv4_iface); 364f7dd017eSJitendra Bhivare phba->ipv4_iface = NULL; 365f7dd017eSJitendra Bhivare } 366f7dd017eSJitendra Bhivare break; 3670e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_GW: 3680152a7e9SJitendra Bhivare gw = info->value; 369290aa376SJitendra Bhivare ret = beiscsi_if_set_gw(phba, BEISCSI_IP_TYPE_V4, gw); 3700e43895eSMike Christie break; 3710e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 3720152a7e9SJitendra Bhivare if (info->value[0] == ISCSI_BOOTPROTO_DHCP) 373290aa376SJitendra Bhivare ret = beiscsi_if_en_dhcp(phba, BEISCSI_IP_TYPE_V4); 3740152a7e9SJitendra Bhivare else if (info->value[0] == ISCSI_BOOTPROTO_STATIC) 3750152a7e9SJitendra Bhivare /* release DHCP IP address */ 376290aa376SJitendra Bhivare ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4, 377290aa376SJitendra Bhivare NULL, NULL); 3780e43895eSMike Christie else 37999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 38099bc5d55SJohn Soni Jose "BS_%d : Invalid BOOTPROTO: %d\n", 3810152a7e9SJitendra Bhivare info->value[0]); 3820152a7e9SJitendra Bhivare break; 3830152a7e9SJitendra Bhivare case ISCSI_NET_PARAM_IPV4_ADDR: 3840152a7e9SJitendra Bhivare ip = info->value; 3850152a7e9SJitendra Bhivare nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET); 3860152a7e9SJitendra Bhivare if (nla) { 3870152a7e9SJitendra Bhivare info = nla_data(nla); 3880152a7e9SJitendra Bhivare subnet = info->value; 3890152a7e9SJitendra Bhivare } 390290aa376SJitendra Bhivare ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4, 391290aa376SJitendra Bhivare ip, subnet); 3920e43895eSMike Christie break; 3930e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_SUBNET: 3940152a7e9SJitendra Bhivare /* 3950152a7e9SJitendra Bhivare * OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR ioctl needs IP 3960152a7e9SJitendra Bhivare * and subnet both. Find IP to be applied for this subnet. 3970152a7e9SJitendra Bhivare */ 3980152a7e9SJitendra Bhivare subnet = info->value; 3990152a7e9SJitendra Bhivare nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR); 4000152a7e9SJitendra Bhivare if (nla) { 4010152a7e9SJitendra Bhivare info = nla_data(nla); 4020152a7e9SJitendra Bhivare ip = info->value; 4030152a7e9SJitendra Bhivare } 404290aa376SJitendra Bhivare ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4, 405290aa376SJitendra Bhivare ip, subnet); 4060e43895eSMike Christie break; 4070e43895eSMike Christie } 4080e43895eSMike Christie 4090e43895eSMike Christie return ret; 4100e43895eSMike Christie } 4110e43895eSMike Christie 4120e43895eSMike Christie static int 4130152a7e9SJitendra Bhivare beiscsi_iface_config_ipv6(struct Scsi_Host *shost, 4140e43895eSMike Christie struct iscsi_iface_param_info *iface_param, 4150e43895eSMike Christie void *data, uint32_t dt_len) 4160e43895eSMike Christie { 4170e43895eSMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 418db02aea9SJitendra Bhivare int ret = -EPERM; 4190e43895eSMike Christie 4200e43895eSMike Christie switch (iface_param->param) { 4210e43895eSMike Christie case ISCSI_NET_PARAM_IFACE_ENABLE: 4220e43895eSMike Christie if (iface_param->value[0] == ISCSI_IFACE_ENABLE) 42396b48b92SJitendra Bhivare ret = beiscsi_iface_create_ipv6(phba); 4240e43895eSMike Christie else { 4250e43895eSMike Christie iscsi_destroy_iface(phba->ipv6_iface); 426f7dd017eSJitendra Bhivare phba->ipv6_iface = NULL; 4270e43895eSMike Christie } 4280e43895eSMike Christie break; 4290e43895eSMike Christie case ISCSI_NET_PARAM_IPV6_ADDR: 430290aa376SJitendra Bhivare ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V6, 4310152a7e9SJitendra Bhivare iface_param->value, NULL); 4320e43895eSMike Christie break; 4330e43895eSMike Christie } 4340e43895eSMike Christie 4350e43895eSMike Christie return ret; 4360e43895eSMike Christie } 4370e43895eSMike Christie 43896b48b92SJitendra Bhivare int beiscsi_iface_set_param(struct Scsi_Host *shost, 4390e43895eSMike Christie void *data, uint32_t dt_len) 4400e43895eSMike Christie { 4410e43895eSMike Christie struct iscsi_iface_param_info *iface_param = NULL; 44299bc5d55SJohn Soni Jose struct beiscsi_hba *phba = iscsi_host_priv(shost); 4430e43895eSMike Christie struct nlattr *attrib; 4440e43895eSMike Christie uint32_t rm_len = dt_len; 445c5bf8889SJitendra Bhivare int ret; 4460e43895eSMike Christie 447*d1d5ca88SJitendra Bhivare if (!beiscsi_hba_is_online(phba)) { 4489122e991SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 4499122e991SJitendra Bhivare "BS_%d : HBA in error 0x%lx\n", phba->state); 4503567f36aSJayamohan Kallickal return -EBUSY; 4513567f36aSJayamohan Kallickal } 4523567f36aSJayamohan Kallickal 453c5bf8889SJitendra Bhivare /* update interface_handle */ 454c5bf8889SJitendra Bhivare ret = beiscsi_if_get_handle(phba); 455c5bf8889SJitendra Bhivare if (ret) { 456c5bf8889SJitendra Bhivare beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 457c5bf8889SJitendra Bhivare "BS_%d : Getting Interface Handle Failed\n"); 458c5bf8889SJitendra Bhivare return ret; 459c5bf8889SJitendra Bhivare } 460c5bf8889SJitendra Bhivare 4610e43895eSMike Christie nla_for_each_attr(attrib, data, dt_len, rm_len) { 4620e43895eSMike Christie iface_param = nla_data(attrib); 4630e43895eSMike Christie 4640e43895eSMike Christie if (iface_param->param_type != ISCSI_NET_PARAM) 4650e43895eSMike Christie continue; 4660e43895eSMike Christie 4670e43895eSMike Christie /* 4680e43895eSMike Christie * BE2ISCSI only supports 1 interface 4690e43895eSMike Christie */ 4700e43895eSMike Christie if (iface_param->iface_num) { 47199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 47299bc5d55SJohn Soni Jose "BS_%d : Invalid iface_num %d." 4730e43895eSMike Christie "Only iface_num 0 is supported.\n", 4740e43895eSMike Christie iface_param->iface_num); 47599bc5d55SJohn Soni Jose 4760e43895eSMike Christie return -EINVAL; 4770e43895eSMike Christie } 4780e43895eSMike Christie 479db02aea9SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 480db02aea9SJitendra Bhivare "BS_%d : %s.0 set param %d", 481db02aea9SJitendra Bhivare (iface_param->iface_type == ISCSI_IFACE_TYPE_IPV4) ? 482db02aea9SJitendra Bhivare "ipv4" : "ipv6", iface_param->param); 483db02aea9SJitendra Bhivare 484db02aea9SJitendra Bhivare ret = -EPERM; 485db02aea9SJitendra Bhivare switch (iface_param->param) { 486db02aea9SJitendra Bhivare case ISCSI_NET_PARAM_VLAN_ENABLED: 487db02aea9SJitendra Bhivare case ISCSI_NET_PARAM_VLAN_TAG: 488db02aea9SJitendra Bhivare ret = beiscsi_iface_config_vlan(shost, iface_param); 489db02aea9SJitendra Bhivare break; 490db02aea9SJitendra Bhivare default: 4910e43895eSMike Christie switch (iface_param->iface_type) { 4920e43895eSMike Christie case ISCSI_IFACE_TYPE_IPV4: 493db02aea9SJitendra Bhivare ret = beiscsi_iface_config_ipv4(shost, 494db02aea9SJitendra Bhivare iface_param, 4950e43895eSMike Christie data, dt_len); 4960e43895eSMike Christie break; 4970e43895eSMike Christie case ISCSI_IFACE_TYPE_IPV6: 498db02aea9SJitendra Bhivare ret = beiscsi_iface_config_ipv6(shost, 499db02aea9SJitendra Bhivare iface_param, 5000e43895eSMike Christie data, dt_len); 5010e43895eSMike Christie break; 502db02aea9SJitendra Bhivare } 5030e43895eSMike Christie } 5040e43895eSMike Christie 505db02aea9SJitendra Bhivare if (ret == -EPERM) { 506db02aea9SJitendra Bhivare __beiscsi_log(phba, KERN_ERR, 507db02aea9SJitendra Bhivare "BS_%d : %s.0 set param %d not permitted", 508db02aea9SJitendra Bhivare (iface_param->iface_type == 509db02aea9SJitendra Bhivare ISCSI_IFACE_TYPE_IPV4) ? "ipv4" : "ipv6", 510db02aea9SJitendra Bhivare iface_param->param); 511db02aea9SJitendra Bhivare ret = 0; 512db02aea9SJitendra Bhivare } 5130e43895eSMike Christie if (ret) 514db02aea9SJitendra Bhivare break; 5150e43895eSMike Christie } 5160e43895eSMike Christie 5170e43895eSMike Christie return ret; 5180e43895eSMike Christie } 5190e43895eSMike Christie 52096b48b92SJitendra Bhivare static int __beiscsi_iface_get_param(struct beiscsi_hba *phba, 52196b48b92SJitendra Bhivare struct iscsi_iface *iface, 52296b48b92SJitendra Bhivare int param, char *buf) 5230e43895eSMike Christie { 5241f536d49SJayamohan Kallickal struct be_cmd_get_if_info_resp *if_info; 525290aa376SJitendra Bhivare int len, ip_type = BEISCSI_IP_TYPE_V4; 5260e43895eSMike Christie 5270e43895eSMike Christie if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) 528290aa376SJitendra Bhivare ip_type = BEISCSI_IP_TYPE_V6; 5290e43895eSMike Christie 53096b48b92SJitendra Bhivare len = beiscsi_if_get_info(phba, ip_type, &if_info); 5310e7c60cbSGeyslan G. Bem if (len) 5320e43895eSMike Christie return len; 5330e43895eSMike Christie 5340e43895eSMike Christie switch (param) { 5350e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_ADDR: 5361f536d49SJayamohan Kallickal len = sprintf(buf, "%pI4\n", if_info->ip_addr.addr); 5370e43895eSMike Christie break; 5380e43895eSMike Christie case ISCSI_NET_PARAM_IPV6_ADDR: 5391f536d49SJayamohan Kallickal len = sprintf(buf, "%pI6\n", if_info->ip_addr.addr); 5400e43895eSMike Christie break; 5410e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 5421f536d49SJayamohan Kallickal if (!if_info->dhcp_state) 5438359c79bSJohn Soni Jose len = sprintf(buf, "static\n"); 5440e43895eSMike Christie else 5458359c79bSJohn Soni Jose len = sprintf(buf, "dhcp\n"); 5460e43895eSMike Christie break; 5470e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_SUBNET: 5481f536d49SJayamohan Kallickal len = sprintf(buf, "%pI4\n", if_info->ip_addr.subnet_mask); 5490e43895eSMike Christie break; 5506f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ENABLED: 5516f72238eSJohn Soni Jose len = sprintf(buf, "%s\n", 552ea89604fSJitendra Bhivare (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) ? 553ea89604fSJitendra Bhivare "disable" : "enable"); 5546f72238eSJohn Soni Jose break; 5556f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ID: 5561f536d49SJayamohan Kallickal if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 5570e7c60cbSGeyslan G. Bem len = -EINVAL; 5586f72238eSJohn Soni Jose else 5596f72238eSJohn Soni Jose len = sprintf(buf, "%d\n", 5601f536d49SJayamohan Kallickal (if_info->vlan_priority & 5616f72238eSJohn Soni Jose ISCSI_MAX_VLAN_ID)); 5626f72238eSJohn Soni Jose break; 5636f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_PRIORITY: 5641f536d49SJayamohan Kallickal if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 5650e7c60cbSGeyslan G. Bem len = -EINVAL; 5666f72238eSJohn Soni Jose else 5676f72238eSJohn Soni Jose len = sprintf(buf, "%d\n", 5681f536d49SJayamohan Kallickal ((if_info->vlan_priority >> 13) & 5696f72238eSJohn Soni Jose ISCSI_MAX_VLAN_PRIORITY)); 5706f72238eSJohn Soni Jose break; 5710e43895eSMike Christie default: 5720e43895eSMike Christie WARN_ON(1); 5730e43895eSMike Christie } 5740e43895eSMike Christie 5751f536d49SJayamohan Kallickal kfree(if_info); 5760e43895eSMike Christie return len; 5770e43895eSMike Christie } 5780e43895eSMike Christie 57996b48b92SJitendra Bhivare int beiscsi_iface_get_param(struct iscsi_iface *iface, 5800e43895eSMike Christie enum iscsi_param_type param_type, 5810e43895eSMike Christie int param, char *buf) 5820e43895eSMike Christie { 5830e43895eSMike Christie struct Scsi_Host *shost = iscsi_iface_to_shost(iface); 5840e43895eSMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 5850e43895eSMike Christie struct be_cmd_get_def_gateway_resp gateway; 586c5bf8889SJitendra Bhivare int len = -EPERM; 5870e43895eSMike Christie 588d8383b34SJitendra Bhivare if (param_type != ISCSI_NET_PARAM) 589d8383b34SJitendra Bhivare return 0; 590*d1d5ca88SJitendra Bhivare if (!beiscsi_hba_is_online(phba)) { 5919122e991SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 5929122e991SJitendra Bhivare "BS_%d : HBA in error 0x%lx\n", phba->state); 5933567f36aSJayamohan Kallickal return -EBUSY; 5943567f36aSJayamohan Kallickal } 5953567f36aSJayamohan Kallickal 5960e43895eSMike Christie switch (param) { 5970e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_ADDR: 5980e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_SUBNET: 5990e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 6000e43895eSMike Christie case ISCSI_NET_PARAM_IPV6_ADDR: 6016f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ENABLED: 6026f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ID: 6036f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_PRIORITY: 60496b48b92SJitendra Bhivare len = __beiscsi_iface_get_param(phba, iface, param, buf); 6050e43895eSMike Christie break; 6060e43895eSMike Christie case ISCSI_NET_PARAM_IFACE_ENABLE: 607f7dd017eSJitendra Bhivare if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) 608f7dd017eSJitendra Bhivare len = sprintf(buf, "%s\n", 609f7dd017eSJitendra Bhivare phba->ipv4_iface ? "enable" : "disable"); 610f7dd017eSJitendra Bhivare else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) 611f7dd017eSJitendra Bhivare len = sprintf(buf, "%s\n", 612f7dd017eSJitendra Bhivare phba->ipv6_iface ? "enable" : "disable"); 6130e43895eSMike Christie break; 6140e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_GW: 6150e43895eSMike Christie memset(&gateway, 0, sizeof(gateway)); 616290aa376SJitendra Bhivare len = beiscsi_if_get_gw(phba, BEISCSI_IP_TYPE_V4, &gateway); 6170e43895eSMike Christie if (!len) 6180e43895eSMike Christie len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr); 6190e43895eSMike Christie break; 6200e43895eSMike Christie } 6210e43895eSMike Christie 6220e43895eSMike Christie return len; 6230e43895eSMike Christie } 6240e43895eSMike Christie 6256733b39aSJayamohan Kallickal /** 626c7f7fd5bSMike Christie * beiscsi_ep_get_param - get the iscsi parameter 627c7f7fd5bSMike Christie * @ep: pointer to iscsi ep 6286733b39aSJayamohan Kallickal * @param: parameter type identifier 6296733b39aSJayamohan Kallickal * @buf: buffer pointer 6306733b39aSJayamohan Kallickal * 6316733b39aSJayamohan Kallickal * returns iscsi parameter 6326733b39aSJayamohan Kallickal */ 633c7f7fd5bSMike Christie int beiscsi_ep_get_param(struct iscsi_endpoint *ep, 6346733b39aSJayamohan Kallickal enum iscsi_param param, char *buf) 6356733b39aSJayamohan Kallickal { 636c7f7fd5bSMike Christie struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 637c5bf8889SJitendra Bhivare int len; 6386733b39aSJayamohan Kallickal 63999bc5d55SJohn Soni Jose beiscsi_log(beiscsi_ep->phba, KERN_INFO, 64099bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG, 64199bc5d55SJohn Soni Jose "BS_%d : In beiscsi_ep_get_param," 64299bc5d55SJohn Soni Jose " param= %d\n", param); 6436733b39aSJayamohan Kallickal 6446733b39aSJayamohan Kallickal switch (param) { 6456733b39aSJayamohan Kallickal case ISCSI_PARAM_CONN_PORT: 6466733b39aSJayamohan Kallickal len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport); 6476733b39aSJayamohan Kallickal break; 6486733b39aSJayamohan Kallickal case ISCSI_PARAM_CONN_ADDRESS: 649290aa376SJitendra Bhivare if (beiscsi_ep->ip_type == BEISCSI_IP_TYPE_V4) 6506733b39aSJayamohan Kallickal len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr); 6516733b39aSJayamohan Kallickal else 6526733b39aSJayamohan Kallickal len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr); 6536733b39aSJayamohan Kallickal break; 6546733b39aSJayamohan Kallickal default: 655c5bf8889SJitendra Bhivare len = -EPERM; 6566733b39aSJayamohan Kallickal } 6576733b39aSJayamohan Kallickal return len; 6586733b39aSJayamohan Kallickal } 6596733b39aSJayamohan Kallickal 6606733b39aSJayamohan Kallickal int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, 6616733b39aSJayamohan Kallickal enum iscsi_param param, char *buf, int buflen) 6626733b39aSJayamohan Kallickal { 6636733b39aSJayamohan Kallickal struct iscsi_conn *conn = cls_conn->dd_data; 6646733b39aSJayamohan Kallickal struct iscsi_session *session = conn->session; 66599bc5d55SJohn Soni Jose struct beiscsi_hba *phba = NULL; 6666733b39aSJayamohan Kallickal int ret; 6676733b39aSJayamohan Kallickal 66899bc5d55SJohn Soni Jose phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 66999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 67099bc5d55SJohn Soni Jose "BS_%d : In beiscsi_conn_set_param," 67199bc5d55SJohn Soni Jose " param= %d\n", param); 67299bc5d55SJohn Soni Jose 6736733b39aSJayamohan Kallickal ret = iscsi_set_param(cls_conn, param, buf, buflen); 6746733b39aSJayamohan Kallickal if (ret) 6756733b39aSJayamohan Kallickal return ret; 6766733b39aSJayamohan Kallickal /* 6776733b39aSJayamohan Kallickal * If userspace tried to set the value to higher than we can 6786733b39aSJayamohan Kallickal * support override here. 6796733b39aSJayamohan Kallickal */ 6806733b39aSJayamohan Kallickal switch (param) { 6816733b39aSJayamohan Kallickal case ISCSI_PARAM_FIRST_BURST: 6826733b39aSJayamohan Kallickal if (session->first_burst > 8192) 6836733b39aSJayamohan Kallickal session->first_burst = 8192; 6846733b39aSJayamohan Kallickal break; 6856733b39aSJayamohan Kallickal case ISCSI_PARAM_MAX_RECV_DLENGTH: 6866733b39aSJayamohan Kallickal if (conn->max_recv_dlength > 65536) 6876733b39aSJayamohan Kallickal conn->max_recv_dlength = 65536; 6886733b39aSJayamohan Kallickal break; 6896733b39aSJayamohan Kallickal case ISCSI_PARAM_MAX_BURST: 690230dceb4SJayamohan Kallickal if (session->max_burst > 262144) 691230dceb4SJayamohan Kallickal session->max_burst = 262144; 6926733b39aSJayamohan Kallickal break; 69342f43c41SJayamohan Kallickal case ISCSI_PARAM_MAX_XMIT_DLENGTH: 6947331613eSJayamohan Kallickal if (conn->max_xmit_dlength > 65536) 69542f43c41SJayamohan Kallickal conn->max_xmit_dlength = 65536; 6966733b39aSJayamohan Kallickal default: 6976733b39aSJayamohan Kallickal return 0; 6986733b39aSJayamohan Kallickal } 6996733b39aSJayamohan Kallickal 7006733b39aSJayamohan Kallickal return 0; 7016733b39aSJayamohan Kallickal } 7026733b39aSJayamohan Kallickal 7036733b39aSJayamohan Kallickal /** 7042177199dSJohn Soni Jose * beiscsi_get_initname - Read Initiator Name from flash 7052177199dSJohn Soni Jose * @buf: buffer bointer 7062177199dSJohn Soni Jose * @phba: The device priv structure instance 7072177199dSJohn Soni Jose * 7082177199dSJohn Soni Jose * returns number of bytes 7092177199dSJohn Soni Jose */ 7102177199dSJohn Soni Jose static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba) 7112177199dSJohn Soni Jose { 7122177199dSJohn Soni Jose int rc; 713e175defeSJohn Soni Jose unsigned int tag; 7142177199dSJohn Soni Jose struct be_mcc_wrb *wrb; 7152177199dSJohn Soni Jose struct be_cmd_hba_name *resp; 7162177199dSJohn Soni Jose 7172177199dSJohn Soni Jose tag = be_cmd_get_initname(phba); 7182177199dSJohn Soni Jose if (!tag) { 71999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 72099bc5d55SJohn Soni Jose "BS_%d : Getting Initiator Name Failed\n"); 72199bc5d55SJohn Soni Jose 7222177199dSJohn Soni Jose return -EBUSY; 723e175defeSJohn Soni Jose } 7242177199dSJohn Soni Jose 72588840332SJitendra Bhivare rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL); 726e175defeSJohn Soni Jose if (rc) { 72799bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, 72899bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 729e175defeSJohn Soni Jose "BS_%d : Initiator Name MBX Failed\n"); 730e175defeSJohn Soni Jose return rc; 7312177199dSJohn Soni Jose } 732e175defeSJohn Soni Jose 7332177199dSJohn Soni Jose resp = embedded_payload(wrb); 7342177199dSJohn Soni Jose rc = sprintf(buf, "%s\n", resp->initiator_name); 7352177199dSJohn Soni Jose return rc; 7362177199dSJohn Soni Jose } 7372177199dSJohn Soni Jose 7382177199dSJohn Soni Jose /** 739c62eef0dSJohn Soni Jose * beiscsi_get_port_state - Get the Port State 740c62eef0dSJohn Soni Jose * @shost : pointer to scsi_host structure 741c62eef0dSJohn Soni Jose * 742c62eef0dSJohn Soni Jose */ 743c62eef0dSJohn Soni Jose static void beiscsi_get_port_state(struct Scsi_Host *shost) 744c62eef0dSJohn Soni Jose { 745c62eef0dSJohn Soni Jose struct beiscsi_hba *phba = iscsi_host_priv(shost); 746c62eef0dSJohn Soni Jose struct iscsi_cls_host *ihost = shost->shost_data; 747c62eef0dSJohn Soni Jose 7489122e991SJitendra Bhivare ihost->port_state = test_bit(BEISCSI_HBA_LINK_UP, &phba->state) ? 749c62eef0dSJohn Soni Jose ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; 750c62eef0dSJohn Soni Jose } 751c62eef0dSJohn Soni Jose 752c62eef0dSJohn Soni Jose /** 753c62eef0dSJohn Soni Jose * beiscsi_get_port_speed - Get the Port Speed from Adapter 754c62eef0dSJohn Soni Jose * @shost : pointer to scsi_host structure 755c62eef0dSJohn Soni Jose * 756c62eef0dSJohn Soni Jose */ 757048084c2SJitendra Bhivare static void beiscsi_get_port_speed(struct Scsi_Host *shost) 758c62eef0dSJohn Soni Jose { 759c62eef0dSJohn Soni Jose struct beiscsi_hba *phba = iscsi_host_priv(shost); 760c62eef0dSJohn Soni Jose struct iscsi_cls_host *ihost = shost->shost_data; 761c62eef0dSJohn Soni Jose 762048084c2SJitendra Bhivare switch (phba->port_speed) { 763c62eef0dSJohn Soni Jose case BE2ISCSI_LINK_SPEED_10MBPS: 764c62eef0dSJohn Soni Jose ihost->port_speed = ISCSI_PORT_SPEED_10MBPS; 765c62eef0dSJohn Soni Jose break; 766c62eef0dSJohn Soni Jose case BE2ISCSI_LINK_SPEED_100MBPS: 7673e393172SJayamohan Kallickal ihost->port_speed = ISCSI_PORT_SPEED_100MBPS; 768c62eef0dSJohn Soni Jose break; 769c62eef0dSJohn Soni Jose case BE2ISCSI_LINK_SPEED_1GBPS: 770c62eef0dSJohn Soni Jose ihost->port_speed = ISCSI_PORT_SPEED_1GBPS; 771c62eef0dSJohn Soni Jose break; 772c62eef0dSJohn Soni Jose case BE2ISCSI_LINK_SPEED_10GBPS: 773c62eef0dSJohn Soni Jose ihost->port_speed = ISCSI_PORT_SPEED_10GBPS; 774c62eef0dSJohn Soni Jose break; 775048084c2SJitendra Bhivare case BE2ISCSI_LINK_SPEED_25GBPS: 776048084c2SJitendra Bhivare ihost->port_speed = ISCSI_PORT_SPEED_25GBPS; 777048084c2SJitendra Bhivare break; 778048084c2SJitendra Bhivare case BE2ISCSI_LINK_SPEED_40GBPS: 779048084c2SJitendra Bhivare ihost->port_speed = ISCSI_PORT_SPEED_40GBPS; 780048084c2SJitendra Bhivare break; 781c62eef0dSJohn Soni Jose default: 782c62eef0dSJohn Soni Jose ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN; 783c62eef0dSJohn Soni Jose } 784c62eef0dSJohn Soni Jose } 785c62eef0dSJohn Soni Jose 786c62eef0dSJohn Soni Jose /** 7876733b39aSJayamohan Kallickal * beiscsi_get_host_param - get the iscsi parameter 7886733b39aSJayamohan Kallickal * @shost: pointer to scsi_host structure 7896733b39aSJayamohan Kallickal * @param: parameter type identifier 7906733b39aSJayamohan Kallickal * @buf: buffer pointer 7916733b39aSJayamohan Kallickal * 7926733b39aSJayamohan Kallickal * returns host parameter 7936733b39aSJayamohan Kallickal */ 7946733b39aSJayamohan Kallickal int beiscsi_get_host_param(struct Scsi_Host *shost, 7956733b39aSJayamohan Kallickal enum iscsi_host_param param, char *buf) 7966733b39aSJayamohan Kallickal { 7973093b048SMike Christie struct beiscsi_hba *phba = iscsi_host_priv(shost); 798b15d05b0SJayamohan Kallickal int status = 0; 7996733b39aSJayamohan Kallickal 800*d1d5ca88SJitendra Bhivare if (!beiscsi_hba_is_online(phba)) { 80199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 8029122e991SJitendra Bhivare "BS_%d : HBA in error 0x%lx\n", phba->state); 8039122e991SJitendra Bhivare return -EBUSY; 8043567f36aSJayamohan Kallickal } 8059122e991SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 8069122e991SJitendra Bhivare "BS_%d : In beiscsi_get_host_param, param = %d\n", param); 80799bc5d55SJohn Soni Jose 8086733b39aSJayamohan Kallickal switch (param) { 8096733b39aSJayamohan Kallickal case ISCSI_HOST_PARAM_HWADDRESS: 810c7acc5b8SJayamohan Kallickal status = beiscsi_get_macaddr(buf, phba); 811c7acc5b8SJayamohan Kallickal if (status < 0) { 81299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 81399bc5d55SJohn Soni Jose "BS_%d : beiscsi_get_macaddr Failed\n"); 814c7acc5b8SJayamohan Kallickal return status; 815c7acc5b8SJayamohan Kallickal } 816c7acc5b8SJayamohan Kallickal break; 8172177199dSJohn Soni Jose case ISCSI_HOST_PARAM_INITIATOR_NAME: 8182177199dSJohn Soni Jose status = beiscsi_get_initname(buf, phba); 8192177199dSJohn Soni Jose if (status < 0) { 82099bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 82199bc5d55SJohn Soni Jose "BS_%d : Retreiving Initiator Name Failed\n"); 8222177199dSJohn Soni Jose return status; 8232177199dSJohn Soni Jose } 8242177199dSJohn Soni Jose break; 825c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_PORT_STATE: 826c62eef0dSJohn Soni Jose beiscsi_get_port_state(shost); 827c62eef0dSJohn Soni Jose status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost)); 828c62eef0dSJohn Soni Jose break; 829c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_PORT_SPEED: 830048084c2SJitendra Bhivare beiscsi_get_port_speed(shost); 831c62eef0dSJohn Soni Jose status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost)); 832c62eef0dSJohn Soni Jose break; 833c7acc5b8SJayamohan Kallickal default: 834c7acc5b8SJayamohan Kallickal return iscsi_host_get_param(shost, param, buf); 835c7acc5b8SJayamohan Kallickal } 836b15d05b0SJayamohan Kallickal return status; 837c7acc5b8SJayamohan Kallickal } 838c7acc5b8SJayamohan Kallickal 839c7acc5b8SJayamohan Kallickal int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) 840c7acc5b8SJayamohan Kallickal { 8410e43895eSMike Christie struct be_cmd_get_nic_conf_resp resp; 842c7acc5b8SJayamohan Kallickal int rc; 843c7acc5b8SJayamohan Kallickal 8446c83185aSJayamohan Kallickal if (phba->mac_addr_set) 845df5d0e6eSJohn Soni Jose return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 846c7acc5b8SJayamohan Kallickal 8470e43895eSMike Christie memset(&resp, 0, sizeof(resp)); 8480e43895eSMike Christie rc = mgmt_get_nic_conf(phba, &resp); 8490e43895eSMike Christie if (rc) 850c7acc5b8SJayamohan Kallickal return rc; 851c7acc5b8SJayamohan Kallickal 8526c83185aSJayamohan Kallickal phba->mac_addr_set = true; 8530e43895eSMike Christie memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); 8540e43895eSMike Christie return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 8550e43895eSMike Christie } 8566733b39aSJayamohan Kallickal 8576733b39aSJayamohan Kallickal /** 8586733b39aSJayamohan Kallickal * beiscsi_conn_get_stats - get the iscsi stats 8596733b39aSJayamohan Kallickal * @cls_conn: pointer to iscsi cls conn 8606733b39aSJayamohan Kallickal * @stats: pointer to iscsi_stats structure 8616733b39aSJayamohan Kallickal * 8626733b39aSJayamohan Kallickal * returns iscsi stats 8636733b39aSJayamohan Kallickal */ 8646733b39aSJayamohan Kallickal void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, 8656733b39aSJayamohan Kallickal struct iscsi_stats *stats) 8666733b39aSJayamohan Kallickal { 8676733b39aSJayamohan Kallickal struct iscsi_conn *conn = cls_conn->dd_data; 86899bc5d55SJohn Soni Jose struct beiscsi_hba *phba = NULL; 8696733b39aSJayamohan Kallickal 87099bc5d55SJohn Soni Jose phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 87199bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 87299bc5d55SJohn Soni Jose "BS_%d : In beiscsi_conn_get_stats\n"); 87399bc5d55SJohn Soni Jose 8746733b39aSJayamohan Kallickal stats->txdata_octets = conn->txdata_octets; 8756733b39aSJayamohan Kallickal stats->rxdata_octets = conn->rxdata_octets; 8766733b39aSJayamohan Kallickal stats->dataout_pdus = conn->dataout_pdus_cnt; 8776733b39aSJayamohan Kallickal stats->scsirsp_pdus = conn->scsirsp_pdus_cnt; 8786733b39aSJayamohan Kallickal stats->scsicmd_pdus = conn->scsicmd_pdus_cnt; 8796733b39aSJayamohan Kallickal stats->datain_pdus = conn->datain_pdus_cnt; 8806733b39aSJayamohan Kallickal stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; 8816733b39aSJayamohan Kallickal stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; 8826733b39aSJayamohan Kallickal stats->r2t_pdus = conn->r2t_pdus_cnt; 8836733b39aSJayamohan Kallickal stats->digest_err = 0; 8846733b39aSJayamohan Kallickal stats->timeout_err = 0; 885915aafd8SMike Christie stats->custom_length = 1; 8866733b39aSJayamohan Kallickal strcpy(stats->custom[0].desc, "eh_abort_cnt"); 8876733b39aSJayamohan Kallickal stats->custom[0].value = conn->eh_abort_cnt; 8886733b39aSJayamohan Kallickal } 8896733b39aSJayamohan Kallickal 8906733b39aSJayamohan Kallickal /** 8916733b39aSJayamohan Kallickal * beiscsi_set_params_for_offld - get the parameters for offload 8926733b39aSJayamohan Kallickal * @beiscsi_conn: pointer to beiscsi_conn 8936733b39aSJayamohan Kallickal * @params: pointer to offload_params structure 8946733b39aSJayamohan Kallickal */ 8956733b39aSJayamohan Kallickal static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn, 8966733b39aSJayamohan Kallickal struct beiscsi_offload_params *params) 8976733b39aSJayamohan Kallickal { 8986733b39aSJayamohan Kallickal struct iscsi_conn *conn = beiscsi_conn->conn; 8996733b39aSJayamohan Kallickal struct iscsi_session *session = conn->session; 9006733b39aSJayamohan Kallickal 9016733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length, 9026733b39aSJayamohan Kallickal params, session->max_burst); 9036733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, 9046733b39aSJayamohan Kallickal max_send_data_segment_length, params, 9056733b39aSJayamohan Kallickal conn->max_xmit_dlength); 9066733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length, 9076733b39aSJayamohan Kallickal params, session->first_burst); 9086733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params, 9096733b39aSJayamohan Kallickal session->erl); 9106733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params, 9116733b39aSJayamohan Kallickal conn->datadgst_en); 9126733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params, 9136733b39aSJayamohan Kallickal conn->hdrdgst_en); 9146733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params, 9156733b39aSJayamohan Kallickal session->initial_r2t_en); 9166733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params, 9176733b39aSJayamohan Kallickal session->imm_data_en); 918acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_beiscsi_offload_params, 919acb9693cSJohn Soni Jose data_seq_inorder, params, 920acb9693cSJohn Soni Jose session->dataseq_inorder_en); 921acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_beiscsi_offload_params, 922acb9693cSJohn Soni Jose pdu_seq_inorder, params, 923acb9693cSJohn Soni Jose session->pdu_inorder_en); 924acb9693cSJohn Soni Jose AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_r2t, params, 925acb9693cSJohn Soni Jose session->max_r2t); 9266733b39aSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params, 9276733b39aSJayamohan Kallickal (conn->exp_statsn - 1)); 9287331613eSJayamohan Kallickal AMAP_SET_BITS(struct amap_beiscsi_offload_params, 9297331613eSJayamohan Kallickal max_recv_data_segment_length, params, 9307331613eSJayamohan Kallickal conn->max_recv_dlength); 9317331613eSJayamohan Kallickal 9326733b39aSJayamohan Kallickal } 9336733b39aSJayamohan Kallickal 9346733b39aSJayamohan Kallickal /** 9356733b39aSJayamohan Kallickal * beiscsi_conn_start - offload of session to chip 9366733b39aSJayamohan Kallickal * @cls_conn: pointer to beiscsi_conn 9376733b39aSJayamohan Kallickal */ 9386733b39aSJayamohan Kallickal int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) 9396733b39aSJayamohan Kallickal { 9406733b39aSJayamohan Kallickal struct iscsi_conn *conn = cls_conn->dd_data; 9416733b39aSJayamohan Kallickal struct beiscsi_conn *beiscsi_conn = conn->dd_data; 9426733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep; 9436733b39aSJayamohan Kallickal struct beiscsi_offload_params params; 9443567f36aSJayamohan Kallickal struct beiscsi_hba *phba; 9456733b39aSJayamohan Kallickal 9463567f36aSJayamohan Kallickal phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 9473567f36aSJayamohan Kallickal 948*d1d5ca88SJitendra Bhivare if (!beiscsi_hba_is_online(phba)) { 9499122e991SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 9509122e991SJitendra Bhivare "BS_%d : HBA in error 0x%lx\n", phba->state); 9513567f36aSJayamohan Kallickal return -EBUSY; 9523567f36aSJayamohan Kallickal } 9539122e991SJitendra Bhivare beiscsi_log(beiscsi_conn->phba, KERN_INFO, BEISCSI_LOG_CONFIG, 9549122e991SJitendra Bhivare "BS_%d : In beiscsi_conn_start\n"); 95599bc5d55SJohn Soni Jose 9566733b39aSJayamohan Kallickal memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); 9576733b39aSJayamohan Kallickal beiscsi_ep = beiscsi_conn->ep; 9586733b39aSJayamohan Kallickal if (!beiscsi_ep) 95999bc5d55SJohn Soni Jose beiscsi_log(beiscsi_conn->phba, KERN_ERR, 96099bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG, 96199bc5d55SJohn Soni Jose "BS_%d : In beiscsi_conn_start , no beiscsi_ep\n"); 9626733b39aSJayamohan Kallickal 9636733b39aSJayamohan Kallickal beiscsi_conn->login_in_progress = 0; 9646733b39aSJayamohan Kallickal beiscsi_set_params_for_offld(beiscsi_conn, ¶ms); 9656733b39aSJayamohan Kallickal beiscsi_offload_connection(beiscsi_conn, ¶ms); 9666733b39aSJayamohan Kallickal iscsi_conn_start(cls_conn); 9676733b39aSJayamohan Kallickal return 0; 9686733b39aSJayamohan Kallickal } 9696733b39aSJayamohan Kallickal 9706733b39aSJayamohan Kallickal /** 9716733b39aSJayamohan Kallickal * beiscsi_get_cid - Allocate a cid 9726733b39aSJayamohan Kallickal * @phba: The phba instance 9736733b39aSJayamohan Kallickal */ 9746733b39aSJayamohan Kallickal static int beiscsi_get_cid(struct beiscsi_hba *phba) 9756733b39aSJayamohan Kallickal { 9760a3db7c0SJayamohan Kallickal unsigned short cid = 0xFFFF, cid_from_ulp; 9770a3db7c0SJayamohan Kallickal struct ulp_cid_info *cid_info = NULL; 9780a3db7c0SJayamohan Kallickal uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1; 9796733b39aSJayamohan Kallickal 9800a3db7c0SJayamohan Kallickal /* Find the ULP which has more CID available */ 9810a3db7c0SJayamohan Kallickal cid_avlbl_ulp0 = (phba->cid_array_info[BEISCSI_ULP0]) ? 9820a3db7c0SJayamohan Kallickal BEISCSI_ULP0_AVLBL_CID(phba) : 0; 9830a3db7c0SJayamohan Kallickal cid_avlbl_ulp1 = (phba->cid_array_info[BEISCSI_ULP1]) ? 9840a3db7c0SJayamohan Kallickal BEISCSI_ULP1_AVLBL_CID(phba) : 0; 9850a3db7c0SJayamohan Kallickal cid_from_ulp = (cid_avlbl_ulp0 > cid_avlbl_ulp1) ? 9860a3db7c0SJayamohan Kallickal BEISCSI_ULP0 : BEISCSI_ULP1; 9870a3db7c0SJayamohan Kallickal 9880a3db7c0SJayamohan Kallickal if (test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported)) { 9890a3db7c0SJayamohan Kallickal cid_info = phba->cid_array_info[cid_from_ulp]; 9900a3db7c0SJayamohan Kallickal if (!cid_info->avlbl_cids) 9916733b39aSJayamohan Kallickal return cid; 9926733b39aSJayamohan Kallickal 9930a3db7c0SJayamohan Kallickal cid = cid_info->cid_array[cid_info->cid_alloc++]; 9940a3db7c0SJayamohan Kallickal 9950a3db7c0SJayamohan Kallickal if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT( 9960a3db7c0SJayamohan Kallickal phba, cid_from_ulp)) 9970a3db7c0SJayamohan Kallickal cid_info->cid_alloc = 0; 9980a3db7c0SJayamohan Kallickal 9990a3db7c0SJayamohan Kallickal cid_info->avlbl_cids--; 10000a3db7c0SJayamohan Kallickal } 10016733b39aSJayamohan Kallickal return cid; 10026733b39aSJayamohan Kallickal } 10036733b39aSJayamohan Kallickal 10046733b39aSJayamohan Kallickal /** 1005fa95d206SMike Christie * beiscsi_put_cid - Free the cid 1006fa95d206SMike Christie * @phba: The phba for which the cid is being freed 1007fa95d206SMike Christie * @cid: The cid to free 1008fa95d206SMike Christie */ 1009fa95d206SMike Christie static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) 1010fa95d206SMike Christie { 10110a3db7c0SJayamohan Kallickal uint16_t cid_post_ulp; 10120a3db7c0SJayamohan Kallickal struct hwi_controller *phwi_ctrlr; 10130a3db7c0SJayamohan Kallickal struct hwi_wrb_context *pwrb_context; 10140a3db7c0SJayamohan Kallickal struct ulp_cid_info *cid_info = NULL; 10150a3db7c0SJayamohan Kallickal uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 10160a3db7c0SJayamohan Kallickal 10170a3db7c0SJayamohan Kallickal phwi_ctrlr = phba->phwi_ctrlr; 10180a3db7c0SJayamohan Kallickal pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; 10190a3db7c0SJayamohan Kallickal cid_post_ulp = pwrb_context->ulp_num; 10200a3db7c0SJayamohan Kallickal 10210a3db7c0SJayamohan Kallickal cid_info = phba->cid_array_info[cid_post_ulp]; 10220a3db7c0SJayamohan Kallickal cid_info->avlbl_cids++; 10230a3db7c0SJayamohan Kallickal 10240a3db7c0SJayamohan Kallickal cid_info->cid_array[cid_info->cid_free++] = cid; 10250a3db7c0SJayamohan Kallickal if (cid_info->cid_free == BEISCSI_GET_CID_COUNT(phba, cid_post_ulp)) 10260a3db7c0SJayamohan Kallickal cid_info->cid_free = 0; 1027fa95d206SMike Christie } 1028fa95d206SMike Christie 1029fa95d206SMike Christie /** 1030fa95d206SMike Christie * beiscsi_free_ep - free endpoint 1031fa95d206SMike Christie * @ep: pointer to iscsi endpoint structure 1032fa95d206SMike Christie */ 1033fa95d206SMike Christie static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) 1034fa95d206SMike Christie { 1035fa95d206SMike Christie struct beiscsi_hba *phba = beiscsi_ep->phba; 103643f388b0SJayamohan Kallickal struct beiscsi_conn *beiscsi_conn; 1037fa95d206SMike Christie 1038fa95d206SMike Christie beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 1039fa95d206SMike Christie beiscsi_ep->phba = NULL; 1040a7909b39SJayamohan Kallickal phba->ep_array[BE_GET_CRI_FROM_CID 1041a7909b39SJayamohan Kallickal (beiscsi_ep->ep_cid)] = NULL; 104243f388b0SJayamohan Kallickal 104343f388b0SJayamohan Kallickal /** 104443f388b0SJayamohan Kallickal * Check if any connection resource allocated by driver 104543f388b0SJayamohan Kallickal * is to be freed.This case occurs when target redirection 104643f388b0SJayamohan Kallickal * or connection retry is done. 104743f388b0SJayamohan Kallickal **/ 104843f388b0SJayamohan Kallickal if (!beiscsi_ep->conn) 104943f388b0SJayamohan Kallickal return; 105043f388b0SJayamohan Kallickal 105143f388b0SJayamohan Kallickal beiscsi_conn = beiscsi_ep->conn; 105243f388b0SJayamohan Kallickal if (beiscsi_conn->login_in_progress) { 10534a4a11b9SJayamohan Kallickal beiscsi_free_mgmt_task_handles(beiscsi_conn, 10544a4a11b9SJayamohan Kallickal beiscsi_conn->task); 105543f388b0SJayamohan Kallickal beiscsi_conn->login_in_progress = 0; 105643f388b0SJayamohan Kallickal } 1057fa95d206SMike Christie } 1058fa95d206SMike Christie 1059fa95d206SMike Christie /** 10606733b39aSJayamohan Kallickal * beiscsi_open_conn - Ask FW to open a TCP connection 10616733b39aSJayamohan Kallickal * @ep: endpoint to be used 10626733b39aSJayamohan Kallickal * @src_addr: The source IP address 10636733b39aSJayamohan Kallickal * @dst_addr: The Destination IP address 10646733b39aSJayamohan Kallickal * 10656733b39aSJayamohan Kallickal * Asks the FW to open a TCP connection 10666733b39aSJayamohan Kallickal */ 10676733b39aSJayamohan Kallickal static int beiscsi_open_conn(struct iscsi_endpoint *ep, 10686733b39aSJayamohan Kallickal struct sockaddr *src_addr, 10696733b39aSJayamohan Kallickal struct sockaddr *dst_addr, int non_blocking) 10706733b39aSJayamohan Kallickal { 10716733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 10726733b39aSJayamohan Kallickal struct beiscsi_hba *phba = beiscsi_ep->phba; 1073756d29c8SJayamohan Kallickal struct tcp_connect_and_offload_out *ptcpcnct_out; 10743cbb7a74SJayamohan Kallickal struct be_dma_mem nonemb_cmd; 1075b3c202dcSJayamohan Kallickal unsigned int tag, req_memsize; 1076d3ad2bb3SJayamohan Kallickal int ret = -ENOMEM; 10776733b39aSJayamohan Kallickal 107899bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 107999bc5d55SJohn Soni Jose "BS_%d : In beiscsi_open_conn\n"); 108099bc5d55SJohn Soni Jose 10816733b39aSJayamohan Kallickal beiscsi_ep->ep_cid = beiscsi_get_cid(phba); 10826733b39aSJayamohan Kallickal if (beiscsi_ep->ep_cid == 0xFFFF) { 108399bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 108499bc5d55SJohn Soni Jose "BS_%d : No free cid available\n"); 10856733b39aSJayamohan Kallickal return ret; 10866733b39aSJayamohan Kallickal } 108799bc5d55SJohn Soni Jose 108899bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 108999bc5d55SJohn Soni Jose "BS_%d : In beiscsi_open_conn, ep_cid=%d\n", 10906733b39aSJayamohan Kallickal beiscsi_ep->ep_cid); 109199bc5d55SJohn Soni Jose 1092a7909b39SJayamohan Kallickal phba->ep_array[BE_GET_CRI_FROM_CID 1093a7909b39SJayamohan Kallickal (beiscsi_ep->ep_cid)] = ep; 10946733b39aSJayamohan Kallickal 10956733b39aSJayamohan Kallickal beiscsi_ep->cid_vld = 0; 1096b3c202dcSJayamohan Kallickal 1097b3c202dcSJayamohan Kallickal if (is_chip_be2_be3r(phba)) 1098b3c202dcSJayamohan Kallickal req_memsize = sizeof(struct tcp_connect_and_offload_in); 1099b3c202dcSJayamohan Kallickal else 1100b3c202dcSJayamohan Kallickal req_memsize = sizeof(struct tcp_connect_and_offload_in_v1); 1101b3c202dcSJayamohan Kallickal 11023cbb7a74SJayamohan Kallickal nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, 1103b3c202dcSJayamohan Kallickal req_memsize, 11043cbb7a74SJayamohan Kallickal &nonemb_cmd.dma); 11053cbb7a74SJayamohan Kallickal if (nonemb_cmd.va == NULL) { 110699bc5d55SJohn Soni Jose 110799bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 110899bc5d55SJohn Soni Jose "BS_%d : Failed to allocate memory for" 110999bc5d55SJohn Soni Jose " mgmt_open_connection\n"); 111099bc5d55SJohn Soni Jose 1111a7909b39SJayamohan Kallickal beiscsi_free_ep(beiscsi_ep); 11123cbb7a74SJayamohan Kallickal return -ENOMEM; 11133cbb7a74SJayamohan Kallickal } 1114b3c202dcSJayamohan Kallickal nonemb_cmd.size = req_memsize; 11153cbb7a74SJayamohan Kallickal memset(nonemb_cmd.va, 0, nonemb_cmd.size); 11163cbb7a74SJayamohan Kallickal tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd); 11171e234bbbSJayamohan Kallickal if (tag <= 0) { 111899bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 111999bc5d55SJohn Soni Jose "BS_%d : mgmt_open_connection Failed for cid=%d\n", 1120756d29c8SJayamohan Kallickal beiscsi_ep->ep_cid); 112199bc5d55SJohn Soni Jose 11223cbb7a74SJayamohan Kallickal pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 11233cbb7a74SJayamohan Kallickal nonemb_cmd.va, nonemb_cmd.dma); 1124a7909b39SJayamohan Kallickal beiscsi_free_ep(beiscsi_ep); 11251f92638fSJayamohan Kallickal return -EAGAIN; 1126756d29c8SJayamohan Kallickal } 1127e175defeSJohn Soni Jose 112888840332SJitendra Bhivare ret = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd); 1129e175defeSJohn Soni Jose if (ret) { 113099bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, 113199bc5d55SJohn Soni Jose BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 1132e175defeSJohn Soni Jose "BS_%d : mgmt_open_connection Failed"); 113399bc5d55SJohn Soni Jose 11341957aa7fSJayamohan Kallickal if (ret != -EBUSY) 11353cbb7a74SJayamohan Kallickal pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 11363cbb7a74SJayamohan Kallickal nonemb_cmd.va, nonemb_cmd.dma); 11371957aa7fSJayamohan Kallickal 1138a7909b39SJayamohan Kallickal beiscsi_free_ep(beiscsi_ep); 11391957aa7fSJayamohan Kallickal return ret; 1140e175defeSJohn Soni Jose } 1141756d29c8SJayamohan Kallickal 11421e234bbbSJayamohan Kallickal ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va; 1143756d29c8SJayamohan Kallickal beiscsi_ep = ep->dd_data; 1144756d29c8SJayamohan Kallickal beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; 1145756d29c8SJayamohan Kallickal beiscsi_ep->cid_vld = 1; 114699bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 114799bc5d55SJohn Soni Jose "BS_%d : mgmt_open_connection Success\n"); 1148e175defeSJohn Soni Jose 11493cbb7a74SJayamohan Kallickal pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 11503cbb7a74SJayamohan Kallickal nonemb_cmd.va, nonemb_cmd.dma); 1151756d29c8SJayamohan Kallickal return 0; 11526733b39aSJayamohan Kallickal } 11536733b39aSJayamohan Kallickal 11546733b39aSJayamohan Kallickal /** 11556733b39aSJayamohan Kallickal * beiscsi_ep_connect - Ask chip to create TCP Conn 11566733b39aSJayamohan Kallickal * @scsi_host: Pointer to scsi_host structure 11576733b39aSJayamohan Kallickal * @dst_addr: The IP address of Target 11586733b39aSJayamohan Kallickal * @non_blocking: blocking or non-blocking call 11596733b39aSJayamohan Kallickal * 11606733b39aSJayamohan Kallickal * This routines first asks chip to create a connection and then allocates an EP 11616733b39aSJayamohan Kallickal */ 11626733b39aSJayamohan Kallickal struct iscsi_endpoint * 11636733b39aSJayamohan Kallickal beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, 11646733b39aSJayamohan Kallickal int non_blocking) 11656733b39aSJayamohan Kallickal { 11666733b39aSJayamohan Kallickal struct beiscsi_hba *phba; 11676733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep; 11686733b39aSJayamohan Kallickal struct iscsi_endpoint *ep; 11696733b39aSJayamohan Kallickal int ret; 11706733b39aSJayamohan Kallickal 11719122e991SJitendra Bhivare if (!shost) { 11726733b39aSJayamohan Kallickal ret = -ENXIO; 11739122e991SJitendra Bhivare pr_err("beiscsi_ep_connect shost is NULL\n"); 11746733b39aSJayamohan Kallickal return ERR_PTR(ret); 11756733b39aSJayamohan Kallickal } 1176bfead3b2SJayamohan Kallickal 11779122e991SJitendra Bhivare phba = iscsi_host_priv(shost); 1178*d1d5ca88SJitendra Bhivare if (!beiscsi_hba_is_online(phba)) { 1179cf6e3c64SJayamohan Kallickal ret = -EIO; 11809122e991SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 11819122e991SJitendra Bhivare "BS_%d : HBA in error 0x%lx\n", phba->state); 1182cf6e3c64SJayamohan Kallickal return ERR_PTR(ret); 1183cf6e3c64SJayamohan Kallickal } 11849122e991SJitendra Bhivare if (!test_bit(BEISCSI_HBA_LINK_UP, &phba->state)) { 1185bfead3b2SJayamohan Kallickal ret = -EBUSY; 11868359c79bSJohn Soni Jose beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 11878359c79bSJohn Soni Jose "BS_%d : The Adapter Port state is Down!!!\n"); 1188bfead3b2SJayamohan Kallickal return ERR_PTR(ret); 1189bfead3b2SJayamohan Kallickal } 1190bfead3b2SJayamohan Kallickal 11916733b39aSJayamohan Kallickal ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint)); 11926733b39aSJayamohan Kallickal if (!ep) { 11936733b39aSJayamohan Kallickal ret = -ENOMEM; 11946733b39aSJayamohan Kallickal return ERR_PTR(ret); 11956733b39aSJayamohan Kallickal } 11966733b39aSJayamohan Kallickal 11976733b39aSJayamohan Kallickal beiscsi_ep = ep->dd_data; 11986733b39aSJayamohan Kallickal beiscsi_ep->phba = phba; 1199c2462288SJayamohan Kallickal beiscsi_ep->openiscsi_ep = ep; 1200f5ed7bd4SJayamohan Kallickal ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking); 1201f5ed7bd4SJayamohan Kallickal if (ret) { 120299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 120399bc5d55SJohn Soni Jose "BS_%d : Failed in beiscsi_open_conn\n"); 12046733b39aSJayamohan Kallickal goto free_ep; 12056733b39aSJayamohan Kallickal } 12066733b39aSJayamohan Kallickal 12076733b39aSJayamohan Kallickal return ep; 12086733b39aSJayamohan Kallickal 12096733b39aSJayamohan Kallickal free_ep: 1210fa95d206SMike Christie iscsi_destroy_endpoint(ep); 12116733b39aSJayamohan Kallickal return ERR_PTR(ret); 12126733b39aSJayamohan Kallickal } 12136733b39aSJayamohan Kallickal 12146733b39aSJayamohan Kallickal /** 12156733b39aSJayamohan Kallickal * beiscsi_ep_poll - Poll to see if connection is established 12166733b39aSJayamohan Kallickal * @ep: endpoint to be used 12176733b39aSJayamohan Kallickal * @timeout_ms: timeout specified in millisecs 12186733b39aSJayamohan Kallickal * 12196733b39aSJayamohan Kallickal * Poll to see if TCP connection established 12206733b39aSJayamohan Kallickal */ 12216733b39aSJayamohan Kallickal int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) 12226733b39aSJayamohan Kallickal { 12236733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 12246733b39aSJayamohan Kallickal 122599bc5d55SJohn Soni Jose beiscsi_log(beiscsi_ep->phba, KERN_INFO, BEISCSI_LOG_CONFIG, 122699bc5d55SJohn Soni Jose "BS_%d : In beiscsi_ep_poll\n"); 122799bc5d55SJohn Soni Jose 12286733b39aSJayamohan Kallickal if (beiscsi_ep->cid_vld == 1) 12296733b39aSJayamohan Kallickal return 1; 12306733b39aSJayamohan Kallickal else 12316733b39aSJayamohan Kallickal return 0; 12326733b39aSJayamohan Kallickal } 12336733b39aSJayamohan Kallickal 12346733b39aSJayamohan Kallickal /** 1235b7ab35b1SJayamohan Kallickal * beiscsi_flush_cq()- Flush the CQ created. 1236b7ab35b1SJayamohan Kallickal * @phba: ptr device priv structure. 1237b7ab35b1SJayamohan Kallickal * 1238b7ab35b1SJayamohan Kallickal * Before the connection resource are freed flush 1239b7ab35b1SJayamohan Kallickal * all the CQ enteries 1240b7ab35b1SJayamohan Kallickal **/ 1241b7ab35b1SJayamohan Kallickal static void beiscsi_flush_cq(struct beiscsi_hba *phba) 1242b7ab35b1SJayamohan Kallickal { 1243b7ab35b1SJayamohan Kallickal uint16_t i; 1244b7ab35b1SJayamohan Kallickal struct be_eq_obj *pbe_eq; 1245b7ab35b1SJayamohan Kallickal struct hwi_controller *phwi_ctrlr; 1246b7ab35b1SJayamohan Kallickal struct hwi_context_memory *phwi_context; 1247b7ab35b1SJayamohan Kallickal 1248b7ab35b1SJayamohan Kallickal phwi_ctrlr = phba->phwi_ctrlr; 1249b7ab35b1SJayamohan Kallickal phwi_context = phwi_ctrlr->phwi_ctxt; 1250b7ab35b1SJayamohan Kallickal 1251b7ab35b1SJayamohan Kallickal for (i = 0; i < phba->num_cpus; i++) { 1252b7ab35b1SJayamohan Kallickal pbe_eq = &phwi_context->be_eq[i]; 1253511cbce2SChristoph Hellwig irq_poll_disable(&pbe_eq->iopoll); 12541094cf68SJitendra Bhivare beiscsi_process_cq(pbe_eq, BE2_MAX_NUM_CQ_PROC); 1255511cbce2SChristoph Hellwig irq_poll_enable(&pbe_eq->iopoll); 1256b7ab35b1SJayamohan Kallickal } 1257b7ab35b1SJayamohan Kallickal } 1258b7ab35b1SJayamohan Kallickal 1259b7ab35b1SJayamohan Kallickal /** 12606733b39aSJayamohan Kallickal * beiscsi_close_conn - Upload the connection 12616733b39aSJayamohan Kallickal * @ep: The iscsi endpoint 12626733b39aSJayamohan Kallickal * @flag: The type of connection closure 12636733b39aSJayamohan Kallickal */ 1264c2462288SJayamohan Kallickal static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) 12656733b39aSJayamohan Kallickal { 12666733b39aSJayamohan Kallickal int ret = 0; 1267756d29c8SJayamohan Kallickal unsigned int tag; 12686733b39aSJayamohan Kallickal struct beiscsi_hba *phba = beiscsi_ep->phba; 12696733b39aSJayamohan Kallickal 1270756d29c8SJayamohan Kallickal tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag); 1271756d29c8SJayamohan Kallickal if (!tag) { 127299bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 127399bc5d55SJohn Soni Jose "BS_%d : upload failed for cid 0x%x\n", 12746733b39aSJayamohan Kallickal beiscsi_ep->ep_cid); 127599bc5d55SJohn Soni Jose 1276d3ad2bb3SJayamohan Kallickal ret = -EAGAIN; 12776733b39aSJayamohan Kallickal } 1278e175defeSJohn Soni Jose 127988840332SJitendra Bhivare ret = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL); 1280b7ab35b1SJayamohan Kallickal 1281b7ab35b1SJayamohan Kallickal /* Flush the CQ entries */ 1282b7ab35b1SJayamohan Kallickal beiscsi_flush_cq(phba); 1283b7ab35b1SJayamohan Kallickal 12846733b39aSJayamohan Kallickal return ret; 12856733b39aSJayamohan Kallickal } 12866733b39aSJayamohan Kallickal 12876733b39aSJayamohan Kallickal /** 12886733b39aSJayamohan Kallickal * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table 12896733b39aSJayamohan Kallickal * @phba: The phba instance 12906733b39aSJayamohan Kallickal * @cid: The cid to free 12916733b39aSJayamohan Kallickal */ 12926733b39aSJayamohan Kallickal static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, 12936733b39aSJayamohan Kallickal unsigned int cid) 12946733b39aSJayamohan Kallickal { 1295a7909b39SJayamohan Kallickal uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 1296a7909b39SJayamohan Kallickal 1297a7909b39SJayamohan Kallickal if (phba->conn_table[cri_index]) 1298a7909b39SJayamohan Kallickal phba->conn_table[cri_index] = NULL; 12996733b39aSJayamohan Kallickal else { 130099bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 130199bc5d55SJohn Soni Jose "BS_%d : Connection table Not occupied.\n"); 13026733b39aSJayamohan Kallickal return -EINVAL; 13036733b39aSJayamohan Kallickal } 13046733b39aSJayamohan Kallickal return 0; 13056733b39aSJayamohan Kallickal } 13066733b39aSJayamohan Kallickal 13076733b39aSJayamohan Kallickal /** 1308fa95d206SMike Christie * beiscsi_ep_disconnect - Tears down the TCP connection 1309fa95d206SMike Christie * @ep: endpoint to be used 1310fa95d206SMike Christie * 1311fa95d206SMike Christie * Tears down the TCP connection 13126733b39aSJayamohan Kallickal */ 1313fa95d206SMike Christie void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) 13146733b39aSJayamohan Kallickal { 1315fa95d206SMike Christie struct beiscsi_conn *beiscsi_conn; 13166733b39aSJayamohan Kallickal struct beiscsi_endpoint *beiscsi_ep; 1317fa95d206SMike Christie struct beiscsi_hba *phba; 1318756d29c8SJayamohan Kallickal unsigned int tag; 13190a513dd8SJohn Soni Jose uint8_t mgmt_invalidate_flag, tcp_upload_flag; 13206733b39aSJayamohan Kallickal unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; 13216733b39aSJayamohan Kallickal 1322fa95d206SMike Christie beiscsi_ep = ep->dd_data; 1323fa95d206SMike Christie phba = beiscsi_ep->phba; 132499bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 132599bc5d55SJohn Soni Jose "BS_%d : In beiscsi_ep_disconnect for ep_cid = %d\n", 1326fa95d206SMike Christie beiscsi_ep->ep_cid); 1327fa95d206SMike Christie 13280a513dd8SJohn Soni Jose if (beiscsi_ep->conn) { 1329fa95d206SMike Christie beiscsi_conn = beiscsi_ep->conn; 1330fa95d206SMike Christie iscsi_suspend_queue(beiscsi_conn->conn); 13310a513dd8SJohn Soni Jose mgmt_invalidate_flag = ~BEISCSI_NO_RST_ISSUE; 13320a513dd8SJohn Soni Jose tcp_upload_flag = CONNECTION_UPLOAD_GRACEFUL; 13330a513dd8SJohn Soni Jose } else { 13340a513dd8SJohn Soni Jose mgmt_invalidate_flag = BEISCSI_NO_RST_ISSUE; 13350a513dd8SJohn Soni Jose tcp_upload_flag = CONNECTION_UPLOAD_ABORT; 13360a513dd8SJohn Soni Jose } 1337fa95d206SMike Christie 1338*d1d5ca88SJitendra Bhivare if (!beiscsi_hba_is_online(phba)) { 13399122e991SJitendra Bhivare beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 13409122e991SJitendra Bhivare "BS_%d : HBA in error 0x%lx\n", phba->state); 13413567f36aSJayamohan Kallickal goto free_ep; 13423567f36aSJayamohan Kallickal } 13433567f36aSJayamohan Kallickal 1344756d29c8SJayamohan Kallickal tag = mgmt_invalidate_connection(phba, beiscsi_ep, 13450a513dd8SJohn Soni Jose beiscsi_ep->ep_cid, 13460a513dd8SJohn Soni Jose mgmt_invalidate_flag, 13476733b39aSJayamohan Kallickal savecfg_flag); 1348756d29c8SJayamohan Kallickal if (!tag) { 134999bc5d55SJohn Soni Jose beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 13500a513dd8SJohn Soni Jose "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n", 13516733b39aSJayamohan Kallickal beiscsi_ep->ep_cid); 13526733b39aSJayamohan Kallickal } 1353fa95d206SMike Christie 135488840332SJitendra Bhivare beiscsi_mccq_compl_wait(phba, tag, NULL, NULL); 13550a513dd8SJohn Soni Jose beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); 13563567f36aSJayamohan Kallickal free_ep: 13579343be74SJayamohan Kallickal msleep(BEISCSI_LOGOUT_SYNC_DELAY); 1358c2462288SJayamohan Kallickal beiscsi_free_ep(beiscsi_ep); 13596733b39aSJayamohan Kallickal beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); 1360fa95d206SMike Christie iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); 13616733b39aSJayamohan Kallickal } 13623128c6c7SMike Christie 136396b48b92SJitendra Bhivare umode_t beiscsi_attr_is_visible(int param_type, int param) 13643128c6c7SMike Christie { 13653128c6c7SMike Christie switch (param_type) { 13660e43895eSMike Christie case ISCSI_NET_PARAM: 13670e43895eSMike Christie switch (param) { 13680e43895eSMike Christie case ISCSI_NET_PARAM_IFACE_ENABLE: 13690e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_ADDR: 13700e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_SUBNET: 13710e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 13720e43895eSMike Christie case ISCSI_NET_PARAM_IPV4_GW: 13730e43895eSMike Christie case ISCSI_NET_PARAM_IPV6_ADDR: 13746f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ID: 13756f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_PRIORITY: 13766f72238eSJohn Soni Jose case ISCSI_NET_PARAM_VLAN_ENABLED: 13770e43895eSMike Christie return S_IRUGO; 13780e43895eSMike Christie default: 13790e43895eSMike Christie return 0; 13800e43895eSMike Christie } 1381f27fb2efSMike Christie case ISCSI_HOST_PARAM: 1382f27fb2efSMike Christie switch (param) { 1383f27fb2efSMike Christie case ISCSI_HOST_PARAM_HWADDRESS: 1384c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_INITIATOR_NAME: 1385c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_PORT_STATE: 1386c62eef0dSJohn Soni Jose case ISCSI_HOST_PARAM_PORT_SPEED: 1387f27fb2efSMike Christie return S_IRUGO; 1388f27fb2efSMike Christie default: 1389f27fb2efSMike Christie return 0; 1390f27fb2efSMike Christie } 13913128c6c7SMike Christie case ISCSI_PARAM: 13923128c6c7SMike Christie switch (param) { 13933128c6c7SMike Christie case ISCSI_PARAM_MAX_RECV_DLENGTH: 13943128c6c7SMike Christie case ISCSI_PARAM_MAX_XMIT_DLENGTH: 13953128c6c7SMike Christie case ISCSI_PARAM_HDRDGST_EN: 13963128c6c7SMike Christie case ISCSI_PARAM_DATADGST_EN: 13973128c6c7SMike Christie case ISCSI_PARAM_CONN_ADDRESS: 13983128c6c7SMike Christie case ISCSI_PARAM_CONN_PORT: 13993128c6c7SMike Christie case ISCSI_PARAM_EXP_STATSN: 14003128c6c7SMike Christie case ISCSI_PARAM_PERSISTENT_ADDRESS: 14013128c6c7SMike Christie case ISCSI_PARAM_PERSISTENT_PORT: 14023128c6c7SMike Christie case ISCSI_PARAM_PING_TMO: 14033128c6c7SMike Christie case ISCSI_PARAM_RECV_TMO: 14041d063c17SMike Christie case ISCSI_PARAM_INITIAL_R2T_EN: 14051d063c17SMike Christie case ISCSI_PARAM_MAX_R2T: 14061d063c17SMike Christie case ISCSI_PARAM_IMM_DATA_EN: 14071d063c17SMike Christie case ISCSI_PARAM_FIRST_BURST: 14081d063c17SMike Christie case ISCSI_PARAM_MAX_BURST: 14091d063c17SMike Christie case ISCSI_PARAM_PDU_INORDER_EN: 14101d063c17SMike Christie case ISCSI_PARAM_DATASEQ_INORDER_EN: 14111d063c17SMike Christie case ISCSI_PARAM_ERL: 14121d063c17SMike Christie case ISCSI_PARAM_TARGET_NAME: 14131d063c17SMike Christie case ISCSI_PARAM_TPGT: 14141d063c17SMike Christie case ISCSI_PARAM_USERNAME: 14151d063c17SMike Christie case ISCSI_PARAM_PASSWORD: 14161d063c17SMike Christie case ISCSI_PARAM_USERNAME_IN: 14171d063c17SMike Christie case ISCSI_PARAM_PASSWORD_IN: 14181d063c17SMike Christie case ISCSI_PARAM_FAST_ABORT: 14191d063c17SMike Christie case ISCSI_PARAM_ABORT_TMO: 14201d063c17SMike Christie case ISCSI_PARAM_LU_RESET_TMO: 14211d063c17SMike Christie case ISCSI_PARAM_IFACE_NAME: 14221d063c17SMike Christie case ISCSI_PARAM_INITIATOR_NAME: 14233128c6c7SMike Christie return S_IRUGO; 14243128c6c7SMike Christie default: 14253128c6c7SMike Christie return 0; 14263128c6c7SMike Christie } 14273128c6c7SMike Christie } 14283128c6c7SMike Christie 14293128c6c7SMike Christie return 0; 14303128c6c7SMike Christie } 1431