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