1 /** 2 * Copyright (C) 2005 - 2016 Broadcom 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License version 2 7 * as published by the Free Software Foundation. The full GNU General 8 * Public License is included in this distribution in the file called COPYING. 9 * 10 * Written by: Jayamohan Kallickal (jayamohan.kallickal@broadcom.com) 11 * 12 * Contact Information: 13 * linux-drivers@broadcom.com 14 * 15 * Emulex 16 * 3333 Susan Street 17 * Costa Mesa, CA 92626 18 */ 19 20 #include <scsi/libiscsi.h> 21 #include <scsi/scsi_transport_iscsi.h> 22 #include <scsi/scsi_transport.h> 23 #include <scsi/scsi_cmnd.h> 24 #include <scsi/scsi_device.h> 25 #include <scsi/scsi_host.h> 26 #include <scsi/scsi_netlink.h> 27 #include <net/netlink.h> 28 #include <scsi/scsi.h> 29 30 #include "be_iscsi.h" 31 32 extern struct iscsi_transport beiscsi_iscsi_transport; 33 34 /** 35 * beiscsi_session_create - creates a new iscsi session 36 * @cmds_max: max commands supported 37 * @qdepth: max queue depth supported 38 * @initial_cmdsn: initial iscsi CMDSN 39 */ 40 struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep, 41 u16 cmds_max, 42 u16 qdepth, 43 u32 initial_cmdsn) 44 { 45 struct Scsi_Host *shost; 46 struct beiscsi_endpoint *beiscsi_ep; 47 struct iscsi_cls_session *cls_session; 48 struct beiscsi_hba *phba; 49 struct iscsi_session *sess; 50 struct beiscsi_session *beiscsi_sess; 51 struct beiscsi_io_task *io_task; 52 53 54 if (!ep) { 55 pr_err("beiscsi_session_create: invalid ep\n"); 56 return NULL; 57 } 58 beiscsi_ep = ep->dd_data; 59 phba = beiscsi_ep->phba; 60 61 if (!beiscsi_hba_is_online(phba)) { 62 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 63 "BS_%d : HBA in error 0x%lx\n", phba->state); 64 return NULL; 65 } 66 67 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 68 "BS_%d : In beiscsi_session_create\n"); 69 if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) { 70 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 71 "BS_%d : Cannot handle %d cmds." 72 "Max cmds per session supported is %d. Using %d." 73 "\n", cmds_max, 74 beiscsi_ep->phba->params.wrbs_per_cxn, 75 beiscsi_ep->phba->params.wrbs_per_cxn); 76 77 cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn; 78 } 79 80 shost = phba->shost; 81 cls_session = iscsi_session_setup(&beiscsi_iscsi_transport, 82 shost, cmds_max, 83 sizeof(*beiscsi_sess), 84 sizeof(*io_task), 85 initial_cmdsn, ISCSI_MAX_TARGET); 86 if (!cls_session) 87 return NULL; 88 sess = cls_session->dd_data; 89 beiscsi_sess = sess->dd_data; 90 beiscsi_sess->bhs_pool = pci_pool_create("beiscsi_bhs_pool", 91 phba->pcidev, 92 sizeof(struct be_cmd_bhs), 93 64, 0); 94 if (!beiscsi_sess->bhs_pool) 95 goto destroy_sess; 96 97 return cls_session; 98 destroy_sess: 99 iscsi_session_teardown(cls_session); 100 return NULL; 101 } 102 103 /** 104 * beiscsi_session_destroy - destroys iscsi session 105 * @cls_session: pointer to iscsi cls session 106 * 107 * Destroys iSCSI session instance and releases 108 * resources allocated for it. 109 */ 110 void beiscsi_session_destroy(struct iscsi_cls_session *cls_session) 111 { 112 struct iscsi_session *sess = cls_session->dd_data; 113 struct beiscsi_session *beiscsi_sess = sess->dd_data; 114 115 printk(KERN_INFO "In beiscsi_session_destroy\n"); 116 pci_pool_destroy(beiscsi_sess->bhs_pool); 117 iscsi_session_teardown(cls_session); 118 } 119 120 /** 121 * beiscsi_session_fail(): Closing session with appropriate error 122 * @cls_session: ptr to session 123 **/ 124 void beiscsi_session_fail(struct iscsi_cls_session *cls_session) 125 { 126 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); 127 } 128 129 130 /** 131 * beiscsi_conn_create - create an instance of iscsi connection 132 * @cls_session: ptr to iscsi_cls_session 133 * @cid: iscsi cid 134 */ 135 struct iscsi_cls_conn * 136 beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid) 137 { 138 struct beiscsi_hba *phba; 139 struct Scsi_Host *shost; 140 struct iscsi_cls_conn *cls_conn; 141 struct beiscsi_conn *beiscsi_conn; 142 struct iscsi_conn *conn; 143 struct iscsi_session *sess; 144 struct beiscsi_session *beiscsi_sess; 145 146 shost = iscsi_session_to_shost(cls_session); 147 phba = iscsi_host_priv(shost); 148 149 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 150 "BS_%d : In beiscsi_conn_create ,cid" 151 "from iscsi layer=%d\n", cid); 152 153 cls_conn = iscsi_conn_setup(cls_session, sizeof(*beiscsi_conn), cid); 154 if (!cls_conn) 155 return NULL; 156 157 conn = cls_conn->dd_data; 158 beiscsi_conn = conn->dd_data; 159 beiscsi_conn->ep = NULL; 160 beiscsi_conn->phba = phba; 161 beiscsi_conn->conn = conn; 162 sess = cls_session->dd_data; 163 beiscsi_sess = sess->dd_data; 164 beiscsi_conn->beiscsi_sess = beiscsi_sess; 165 return cls_conn; 166 } 167 168 /** 169 * beiscsi_bindconn_cid - Bind the beiscsi_conn with phba connection table 170 * @beiscsi_conn: The pointer to beiscsi_conn structure 171 * @phba: The phba instance 172 * @cid: The cid to free 173 */ 174 static int beiscsi_bindconn_cid(struct beiscsi_hba *phba, 175 struct beiscsi_conn *beiscsi_conn, 176 unsigned int cid) 177 { 178 uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 179 180 if (phba->conn_table[cri_index]) { 181 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 182 "BS_%d : Connection table already occupied. Detected clash\n"); 183 184 return -EINVAL; 185 } else { 186 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 187 "BS_%d : phba->conn_table[%d]=%p(beiscsi_conn)\n", 188 cri_index, beiscsi_conn); 189 190 phba->conn_table[cri_index] = beiscsi_conn; 191 } 192 return 0; 193 } 194 195 /** 196 * beiscsi_conn_bind - Binds iscsi session/connection with TCP connection 197 * @cls_session: pointer to iscsi cls session 198 * @cls_conn: pointer to iscsi cls conn 199 * @transport_fd: EP handle(64 bit) 200 * 201 * This function binds the TCP Conn with iSCSI Connection and Session. 202 */ 203 int beiscsi_conn_bind(struct iscsi_cls_session *cls_session, 204 struct iscsi_cls_conn *cls_conn, 205 u64 transport_fd, int is_leading) 206 { 207 struct iscsi_conn *conn = cls_conn->dd_data; 208 struct beiscsi_conn *beiscsi_conn = conn->dd_data; 209 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 210 struct beiscsi_hba *phba = iscsi_host_priv(shost); 211 struct hwi_controller *phwi_ctrlr = phba->phwi_ctrlr; 212 struct hwi_wrb_context *pwrb_context; 213 struct beiscsi_endpoint *beiscsi_ep; 214 struct iscsi_endpoint *ep; 215 216 ep = iscsi_lookup_endpoint(transport_fd); 217 if (!ep) 218 return -EINVAL; 219 220 beiscsi_ep = ep->dd_data; 221 222 if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) 223 return -EINVAL; 224 225 if (beiscsi_ep->phba != phba) { 226 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 227 "BS_%d : beiscsi_ep->hba=%p not equal to phba=%p\n", 228 beiscsi_ep->phba, phba); 229 230 return -EEXIST; 231 } 232 233 pwrb_context = &phwi_ctrlr->wrb_context[BE_GET_CRI_FROM_CID( 234 beiscsi_ep->ep_cid)]; 235 236 beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid; 237 beiscsi_conn->ep = beiscsi_ep; 238 beiscsi_ep->conn = beiscsi_conn; 239 beiscsi_conn->doorbell_offset = pwrb_context->doorbell_offset; 240 241 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 242 "BS_%d : beiscsi_conn=%p conn=%p ep_cid=%d\n", 243 beiscsi_conn, conn, beiscsi_ep->ep_cid); 244 245 return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid); 246 } 247 248 static int beiscsi_iface_create_ipv4(struct beiscsi_hba *phba) 249 { 250 if (phba->ipv4_iface) 251 return 0; 252 253 phba->ipv4_iface = iscsi_create_iface(phba->shost, 254 &beiscsi_iscsi_transport, 255 ISCSI_IFACE_TYPE_IPV4, 256 0, 0); 257 if (!phba->ipv4_iface) { 258 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 259 "BS_%d : Could not " 260 "create default IPv4 address.\n"); 261 return -ENODEV; 262 } 263 264 return 0; 265 } 266 267 static int beiscsi_iface_create_ipv6(struct beiscsi_hba *phba) 268 { 269 if (phba->ipv6_iface) 270 return 0; 271 272 phba->ipv6_iface = iscsi_create_iface(phba->shost, 273 &beiscsi_iscsi_transport, 274 ISCSI_IFACE_TYPE_IPV6, 275 0, 0); 276 if (!phba->ipv6_iface) { 277 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 278 "BS_%d : Could not " 279 "create default IPv6 address.\n"); 280 return -ENODEV; 281 } 282 283 return 0; 284 } 285 286 void beiscsi_iface_create_default(struct beiscsi_hba *phba) 287 { 288 struct be_cmd_get_if_info_resp *if_info; 289 290 if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V4, &if_info)) { 291 beiscsi_iface_create_ipv4(phba); 292 kfree(if_info); 293 } 294 295 if (!beiscsi_if_get_info(phba, BEISCSI_IP_TYPE_V6, &if_info)) { 296 beiscsi_iface_create_ipv6(phba); 297 kfree(if_info); 298 } 299 } 300 301 void beiscsi_iface_destroy_default(struct beiscsi_hba *phba) 302 { 303 if (phba->ipv6_iface) { 304 iscsi_destroy_iface(phba->ipv6_iface); 305 phba->ipv6_iface = NULL; 306 } 307 if (phba->ipv4_iface) { 308 iscsi_destroy_iface(phba->ipv4_iface); 309 phba->ipv4_iface = NULL; 310 } 311 } 312 313 /** 314 * beiscsi_set_vlan_tag()- Set the VLAN TAG 315 * @shost: Scsi Host for the driver instance 316 * @iface_param: Interface paramters 317 * 318 * Set the VLAN TAG for the adapter or disable 319 * the VLAN config 320 * 321 * returns 322 * Success: 0 323 * Failure: Non-Zero Value 324 **/ 325 static int 326 beiscsi_iface_config_vlan(struct Scsi_Host *shost, 327 struct iscsi_iface_param_info *iface_param) 328 { 329 struct beiscsi_hba *phba = iscsi_host_priv(shost); 330 int ret = -EPERM; 331 332 switch (iface_param->param) { 333 case ISCSI_NET_PARAM_VLAN_ENABLED: 334 ret = 0; 335 if (iface_param->value[0] != ISCSI_VLAN_ENABLE) 336 ret = beiscsi_if_set_vlan(phba, BEISCSI_VLAN_DISABLE); 337 break; 338 case ISCSI_NET_PARAM_VLAN_TAG: 339 ret = beiscsi_if_set_vlan(phba, 340 *((uint16_t *)iface_param->value)); 341 break; 342 } 343 return ret; 344 } 345 346 347 static int 348 beiscsi_iface_config_ipv4(struct Scsi_Host *shost, 349 struct iscsi_iface_param_info *info, 350 void *data, uint32_t dt_len) 351 { 352 struct beiscsi_hba *phba = iscsi_host_priv(shost); 353 u8 *ip = NULL, *subnet = NULL, *gw; 354 struct nlattr *nla; 355 int ret = -EPERM; 356 357 /* Check the param */ 358 switch (info->param) { 359 case ISCSI_NET_PARAM_IFACE_ENABLE: 360 if (info->value[0] == ISCSI_IFACE_ENABLE) 361 ret = beiscsi_iface_create_ipv4(phba); 362 else { 363 iscsi_destroy_iface(phba->ipv4_iface); 364 phba->ipv4_iface = NULL; 365 } 366 break; 367 case ISCSI_NET_PARAM_IPV4_GW: 368 gw = info->value; 369 ret = beiscsi_if_set_gw(phba, BEISCSI_IP_TYPE_V4, gw); 370 break; 371 case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 372 if (info->value[0] == ISCSI_BOOTPROTO_DHCP) 373 ret = beiscsi_if_en_dhcp(phba, BEISCSI_IP_TYPE_V4); 374 else if (info->value[0] == ISCSI_BOOTPROTO_STATIC) 375 /* release DHCP IP address */ 376 ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4, 377 NULL, NULL); 378 else 379 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 380 "BS_%d : Invalid BOOTPROTO: %d\n", 381 info->value[0]); 382 break; 383 case ISCSI_NET_PARAM_IPV4_ADDR: 384 ip = info->value; 385 nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET); 386 if (nla) { 387 info = nla_data(nla); 388 subnet = info->value; 389 } 390 ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4, 391 ip, subnet); 392 break; 393 case ISCSI_NET_PARAM_IPV4_SUBNET: 394 /* 395 * OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR ioctl needs IP 396 * and subnet both. Find IP to be applied for this subnet. 397 */ 398 subnet = info->value; 399 nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR); 400 if (nla) { 401 info = nla_data(nla); 402 ip = info->value; 403 } 404 ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V4, 405 ip, subnet); 406 break; 407 } 408 409 return ret; 410 } 411 412 static int 413 beiscsi_iface_config_ipv6(struct Scsi_Host *shost, 414 struct iscsi_iface_param_info *iface_param, 415 void *data, uint32_t dt_len) 416 { 417 struct beiscsi_hba *phba = iscsi_host_priv(shost); 418 int ret = -EPERM; 419 420 switch (iface_param->param) { 421 case ISCSI_NET_PARAM_IFACE_ENABLE: 422 if (iface_param->value[0] == ISCSI_IFACE_ENABLE) 423 ret = beiscsi_iface_create_ipv6(phba); 424 else { 425 iscsi_destroy_iface(phba->ipv6_iface); 426 phba->ipv6_iface = NULL; 427 } 428 break; 429 case ISCSI_NET_PARAM_IPV6_ADDR: 430 ret = beiscsi_if_en_static(phba, BEISCSI_IP_TYPE_V6, 431 iface_param->value, NULL); 432 break; 433 } 434 435 return ret; 436 } 437 438 int beiscsi_iface_set_param(struct Scsi_Host *shost, 439 void *data, uint32_t dt_len) 440 { 441 struct iscsi_iface_param_info *iface_param = NULL; 442 struct beiscsi_hba *phba = iscsi_host_priv(shost); 443 struct nlattr *attrib; 444 uint32_t rm_len = dt_len; 445 int ret; 446 447 if (!beiscsi_hba_is_online(phba)) { 448 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 449 "BS_%d : HBA in error 0x%lx\n", phba->state); 450 return -EBUSY; 451 } 452 453 /* update interface_handle */ 454 ret = beiscsi_if_get_handle(phba); 455 if (ret) { 456 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 457 "BS_%d : Getting Interface Handle Failed\n"); 458 return ret; 459 } 460 461 nla_for_each_attr(attrib, data, dt_len, rm_len) { 462 iface_param = nla_data(attrib); 463 464 if (iface_param->param_type != ISCSI_NET_PARAM) 465 continue; 466 467 /* 468 * BE2ISCSI only supports 1 interface 469 */ 470 if (iface_param->iface_num) { 471 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 472 "BS_%d : Invalid iface_num %d." 473 "Only iface_num 0 is supported.\n", 474 iface_param->iface_num); 475 476 return -EINVAL; 477 } 478 479 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 480 "BS_%d : %s.0 set param %d", 481 (iface_param->iface_type == ISCSI_IFACE_TYPE_IPV4) ? 482 "ipv4" : "ipv6", iface_param->param); 483 484 ret = -EPERM; 485 switch (iface_param->param) { 486 case ISCSI_NET_PARAM_VLAN_ENABLED: 487 case ISCSI_NET_PARAM_VLAN_TAG: 488 ret = beiscsi_iface_config_vlan(shost, iface_param); 489 break; 490 default: 491 switch (iface_param->iface_type) { 492 case ISCSI_IFACE_TYPE_IPV4: 493 ret = beiscsi_iface_config_ipv4(shost, 494 iface_param, 495 data, dt_len); 496 break; 497 case ISCSI_IFACE_TYPE_IPV6: 498 ret = beiscsi_iface_config_ipv6(shost, 499 iface_param, 500 data, dt_len); 501 break; 502 } 503 } 504 505 if (ret == -EPERM) { 506 __beiscsi_log(phba, KERN_ERR, 507 "BS_%d : %s.0 set param %d not permitted", 508 (iface_param->iface_type == 509 ISCSI_IFACE_TYPE_IPV4) ? "ipv4" : "ipv6", 510 iface_param->param); 511 ret = 0; 512 } 513 if (ret) 514 break; 515 } 516 517 return ret; 518 } 519 520 static int __beiscsi_iface_get_param(struct beiscsi_hba *phba, 521 struct iscsi_iface *iface, 522 int param, char *buf) 523 { 524 struct be_cmd_get_if_info_resp *if_info; 525 int len, ip_type = BEISCSI_IP_TYPE_V4; 526 527 if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) 528 ip_type = BEISCSI_IP_TYPE_V6; 529 530 len = beiscsi_if_get_info(phba, ip_type, &if_info); 531 if (len) 532 return len; 533 534 switch (param) { 535 case ISCSI_NET_PARAM_IPV4_ADDR: 536 len = sprintf(buf, "%pI4\n", if_info->ip_addr.addr); 537 break; 538 case ISCSI_NET_PARAM_IPV6_ADDR: 539 len = sprintf(buf, "%pI6\n", if_info->ip_addr.addr); 540 break; 541 case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 542 if (!if_info->dhcp_state) 543 len = sprintf(buf, "static\n"); 544 else 545 len = sprintf(buf, "dhcp\n"); 546 break; 547 case ISCSI_NET_PARAM_IPV4_SUBNET: 548 len = sprintf(buf, "%pI4\n", if_info->ip_addr.subnet_mask); 549 break; 550 case ISCSI_NET_PARAM_VLAN_ENABLED: 551 len = sprintf(buf, "%s\n", 552 (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) ? 553 "disable" : "enable"); 554 break; 555 case ISCSI_NET_PARAM_VLAN_ID: 556 if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 557 len = -EINVAL; 558 else 559 len = sprintf(buf, "%d\n", 560 (if_info->vlan_priority & 561 ISCSI_MAX_VLAN_ID)); 562 break; 563 case ISCSI_NET_PARAM_VLAN_PRIORITY: 564 if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 565 len = -EINVAL; 566 else 567 len = sprintf(buf, "%d\n", 568 ((if_info->vlan_priority >> 13) & 569 ISCSI_MAX_VLAN_PRIORITY)); 570 break; 571 default: 572 WARN_ON(1); 573 } 574 575 kfree(if_info); 576 return len; 577 } 578 579 int beiscsi_iface_get_param(struct iscsi_iface *iface, 580 enum iscsi_param_type param_type, 581 int param, char *buf) 582 { 583 struct Scsi_Host *shost = iscsi_iface_to_shost(iface); 584 struct beiscsi_hba *phba = iscsi_host_priv(shost); 585 struct be_cmd_get_def_gateway_resp gateway; 586 int len = -EPERM; 587 588 if (param_type != ISCSI_NET_PARAM) 589 return 0; 590 if (!beiscsi_hba_is_online(phba)) { 591 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 592 "BS_%d : HBA in error 0x%lx\n", phba->state); 593 return -EBUSY; 594 } 595 596 switch (param) { 597 case ISCSI_NET_PARAM_IPV4_ADDR: 598 case ISCSI_NET_PARAM_IPV4_SUBNET: 599 case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 600 case ISCSI_NET_PARAM_IPV6_ADDR: 601 case ISCSI_NET_PARAM_VLAN_ENABLED: 602 case ISCSI_NET_PARAM_VLAN_ID: 603 case ISCSI_NET_PARAM_VLAN_PRIORITY: 604 len = __beiscsi_iface_get_param(phba, iface, param, buf); 605 break; 606 case ISCSI_NET_PARAM_IFACE_ENABLE: 607 if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) 608 len = sprintf(buf, "%s\n", 609 phba->ipv4_iface ? "enable" : "disable"); 610 else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) 611 len = sprintf(buf, "%s\n", 612 phba->ipv6_iface ? "enable" : "disable"); 613 break; 614 case ISCSI_NET_PARAM_IPV4_GW: 615 memset(&gateway, 0, sizeof(gateway)); 616 len = beiscsi_if_get_gw(phba, BEISCSI_IP_TYPE_V4, &gateway); 617 if (!len) 618 len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr); 619 break; 620 } 621 622 return len; 623 } 624 625 /** 626 * beiscsi_ep_get_param - get the iscsi parameter 627 * @ep: pointer to iscsi ep 628 * @param: parameter type identifier 629 * @buf: buffer pointer 630 * 631 * returns iscsi parameter 632 */ 633 int beiscsi_ep_get_param(struct iscsi_endpoint *ep, 634 enum iscsi_param param, char *buf) 635 { 636 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 637 int len; 638 639 beiscsi_log(beiscsi_ep->phba, KERN_INFO, 640 BEISCSI_LOG_CONFIG, 641 "BS_%d : In beiscsi_ep_get_param," 642 " param= %d\n", param); 643 644 switch (param) { 645 case ISCSI_PARAM_CONN_PORT: 646 len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport); 647 break; 648 case ISCSI_PARAM_CONN_ADDRESS: 649 if (beiscsi_ep->ip_type == BEISCSI_IP_TYPE_V4) 650 len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr); 651 else 652 len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr); 653 break; 654 default: 655 len = -EPERM; 656 } 657 return len; 658 } 659 660 int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, 661 enum iscsi_param param, char *buf, int buflen) 662 { 663 struct iscsi_conn *conn = cls_conn->dd_data; 664 struct iscsi_session *session = conn->session; 665 struct beiscsi_hba *phba = NULL; 666 int ret; 667 668 phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 669 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 670 "BS_%d : In beiscsi_conn_set_param," 671 " param= %d\n", param); 672 673 ret = iscsi_set_param(cls_conn, param, buf, buflen); 674 if (ret) 675 return ret; 676 /* 677 * If userspace tried to set the value to higher than we can 678 * support override here. 679 */ 680 switch (param) { 681 case ISCSI_PARAM_FIRST_BURST: 682 if (session->first_burst > 8192) 683 session->first_burst = 8192; 684 break; 685 case ISCSI_PARAM_MAX_RECV_DLENGTH: 686 if (conn->max_recv_dlength > 65536) 687 conn->max_recv_dlength = 65536; 688 break; 689 case ISCSI_PARAM_MAX_BURST: 690 if (session->max_burst > 262144) 691 session->max_burst = 262144; 692 break; 693 case ISCSI_PARAM_MAX_XMIT_DLENGTH: 694 if (conn->max_xmit_dlength > 65536) 695 conn->max_xmit_dlength = 65536; 696 default: 697 return 0; 698 } 699 700 return 0; 701 } 702 703 /** 704 * beiscsi_get_initname - Read Initiator Name from flash 705 * @buf: buffer bointer 706 * @phba: The device priv structure instance 707 * 708 * returns number of bytes 709 */ 710 static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba) 711 { 712 int rc; 713 unsigned int tag; 714 struct be_mcc_wrb *wrb; 715 struct be_cmd_hba_name *resp; 716 717 tag = be_cmd_get_initname(phba); 718 if (!tag) { 719 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 720 "BS_%d : Getting Initiator Name Failed\n"); 721 722 return -EBUSY; 723 } 724 725 rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL); 726 if (rc) { 727 beiscsi_log(phba, KERN_ERR, 728 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 729 "BS_%d : Initiator Name MBX Failed\n"); 730 return rc; 731 } 732 733 resp = embedded_payload(wrb); 734 rc = sprintf(buf, "%s\n", resp->initiator_name); 735 return rc; 736 } 737 738 /** 739 * beiscsi_get_port_state - Get the Port State 740 * @shost : pointer to scsi_host structure 741 * 742 */ 743 static void beiscsi_get_port_state(struct Scsi_Host *shost) 744 { 745 struct beiscsi_hba *phba = iscsi_host_priv(shost); 746 struct iscsi_cls_host *ihost = shost->shost_data; 747 748 ihost->port_state = test_bit(BEISCSI_HBA_LINK_UP, &phba->state) ? 749 ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; 750 } 751 752 /** 753 * beiscsi_get_port_speed - Get the Port Speed from Adapter 754 * @shost : pointer to scsi_host structure 755 * 756 */ 757 static void beiscsi_get_port_speed(struct Scsi_Host *shost) 758 { 759 struct beiscsi_hba *phba = iscsi_host_priv(shost); 760 struct iscsi_cls_host *ihost = shost->shost_data; 761 762 switch (phba->port_speed) { 763 case BE2ISCSI_LINK_SPEED_10MBPS: 764 ihost->port_speed = ISCSI_PORT_SPEED_10MBPS; 765 break; 766 case BE2ISCSI_LINK_SPEED_100MBPS: 767 ihost->port_speed = ISCSI_PORT_SPEED_100MBPS; 768 break; 769 case BE2ISCSI_LINK_SPEED_1GBPS: 770 ihost->port_speed = ISCSI_PORT_SPEED_1GBPS; 771 break; 772 case BE2ISCSI_LINK_SPEED_10GBPS: 773 ihost->port_speed = ISCSI_PORT_SPEED_10GBPS; 774 break; 775 case BE2ISCSI_LINK_SPEED_25GBPS: 776 ihost->port_speed = ISCSI_PORT_SPEED_25GBPS; 777 break; 778 case BE2ISCSI_LINK_SPEED_40GBPS: 779 ihost->port_speed = ISCSI_PORT_SPEED_40GBPS; 780 break; 781 default: 782 ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN; 783 } 784 } 785 786 /** 787 * beiscsi_get_host_param - get the iscsi parameter 788 * @shost: pointer to scsi_host structure 789 * @param: parameter type identifier 790 * @buf: buffer pointer 791 * 792 * returns host parameter 793 */ 794 int beiscsi_get_host_param(struct Scsi_Host *shost, 795 enum iscsi_host_param param, char *buf) 796 { 797 struct beiscsi_hba *phba = iscsi_host_priv(shost); 798 int status = 0; 799 800 if (!beiscsi_hba_is_online(phba)) { 801 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 802 "BS_%d : HBA in error 0x%lx\n", phba->state); 803 return -EBUSY; 804 } 805 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 806 "BS_%d : In beiscsi_get_host_param, param = %d\n", param); 807 808 switch (param) { 809 case ISCSI_HOST_PARAM_HWADDRESS: 810 status = beiscsi_get_macaddr(buf, phba); 811 if (status < 0) { 812 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 813 "BS_%d : beiscsi_get_macaddr Failed\n"); 814 return status; 815 } 816 break; 817 case ISCSI_HOST_PARAM_INITIATOR_NAME: 818 status = beiscsi_get_initname(buf, phba); 819 if (status < 0) { 820 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 821 "BS_%d : Retreiving Initiator Name Failed\n"); 822 return status; 823 } 824 break; 825 case ISCSI_HOST_PARAM_PORT_STATE: 826 beiscsi_get_port_state(shost); 827 status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost)); 828 break; 829 case ISCSI_HOST_PARAM_PORT_SPEED: 830 beiscsi_get_port_speed(shost); 831 status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost)); 832 break; 833 default: 834 return iscsi_host_get_param(shost, param, buf); 835 } 836 return status; 837 } 838 839 int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) 840 { 841 struct be_cmd_get_nic_conf_resp resp; 842 int rc; 843 844 if (phba->mac_addr_set) 845 return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 846 847 memset(&resp, 0, sizeof(resp)); 848 rc = mgmt_get_nic_conf(phba, &resp); 849 if (rc) 850 return rc; 851 852 phba->mac_addr_set = true; 853 memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); 854 return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 855 } 856 857 /** 858 * beiscsi_conn_get_stats - get the iscsi stats 859 * @cls_conn: pointer to iscsi cls conn 860 * @stats: pointer to iscsi_stats structure 861 * 862 * returns iscsi stats 863 */ 864 void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, 865 struct iscsi_stats *stats) 866 { 867 struct iscsi_conn *conn = cls_conn->dd_data; 868 struct beiscsi_hba *phba = NULL; 869 870 phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 871 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 872 "BS_%d : In beiscsi_conn_get_stats\n"); 873 874 stats->txdata_octets = conn->txdata_octets; 875 stats->rxdata_octets = conn->rxdata_octets; 876 stats->dataout_pdus = conn->dataout_pdus_cnt; 877 stats->scsirsp_pdus = conn->scsirsp_pdus_cnt; 878 stats->scsicmd_pdus = conn->scsicmd_pdus_cnt; 879 stats->datain_pdus = conn->datain_pdus_cnt; 880 stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; 881 stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; 882 stats->r2t_pdus = conn->r2t_pdus_cnt; 883 stats->digest_err = 0; 884 stats->timeout_err = 0; 885 stats->custom_length = 1; 886 strcpy(stats->custom[0].desc, "eh_abort_cnt"); 887 stats->custom[0].value = conn->eh_abort_cnt; 888 } 889 890 /** 891 * beiscsi_set_params_for_offld - get the parameters for offload 892 * @beiscsi_conn: pointer to beiscsi_conn 893 * @params: pointer to offload_params structure 894 */ 895 static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn, 896 struct beiscsi_offload_params *params) 897 { 898 struct iscsi_conn *conn = beiscsi_conn->conn; 899 struct iscsi_session *session = conn->session; 900 901 AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length, 902 params, session->max_burst); 903 AMAP_SET_BITS(struct amap_beiscsi_offload_params, 904 max_send_data_segment_length, params, 905 conn->max_xmit_dlength); 906 AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length, 907 params, session->first_burst); 908 AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params, 909 session->erl); 910 AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params, 911 conn->datadgst_en); 912 AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params, 913 conn->hdrdgst_en); 914 AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params, 915 session->initial_r2t_en); 916 AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params, 917 session->imm_data_en); 918 AMAP_SET_BITS(struct amap_beiscsi_offload_params, 919 data_seq_inorder, params, 920 session->dataseq_inorder_en); 921 AMAP_SET_BITS(struct amap_beiscsi_offload_params, 922 pdu_seq_inorder, params, 923 session->pdu_inorder_en); 924 AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_r2t, params, 925 session->max_r2t); 926 AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params, 927 (conn->exp_statsn - 1)); 928 AMAP_SET_BITS(struct amap_beiscsi_offload_params, 929 max_recv_data_segment_length, params, 930 conn->max_recv_dlength); 931 932 } 933 934 /** 935 * beiscsi_conn_start - offload of session to chip 936 * @cls_conn: pointer to beiscsi_conn 937 */ 938 int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) 939 { 940 struct iscsi_conn *conn = cls_conn->dd_data; 941 struct beiscsi_conn *beiscsi_conn = conn->dd_data; 942 struct beiscsi_endpoint *beiscsi_ep; 943 struct beiscsi_offload_params params; 944 struct beiscsi_hba *phba; 945 946 phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 947 948 if (!beiscsi_hba_is_online(phba)) { 949 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 950 "BS_%d : HBA in error 0x%lx\n", phba->state); 951 return -EBUSY; 952 } 953 beiscsi_log(beiscsi_conn->phba, KERN_INFO, BEISCSI_LOG_CONFIG, 954 "BS_%d : In beiscsi_conn_start\n"); 955 956 memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); 957 beiscsi_ep = beiscsi_conn->ep; 958 if (!beiscsi_ep) 959 beiscsi_log(beiscsi_conn->phba, KERN_ERR, 960 BEISCSI_LOG_CONFIG, 961 "BS_%d : In beiscsi_conn_start , no beiscsi_ep\n"); 962 963 beiscsi_conn->login_in_progress = 0; 964 beiscsi_set_params_for_offld(beiscsi_conn, ¶ms); 965 beiscsi_offload_connection(beiscsi_conn, ¶ms); 966 iscsi_conn_start(cls_conn); 967 return 0; 968 } 969 970 /** 971 * beiscsi_get_cid - Allocate a cid 972 * @phba: The phba instance 973 */ 974 static int beiscsi_get_cid(struct beiscsi_hba *phba) 975 { 976 unsigned short cid = 0xFFFF, cid_from_ulp; 977 struct ulp_cid_info *cid_info = NULL; 978 uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1; 979 980 /* Find the ULP which has more CID available */ 981 cid_avlbl_ulp0 = (phba->cid_array_info[BEISCSI_ULP0]) ? 982 BEISCSI_ULP0_AVLBL_CID(phba) : 0; 983 cid_avlbl_ulp1 = (phba->cid_array_info[BEISCSI_ULP1]) ? 984 BEISCSI_ULP1_AVLBL_CID(phba) : 0; 985 cid_from_ulp = (cid_avlbl_ulp0 > cid_avlbl_ulp1) ? 986 BEISCSI_ULP0 : BEISCSI_ULP1; 987 988 if (test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported)) { 989 cid_info = phba->cid_array_info[cid_from_ulp]; 990 if (!cid_info->avlbl_cids) 991 return cid; 992 993 cid = cid_info->cid_array[cid_info->cid_alloc++]; 994 995 if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT( 996 phba, cid_from_ulp)) 997 cid_info->cid_alloc = 0; 998 999 cid_info->avlbl_cids--; 1000 } 1001 return cid; 1002 } 1003 1004 /** 1005 * beiscsi_put_cid - Free the cid 1006 * @phba: The phba for which the cid is being freed 1007 * @cid: The cid to free 1008 */ 1009 static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) 1010 { 1011 uint16_t cid_post_ulp; 1012 struct hwi_controller *phwi_ctrlr; 1013 struct hwi_wrb_context *pwrb_context; 1014 struct ulp_cid_info *cid_info = NULL; 1015 uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 1016 1017 phwi_ctrlr = phba->phwi_ctrlr; 1018 pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; 1019 cid_post_ulp = pwrb_context->ulp_num; 1020 1021 cid_info = phba->cid_array_info[cid_post_ulp]; 1022 cid_info->avlbl_cids++; 1023 1024 cid_info->cid_array[cid_info->cid_free++] = cid; 1025 if (cid_info->cid_free == BEISCSI_GET_CID_COUNT(phba, cid_post_ulp)) 1026 cid_info->cid_free = 0; 1027 } 1028 1029 /** 1030 * beiscsi_free_ep - free endpoint 1031 * @ep: pointer to iscsi endpoint structure 1032 */ 1033 static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) 1034 { 1035 struct beiscsi_hba *phba = beiscsi_ep->phba; 1036 struct beiscsi_conn *beiscsi_conn; 1037 1038 beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 1039 beiscsi_ep->phba = NULL; 1040 phba->ep_array[BE_GET_CRI_FROM_CID 1041 (beiscsi_ep->ep_cid)] = NULL; 1042 1043 /** 1044 * Check if any connection resource allocated by driver 1045 * is to be freed.This case occurs when target redirection 1046 * or connection retry is done. 1047 **/ 1048 if (!beiscsi_ep->conn) 1049 return; 1050 1051 beiscsi_conn = beiscsi_ep->conn; 1052 if (beiscsi_conn->login_in_progress) { 1053 beiscsi_free_mgmt_task_handles(beiscsi_conn, 1054 beiscsi_conn->task); 1055 beiscsi_conn->login_in_progress = 0; 1056 } 1057 } 1058 1059 /** 1060 * beiscsi_open_conn - Ask FW to open a TCP connection 1061 * @ep: endpoint to be used 1062 * @src_addr: The source IP address 1063 * @dst_addr: The Destination IP address 1064 * 1065 * Asks the FW to open a TCP connection 1066 */ 1067 static int beiscsi_open_conn(struct iscsi_endpoint *ep, 1068 struct sockaddr *src_addr, 1069 struct sockaddr *dst_addr, int non_blocking) 1070 { 1071 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 1072 struct beiscsi_hba *phba = beiscsi_ep->phba; 1073 struct tcp_connect_and_offload_out *ptcpcnct_out; 1074 struct be_dma_mem nonemb_cmd; 1075 unsigned int tag, req_memsize; 1076 int ret = -ENOMEM; 1077 1078 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1079 "BS_%d : In beiscsi_open_conn\n"); 1080 1081 beiscsi_ep->ep_cid = beiscsi_get_cid(phba); 1082 if (beiscsi_ep->ep_cid == 0xFFFF) { 1083 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1084 "BS_%d : No free cid available\n"); 1085 return ret; 1086 } 1087 1088 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1089 "BS_%d : In beiscsi_open_conn, ep_cid=%d\n", 1090 beiscsi_ep->ep_cid); 1091 1092 phba->ep_array[BE_GET_CRI_FROM_CID 1093 (beiscsi_ep->ep_cid)] = ep; 1094 1095 beiscsi_ep->cid_vld = 0; 1096 1097 if (is_chip_be2_be3r(phba)) 1098 req_memsize = sizeof(struct tcp_connect_and_offload_in); 1099 else 1100 req_memsize = sizeof(struct tcp_connect_and_offload_in_v1); 1101 1102 nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, 1103 req_memsize, 1104 &nonemb_cmd.dma); 1105 if (nonemb_cmd.va == NULL) { 1106 1107 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1108 "BS_%d : Failed to allocate memory for" 1109 " mgmt_open_connection\n"); 1110 1111 beiscsi_free_ep(beiscsi_ep); 1112 return -ENOMEM; 1113 } 1114 nonemb_cmd.size = req_memsize; 1115 memset(nonemb_cmd.va, 0, nonemb_cmd.size); 1116 tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd); 1117 if (tag <= 0) { 1118 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1119 "BS_%d : mgmt_open_connection Failed for cid=%d\n", 1120 beiscsi_ep->ep_cid); 1121 1122 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1123 nonemb_cmd.va, nonemb_cmd.dma); 1124 beiscsi_free_ep(beiscsi_ep); 1125 return -EAGAIN; 1126 } 1127 1128 ret = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd); 1129 if (ret) { 1130 beiscsi_log(phba, KERN_ERR, 1131 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 1132 "BS_%d : mgmt_open_connection Failed"); 1133 1134 if (ret != -EBUSY) 1135 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1136 nonemb_cmd.va, nonemb_cmd.dma); 1137 1138 beiscsi_free_ep(beiscsi_ep); 1139 return ret; 1140 } 1141 1142 ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va; 1143 beiscsi_ep = ep->dd_data; 1144 beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; 1145 beiscsi_ep->cid_vld = 1; 1146 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1147 "BS_%d : mgmt_open_connection Success\n"); 1148 1149 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1150 nonemb_cmd.va, nonemb_cmd.dma); 1151 return 0; 1152 } 1153 1154 /** 1155 * beiscsi_ep_connect - Ask chip to create TCP Conn 1156 * @scsi_host: Pointer to scsi_host structure 1157 * @dst_addr: The IP address of Target 1158 * @non_blocking: blocking or non-blocking call 1159 * 1160 * This routines first asks chip to create a connection and then allocates an EP 1161 */ 1162 struct iscsi_endpoint * 1163 beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, 1164 int non_blocking) 1165 { 1166 struct beiscsi_hba *phba; 1167 struct beiscsi_endpoint *beiscsi_ep; 1168 struct iscsi_endpoint *ep; 1169 int ret; 1170 1171 if (!shost) { 1172 ret = -ENXIO; 1173 pr_err("beiscsi_ep_connect shost is NULL\n"); 1174 return ERR_PTR(ret); 1175 } 1176 1177 phba = iscsi_host_priv(shost); 1178 if (!beiscsi_hba_is_online(phba)) { 1179 ret = -EIO; 1180 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1181 "BS_%d : HBA in error 0x%lx\n", phba->state); 1182 return ERR_PTR(ret); 1183 } 1184 if (!test_bit(BEISCSI_HBA_LINK_UP, &phba->state)) { 1185 ret = -EBUSY; 1186 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 1187 "BS_%d : The Adapter Port state is Down!!!\n"); 1188 return ERR_PTR(ret); 1189 } 1190 1191 ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint)); 1192 if (!ep) { 1193 ret = -ENOMEM; 1194 return ERR_PTR(ret); 1195 } 1196 1197 beiscsi_ep = ep->dd_data; 1198 beiscsi_ep->phba = phba; 1199 beiscsi_ep->openiscsi_ep = ep; 1200 ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking); 1201 if (ret) { 1202 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1203 "BS_%d : Failed in beiscsi_open_conn\n"); 1204 goto free_ep; 1205 } 1206 1207 return ep; 1208 1209 free_ep: 1210 iscsi_destroy_endpoint(ep); 1211 return ERR_PTR(ret); 1212 } 1213 1214 /** 1215 * beiscsi_ep_poll - Poll to see if connection is established 1216 * @ep: endpoint to be used 1217 * @timeout_ms: timeout specified in millisecs 1218 * 1219 * Poll to see if TCP connection established 1220 */ 1221 int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) 1222 { 1223 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 1224 1225 beiscsi_log(beiscsi_ep->phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1226 "BS_%d : In beiscsi_ep_poll\n"); 1227 1228 if (beiscsi_ep->cid_vld == 1) 1229 return 1; 1230 else 1231 return 0; 1232 } 1233 1234 /** 1235 * beiscsi_flush_cq()- Flush the CQ created. 1236 * @phba: ptr device priv structure. 1237 * 1238 * Before the connection resource are freed flush 1239 * all the CQ enteries 1240 **/ 1241 static void beiscsi_flush_cq(struct beiscsi_hba *phba) 1242 { 1243 uint16_t i; 1244 struct be_eq_obj *pbe_eq; 1245 struct hwi_controller *phwi_ctrlr; 1246 struct hwi_context_memory *phwi_context; 1247 1248 phwi_ctrlr = phba->phwi_ctrlr; 1249 phwi_context = phwi_ctrlr->phwi_ctxt; 1250 1251 for (i = 0; i < phba->num_cpus; i++) { 1252 pbe_eq = &phwi_context->be_eq[i]; 1253 irq_poll_disable(&pbe_eq->iopoll); 1254 beiscsi_process_cq(pbe_eq, BE2_MAX_NUM_CQ_PROC); 1255 irq_poll_enable(&pbe_eq->iopoll); 1256 } 1257 } 1258 1259 /** 1260 * beiscsi_close_conn - Upload the connection 1261 * @ep: The iscsi endpoint 1262 * @flag: The type of connection closure 1263 */ 1264 static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) 1265 { 1266 int ret = 0; 1267 unsigned int tag; 1268 struct beiscsi_hba *phba = beiscsi_ep->phba; 1269 1270 tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag); 1271 if (!tag) { 1272 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1273 "BS_%d : upload failed for cid 0x%x\n", 1274 beiscsi_ep->ep_cid); 1275 1276 ret = -EAGAIN; 1277 } 1278 1279 ret = beiscsi_mccq_compl_wait(phba, tag, NULL, NULL); 1280 1281 /* Flush the CQ entries */ 1282 beiscsi_flush_cq(phba); 1283 1284 return ret; 1285 } 1286 1287 /** 1288 * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table 1289 * @phba: The phba instance 1290 * @cid: The cid to free 1291 */ 1292 static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, 1293 unsigned int cid) 1294 { 1295 uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 1296 1297 if (phba->conn_table[cri_index]) 1298 phba->conn_table[cri_index] = NULL; 1299 else { 1300 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1301 "BS_%d : Connection table Not occupied.\n"); 1302 return -EINVAL; 1303 } 1304 return 0; 1305 } 1306 1307 /** 1308 * beiscsi_ep_disconnect - Tears down the TCP connection 1309 * @ep: endpoint to be used 1310 * 1311 * Tears down the TCP connection 1312 */ 1313 void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) 1314 { 1315 struct beiscsi_conn *beiscsi_conn; 1316 struct beiscsi_endpoint *beiscsi_ep; 1317 struct beiscsi_hba *phba; 1318 unsigned int tag; 1319 uint8_t mgmt_invalidate_flag, tcp_upload_flag; 1320 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; 1321 1322 beiscsi_ep = ep->dd_data; 1323 phba = beiscsi_ep->phba; 1324 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1325 "BS_%d : In beiscsi_ep_disconnect for ep_cid = %d\n", 1326 beiscsi_ep->ep_cid); 1327 1328 if (beiscsi_ep->conn) { 1329 beiscsi_conn = beiscsi_ep->conn; 1330 iscsi_suspend_queue(beiscsi_conn->conn); 1331 mgmt_invalidate_flag = ~BEISCSI_NO_RST_ISSUE; 1332 tcp_upload_flag = CONNECTION_UPLOAD_GRACEFUL; 1333 } else { 1334 mgmt_invalidate_flag = BEISCSI_NO_RST_ISSUE; 1335 tcp_upload_flag = CONNECTION_UPLOAD_ABORT; 1336 } 1337 1338 if (!beiscsi_hba_is_online(phba)) { 1339 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1340 "BS_%d : HBA in error 0x%lx\n", phba->state); 1341 goto free_ep; 1342 } 1343 1344 tag = mgmt_invalidate_connection(phba, beiscsi_ep, 1345 beiscsi_ep->ep_cid, 1346 mgmt_invalidate_flag, 1347 savecfg_flag); 1348 if (!tag) { 1349 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1350 "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n", 1351 beiscsi_ep->ep_cid); 1352 } 1353 1354 beiscsi_mccq_compl_wait(phba, tag, NULL, NULL); 1355 beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); 1356 free_ep: 1357 msleep(BEISCSI_LOGOUT_SYNC_DELAY); 1358 beiscsi_free_ep(beiscsi_ep); 1359 beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); 1360 iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); 1361 } 1362 1363 umode_t beiscsi_attr_is_visible(int param_type, int param) 1364 { 1365 switch (param_type) { 1366 case ISCSI_NET_PARAM: 1367 switch (param) { 1368 case ISCSI_NET_PARAM_IFACE_ENABLE: 1369 case ISCSI_NET_PARAM_IPV4_ADDR: 1370 case ISCSI_NET_PARAM_IPV4_SUBNET: 1371 case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 1372 case ISCSI_NET_PARAM_IPV4_GW: 1373 case ISCSI_NET_PARAM_IPV6_ADDR: 1374 case ISCSI_NET_PARAM_VLAN_ID: 1375 case ISCSI_NET_PARAM_VLAN_PRIORITY: 1376 case ISCSI_NET_PARAM_VLAN_ENABLED: 1377 return S_IRUGO; 1378 default: 1379 return 0; 1380 } 1381 case ISCSI_HOST_PARAM: 1382 switch (param) { 1383 case ISCSI_HOST_PARAM_HWADDRESS: 1384 case ISCSI_HOST_PARAM_INITIATOR_NAME: 1385 case ISCSI_HOST_PARAM_PORT_STATE: 1386 case ISCSI_HOST_PARAM_PORT_SPEED: 1387 return S_IRUGO; 1388 default: 1389 return 0; 1390 } 1391 case ISCSI_PARAM: 1392 switch (param) { 1393 case ISCSI_PARAM_MAX_RECV_DLENGTH: 1394 case ISCSI_PARAM_MAX_XMIT_DLENGTH: 1395 case ISCSI_PARAM_HDRDGST_EN: 1396 case ISCSI_PARAM_DATADGST_EN: 1397 case ISCSI_PARAM_CONN_ADDRESS: 1398 case ISCSI_PARAM_CONN_PORT: 1399 case ISCSI_PARAM_EXP_STATSN: 1400 case ISCSI_PARAM_PERSISTENT_ADDRESS: 1401 case ISCSI_PARAM_PERSISTENT_PORT: 1402 case ISCSI_PARAM_PING_TMO: 1403 case ISCSI_PARAM_RECV_TMO: 1404 case ISCSI_PARAM_INITIAL_R2T_EN: 1405 case ISCSI_PARAM_MAX_R2T: 1406 case ISCSI_PARAM_IMM_DATA_EN: 1407 case ISCSI_PARAM_FIRST_BURST: 1408 case ISCSI_PARAM_MAX_BURST: 1409 case ISCSI_PARAM_PDU_INORDER_EN: 1410 case ISCSI_PARAM_DATASEQ_INORDER_EN: 1411 case ISCSI_PARAM_ERL: 1412 case ISCSI_PARAM_TARGET_NAME: 1413 case ISCSI_PARAM_TPGT: 1414 case ISCSI_PARAM_USERNAME: 1415 case ISCSI_PARAM_PASSWORD: 1416 case ISCSI_PARAM_USERNAME_IN: 1417 case ISCSI_PARAM_PASSWORD_IN: 1418 case ISCSI_PARAM_FAST_ABORT: 1419 case ISCSI_PARAM_ABORT_TMO: 1420 case ISCSI_PARAM_LU_RESET_TMO: 1421 case ISCSI_PARAM_IFACE_NAME: 1422 case ISCSI_PARAM_INITIATOR_NAME: 1423 return S_IRUGO; 1424 default: 1425 return 0; 1426 } 1427 } 1428 1429 return 0; 1430 } 1431