aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2012-04-04 00:41:51 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-04-25 04:35:31 -0400
commit0e43895ec1f405a25b5d57bc95c11fe17224ec43 (patch)
tree27002f8f9ce3983fdf7e6276532e788f4c8f2185 /drivers/scsi/be2iscsi
parentffce3e2e8ce4ff2ee96df0944ee5daa783d5b2d0 (diff)
[SCSI] be2iscsi: adding functionality to change network settings using iscsiadm
This patch allows iscsiadm to set/ delete static IP and enable /disable DHCP. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h114
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c354
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.h15
-rw-r--r--drivers/scsi/be2iscsi/be_main.c33
-rw-r--r--drivers/scsi/be2iscsi/be_main.h4
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c413
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h31
7 files changed, 858 insertions, 106 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index b15de3eaddf0..60d144550f76 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -163,7 +163,8 @@ struct be_mcc_mailbox {
163#define OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES 3 163#define OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES 3
164#define OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG 7 164#define OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG 7
165#define OPCODE_COMMON_ISCSI_NTWK_SET_VLAN 14 165#define OPCODE_COMMON_ISCSI_NTWK_SET_VLAN 14
166#define OPCODE_COMMON_ISCSI_NTWK_CONFIGURE_STATELESS_IP_ADDR 17 166#define OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR 17
167#define OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR 18
167#define OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR 21 168#define OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR 21
168#define OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY 22 169#define OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY 22
169#define OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY 23 170#define OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY 23
@@ -274,15 +275,15 @@ struct mgmt_conn_login_options {
274 struct mgmt_auth_method_format auth_data; 275 struct mgmt_auth_method_format auth_data;
275} __packed; 276} __packed;
276 277
277struct ip_address_format { 278struct ip_addr_format {
278 u16 size_of_structure; 279 u16 size_of_structure;
279 u8 reserved; 280 u8 reserved;
280 u8 ip_type; 281 u8 ip_type;
281 u8 ip_address[16]; 282 u8 addr[16];
282 u32 rsvd0; 283 u32 rsvd0;
283} __packed; 284} __packed;
284 285
285struct mgmt_conn_info { 286struct mgmt_conn_info {
286 u32 connection_handle; 287 u32 connection_handle;
287 u32 connection_status; 288 u32 connection_status;
288 u16 src_port; 289 u16 src_port;
@@ -290,9 +291,9 @@ struct mgmt_conn_info {
290 u16 dest_port_redirected; 291 u16 dest_port_redirected;
291 u16 cid; 292 u16 cid;
292 u32 estimated_throughput; 293 u32 estimated_throughput;
293 struct ip_address_format src_ipaddr; 294 struct ip_addr_format src_ipaddr;
294 struct ip_address_format dest_ipaddr; 295 struct ip_addr_format dest_ipaddr;
295 struct ip_address_format dest_ipaddr_redirected; 296 struct ip_addr_format dest_ipaddr_redirected;
296 struct mgmt_conn_login_options negotiated_login_options; 297 struct mgmt_conn_login_options negotiated_login_options;
297} __packed; 298} __packed;
298 299
@@ -322,43 +323,115 @@ struct mgmt_session_info {
322 struct mgmt_conn_info conn_list[1]; 323 struct mgmt_conn_info conn_list[1];
323} __packed; 324} __packed;
324 325
325struct be_cmd_req_get_session { 326struct be_cmd_get_session_req {
326 struct be_cmd_req_hdr hdr; 327 struct be_cmd_req_hdr hdr;
327 u32 session_handle; 328 u32 session_handle;
328} __packed; 329} __packed;
329 330
330struct be_cmd_resp_get_session { 331struct be_cmd_get_session_resp {
331 struct be_cmd_resp_hdr hdr; 332 struct be_cmd_resp_hdr hdr;
332 struct mgmt_session_info session_info; 333 struct mgmt_session_info session_info;
333} __packed; 334} __packed;
334 335
335struct mac_addr { 336struct mac_addr {
336 u16 size_of_struct; 337 u16 size_of_structure;
337 u8 addr[ETH_ALEN]; 338 u8 addr[ETH_ALEN];
338} __packed; 339} __packed;
339 340
340struct be_cmd_req_get_boot_target { 341struct be_cmd_get_boot_target_req {
341 struct be_cmd_req_hdr hdr; 342 struct be_cmd_req_hdr hdr;
342} __packed; 343} __packed;
343 344
344struct be_cmd_resp_get_boot_target { 345struct be_cmd_get_boot_target_resp {
345 struct be_cmd_resp_hdr hdr; 346 struct be_cmd_resp_hdr hdr;
346 u32 boot_session_count; 347 u32 boot_session_count;
347 int boot_session_handle; 348 int boot_session_handle;
348}; 349};
349 350
350struct be_cmd_req_mac_query { 351struct be_cmd_mac_query_req {
351 struct be_cmd_req_hdr hdr; 352 struct be_cmd_req_hdr hdr;
352 u8 type; 353 u8 type;
353 u8 permanent; 354 u8 permanent;
354 u16 if_id; 355 u16 if_id;
355} __packed; 356} __packed;
356 357
357struct be_cmd_resp_mac_query { 358struct be_cmd_get_mac_resp {
358 struct be_cmd_resp_hdr hdr; 359 struct be_cmd_resp_hdr hdr;
359 struct mac_addr mac; 360 struct mac_addr mac;
360}; 361};
361 362
363struct be_ip_addr_subnet_format {
364 u16 size_of_structure;
365 u8 ip_type;
366 u8 ipv6_prefix_length;
367 u8 addr[16];
368 u8 subnet_mask[16];
369 u32 rsvd0;
370} __packed;
371
372struct be_cmd_get_if_info_req {
373 struct be_cmd_req_hdr hdr;
374 u32 interface_hndl;
375 u32 ip_type;
376} __packed;
377
378struct be_cmd_get_if_info_resp {
379 struct be_cmd_req_hdr hdr;
380 u32 interface_hndl;
381 u32 vlan_priority;
382 u32 ip_addr_count;
383 u32 dhcp_state;
384 struct be_ip_addr_subnet_format ip_addr;
385} __packed;
386
387struct be_ip_addr_record {
388 u32 action;
389 u32 interface_hndl;
390 struct be_ip_addr_subnet_format ip_addr;
391 u32 status;
392} __packed;
393
394struct be_ip_addr_record_params {
395 u32 record_entry_count;
396 struct be_ip_addr_record ip_record;
397} __packed;
398
399struct be_cmd_set_ip_addr_req {
400 struct be_cmd_req_hdr hdr;
401 struct be_ip_addr_record_params ip_params;
402} __packed;
403
404
405struct be_cmd_set_dhcp_req {
406 struct be_cmd_req_hdr hdr;
407 u32 interface_hndl;
408 u32 ip_type;
409 u32 flags;
410 u32 retry_count;
411} __packed;
412
413struct be_cmd_rel_dhcp_req {
414 struct be_cmd_req_hdr hdr;
415 u32 interface_hndl;
416 u32 ip_type;
417} __packed;
418
419struct be_cmd_set_def_gateway_req {
420 struct be_cmd_req_hdr hdr;
421 u32 action;
422 struct ip_addr_format ip_addr;
423} __packed;
424
425struct be_cmd_get_def_gateway_req {
426 struct be_cmd_req_hdr hdr;
427 u32 ip_type;
428} __packed;
429
430struct be_cmd_get_def_gateway_resp {
431 struct be_cmd_req_hdr hdr;
432 struct ip_addr_format ip_addr;
433} __packed;
434
362/******************** Create CQ ***************************/ 435/******************** Create CQ ***************************/
363/** 436/**
364 * Pseudo amap definition in which each bit of the actual structure is defined 437 * Pseudo amap definition in which each bit of the actual structure is defined
@@ -489,7 +562,7 @@ struct be_cmd_req_modify_eq_delay {
489 562
490#define ETH_ALEN 6 563#define ETH_ALEN 6
491 564
492struct be_cmd_req_get_mac_addr { 565struct be_cmd_get_nic_conf_req {
493 struct be_cmd_req_hdr hdr; 566 struct be_cmd_req_hdr hdr;
494 u32 nic_port_count; 567 u32 nic_port_count;
495 u32 speed; 568 u32 speed;
@@ -501,7 +574,7 @@ struct be_cmd_req_get_mac_addr {
501 u32 rsvd[23]; 574 u32 rsvd[23];
502}; 575};
503 576
504struct be_cmd_resp_get_mac_addr { 577struct be_cmd_get_nic_conf_resp {
505 struct be_cmd_resp_hdr hdr; 578 struct be_cmd_resp_hdr hdr;
506 u32 nic_port_count; 579 u32 nic_port_count;
507 u32 speed; 580 u32 speed;
@@ -541,12 +614,7 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
541int be_poll_mcc(struct be_ctrl_info *ctrl); 614int be_poll_mcc(struct be_ctrl_info *ctrl);
542int mgmt_check_supported_fw(struct be_ctrl_info *ctrl, 615int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
543 struct beiscsi_hba *phba); 616 struct beiscsi_hba *phba);
544unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba);
545unsigned int be_cmd_get_initname(struct beiscsi_hba *phba); 617unsigned int be_cmd_get_initname(struct beiscsi_hba *phba);
546unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba);
547unsigned int beiscsi_get_session_info(struct beiscsi_hba *phba,
548 u32 boot_session_handle,
549 struct be_dma_mem *nonemb_cmd);
550 618
551void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); 619void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
552/*ISCSI Functuions */ 620/*ISCSI Functuions */
@@ -727,7 +795,7 @@ struct be_eq_delay_params_in {
727 795
728struct tcp_connect_and_offload_in { 796struct tcp_connect_and_offload_in {
729 struct be_cmd_req_hdr hdr; 797 struct be_cmd_req_hdr hdr;
730 struct ip_address_format ip_address; 798 struct ip_addr_format ip_address;
731 u16 tcp_port; 799 u16 tcp_port;
732 u16 cid; 800 u16 cid;
733 u16 cq_id; 801 u16 cq_id;
@@ -804,7 +872,7 @@ struct be_fw_cfg {
804 u32 function_caps; 872 u32 function_caps;
805} __packed; 873} __packed;
806 874
807struct be_all_if_id { 875struct be_cmd_get_all_if_id_req {
808 struct be_cmd_req_hdr hdr; 876 struct be_cmd_req_hdr hdr;
809 u32 if_count; 877 u32 if_count;
810 u32 if_hndl_list[1]; 878 u32 if_hndl_list[1];
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 1af777474e42..46cc40e83b36 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -23,6 +23,8 @@
23#include <scsi/scsi_cmnd.h> 23#include <scsi/scsi_cmnd.h>
24#include <scsi/scsi_device.h> 24#include <scsi/scsi_device.h>
25#include <scsi/scsi_host.h> 25#include <scsi/scsi_host.h>
26#include <scsi/scsi_netlink.h>
27#include <net/netlink.h>
26#include <scsi/scsi.h> 28#include <scsi/scsi.h>
27 29
28#include "be_iscsi.h" 30#include "be_iscsi.h"
@@ -207,6 +209,301 @@ int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
207 return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid); 209 return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid);
208} 210}
209 211
212static int beiscsi_create_ipv4_iface(struct beiscsi_hba *phba)
213{
214 if (phba->ipv4_iface)
215 return 0;
216
217 phba->ipv4_iface = iscsi_create_iface(phba->shost,
218 &beiscsi_iscsi_transport,
219 ISCSI_IFACE_TYPE_IPV4,
220 0, 0);
221 if (!phba->ipv4_iface) {
222 shost_printk(KERN_ERR, phba->shost, "Could not "
223 "create default IPv4 address.\n");
224 return -ENODEV;
225 }
226
227 return 0;
228}
229
230static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba)
231{
232 if (phba->ipv6_iface)
233 return 0;
234
235 phba->ipv6_iface = iscsi_create_iface(phba->shost,
236 &beiscsi_iscsi_transport,
237 ISCSI_IFACE_TYPE_IPV6,
238 0, 0);
239 if (!phba->ipv6_iface) {
240 shost_printk(KERN_ERR, phba->shost, "Could not "
241 "create default IPv6 address.\n");
242 return -ENODEV;
243 }
244
245 return 0;
246}
247
248void beiscsi_create_def_ifaces(struct beiscsi_hba *phba)
249{
250 struct be_cmd_get_if_info_resp if_info;
251
252 if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info))
253 beiscsi_create_ipv4_iface(phba);
254
255 if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info))
256 beiscsi_create_ipv6_iface(phba);
257}
258
259void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba)
260{
261 if (phba->ipv6_iface)
262 iscsi_destroy_iface(phba->ipv6_iface);
263 if (phba->ipv4_iface)
264 iscsi_destroy_iface(phba->ipv4_iface);
265}
266
267static int
268beiscsi_set_static_ip(struct Scsi_Host *shost,
269 struct iscsi_iface_param_info *iface_param,
270 void *data, uint32_t dt_len)
271{
272 struct beiscsi_hba *phba = iscsi_host_priv(shost);
273 struct iscsi_iface_param_info *iface_ip = NULL;
274 struct iscsi_iface_param_info *iface_subnet = NULL;
275 struct nlattr *nla;
276 int ret;
277
278
279 switch (iface_param->param) {
280 case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
281 nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR);
282 if (nla)
283 iface_ip = nla_data(nla);
284
285 nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET);
286 if (nla)
287 iface_subnet = nla_data(nla);
288 break;
289 case ISCSI_NET_PARAM_IPV4_ADDR:
290 iface_ip = iface_param;
291 nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_SUBNET);
292 if (nla)
293 iface_subnet = nla_data(nla);
294 break;
295 case ISCSI_NET_PARAM_IPV4_SUBNET:
296 iface_subnet = iface_param;
297 nla = nla_find(data, dt_len, ISCSI_NET_PARAM_IPV4_ADDR);
298 if (nla)
299 iface_ip = nla_data(nla);
300 break;
301 default:
302 shost_printk(KERN_ERR, shost, "Unsupported param %d\n",
303 iface_param->param);
304 }
305
306 if (!iface_ip || !iface_subnet) {
307 shost_printk(KERN_ERR, shost, "IP and Subnet Mask required\n");
308 return -EINVAL;
309 }
310
311 ret = mgmt_set_ip(phba, iface_ip, iface_subnet,
312 ISCSI_BOOTPROTO_STATIC);
313
314 return ret;
315}
316
317static int
318beiscsi_set_ipv4(struct Scsi_Host *shost,
319 struct iscsi_iface_param_info *iface_param,
320 void *data, uint32_t dt_len)
321{
322 struct beiscsi_hba *phba = iscsi_host_priv(shost);
323 int ret = 0;
324
325 /* Check the param */
326 switch (iface_param->param) {
327 case ISCSI_NET_PARAM_IPV4_GW:
328 ret = mgmt_set_gateway(phba, iface_param);
329 break;
330 case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
331 if (iface_param->value[0] == ISCSI_BOOTPROTO_DHCP)
332 ret = mgmt_set_ip(phba, iface_param,
333 NULL, ISCSI_BOOTPROTO_DHCP);
334 else if (iface_param->value[0] == ISCSI_BOOTPROTO_STATIC)
335 ret = beiscsi_set_static_ip(shost, iface_param,
336 data, dt_len);
337 else
338 shost_printk(KERN_ERR, shost, "Invalid BOOTPROTO: %d\n",
339 iface_param->value[0]);
340 break;
341 case ISCSI_NET_PARAM_IFACE_ENABLE:
342 if (iface_param->value[0] == ISCSI_IFACE_ENABLE)
343 ret = beiscsi_create_ipv4_iface(phba);
344 else
345 iscsi_destroy_iface(phba->ipv4_iface);
346 break;
347 case ISCSI_NET_PARAM_IPV4_SUBNET:
348 case ISCSI_NET_PARAM_IPV4_ADDR:
349 ret = beiscsi_set_static_ip(shost, iface_param,
350 data, dt_len);
351 break;
352 default:
353 shost_printk(KERN_ERR, shost, "Param %d not supported\n",
354 iface_param->param);
355 }
356
357 return ret;
358}
359
360static int
361beiscsi_set_ipv6(struct Scsi_Host *shost,
362 struct iscsi_iface_param_info *iface_param,
363 void *data, uint32_t dt_len)
364{
365 struct beiscsi_hba *phba = iscsi_host_priv(shost);
366 int ret = 0;
367
368 switch (iface_param->param) {
369 case ISCSI_NET_PARAM_IFACE_ENABLE:
370 if (iface_param->value[0] == ISCSI_IFACE_ENABLE)
371 ret = beiscsi_create_ipv6_iface(phba);
372 else {
373 iscsi_destroy_iface(phba->ipv6_iface);
374 ret = 0;
375 }
376 break;
377 case ISCSI_NET_PARAM_IPV6_ADDR:
378 ret = mgmt_set_ip(phba, iface_param, NULL,
379 ISCSI_BOOTPROTO_STATIC);
380 break;
381 default:
382 shost_printk(KERN_ERR, shost, "Param %d not supported\n",
383 iface_param->param);
384 }
385
386 return ret;
387}
388
389int be2iscsi_iface_set_param(struct Scsi_Host *shost,
390 void *data, uint32_t dt_len)
391{
392 struct iscsi_iface_param_info *iface_param = NULL;
393 struct nlattr *attrib;
394 uint32_t rm_len = dt_len;
395 int ret = 0 ;
396
397 nla_for_each_attr(attrib, data, dt_len, rm_len) {
398 iface_param = nla_data(attrib);
399
400 if (iface_param->param_type != ISCSI_NET_PARAM)
401 continue;
402
403 /*
404 * BE2ISCSI only supports 1 interface
405 */
406 if (iface_param->iface_num) {
407 shost_printk(KERN_ERR, shost, "Invalid iface_num %d."
408 "Only iface_num 0 is supported.\n",
409 iface_param->iface_num);
410 return -EINVAL;
411 }
412
413 switch (iface_param->iface_type) {
414 case ISCSI_IFACE_TYPE_IPV4:
415 ret = beiscsi_set_ipv4(shost, iface_param,
416 data, dt_len);
417 break;
418 case ISCSI_IFACE_TYPE_IPV6:
419 ret = beiscsi_set_ipv6(shost, iface_param,
420 data, dt_len);
421 break;
422 default:
423 shost_printk(KERN_ERR, shost,
424 "Invalid iface type :%d passed\n",
425 iface_param->iface_type);
426 break;
427 }
428
429 if (ret)
430 return ret;
431 }
432
433 return ret;
434}
435
436static int be2iscsi_get_if_param(struct beiscsi_hba *phba,
437 struct iscsi_iface *iface, int param,
438 char *buf)
439{
440 struct be_cmd_get_if_info_resp if_info;
441 int len, ip_type = BE2_IPV4;
442
443 memset(&if_info, 0, sizeof(if_info));
444
445 if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
446 ip_type = BE2_IPV6;
447
448 len = mgmt_get_if_info(phba, ip_type, &if_info);
449 if (len)
450 return len;
451
452 switch (param) {
453 case ISCSI_NET_PARAM_IPV4_ADDR:
454 len = sprintf(buf, "%pI4\n", &if_info.ip_addr.addr);
455 break;
456 case ISCSI_NET_PARAM_IPV6_ADDR:
457 len = sprintf(buf, "%pI6\n", &if_info.ip_addr.addr);
458 break;
459 case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
460 if (!if_info.dhcp_state)
461 len = sprintf(buf, "static");
462 else
463 len = sprintf(buf, "dhcp");
464 break;
465 case ISCSI_NET_PARAM_IPV4_SUBNET:
466 len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask);
467 break;
468 default:
469 WARN_ON(1);
470 }
471
472 return len;
473}
474
475int be2iscsi_iface_get_param(struct iscsi_iface *iface,
476 enum iscsi_param_type param_type,
477 int param, char *buf)
478{
479 struct Scsi_Host *shost = iscsi_iface_to_shost(iface);
480 struct beiscsi_hba *phba = iscsi_host_priv(shost);
481 struct be_cmd_get_def_gateway_resp gateway;
482 int len = -ENOSYS;
483
484 switch (param) {
485 case ISCSI_NET_PARAM_IPV4_ADDR:
486 case ISCSI_NET_PARAM_IPV4_SUBNET:
487 case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
488 case ISCSI_NET_PARAM_IPV6_ADDR:
489 len = be2iscsi_get_if_param(phba, iface, param, buf);
490 break;
491 case ISCSI_NET_PARAM_IFACE_ENABLE:
492 len = sprintf(buf, "enabled");
493 break;
494 case ISCSI_NET_PARAM_IPV4_GW:
495 memset(&gateway, 0, sizeof(gateway));
496 len = mgmt_get_gateway(phba, BE2_IPV4, &gateway);
497 if (!len)
498 len = sprintf(buf, "%pI4\n", &gateway.ip_addr.addr);
499 break;
500 default:
501 len = -ENOSYS;
502 }
503
504 return len;
505}
506
210/** 507/**
211 * beiscsi_ep_get_param - get the iscsi parameter 508 * beiscsi_ep_get_param - get the iscsi parameter
212 * @ep: pointer to iscsi ep 509 * @ep: pointer to iscsi ep
@@ -359,46 +656,21 @@ int beiscsi_get_host_param(struct Scsi_Host *shost,
359 656
360int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) 657int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba)
361{ 658{
362 struct be_cmd_resp_get_mac_addr *resp; 659 struct be_cmd_get_nic_conf_resp resp;
363 struct be_mcc_wrb *wrb;
364 unsigned int tag, wrb_num;
365 unsigned short status, extd_status;
366 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
367 int rc; 660 int rc;
368 661
369 if (phba->read_mac_address) 662 if (strlen(phba->mac_address))
370 return sysfs_format_mac(buf, phba->mac_address, 663 return strlcpy(buf, phba->mac_address, PAGE_SIZE);
371 ETH_ALEN);
372 664
373 tag = be_cmd_get_mac_addr(phba); 665 memset(&resp, 0, sizeof(resp));
374 if (!tag) { 666 rc = mgmt_get_nic_conf(phba, &resp);
375 SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); 667 if (rc)
376 return -EBUSY; 668 return rc;
377 } else
378 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
379 phba->ctrl.mcc_numtag[tag]);
380 669
381 wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; 670 memcpy(phba->mac_address, resp.mac_address, ETH_ALEN);
382 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; 671 return sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
383 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
384 if (status || extd_status) {
385 SE_DEBUG(DBG_LVL_1, "Failed to get be_cmd_get_mac_addr"
386 " status = %d extd_status = %d\n",
387 status, extd_status);
388 free_mcc_tag(&phba->ctrl, tag);
389 return -EAGAIN;
390 }
391 wrb = queue_get_wrb(mccq, wrb_num);
392 free_mcc_tag(&phba->ctrl, tag);
393 resp = embedded_payload(wrb);
394 memcpy(phba->mac_address, resp->mac_address, ETH_ALEN);
395 rc = sysfs_format_mac(buf, phba->mac_address,
396 ETH_ALEN);
397 phba->read_mac_address = 1;
398 return rc;
399} 672}
400 673
401
402/** 674/**
403 * beiscsi_conn_get_stats - get the iscsi stats 675 * beiscsi_conn_get_stats - get the iscsi stats
404 * @cls_conn: pointer to iscsi cls conn 676 * @cls_conn: pointer to iscsi cls conn
@@ -786,11 +1058,21 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
786umode_t be2iscsi_attr_is_visible(int param_type, int param) 1058umode_t be2iscsi_attr_is_visible(int param_type, int param)
787{ 1059{
788 switch (param_type) { 1060 switch (param_type) {
1061 case ISCSI_NET_PARAM:
1062 switch (param) {
1063 case ISCSI_NET_PARAM_IFACE_ENABLE:
1064 case ISCSI_NET_PARAM_IPV4_ADDR:
1065 case ISCSI_NET_PARAM_IPV4_SUBNET:
1066 case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
1067 case ISCSI_NET_PARAM_IPV4_GW:
1068 case ISCSI_NET_PARAM_IPV6_ADDR:
1069 return S_IRUGO;
1070 default:
1071 return 0;
1072 }
789 case ISCSI_HOST_PARAM: 1073 case ISCSI_HOST_PARAM:
790 switch (param) { 1074 switch (param) {
791 case ISCSI_HOST_PARAM_HWADDRESS: 1075 case ISCSI_HOST_PARAM_HWADDRESS:
792 case ISCSI_HOST_PARAM_IPADDRESS:
793 case ISCSI_HOST_PARAM_INITIATOR_NAME:
794 return S_IRUGO; 1076 return S_IRUGO;
795 default: 1077 default:
796 return 0; 1078 return 0;
diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h
index 5c45be134501..8b826fc06bcc 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.h
+++ b/drivers/scsi/be2iscsi/be_iscsi.h
@@ -25,6 +25,21 @@
25 25
26#define BE2_IPV4 0x1 26#define BE2_IPV4 0x1
27#define BE2_IPV6 0x10 27#define BE2_IPV6 0x10
28#define BE2_DHCP_V4 0x05
29
30#define NON_BLOCKING 0x0
31#define BLOCKING 0x1
32
33void beiscsi_create_def_ifaces(struct beiscsi_hba *phba);
34
35void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba);
36
37int be2iscsi_iface_get_param(struct iscsi_iface *iface,
38 enum iscsi_param_type param_type,
39 int param, char *buf);
40
41int be2iscsi_iface_set_param(struct Scsi_Host *shost,
42 void *data, uint32_t count);
28 43
29umode_t be2iscsi_attr_is_visible(int param_type, int param); 44umode_t be2iscsi_attr_is_visible(int param_type, int param);
30 45
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index ff6f851d6fb8..0b1d99c99fd2 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -231,10 +231,10 @@ static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf)
231 case ISCSI_BOOT_TGT_IP_ADDR: 231 case ISCSI_BOOT_TGT_IP_ADDR:
232 if (boot_conn->dest_ipaddr.ip_type == 0x1) 232 if (boot_conn->dest_ipaddr.ip_type == 0x1)
233 rc = sprintf(buf, "%pI4\n", 233 rc = sprintf(buf, "%pI4\n",
234 (char *)&boot_conn->dest_ipaddr.ip_address); 234 (char *)&boot_conn->dest_ipaddr.addr);
235 else 235 else
236 rc = sprintf(str, "%pI6\n", 236 rc = sprintf(str, "%pI6\n",
237 (char *)&boot_conn->dest_ipaddr.ip_address); 237 (char *)&boot_conn->dest_ipaddr.addr);
238 break; 238 break;
239 case ISCSI_BOOT_TGT_PORT: 239 case ISCSI_BOOT_TGT_PORT:
240 rc = sprintf(str, "%d\n", boot_conn->dest_port); 240 rc = sprintf(str, "%d\n", boot_conn->dest_port);
@@ -312,12 +312,8 @@ static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf)
312 rc = sprintf(str, "0\n"); 312 rc = sprintf(str, "0\n");
313 break; 313 break;
314 case ISCSI_BOOT_ETH_MAC: 314 case ISCSI_BOOT_ETH_MAC:
315 rc = beiscsi_get_macaddr(buf, phba); 315 rc = beiscsi_get_macaddr(str, phba);
316 if (rc < 0) { 316 break;
317 SE_DEBUG(DBG_LVL_1, "beiscsi_get_macaddr Failed\n");
318 return rc;
319 }
320 break;
321 default: 317 default:
322 rc = -ENOSYS; 318 rc = -ENOSYS;
323 break; 319 break;
@@ -438,6 +434,7 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
438 phba->shost = shost; 434 phba->shost = shost;
439 phba->pcidev = pci_dev_get(pcidev); 435 phba->pcidev = pci_dev_get(pcidev);
440 pci_set_drvdata(pcidev, phba); 436 pci_set_drvdata(pcidev, phba);
437 phba->interface_handle = 0xFFFFFFFF;
441 438
442 if (iscsi_host_add(shost, &phba->pcidev->dev)) 439 if (iscsi_host_add(shost, &phba->pcidev->dev))
443 goto free_devices; 440 goto free_devices;
@@ -3471,8 +3468,8 @@ static void hwi_disable_intr(struct beiscsi_hba *phba)
3471 3468
3472static int beiscsi_get_boot_info(struct beiscsi_hba *phba) 3469static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
3473{ 3470{
3474 struct be_cmd_resp_get_boot_target *boot_resp; 3471 struct be_cmd_get_boot_target_resp *boot_resp;
3475 struct be_cmd_resp_get_session *session_resp; 3472 struct be_cmd_get_session_resp *session_resp;
3476 struct be_mcc_wrb *wrb; 3473 struct be_mcc_wrb *wrb;
3477 struct be_dma_mem nonemb_cmd; 3474 struct be_dma_mem nonemb_cmd;
3478 unsigned int tag, wrb_num; 3475 unsigned int tag, wrb_num;
@@ -3480,9 +3477,9 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
3480 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 3477 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
3481 int ret = -ENOMEM; 3478 int ret = -ENOMEM;
3482 3479
3483 tag = beiscsi_get_boot_target(phba); 3480 tag = mgmt_get_boot_target(phba);
3484 if (!tag) { 3481 if (!tag) {
3485 SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); 3482 SE_DEBUG(DBG_LVL_1, "beiscsi_get_boot_info Failed\n");
3486 return -EAGAIN; 3483 return -EAGAIN;
3487 } else 3484 } else
3488 wait_event_interruptible(phba->ctrl.mcc_wait[tag], 3485 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
@@ -3492,7 +3489,7 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
3492 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; 3489 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
3493 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; 3490 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
3494 if (status || extd_status) { 3491 if (status || extd_status) {
3495 SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed" 3492 SE_DEBUG(DBG_LVL_1, "beiscsi_get_boot_info Failed"
3496 " status = %d extd_status = %d\n", 3493 " status = %d extd_status = %d\n",
3497 status, extd_status); 3494 status, extd_status);
3498 free_mcc_tag(&phba->ctrl, tag); 3495 free_mcc_tag(&phba->ctrl, tag);
@@ -3518,8 +3515,8 @@ static int beiscsi_get_boot_info(struct beiscsi_hba *phba)
3518 } 3515 }
3519 3516
3520 memset(nonemb_cmd.va, 0, sizeof(*session_resp)); 3517 memset(nonemb_cmd.va, 0, sizeof(*session_resp));
3521 tag = beiscsi_get_session_info(phba, 3518 tag = mgmt_get_session_info(phba, boot_resp->boot_session_handle,
3522 boot_resp->boot_session_handle, &nonemb_cmd); 3519 &nonemb_cmd);
3523 if (!tag) { 3520 if (!tag) {
3524 SE_DEBUG(DBG_LVL_1, "beiscsi_get_session_info" 3521 SE_DEBUG(DBG_LVL_1, "beiscsi_get_session_info"
3525 " Failed\n"); 3522 " Failed\n");
@@ -4267,6 +4264,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
4267 return; 4264 return;
4268 } 4265 }
4269 4266
4267 beiscsi_destroy_def_ifaces(phba);
4270 beiscsi_quiesce(phba); 4268 beiscsi_quiesce(phba);
4271 iscsi_boot_destroy_kset(phba->boot_kset); 4269 iscsi_boot_destroy_kset(phba->boot_kset);
4272 iscsi_host_remove(phba->shost); 4270 iscsi_host_remove(phba->shost);
@@ -4453,8 +4451,9 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
4453 * iscsi boot. 4451 * iscsi boot.
4454 */ 4452 */
4455 shost_printk(KERN_ERR, phba->shost, "Could not set up " 4453 shost_printk(KERN_ERR, phba->shost, "Could not set up "
4456 "iSCSI boot info."); 4454 "iSCSI boot info.\n");
4457 4455
4456 beiscsi_create_def_ifaces(phba);
4458 SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n"); 4457 SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n");
4459 return 0; 4458 return 0;
4460 4459
@@ -4505,6 +4504,8 @@ struct iscsi_transport beiscsi_iscsi_transport = {
4505 .bind_conn = beiscsi_conn_bind, 4504 .bind_conn = beiscsi_conn_bind,
4506 .destroy_conn = iscsi_conn_teardown, 4505 .destroy_conn = iscsi_conn_teardown,
4507 .attr_is_visible = be2iscsi_attr_is_visible, 4506 .attr_is_visible = be2iscsi_attr_is_visible,
4507 .set_iface_param = be2iscsi_iface_set_param,
4508 .get_iface_param = be2iscsi_iface_get_param,
4508 .set_param = beiscsi_set_param, 4509 .set_param = beiscsi_set_param,
4509 .get_conn_param = iscsi_conn_get_param, 4510 .get_conn_param = iscsi_conn_get_param,
4510 .get_session_param = iscsi_session_get_param, 4511 .get_session_param = iscsi_session_get_param,
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 13e3bef1d324..40fea6ec879c 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -316,6 +316,8 @@ struct beiscsi_hba {
316 struct iscsi_endpoint **ep_array; 316 struct iscsi_endpoint **ep_array;
317 struct iscsi_boot_kset *boot_kset; 317 struct iscsi_boot_kset *boot_kset;
318 struct Scsi_Host *shost; 318 struct Scsi_Host *shost;
319 struct iscsi_iface *ipv4_iface;
320 struct iscsi_iface *ipv6_iface;
319 struct { 321 struct {
320 /** 322 /**
321 * group together since they are used most frequently 323 * group together since they are used most frequently
@@ -345,7 +347,7 @@ struct beiscsi_hba {
345 struct work_struct work_cqs; /* The work being queued */ 347 struct work_struct work_cqs; /* The work being queued */
346 struct be_ctrl_info ctrl; 348 struct be_ctrl_info ctrl;
347 unsigned int generation; 349 unsigned int generation;
348 unsigned int read_mac_address; 350 unsigned int interface_handle;
349 struct mgmt_session_info boot_sess; 351 struct mgmt_session_info boot_sess;
350 struct invalidate_command_table inv_tbl[128]; 352 struct invalidate_command_table inv_tbl[128];
351 353
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index ccc3852a7f30..e6cb10d2e74e 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -23,11 +23,11 @@
23#include "be_mgmt.h" 23#include "be_mgmt.h"
24#include "be_iscsi.h" 24#include "be_iscsi.h"
25 25
26unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba) 26unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba)
27{ 27{
28 struct be_ctrl_info *ctrl = &phba->ctrl; 28 struct be_ctrl_info *ctrl = &phba->ctrl;
29 struct be_mcc_wrb *wrb; 29 struct be_mcc_wrb *wrb;
30 struct be_cmd_req_get_mac_addr *req; 30 struct be_cmd_get_boot_target_req *req;
31 unsigned int tag = 0; 31 unsigned int tag = 0;
32 32
33 SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n"); 33 SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n");
@@ -44,22 +44,22 @@ unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba)
44 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 44 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
45 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, 45 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
46 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET, 46 OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET,
47 sizeof(*req)); 47 sizeof(struct be_cmd_get_boot_target_resp));
48 48
49 be_mcc_notify(phba); 49 be_mcc_notify(phba);
50 spin_unlock(&ctrl->mbox_lock); 50 spin_unlock(&ctrl->mbox_lock);
51 return tag; 51 return tag;
52} 52}
53 53
54unsigned int beiscsi_get_session_info(struct beiscsi_hba *phba, 54unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
55 u32 boot_session_handle, 55 u32 boot_session_handle,
56 struct be_dma_mem *nonemb_cmd) 56 struct be_dma_mem *nonemb_cmd)
57{ 57{
58 struct be_ctrl_info *ctrl = &phba->ctrl; 58 struct be_ctrl_info *ctrl = &phba->ctrl;
59 struct be_mcc_wrb *wrb; 59 struct be_mcc_wrb *wrb;
60 unsigned int tag = 0; 60 unsigned int tag = 0;
61 struct be_cmd_req_get_session *req; 61 struct be_cmd_get_session_req *req;
62 struct be_cmd_resp_get_session *resp; 62 struct be_cmd_get_session_resp *resp;
63 struct be_sge *sge; 63 struct be_sge *sge;
64 64
65 SE_DEBUG(DBG_LVL_8, "In beiscsi_get_session_info\n"); 65 SE_DEBUG(DBG_LVL_8, "In beiscsi_get_session_info\n");
@@ -396,7 +396,6 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
396 struct sockaddr *dst_addr, 396 struct sockaddr *dst_addr,
397 struct beiscsi_endpoint *beiscsi_ep, 397 struct beiscsi_endpoint *beiscsi_ep,
398 struct be_dma_mem *nonemb_cmd) 398 struct be_dma_mem *nonemb_cmd)
399
400{ 399{
401 struct hwi_controller *phwi_ctrlr; 400 struct hwi_controller *phwi_ctrlr;
402 struct hwi_context_memory *phwi_context; 401 struct hwi_context_memory *phwi_context;
@@ -442,17 +441,17 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
442 if (dst_addr->sa_family == PF_INET) { 441 if (dst_addr->sa_family == PF_INET) {
443 __be32 s_addr = daddr_in->sin_addr.s_addr; 442 __be32 s_addr = daddr_in->sin_addr.s_addr;
444 req->ip_address.ip_type = BE2_IPV4; 443 req->ip_address.ip_type = BE2_IPV4;
445 req->ip_address.ip_address[0] = s_addr & 0x000000ff; 444 req->ip_address.addr[0] = s_addr & 0x000000ff;
446 req->ip_address.ip_address[1] = (s_addr & 0x0000ff00) >> 8; 445 req->ip_address.addr[1] = (s_addr & 0x0000ff00) >> 8;
447 req->ip_address.ip_address[2] = (s_addr & 0x00ff0000) >> 16; 446 req->ip_address.addr[2] = (s_addr & 0x00ff0000) >> 16;
448 req->ip_address.ip_address[3] = (s_addr & 0xff000000) >> 24; 447 req->ip_address.addr[3] = (s_addr & 0xff000000) >> 24;
449 req->tcp_port = ntohs(daddr_in->sin_port); 448 req->tcp_port = ntohs(daddr_in->sin_port);
450 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr; 449 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
451 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port); 450 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
452 beiscsi_ep->ip_type = BE2_IPV4; 451 beiscsi_ep->ip_type = BE2_IPV4;
453 } else if (dst_addr->sa_family == PF_INET6) { 452 } else if (dst_addr->sa_family == PF_INET6) {
454 req->ip_address.ip_type = BE2_IPV6; 453 req->ip_address.ip_type = BE2_IPV6;
455 memcpy(&req->ip_address.ip_address, 454 memcpy(&req->ip_address.addr,
456 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16); 455 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
457 req->tcp_port = ntohs(daddr_in6->sin6_port); 456 req->tcp_port = ntohs(daddr_in6->sin6_port);
458 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port); 457 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
@@ -487,34 +486,392 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
487 return tag; 486 return tag;
488} 487}
489 488
490unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba) 489unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
491{ 490{
492 struct be_ctrl_info *ctrl = &phba->ctrl; 491 struct be_ctrl_info *ctrl = &phba->ctrl;
493 struct be_mcc_wrb *wrb; 492 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
494 struct be_cmd_req_get_mac_addr *req; 493 struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
495 unsigned int tag = 0; 494 struct be_cmd_get_all_if_id_req *pbe_allid = req;
495 int status = 0;
496
497 memset(wrb, 0, sizeof(*wrb));
498
499 spin_lock(&ctrl->mbox_lock);
500
501 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
502 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
503 OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID,
504 sizeof(*req));
505 status = be_mbox_notify(ctrl);
506 if (!status)
507 phba->interface_handle = pbe_allid->if_hndl_list[0];
508 else {
509 shost_printk(KERN_WARNING, phba->shost,
510 "Failed in mgmt_get_all_if_id\n");
511 }
512 spin_unlock(&ctrl->mbox_lock);
513
514 return status;
515}
516
517static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
518 struct be_dma_mem *nonemb_cmd, void *resp_buf,
519 int resp_buf_len)
520{
521 struct be_ctrl_info *ctrl = &phba->ctrl;
522 struct be_mcc_wrb *wrb = wrb_from_mccq(phba);
523 unsigned short status, extd_status;
524 struct be_sge *sge;
525 unsigned int tag;
526 int rc = 0;
496 527
497 SE_DEBUG(DBG_LVL_8, "In be_cmd_get_mac_addr\n");
498 spin_lock(&ctrl->mbox_lock); 528 spin_lock(&ctrl->mbox_lock);
499 tag = alloc_mcc_tag(phba); 529 tag = alloc_mcc_tag(phba);
500 if (!tag) { 530 if (!tag) {
501 spin_unlock(&ctrl->mbox_lock); 531 spin_unlock(&ctrl->mbox_lock);
502 return tag; 532 rc = -ENOMEM;
533 goto free_cmd;
503 } 534 }
504 535 memset(wrb, 0, sizeof(*wrb));
505 wrb = wrb_from_mccq(phba);
506 req = embedded_payload(wrb);
507 wrb->tag0 |= tag; 536 wrb->tag0 |= tag;
508 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 537 sge = nonembedded_sgl(wrb);
509 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI, 538
510 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG, 539 be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1);
511 sizeof(*req)); 540 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma));
541 sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
542 sge->len = cpu_to_le32(nonemb_cmd->size);
512 543
513 be_mcc_notify(phba); 544 be_mcc_notify(phba);
514 spin_unlock(&ctrl->mbox_lock); 545 spin_unlock(&ctrl->mbox_lock);
515 return tag; 546
547 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
548 phba->ctrl.mcc_numtag[tag]);
549
550 extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
551 status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
552 if (status || extd_status) {
553 SE_DEBUG(DBG_LVL_1,
554 "mgmt_exec_nonemb_cmd Failed status = %d"
555 "extd_status = %d\n", status, extd_status);
556 rc = -EIO;
557 goto free_tag;
558 }
559
560 if (resp_buf)
561 memcpy(resp_buf, nonemb_cmd->va, resp_buf_len);
562
563free_tag:
564 free_mcc_tag(&phba->ctrl, tag);
565free_cmd:
566 pci_free_consistent(ctrl->pdev, nonemb_cmd->size,
567 nonemb_cmd->va, nonemb_cmd->dma);
568 return rc;
569}
570
571static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd,
572 int iscsi_cmd, int size)
573{
574 cmd->va = pci_alloc_consistent(phba->ctrl.pdev, sizeof(size),
575 &cmd->dma);
576 if (!cmd->va) {
577 SE_DEBUG(DBG_LVL_1, "Failed to allocate memory for if info\n");
578 return -ENOMEM;
579 }
580 memset(cmd->va, 0, sizeof(size));
581 cmd->size = size;
582 be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size);
583 return 0;
516} 584}
517 585
586static int
587mgmt_static_ip_modify(struct beiscsi_hba *phba,
588 struct be_cmd_get_if_info_resp *if_info,
589 struct iscsi_iface_param_info *ip_param,
590 struct iscsi_iface_param_info *subnet_param,
591 uint32_t ip_action)
592{
593 struct be_cmd_set_ip_addr_req *req;
594 struct be_dma_mem nonemb_cmd;
595 uint32_t ip_type;
596 int rc;
597
598 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
599 OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR,
600 sizeof(*req));
601 if (rc)
602 return rc;
603
604 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
605 BE2_IPV6 : BE2_IPV4 ;
606
607 req = nonemb_cmd.va;
608 req->ip_params.record_entry_count = 1;
609 req->ip_params.ip_record.action = ip_action;
610 req->ip_params.ip_record.interface_hndl =
611 phba->interface_handle;
612 req->ip_params.ip_record.ip_addr.size_of_structure =
613 sizeof(struct be_ip_addr_subnet_format);
614 req->ip_params.ip_record.ip_addr.ip_type = ip_type;
615
616 if (ip_action == IP_ACTION_ADD) {
617 memcpy(req->ip_params.ip_record.ip_addr.addr, ip_param->value,
618 ip_param->len);
619
620 if (subnet_param)
621 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
622 subnet_param->value, subnet_param->len);
623 } else {
624 memcpy(req->ip_params.ip_record.ip_addr.addr,
625 if_info->ip_addr.addr, ip_param->len);
626
627 memcpy(req->ip_params.ip_record.ip_addr.subnet_mask,
628 if_info->ip_addr.subnet_mask, ip_param->len);
629 }
630
631 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
632 if (rc < 0)
633 shost_printk(KERN_WARNING, phba->shost,
634 "Failed to Modify existing IP Address\n");
635 return rc;
636}
637
638static int mgmt_modify_gateway(struct beiscsi_hba *phba, uint8_t *gt_addr,
639 uint32_t gtway_action, uint32_t param_len)
640{
641 struct be_cmd_set_def_gateway_req *req;
642 struct be_dma_mem nonemb_cmd;
643 int rt_val;
644
645
646 rt_val = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
647 OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY,
648 sizeof(*req));
649 if (rt_val)
650 return rt_val;
651
652 req = nonemb_cmd.va;
653 req->action = gtway_action;
654 req->ip_addr.ip_type = BE2_IPV4;
655
656 memcpy(req->ip_addr.addr, gt_addr, param_len);
657
658 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
659}
660
661int mgmt_set_ip(struct beiscsi_hba *phba,
662 struct iscsi_iface_param_info *ip_param,
663 struct iscsi_iface_param_info *subnet_param,
664 uint32_t boot_proto)
665{
666 struct be_cmd_get_def_gateway_resp gtway_addr_set;
667 struct be_cmd_get_if_info_resp if_info;
668 struct be_cmd_set_dhcp_req *dhcpreq;
669 struct be_cmd_rel_dhcp_req *reldhcp;
670 struct be_dma_mem nonemb_cmd;
671 uint8_t *gtway_addr;
672 uint32_t ip_type;
673 int rc;
674
675 if (mgmt_get_all_if_id(phba))
676 return -EIO;
677
678 memset(&if_info, 0, sizeof(if_info));
679 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
680 BE2_IPV6 : BE2_IPV4 ;
681
682 rc = mgmt_get_if_info(phba, ip_type, &if_info);
683 if (rc)
684 return rc;
685
686 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
687 if (if_info.dhcp_state) {
688 shost_printk(KERN_WARNING, phba->shost,
689 "DHCP Already Enabled\n");
690 return 0;
691 }
692 /* The ip_param->len is 1 in DHCP case. Setting
693 proper IP len as this it is used while
694 freeing the Static IP.
695 */
696 ip_param->len = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
697 IP_V6_LEN : IP_V4_LEN;
698
699 } else {
700 if (if_info.dhcp_state) {
701
702 memset(&if_info, 0, sizeof(if_info));
703 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
704 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
705 sizeof(*reldhcp));
706
707 if (rc)
708 return rc;
709
710 reldhcp = nonemb_cmd.va;
711 reldhcp->interface_hndl = phba->interface_handle;
712 reldhcp->ip_type = ip_type;
713
714 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
715 if (rc < 0) {
716 shost_printk(KERN_WARNING, phba->shost,
717 "Failed to Delete existing dhcp\n");
718 return rc;
719 }
720 }
721 }
722
723 /* Delete the Static IP Set */
724 if (if_info.ip_addr.addr[0]) {
725 rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL,
726 IP_ACTION_DEL);
727 if (rc)
728 return rc;
729 }
730
731 /* Delete the Gateway settings if mode change is to DHCP */
732 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
733 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
734 rc = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
735 if (rc) {
736 shost_printk(KERN_WARNING, phba->shost,
737 "Failed to Get Gateway Addr\n");
738 return rc;
739 }
740
741 if (gtway_addr_set.ip_addr.addr[0]) {
742 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
743 rc = mgmt_modify_gateway(phba, gtway_addr,
744 IP_ACTION_DEL, IP_V4_LEN);
745
746 if (rc) {
747 shost_printk(KERN_WARNING, phba->shost,
748 "Failed to clear Gateway Addr Set\n");
749 return rc;
750 }
751 }
752 }
753
754 /* Set Adapter to DHCP/Static Mode */
755 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
756 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
757 OPCODE_COMMON_ISCSI_NTWK_CONFIG_STATELESS_IP_ADDR,
758 sizeof(*dhcpreq));
759 if (rc)
760 return rc;
761
762 dhcpreq = nonemb_cmd.va;
763 dhcpreq->flags = BLOCKING;
764 dhcpreq->retry_count = 1;
765 dhcpreq->interface_hndl = phba->interface_handle;
766 dhcpreq->ip_type = BE2_DHCP_V4;
767
768 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
769 } else {
770 return mgmt_static_ip_modify(phba, &if_info, ip_param,
771 subnet_param, IP_ACTION_ADD);
772 }
773
774 return rc;
775}
776
777int mgmt_set_gateway(struct beiscsi_hba *phba,
778 struct iscsi_iface_param_info *gateway_param)
779{
780 struct be_cmd_get_def_gateway_resp gtway_addr_set;
781 uint8_t *gtway_addr;
782 int rt_val;
783
784 memset(&gtway_addr_set, 0, sizeof(gtway_addr_set));
785 rt_val = mgmt_get_gateway(phba, BE2_IPV4, &gtway_addr_set);
786 if (rt_val) {
787 shost_printk(KERN_WARNING, phba->shost,
788 "Failed to Get Gateway Addr\n");
789 return rt_val;
790 }
791
792 if (gtway_addr_set.ip_addr.addr[0]) {
793 gtway_addr = (uint8_t *)&gtway_addr_set.ip_addr.addr;
794 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_DEL,
795 gateway_param->len);
796 if (rt_val) {
797 shost_printk(KERN_WARNING, phba->shost,
798 "Failed to clear Gateway Addr Set\n");
799 return rt_val;
800 }
801 }
802
803 gtway_addr = (uint8_t *)&gateway_param->value;
804 rt_val = mgmt_modify_gateway(phba, gtway_addr, IP_ACTION_ADD,
805 gateway_param->len);
806
807 if (rt_val)
808 shost_printk(KERN_WARNING, phba->shost,
809 "Failed to Set Gateway Addr\n");
810
811 return rt_val;
812}
813
814int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
815 struct be_cmd_get_def_gateway_resp *gateway)
816{
817 struct be_cmd_get_def_gateway_req *req;
818 struct be_dma_mem nonemb_cmd;
819 int rc;
820
821 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
822 OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY,
823 sizeof(*gateway));
824 if (rc)
825 return rc;
826
827 req = nonemb_cmd.va;
828 req->ip_type = ip_type;
829
830 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, gateway,
831 sizeof(*gateway));
832}
833
834int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
835 struct be_cmd_get_if_info_resp *if_info)
836{
837 struct be_cmd_get_if_info_req *req;
838 struct be_dma_mem nonemb_cmd;
839 int rc;
840
841 if (mgmt_get_all_if_id(phba))
842 return -EIO;
843
844 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
845 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
846 sizeof(*if_info));
847 if (rc)
848 return rc;
849
850 req = nonemb_cmd.va;
851 req->interface_hndl = phba->interface_handle;
852 req->ip_type = ip_type;
853
854 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info,
855 sizeof(*if_info));
856}
857
858int mgmt_get_nic_conf(struct beiscsi_hba *phba,
859 struct be_cmd_get_nic_conf_resp *nic)
860{
861 struct be_dma_mem nonemb_cmd;
862 int rc;
863
864 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
865 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
866 sizeof(*nic));
867 if (rc)
868 return rc;
869
870 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, nic, sizeof(*nic));
871}
872
873
874
518unsigned int be_cmd_get_initname(struct beiscsi_hba *phba) 875unsigned int be_cmd_get_initname(struct beiscsi_hba *phba)
519{ 876{
520 unsigned int tag = 0; 877 unsigned int tag = 0;
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 03400f3f666f..5c2e37693ca8 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -20,12 +20,16 @@
20#ifndef _BEISCSI_MGMT_ 20#ifndef _BEISCSI_MGMT_
21#define _BEISCSI_MGMT_ 21#define _BEISCSI_MGMT_
22 22
23#include <linux/types.h>
24#include <linux/list.h>
25#include <scsi/scsi_bsg_iscsi.h> 23#include <scsi/scsi_bsg_iscsi.h>
26#include "be_iscsi.h" 24#include "be_iscsi.h"
27#include "be_main.h" 25#include "be_main.h"
28 26
27#define IP_ACTION_ADD 0x01
28#define IP_ACTION_DEL 0x02
29
30#define IP_V6_LEN 16
31#define IP_V4_LEN 4
32
29/** 33/**
30 * Pseudo amap definition in which each bit of the actual structure is defined 34 * Pseudo amap definition in which each bit of the actual structure is defined
31 * as a byte: used to calculate offset/shift/mask of each field 35 * as a byte: used to calculate offset/shift/mask of each field
@@ -263,4 +267,27 @@ unsigned int mgmt_invalidate_connection(struct beiscsi_hba *phba,
263 unsigned short issue_reset, 267 unsigned short issue_reset,
264 unsigned short savecfg_flag); 268 unsigned short savecfg_flag);
265 269
270int mgmt_set_ip(struct beiscsi_hba *phba,
271 struct iscsi_iface_param_info *ip_param,
272 struct iscsi_iface_param_info *subnet_param,
273 uint32_t boot_proto);
274
275unsigned int mgmt_get_boot_target(struct beiscsi_hba *phba);
276
277unsigned int mgmt_get_session_info(struct beiscsi_hba *phba,
278 u32 boot_session_handle,
279 struct be_dma_mem *nonemb_cmd);
280
281int mgmt_get_nic_conf(struct beiscsi_hba *phba,
282 struct be_cmd_get_nic_conf_resp *mac);
283
284int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
285 struct be_cmd_get_if_info_resp *if_info);
286
287int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
288 struct be_cmd_get_def_gateway_resp *gateway);
289
290int mgmt_set_gateway(struct beiscsi_hba *phba,
291 struct iscsi_iface_param_info *gateway_param);
292
266#endif 293#endif