1 /** 2 * Copyright (C) 2005 - 2015 Avago Technologies 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@avagotech.com) 11 * 12 * Contact Information: 13 * linux-drivers@avagotech.com 14 * 15 * Avago Technologies 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 return len; 546 547 switch (param) { 548 case ISCSI_NET_PARAM_IPV4_ADDR: 549 len = sprintf(buf, "%pI4\n", if_info->ip_addr.addr); 550 break; 551 case ISCSI_NET_PARAM_IPV6_ADDR: 552 len = sprintf(buf, "%pI6\n", if_info->ip_addr.addr); 553 break; 554 case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 555 if (!if_info->dhcp_state) 556 len = sprintf(buf, "static\n"); 557 else 558 len = sprintf(buf, "dhcp\n"); 559 break; 560 case ISCSI_NET_PARAM_IPV4_SUBNET: 561 len = sprintf(buf, "%pI4\n", if_info->ip_addr.subnet_mask); 562 break; 563 case ISCSI_NET_PARAM_VLAN_ENABLED: 564 len = sprintf(buf, "%s\n", 565 (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 566 ? "Disabled\n" : "Enabled\n"); 567 break; 568 case ISCSI_NET_PARAM_VLAN_ID: 569 if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 570 len = -EINVAL; 571 else 572 len = sprintf(buf, "%d\n", 573 (if_info->vlan_priority & 574 ISCSI_MAX_VLAN_ID)); 575 break; 576 case ISCSI_NET_PARAM_VLAN_PRIORITY: 577 if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE) 578 len = -EINVAL; 579 else 580 len = sprintf(buf, "%d\n", 581 ((if_info->vlan_priority >> 13) & 582 ISCSI_MAX_VLAN_PRIORITY)); 583 break; 584 default: 585 WARN_ON(1); 586 } 587 588 kfree(if_info); 589 return len; 590 } 591 592 int be2iscsi_iface_get_param(struct iscsi_iface *iface, 593 enum iscsi_param_type param_type, 594 int param, char *buf) 595 { 596 struct Scsi_Host *shost = iscsi_iface_to_shost(iface); 597 struct beiscsi_hba *phba = iscsi_host_priv(shost); 598 struct be_cmd_get_def_gateway_resp gateway; 599 int len = -ENOSYS; 600 601 if (phba->state & BE_ADAPTER_PCI_ERR) { 602 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 603 "BS_%d : In PCI_ERROR Recovery\n"); 604 return -EBUSY; 605 } 606 607 switch (param) { 608 case ISCSI_NET_PARAM_IPV4_ADDR: 609 case ISCSI_NET_PARAM_IPV4_SUBNET: 610 case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 611 case ISCSI_NET_PARAM_IPV6_ADDR: 612 case ISCSI_NET_PARAM_VLAN_ENABLED: 613 case ISCSI_NET_PARAM_VLAN_ID: 614 case ISCSI_NET_PARAM_VLAN_PRIORITY: 615 len = be2iscsi_get_if_param(phba, iface, param, buf); 616 break; 617 case ISCSI_NET_PARAM_IFACE_ENABLE: 618 len = sprintf(buf, "enabled\n"); 619 break; 620 case ISCSI_NET_PARAM_IPV4_GW: 621 memset(&gateway, 0, sizeof(gateway)); 622 len = mgmt_get_gateway(phba, BE2_IPV4, &gateway); 623 if (!len) 624 len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr); 625 break; 626 default: 627 len = -ENOSYS; 628 } 629 630 return len; 631 } 632 633 /** 634 * beiscsi_ep_get_param - get the iscsi parameter 635 * @ep: pointer to iscsi ep 636 * @param: parameter type identifier 637 * @buf: buffer pointer 638 * 639 * returns iscsi parameter 640 */ 641 int beiscsi_ep_get_param(struct iscsi_endpoint *ep, 642 enum iscsi_param param, char *buf) 643 { 644 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 645 int len = 0; 646 647 beiscsi_log(beiscsi_ep->phba, KERN_INFO, 648 BEISCSI_LOG_CONFIG, 649 "BS_%d : In beiscsi_ep_get_param," 650 " param= %d\n", param); 651 652 switch (param) { 653 case ISCSI_PARAM_CONN_PORT: 654 len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport); 655 break; 656 case ISCSI_PARAM_CONN_ADDRESS: 657 if (beiscsi_ep->ip_type == BE2_IPV4) 658 len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr); 659 else 660 len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr); 661 break; 662 default: 663 return -ENOSYS; 664 } 665 return len; 666 } 667 668 int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, 669 enum iscsi_param param, char *buf, int buflen) 670 { 671 struct iscsi_conn *conn = cls_conn->dd_data; 672 struct iscsi_session *session = conn->session; 673 struct beiscsi_hba *phba = NULL; 674 int ret; 675 676 phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 677 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 678 "BS_%d : In beiscsi_conn_set_param," 679 " param= %d\n", param); 680 681 ret = iscsi_set_param(cls_conn, param, buf, buflen); 682 if (ret) 683 return ret; 684 /* 685 * If userspace tried to set the value to higher than we can 686 * support override here. 687 */ 688 switch (param) { 689 case ISCSI_PARAM_FIRST_BURST: 690 if (session->first_burst > 8192) 691 session->first_burst = 8192; 692 break; 693 case ISCSI_PARAM_MAX_RECV_DLENGTH: 694 if (conn->max_recv_dlength > 65536) 695 conn->max_recv_dlength = 65536; 696 break; 697 case ISCSI_PARAM_MAX_BURST: 698 if (session->max_burst > 262144) 699 session->max_burst = 262144; 700 break; 701 case ISCSI_PARAM_MAX_XMIT_DLENGTH: 702 if (conn->max_xmit_dlength > 65536) 703 conn->max_xmit_dlength = 65536; 704 default: 705 return 0; 706 } 707 708 return 0; 709 } 710 711 /** 712 * beiscsi_get_initname - Read Initiator Name from flash 713 * @buf: buffer bointer 714 * @phba: The device priv structure instance 715 * 716 * returns number of bytes 717 */ 718 static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba) 719 { 720 int rc; 721 unsigned int tag; 722 struct be_mcc_wrb *wrb; 723 struct be_cmd_hba_name *resp; 724 725 tag = be_cmd_get_initname(phba); 726 if (!tag) { 727 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 728 "BS_%d : Getting Initiator Name Failed\n"); 729 730 return -EBUSY; 731 } 732 733 rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL); 734 if (rc) { 735 beiscsi_log(phba, KERN_ERR, 736 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 737 "BS_%d : Initiator Name MBX Failed\n"); 738 return rc; 739 } 740 741 resp = embedded_payload(wrb); 742 rc = sprintf(buf, "%s\n", resp->initiator_name); 743 return rc; 744 } 745 746 /** 747 * beiscsi_get_port_state - Get the Port State 748 * @shost : pointer to scsi_host structure 749 * 750 */ 751 static void beiscsi_get_port_state(struct Scsi_Host *shost) 752 { 753 struct beiscsi_hba *phba = iscsi_host_priv(shost); 754 struct iscsi_cls_host *ihost = shost->shost_data; 755 756 ihost->port_state = (phba->state == BE_ADAPTER_LINK_UP) ? 757 ISCSI_PORT_STATE_UP : ISCSI_PORT_STATE_DOWN; 758 } 759 760 /** 761 * beiscsi_get_port_speed - Get the Port Speed from Adapter 762 * @shost : pointer to scsi_host structure 763 * 764 * returns Success/Failure 765 */ 766 static int beiscsi_get_port_speed(struct Scsi_Host *shost) 767 { 768 int rc; 769 unsigned int tag; 770 struct be_mcc_wrb *wrb; 771 struct be_cmd_ntwk_link_status_resp *resp; 772 struct beiscsi_hba *phba = iscsi_host_priv(shost); 773 struct iscsi_cls_host *ihost = shost->shost_data; 774 775 tag = be_cmd_get_port_speed(phba); 776 if (!tag) { 777 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 778 "BS_%d : Getting Port Speed Failed\n"); 779 780 return -EBUSY; 781 } 782 rc = beiscsi_mccq_compl(phba, tag, &wrb, NULL); 783 if (rc) { 784 beiscsi_log(phba, KERN_ERR, 785 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 786 "BS_%d : Port Speed MBX Failed\n"); 787 return rc; 788 } 789 resp = embedded_payload(wrb); 790 791 switch (resp->mac_speed) { 792 case BE2ISCSI_LINK_SPEED_10MBPS: 793 ihost->port_speed = ISCSI_PORT_SPEED_10MBPS; 794 break; 795 case BE2ISCSI_LINK_SPEED_100MBPS: 796 ihost->port_speed = ISCSI_PORT_SPEED_100MBPS; 797 break; 798 case BE2ISCSI_LINK_SPEED_1GBPS: 799 ihost->port_speed = ISCSI_PORT_SPEED_1GBPS; 800 break; 801 case BE2ISCSI_LINK_SPEED_10GBPS: 802 ihost->port_speed = ISCSI_PORT_SPEED_10GBPS; 803 break; 804 default: 805 ihost->port_speed = ISCSI_PORT_SPEED_UNKNOWN; 806 } 807 return 0; 808 } 809 810 /** 811 * beiscsi_get_host_param - get the iscsi parameter 812 * @shost: pointer to scsi_host structure 813 * @param: parameter type identifier 814 * @buf: buffer pointer 815 * 816 * returns host parameter 817 */ 818 int beiscsi_get_host_param(struct Scsi_Host *shost, 819 enum iscsi_host_param param, char *buf) 820 { 821 struct beiscsi_hba *phba = iscsi_host_priv(shost); 822 int status = 0; 823 824 825 if (phba->state & BE_ADAPTER_PCI_ERR) { 826 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 827 "BS_%d : In PCI_ERROR Recovery\n"); 828 return -EBUSY; 829 } else { 830 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 831 "BS_%d : In beiscsi_get_host_param," 832 " param = %d\n", param); 833 } 834 835 switch (param) { 836 case ISCSI_HOST_PARAM_HWADDRESS: 837 status = beiscsi_get_macaddr(buf, phba); 838 if (status < 0) { 839 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 840 "BS_%d : beiscsi_get_macaddr Failed\n"); 841 return status; 842 } 843 break; 844 case ISCSI_HOST_PARAM_INITIATOR_NAME: 845 status = beiscsi_get_initname(buf, phba); 846 if (status < 0) { 847 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 848 "BS_%d : Retreiving Initiator Name Failed\n"); 849 return status; 850 } 851 break; 852 case ISCSI_HOST_PARAM_PORT_STATE: 853 beiscsi_get_port_state(shost); 854 status = sprintf(buf, "%s\n", iscsi_get_port_state_name(shost)); 855 break; 856 case ISCSI_HOST_PARAM_PORT_SPEED: 857 status = beiscsi_get_port_speed(shost); 858 if (status) { 859 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 860 "BS_%d : Retreiving Port Speed Failed\n"); 861 return status; 862 } 863 status = sprintf(buf, "%s\n", iscsi_get_port_speed_name(shost)); 864 break; 865 default: 866 return iscsi_host_get_param(shost, param, buf); 867 } 868 return status; 869 } 870 871 int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) 872 { 873 struct be_cmd_get_nic_conf_resp resp; 874 int rc; 875 876 if (phba->mac_addr_set) 877 return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 878 879 memset(&resp, 0, sizeof(resp)); 880 rc = mgmt_get_nic_conf(phba, &resp); 881 if (rc) 882 return rc; 883 884 phba->mac_addr_set = true; 885 memcpy(phba->mac_address, resp.mac_address, ETH_ALEN); 886 return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN); 887 } 888 889 /** 890 * beiscsi_conn_get_stats - get the iscsi stats 891 * @cls_conn: pointer to iscsi cls conn 892 * @stats: pointer to iscsi_stats structure 893 * 894 * returns iscsi stats 895 */ 896 void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, 897 struct iscsi_stats *stats) 898 { 899 struct iscsi_conn *conn = cls_conn->dd_data; 900 struct beiscsi_hba *phba = NULL; 901 902 phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 903 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 904 "BS_%d : In beiscsi_conn_get_stats\n"); 905 906 stats->txdata_octets = conn->txdata_octets; 907 stats->rxdata_octets = conn->rxdata_octets; 908 stats->dataout_pdus = conn->dataout_pdus_cnt; 909 stats->scsirsp_pdus = conn->scsirsp_pdus_cnt; 910 stats->scsicmd_pdus = conn->scsicmd_pdus_cnt; 911 stats->datain_pdus = conn->datain_pdus_cnt; 912 stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; 913 stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; 914 stats->r2t_pdus = conn->r2t_pdus_cnt; 915 stats->digest_err = 0; 916 stats->timeout_err = 0; 917 stats->custom_length = 1; 918 strcpy(stats->custom[0].desc, "eh_abort_cnt"); 919 stats->custom[0].value = conn->eh_abort_cnt; 920 } 921 922 /** 923 * beiscsi_set_params_for_offld - get the parameters for offload 924 * @beiscsi_conn: pointer to beiscsi_conn 925 * @params: pointer to offload_params structure 926 */ 927 static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn, 928 struct beiscsi_offload_params *params) 929 { 930 struct iscsi_conn *conn = beiscsi_conn->conn; 931 struct iscsi_session *session = conn->session; 932 933 AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length, 934 params, session->max_burst); 935 AMAP_SET_BITS(struct amap_beiscsi_offload_params, 936 max_send_data_segment_length, params, 937 conn->max_xmit_dlength); 938 AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length, 939 params, session->first_burst); 940 AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params, 941 session->erl); 942 AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params, 943 conn->datadgst_en); 944 AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params, 945 conn->hdrdgst_en); 946 AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params, 947 session->initial_r2t_en); 948 AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params, 949 session->imm_data_en); 950 AMAP_SET_BITS(struct amap_beiscsi_offload_params, 951 data_seq_inorder, params, 952 session->dataseq_inorder_en); 953 AMAP_SET_BITS(struct amap_beiscsi_offload_params, 954 pdu_seq_inorder, params, 955 session->pdu_inorder_en); 956 AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_r2t, params, 957 session->max_r2t); 958 AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params, 959 (conn->exp_statsn - 1)); 960 AMAP_SET_BITS(struct amap_beiscsi_offload_params, 961 max_recv_data_segment_length, params, 962 conn->max_recv_dlength); 963 964 } 965 966 /** 967 * beiscsi_conn_start - offload of session to chip 968 * @cls_conn: pointer to beiscsi_conn 969 */ 970 int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn) 971 { 972 struct iscsi_conn *conn = cls_conn->dd_data; 973 struct beiscsi_conn *beiscsi_conn = conn->dd_data; 974 struct beiscsi_endpoint *beiscsi_ep; 975 struct beiscsi_offload_params params; 976 struct beiscsi_hba *phba; 977 978 phba = ((struct beiscsi_conn *)conn->dd_data)->phba; 979 980 if (phba->state & BE_ADAPTER_PCI_ERR) { 981 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 982 "BS_%d : In PCI_ERROR Recovery\n"); 983 return -EBUSY; 984 } else { 985 beiscsi_log(beiscsi_conn->phba, KERN_INFO, 986 BEISCSI_LOG_CONFIG, 987 "BS_%d : In beiscsi_conn_start\n"); 988 } 989 990 memset(¶ms, 0, sizeof(struct beiscsi_offload_params)); 991 beiscsi_ep = beiscsi_conn->ep; 992 if (!beiscsi_ep) 993 beiscsi_log(beiscsi_conn->phba, KERN_ERR, 994 BEISCSI_LOG_CONFIG, 995 "BS_%d : In beiscsi_conn_start , no beiscsi_ep\n"); 996 997 beiscsi_conn->login_in_progress = 0; 998 beiscsi_set_params_for_offld(beiscsi_conn, ¶ms); 999 beiscsi_offload_connection(beiscsi_conn, ¶ms); 1000 iscsi_conn_start(cls_conn); 1001 return 0; 1002 } 1003 1004 /** 1005 * beiscsi_get_cid - Allocate a cid 1006 * @phba: The phba instance 1007 */ 1008 static int beiscsi_get_cid(struct beiscsi_hba *phba) 1009 { 1010 unsigned short cid = 0xFFFF, cid_from_ulp; 1011 struct ulp_cid_info *cid_info = NULL; 1012 uint16_t cid_avlbl_ulp0, cid_avlbl_ulp1; 1013 1014 /* Find the ULP which has more CID available */ 1015 cid_avlbl_ulp0 = (phba->cid_array_info[BEISCSI_ULP0]) ? 1016 BEISCSI_ULP0_AVLBL_CID(phba) : 0; 1017 cid_avlbl_ulp1 = (phba->cid_array_info[BEISCSI_ULP1]) ? 1018 BEISCSI_ULP1_AVLBL_CID(phba) : 0; 1019 cid_from_ulp = (cid_avlbl_ulp0 > cid_avlbl_ulp1) ? 1020 BEISCSI_ULP0 : BEISCSI_ULP1; 1021 1022 if (test_bit(cid_from_ulp, (void *)&phba->fw_config.ulp_supported)) { 1023 cid_info = phba->cid_array_info[cid_from_ulp]; 1024 if (!cid_info->avlbl_cids) 1025 return cid; 1026 1027 cid = cid_info->cid_array[cid_info->cid_alloc++]; 1028 1029 if (cid_info->cid_alloc == BEISCSI_GET_CID_COUNT( 1030 phba, cid_from_ulp)) 1031 cid_info->cid_alloc = 0; 1032 1033 cid_info->avlbl_cids--; 1034 } 1035 return cid; 1036 } 1037 1038 /** 1039 * beiscsi_put_cid - Free the cid 1040 * @phba: The phba for which the cid is being freed 1041 * @cid: The cid to free 1042 */ 1043 static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) 1044 { 1045 uint16_t cid_post_ulp; 1046 struct hwi_controller *phwi_ctrlr; 1047 struct hwi_wrb_context *pwrb_context; 1048 struct ulp_cid_info *cid_info = NULL; 1049 uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 1050 1051 phwi_ctrlr = phba->phwi_ctrlr; 1052 pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; 1053 cid_post_ulp = pwrb_context->ulp_num; 1054 1055 cid_info = phba->cid_array_info[cid_post_ulp]; 1056 cid_info->avlbl_cids++; 1057 1058 cid_info->cid_array[cid_info->cid_free++] = cid; 1059 if (cid_info->cid_free == BEISCSI_GET_CID_COUNT(phba, cid_post_ulp)) 1060 cid_info->cid_free = 0; 1061 } 1062 1063 /** 1064 * beiscsi_free_ep - free endpoint 1065 * @ep: pointer to iscsi endpoint structure 1066 */ 1067 static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) 1068 { 1069 struct beiscsi_hba *phba = beiscsi_ep->phba; 1070 struct beiscsi_conn *beiscsi_conn; 1071 1072 beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 1073 beiscsi_ep->phba = NULL; 1074 phba->ep_array[BE_GET_CRI_FROM_CID 1075 (beiscsi_ep->ep_cid)] = NULL; 1076 1077 /** 1078 * Check if any connection resource allocated by driver 1079 * is to be freed.This case occurs when target redirection 1080 * or connection retry is done. 1081 **/ 1082 if (!beiscsi_ep->conn) 1083 return; 1084 1085 beiscsi_conn = beiscsi_ep->conn; 1086 if (beiscsi_conn->login_in_progress) { 1087 beiscsi_free_mgmt_task_handles(beiscsi_conn, 1088 beiscsi_conn->task); 1089 beiscsi_conn->login_in_progress = 0; 1090 } 1091 } 1092 1093 /** 1094 * beiscsi_open_conn - Ask FW to open a TCP connection 1095 * @ep: endpoint to be used 1096 * @src_addr: The source IP address 1097 * @dst_addr: The Destination IP address 1098 * 1099 * Asks the FW to open a TCP connection 1100 */ 1101 static int beiscsi_open_conn(struct iscsi_endpoint *ep, 1102 struct sockaddr *src_addr, 1103 struct sockaddr *dst_addr, int non_blocking) 1104 { 1105 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 1106 struct beiscsi_hba *phba = beiscsi_ep->phba; 1107 struct tcp_connect_and_offload_out *ptcpcnct_out; 1108 struct be_dma_mem nonemb_cmd; 1109 unsigned int tag, req_memsize; 1110 int ret = -ENOMEM; 1111 1112 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1113 "BS_%d : In beiscsi_open_conn\n"); 1114 1115 beiscsi_ep->ep_cid = beiscsi_get_cid(phba); 1116 if (beiscsi_ep->ep_cid == 0xFFFF) { 1117 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1118 "BS_%d : No free cid available\n"); 1119 return ret; 1120 } 1121 1122 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1123 "BS_%d : In beiscsi_open_conn, ep_cid=%d\n", 1124 beiscsi_ep->ep_cid); 1125 1126 phba->ep_array[BE_GET_CRI_FROM_CID 1127 (beiscsi_ep->ep_cid)] = ep; 1128 1129 beiscsi_ep->cid_vld = 0; 1130 1131 if (is_chip_be2_be3r(phba)) 1132 req_memsize = sizeof(struct tcp_connect_and_offload_in); 1133 else 1134 req_memsize = sizeof(struct tcp_connect_and_offload_in_v1); 1135 1136 nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, 1137 req_memsize, 1138 &nonemb_cmd.dma); 1139 if (nonemb_cmd.va == NULL) { 1140 1141 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1142 "BS_%d : Failed to allocate memory for" 1143 " mgmt_open_connection\n"); 1144 1145 beiscsi_free_ep(beiscsi_ep); 1146 return -ENOMEM; 1147 } 1148 nonemb_cmd.size = req_memsize; 1149 memset(nonemb_cmd.va, 0, nonemb_cmd.size); 1150 tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd); 1151 if (tag <= 0) { 1152 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1153 "BS_%d : mgmt_open_connection Failed for cid=%d\n", 1154 beiscsi_ep->ep_cid); 1155 1156 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1157 nonemb_cmd.va, nonemb_cmd.dma); 1158 beiscsi_free_ep(beiscsi_ep); 1159 return -EAGAIN; 1160 } 1161 1162 ret = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd); 1163 if (ret) { 1164 beiscsi_log(phba, KERN_ERR, 1165 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 1166 "BS_%d : mgmt_open_connection Failed"); 1167 1168 if (ret != -EBUSY) 1169 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1170 nonemb_cmd.va, nonemb_cmd.dma); 1171 1172 beiscsi_free_ep(beiscsi_ep); 1173 return ret; 1174 } 1175 1176 ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va; 1177 beiscsi_ep = ep->dd_data; 1178 beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; 1179 beiscsi_ep->cid_vld = 1; 1180 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1181 "BS_%d : mgmt_open_connection Success\n"); 1182 1183 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1184 nonemb_cmd.va, nonemb_cmd.dma); 1185 return 0; 1186 } 1187 1188 /** 1189 * beiscsi_ep_connect - Ask chip to create TCP Conn 1190 * @scsi_host: Pointer to scsi_host structure 1191 * @dst_addr: The IP address of Target 1192 * @non_blocking: blocking or non-blocking call 1193 * 1194 * This routines first asks chip to create a connection and then allocates an EP 1195 */ 1196 struct iscsi_endpoint * 1197 beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, 1198 int non_blocking) 1199 { 1200 struct beiscsi_hba *phba; 1201 struct beiscsi_endpoint *beiscsi_ep; 1202 struct iscsi_endpoint *ep; 1203 int ret; 1204 1205 if (shost) 1206 phba = iscsi_host_priv(shost); 1207 else { 1208 ret = -ENXIO; 1209 printk(KERN_ERR 1210 "beiscsi_ep_connect shost is NULL\n"); 1211 return ERR_PTR(ret); 1212 } 1213 1214 if (beiscsi_error(phba)) { 1215 ret = -EIO; 1216 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 1217 "BS_%d : The FW state Not Stable!!!\n"); 1218 return ERR_PTR(ret); 1219 } 1220 1221 if (phba->state & BE_ADAPTER_PCI_ERR) { 1222 ret = -EBUSY; 1223 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1224 "BS_%d : In PCI_ERROR Recovery\n"); 1225 return ERR_PTR(ret); 1226 } else if (phba->state & BE_ADAPTER_LINK_DOWN) { 1227 ret = -EBUSY; 1228 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 1229 "BS_%d : The Adapter Port state is Down!!!\n"); 1230 return ERR_PTR(ret); 1231 } 1232 1233 ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint)); 1234 if (!ep) { 1235 ret = -ENOMEM; 1236 return ERR_PTR(ret); 1237 } 1238 1239 beiscsi_ep = ep->dd_data; 1240 beiscsi_ep->phba = phba; 1241 beiscsi_ep->openiscsi_ep = ep; 1242 ret = beiscsi_open_conn(ep, NULL, dst_addr, non_blocking); 1243 if (ret) { 1244 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1245 "BS_%d : Failed in beiscsi_open_conn\n"); 1246 goto free_ep; 1247 } 1248 1249 return ep; 1250 1251 free_ep: 1252 iscsi_destroy_endpoint(ep); 1253 return ERR_PTR(ret); 1254 } 1255 1256 /** 1257 * beiscsi_ep_poll - Poll to see if connection is established 1258 * @ep: endpoint to be used 1259 * @timeout_ms: timeout specified in millisecs 1260 * 1261 * Poll to see if TCP connection established 1262 */ 1263 int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) 1264 { 1265 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 1266 1267 beiscsi_log(beiscsi_ep->phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1268 "BS_%d : In beiscsi_ep_poll\n"); 1269 1270 if (beiscsi_ep->cid_vld == 1) 1271 return 1; 1272 else 1273 return 0; 1274 } 1275 1276 /** 1277 * beiscsi_flush_cq()- Flush the CQ created. 1278 * @phba: ptr device priv structure. 1279 * 1280 * Before the connection resource are freed flush 1281 * all the CQ enteries 1282 **/ 1283 static void beiscsi_flush_cq(struct beiscsi_hba *phba) 1284 { 1285 uint16_t i; 1286 struct be_eq_obj *pbe_eq; 1287 struct hwi_controller *phwi_ctrlr; 1288 struct hwi_context_memory *phwi_context; 1289 1290 phwi_ctrlr = phba->phwi_ctrlr; 1291 phwi_context = phwi_ctrlr->phwi_ctxt; 1292 1293 for (i = 0; i < phba->num_cpus; i++) { 1294 pbe_eq = &phwi_context->be_eq[i]; 1295 blk_iopoll_disable(&pbe_eq->iopoll); 1296 beiscsi_process_cq(pbe_eq); 1297 blk_iopoll_enable(&pbe_eq->iopoll); 1298 } 1299 } 1300 1301 /** 1302 * beiscsi_close_conn - Upload the connection 1303 * @ep: The iscsi endpoint 1304 * @flag: The type of connection closure 1305 */ 1306 static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) 1307 { 1308 int ret = 0; 1309 unsigned int tag; 1310 struct beiscsi_hba *phba = beiscsi_ep->phba; 1311 1312 tag = mgmt_upload_connection(phba, beiscsi_ep->ep_cid, flag); 1313 if (!tag) { 1314 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1315 "BS_%d : upload failed for cid 0x%x\n", 1316 beiscsi_ep->ep_cid); 1317 1318 ret = -EAGAIN; 1319 } 1320 1321 ret = beiscsi_mccq_compl(phba, tag, NULL, NULL); 1322 1323 /* Flush the CQ entries */ 1324 beiscsi_flush_cq(phba); 1325 1326 return ret; 1327 } 1328 1329 /** 1330 * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table 1331 * @phba: The phba instance 1332 * @cid: The cid to free 1333 */ 1334 static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, 1335 unsigned int cid) 1336 { 1337 uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); 1338 1339 if (phba->conn_table[cri_index]) 1340 phba->conn_table[cri_index] = NULL; 1341 else { 1342 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1343 "BS_%d : Connection table Not occupied.\n"); 1344 return -EINVAL; 1345 } 1346 return 0; 1347 } 1348 1349 /** 1350 * beiscsi_ep_disconnect - Tears down the TCP connection 1351 * @ep: endpoint to be used 1352 * 1353 * Tears down the TCP connection 1354 */ 1355 void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) 1356 { 1357 struct beiscsi_conn *beiscsi_conn; 1358 struct beiscsi_endpoint *beiscsi_ep; 1359 struct beiscsi_hba *phba; 1360 unsigned int tag; 1361 uint8_t mgmt_invalidate_flag, tcp_upload_flag; 1362 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; 1363 1364 beiscsi_ep = ep->dd_data; 1365 phba = beiscsi_ep->phba; 1366 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1367 "BS_%d : In beiscsi_ep_disconnect for ep_cid = %d\n", 1368 beiscsi_ep->ep_cid); 1369 1370 if (beiscsi_ep->conn) { 1371 beiscsi_conn = beiscsi_ep->conn; 1372 iscsi_suspend_queue(beiscsi_conn->conn); 1373 mgmt_invalidate_flag = ~BEISCSI_NO_RST_ISSUE; 1374 tcp_upload_flag = CONNECTION_UPLOAD_GRACEFUL; 1375 } else { 1376 mgmt_invalidate_flag = BEISCSI_NO_RST_ISSUE; 1377 tcp_upload_flag = CONNECTION_UPLOAD_ABORT; 1378 } 1379 1380 if (phba->state & BE_ADAPTER_PCI_ERR) { 1381 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1382 "BS_%d : PCI_ERROR Recovery\n"); 1383 goto free_ep; 1384 } 1385 1386 tag = mgmt_invalidate_connection(phba, beiscsi_ep, 1387 beiscsi_ep->ep_cid, 1388 mgmt_invalidate_flag, 1389 savecfg_flag); 1390 if (!tag) { 1391 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1392 "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n", 1393 beiscsi_ep->ep_cid); 1394 } 1395 1396 beiscsi_mccq_compl(phba, tag, NULL, NULL); 1397 beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); 1398 free_ep: 1399 msleep(BEISCSI_LOGOUT_SYNC_DELAY); 1400 beiscsi_free_ep(beiscsi_ep); 1401 beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); 1402 iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); 1403 } 1404 1405 umode_t be2iscsi_attr_is_visible(int param_type, int param) 1406 { 1407 switch (param_type) { 1408 case ISCSI_NET_PARAM: 1409 switch (param) { 1410 case ISCSI_NET_PARAM_IFACE_ENABLE: 1411 case ISCSI_NET_PARAM_IPV4_ADDR: 1412 case ISCSI_NET_PARAM_IPV4_SUBNET: 1413 case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 1414 case ISCSI_NET_PARAM_IPV4_GW: 1415 case ISCSI_NET_PARAM_IPV6_ADDR: 1416 case ISCSI_NET_PARAM_VLAN_ID: 1417 case ISCSI_NET_PARAM_VLAN_PRIORITY: 1418 case ISCSI_NET_PARAM_VLAN_ENABLED: 1419 return S_IRUGO; 1420 default: 1421 return 0; 1422 } 1423 case ISCSI_HOST_PARAM: 1424 switch (param) { 1425 case ISCSI_HOST_PARAM_HWADDRESS: 1426 case ISCSI_HOST_PARAM_INITIATOR_NAME: 1427 case ISCSI_HOST_PARAM_PORT_STATE: 1428 case ISCSI_HOST_PARAM_PORT_SPEED: 1429 return S_IRUGO; 1430 default: 1431 return 0; 1432 } 1433 case ISCSI_PARAM: 1434 switch (param) { 1435 case ISCSI_PARAM_MAX_RECV_DLENGTH: 1436 case ISCSI_PARAM_MAX_XMIT_DLENGTH: 1437 case ISCSI_PARAM_HDRDGST_EN: 1438 case ISCSI_PARAM_DATADGST_EN: 1439 case ISCSI_PARAM_CONN_ADDRESS: 1440 case ISCSI_PARAM_CONN_PORT: 1441 case ISCSI_PARAM_EXP_STATSN: 1442 case ISCSI_PARAM_PERSISTENT_ADDRESS: 1443 case ISCSI_PARAM_PERSISTENT_PORT: 1444 case ISCSI_PARAM_PING_TMO: 1445 case ISCSI_PARAM_RECV_TMO: 1446 case ISCSI_PARAM_INITIAL_R2T_EN: 1447 case ISCSI_PARAM_MAX_R2T: 1448 case ISCSI_PARAM_IMM_DATA_EN: 1449 case ISCSI_PARAM_FIRST_BURST: 1450 case ISCSI_PARAM_MAX_BURST: 1451 case ISCSI_PARAM_PDU_INORDER_EN: 1452 case ISCSI_PARAM_DATASEQ_INORDER_EN: 1453 case ISCSI_PARAM_ERL: 1454 case ISCSI_PARAM_TARGET_NAME: 1455 case ISCSI_PARAM_TPGT: 1456 case ISCSI_PARAM_USERNAME: 1457 case ISCSI_PARAM_PASSWORD: 1458 case ISCSI_PARAM_USERNAME_IN: 1459 case ISCSI_PARAM_PASSWORD_IN: 1460 case ISCSI_PARAM_FAST_ABORT: 1461 case ISCSI_PARAM_ABORT_TMO: 1462 case ISCSI_PARAM_LU_RESET_TMO: 1463 case ISCSI_PARAM_IFACE_NAME: 1464 case ISCSI_PARAM_INITIATOR_NAME: 1465 return S_IRUGO; 1466 default: 1467 return 0; 1468 } 1469 } 1470 1471 return 0; 1472 } 1473