1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright (c) 2016 by Delphix. All rights reserved. 25 */ 26 27 /* 28 * SunOS 5.x Multithreaded STREAMS DLPI FCIP Module 29 * This is a pseudo driver module to handle encapsulation of IP and ARP 30 * datagrams over FibreChannel interfaces. FCIP is a cloneable STREAMS 31 * driver module which interfaces with IP/ARP using DLPI. This module 32 * is a Style-2 DLS provider. 33 * 34 * The implementation of this module is based on RFC 2625 which gives 35 * details on the encapsulation of IP/ARP data over FibreChannel. 36 * The fcip module needs to resolve an IP address to a port address before 37 * sending data to a destination port. A FC device port has 2 addresses 38 * associated with it: A 8 byte World Wide unique Port Name and a 3 byte 39 * volatile Port number or Port_ID. 40 * 41 * The mapping between a IP address and the World Wide Port Name is handled 42 * by the ARP layer since the IP over FC draft requires the MAC address to 43 * be the least significant six bytes of the WorldWide Port Names. The 44 * fcip module however needs to identify the destination port uniquely when 45 * the destination FC device has multiple FC ports. 46 * 47 * The FC layer mapping between the World Wide Port Name and the Port_ID 48 * will be handled through the use of a fabric name server or through the 49 * use of the FARP ELS command as described in the draft. Since the Port_IDs 50 * are volatile, the mapping between the World Wide Port Name and Port_IDs 51 * must be maintained and validated before use each time a datagram 52 * needs to be sent to the destination ports. The FC transport module 53 * informs the fcip module of all changes to states of ports on the 54 * fabric through registered callbacks. This enables the fcip module 55 * to maintain the WW_PN to Port_ID mappings current. 56 * 57 * For details on how this module interfaces with the FibreChannel Transport 58 * modules, refer to PSARC/1997/385. Chapter 3 of the FibreChannel Transport 59 * Programming guide details the APIs between ULPs and the Transport. 60 * 61 * Now for some Caveats: 62 * 63 * RFC 2625 requires that a FibreChannel Port name (the Port WWN) have 64 * the NAA bits set to '0001' indicating a IEEE 48bit address which 65 * corresponds to a ULA (Universal LAN MAC address). But with FibreChannel 66 * adapters containing 2 or more ports, IEEE naming cannot identify the 67 * ports on an adapter uniquely so we will in the first implementation 68 * be operating only on Port 0 of each adapter. 69 */ 70 71 #include <sys/types.h> 72 #include <sys/errno.h> 73 #include <sys/debug.h> 74 #include <sys/time.h> 75 #include <sys/sysmacros.h> 76 #include <sys/systm.h> 77 #include <sys/user.h> 78 #include <sys/stropts.h> 79 #include <sys/stream.h> 80 #include <sys/strlog.h> 81 #include <sys/strsubr.h> 82 #include <sys/cmn_err.h> 83 #include <sys/cpu.h> 84 #include <sys/kmem.h> 85 #include <sys/conf.h> 86 #include <sys/ddi.h> 87 #include <sys/sunddi.h> 88 #include <sys/ksynch.h> 89 #include <sys/stat.h> 90 #include <sys/kstat.h> 91 #include <sys/vtrace.h> 92 #include <sys/strsun.h> 93 #include <sys/varargs.h> 94 #include <sys/modctl.h> 95 #include <sys/thread.h> 96 #include <sys/var.h> 97 #include <sys/proc.h> 98 #include <inet/common.h> 99 #include <netinet/ip6.h> 100 #include <inet/ip.h> 101 #include <inet/arp.h> 102 #include <inet/mi.h> 103 #include <inet/nd.h> 104 #include <sys/dlpi.h> 105 #include <sys/ethernet.h> 106 #include <sys/file.h> 107 #include <sys/syslog.h> 108 #include <sys/disp.h> 109 #include <sys/taskq.h> 110 111 /* 112 * Leadville includes 113 */ 114 115 #include <sys/fibre-channel/fc.h> 116 #include <sys/fibre-channel/impl/fc_ulpif.h> 117 #include <sys/fibre-channel/ulp/fcip.h> 118 119 /* 120 * TNF Probe/trace facility include 121 */ 122 #if defined(lint) || defined(FCIP_TNF_ENABLED) 123 #include <sys/tnf_probe.h> 124 #endif 125 126 #define FCIP_ESBALLOC 127 128 /* 129 * Function prototypes 130 */ 131 132 /* standard loadable modules entry points */ 133 static int fcip_attach(dev_info_t *, ddi_attach_cmd_t); 134 static int fcip_detach(dev_info_t *, ddi_detach_cmd_t); 135 static void fcip_dodetach(struct fcipstr *slp); 136 static int fcip_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, 137 void *arg, void **result); 138 139 140 /* streams specific */ 141 static void fcip_setipq(struct fcip *fptr); 142 static int fcip_wput(queue_t *, mblk_t *); 143 static int fcip_wsrv(queue_t *); 144 static void fcip_proto(queue_t *, mblk_t *); 145 static void fcip_ioctl(queue_t *, mblk_t *); 146 static int fcip_open(queue_t *wq, dev_t *devp, int flag, 147 int sflag, cred_t *credp); 148 static int fcip_close(queue_t *rq, int flag, cred_t *credp); 149 static int fcip_start(queue_t *wq, mblk_t *mp, struct fcip *fptr, 150 struct fcip_dest *fdestp, int flags); 151 static void fcip_sendup(struct fcip *fptr, mblk_t *mp, 152 struct fcipstr *(*acceptfunc)()); 153 static struct fcipstr *fcip_accept(struct fcipstr *slp, struct fcip *fptr, 154 int type, la_wwn_t *dhostp); 155 static mblk_t *fcip_addudind(struct fcip *fptr, mblk_t *mp, 156 fcph_network_hdr_t *nhdr, int type); 157 static int fcip_setup_mac_addr(struct fcip *fptr); 158 static void fcip_kstat_init(struct fcip *fptr); 159 static int fcip_stat_update(kstat_t *, int); 160 161 162 /* dlpi specific */ 163 static void fcip_spareq(queue_t *wq, mblk_t *mp); 164 static void fcip_pareq(queue_t *wq, mblk_t *mp); 165 static void fcip_ubreq(queue_t *wq, mblk_t *mp); 166 static void fcip_breq(queue_t *wq, mblk_t *mp); 167 static void fcip_dreq(queue_t *wq, mblk_t *mp); 168 static void fcip_areq(queue_t *wq, mblk_t *mp); 169 static void fcip_udreq(queue_t *wq, mblk_t *mp); 170 static void fcip_ireq(queue_t *wq, mblk_t *mp); 171 static void fcip_dl_ioc_hdr_info(queue_t *wq, mblk_t *mp); 172 173 174 /* solaris sundry, DR/CPR etc */ 175 static int fcip_cache_constructor(void *buf, void *arg, int size); 176 static void fcip_cache_destructor(void *buf, void *size); 177 static int fcip_handle_suspend(fcip_port_info_t *fport, fc_detach_cmd_t cmd); 178 static int fcip_handle_resume(fcip_port_info_t *fport, 179 fc_ulp_port_info_t *port_info, fc_attach_cmd_t cmd); 180 static fcip_port_info_t *fcip_softstate_free(fcip_port_info_t *fport); 181 static int fcip_port_attach_handler(struct fcip *fptr); 182 183 184 /* 185 * ulp - transport interface function prototypes 186 */ 187 static int fcip_port_attach(opaque_t ulp_handle, fc_ulp_port_info_t *, 188 fc_attach_cmd_t cmd, uint32_t sid); 189 static int fcip_port_detach(opaque_t ulp_handle, fc_ulp_port_info_t *, 190 fc_detach_cmd_t cmd); 191 static int fcip_port_ioctl(opaque_t ulp_handle, opaque_t port_handle, 192 dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, int *rval, 193 uint32_t claimed); 194 static void fcip_statec_cb(opaque_t ulp_handle, opaque_t phandle, 195 uint32_t port_state, uint32_t port_top, fc_portmap_t changelist[], 196 uint32_t listlen, uint32_t sid); 197 static int fcip_els_cb(opaque_t ulp_handle, opaque_t phandle, 198 fc_unsol_buf_t *buf, uint32_t claimed); 199 static int fcip_data_cb(opaque_t ulp_handle, opaque_t phandle, 200 fc_unsol_buf_t *payload, uint32_t claimed); 201 202 203 /* Routing table specific */ 204 static void fcip_handle_topology(struct fcip *fptr); 205 static int fcip_init_port(struct fcip *fptr); 206 struct fcip_routing_table *fcip_lookup_rtable(struct fcip *fptr, 207 la_wwn_t *pwwn, int matchflag); 208 static void fcip_rt_update(struct fcip *fptr, fc_portmap_t *devlist, 209 uint32_t listlen); 210 static void fcip_rt_flush(struct fcip *fptr); 211 static void fcip_rte_remove_deferred(void *arg); 212 static int fcip_do_plogi(struct fcip *fptr, struct fcip_routing_table *frp); 213 214 215 /* dest table specific */ 216 static struct fcip_dest *fcip_get_dest(struct fcip *fptr, 217 la_wwn_t *dlphys); 218 static struct fcip_dest *fcip_add_dest(struct fcip *fptr, 219 struct fcip_routing_table *frp); 220 static int fcip_dest_add_broadcast_entry(struct fcip *fptr, int new_flag); 221 static uint32_t fcip_get_broadcast_did(struct fcip *fptr); 222 static void fcip_cleanup_dest(struct fcip *fptr); 223 224 225 /* helper functions */ 226 static fcip_port_info_t *fcip_get_port(opaque_t phandle); 227 static int fcip_wwn_compare(la_wwn_t *wwn1, la_wwn_t *wwn2, int flag); 228 static void fcip_ether_to_str(struct ether_addr *e, caddr_t s); 229 static int fcip_port_get_num_pkts(struct fcip *fptr); 230 static int fcip_check_port_busy(struct fcip *fptr); 231 static void fcip_check_remove_minor_node(void); 232 static int fcip_set_wwn(la_wwn_t *pwwn); 233 static int fcip_plogi_in_progress(struct fcip *fptr); 234 static int fcip_check_port_exists(struct fcip *fptr); 235 static int fcip_is_supported_fc_topology(int fc_topology); 236 237 238 /* pkt specific */ 239 static fcip_pkt_t *fcip_pkt_alloc(struct fcip *fptr, mblk_t *bp, 240 int flags, int datalen); 241 static void fcip_pkt_free(struct fcip_pkt *fcip_pkt, int flags); 242 static fcip_pkt_t *fcip_ipkt_alloc(struct fcip *fptr, int cmdlen, 243 int resplen, opaque_t pd, int flags); 244 static void fcip_ipkt_free(fcip_pkt_t *fcip_pkt); 245 static void fcip_ipkt_callback(fc_packet_t *fc_pkt); 246 static void fcip_free_pkt_dma(fcip_pkt_t *fcip_pkt); 247 static void fcip_pkt_callback(fc_packet_t *fc_pkt); 248 static void fcip_init_unicast_pkt(fcip_pkt_t *fcip_pkt, fc_portid_t sid, 249 fc_portid_t did, void (*comp) ()); 250 static int fcip_transport(fcip_pkt_t *fcip_pkt); 251 static void fcip_pkt_timeout(void *arg); 252 static void fcip_timeout(void *arg); 253 static void fcip_fdestp_enqueue_pkt(struct fcip_dest *fdestp, 254 fcip_pkt_t *fcip_pkt); 255 static int fcip_fdestp_dequeue_pkt(struct fcip_dest *fdestp, 256 fcip_pkt_t *fcip_pkt); 257 static int fcip_sendup_constructor(void *buf, void *arg, int flags); 258 static void fcip_sendup_thr(void *arg); 259 static int fcip_sendup_alloc_enque(struct fcip *ftpr, mblk_t *mp, 260 struct fcipstr *(*f)()); 261 262 /* 263 * zero copy inbound data handling 264 */ 265 #ifdef FCIP_ESBALLOC 266 static void fcip_ubfree(char *arg); 267 #endif /* FCIP_ESBALLOC */ 268 269 #if !defined(FCIP_ESBALLOC) 270 static void *fcip_allocb(size_t size, uint_t pri); 271 #endif 272 273 274 /* FCIP FARP support functions */ 275 static struct fcip_dest *fcip_do_farp(struct fcip *fptr, la_wwn_t *pwwn, 276 char *ip_addr, size_t ip_addr_len, int flags); 277 static void fcip_init_broadcast_pkt(fcip_pkt_t *fcip_pkt, void (*comp) (), 278 int is_els); 279 static int fcip_handle_farp_request(struct fcip *fptr, la_els_farp_t *fcmd); 280 static int fcip_handle_farp_response(struct fcip *fptr, la_els_farp_t *fcmd); 281 static void fcip_cache_arp_broadcast(struct fcip *ftpr, fc_unsol_buf_t *buf); 282 static void fcip_port_ns(void *arg); 283 284 #ifdef DEBUG 285 286 #include <sys/debug.h> 287 288 #define FCIP_DEBUG_DEFAULT 0x1 289 #define FCIP_DEBUG_ATTACH 0x2 290 #define FCIP_DEBUG_INIT 0x4 291 #define FCIP_DEBUG_DETACH 0x8 292 #define FCIP_DEBUG_DLPI 0x10 293 #define FCIP_DEBUG_ELS 0x20 294 #define FCIP_DEBUG_DOWNSTREAM 0x40 295 #define FCIP_DEBUG_UPSTREAM 0x80 296 #define FCIP_DEBUG_MISC 0x100 297 298 #define FCIP_DEBUG_STARTUP (FCIP_DEBUG_ATTACH|FCIP_DEBUG_INIT) 299 #define FCIP_DEBUG_DATAOUT (FCIP_DEBUG_DLPI|FCIP_DEBUG_DOWNSTREAM) 300 #define FCIP_DEBUG_DATAIN (FCIP_DEBUG_ELS|FCIP_DEBUG_UPSTREAM) 301 302 static int fcip_debug = FCIP_DEBUG_DEFAULT; 303 304 #define FCIP_DEBUG(level, args) \ 305 if (fcip_debug & (level)) cmn_err args; 306 307 #else /* DEBUG */ 308 309 #define FCIP_DEBUG(level, args) /* do nothing */ 310 311 #endif /* DEBUG */ 312 313 #define KIOIP KSTAT_INTR_PTR(fcip->fcip_intrstats) 314 315 /* 316 * Endian independent ethernet to WWN copy 317 */ 318 #define ether_to_wwn(E, W) \ 319 bzero((void *)(W), sizeof (la_wwn_t)); \ 320 bcopy((void *)(E), (void *)&((W)->raw_wwn[2]), ETHERADDRL); \ 321 (W)->raw_wwn[0] |= 0x10 322 323 /* 324 * wwn_to_ether : Endian independent, copies a WWN to struct ether_addr. 325 * The args to the macro are pointers to WWN and ether_addr structures 326 */ 327 #define wwn_to_ether(W, E) \ 328 bcopy((void *)&((W)->raw_wwn[2]), (void *)E, ETHERADDRL) 329 330 /* 331 * The module_info structure contains identification and limit values. 332 * All queues associated with a certain driver share the same module_info 333 * structures. This structure defines the characteristics of that driver/ 334 * module's queues. The module name must be unique. The max and min packet 335 * sizes limit the no. of characters in M_DATA messages. The Hi and Lo 336 * water marks are for flow control when a module has a service procedure. 337 */ 338 static struct module_info fcipminfo = { 339 FCIPIDNUM, /* mi_idnum : Module ID num */ 340 FCIPNAME, /* mi_idname: Module Name */ 341 FCIPMINPSZ, /* mi_minpsz: Min packet size */ 342 FCIPMAXPSZ, /* mi_maxpsz: Max packet size */ 343 FCIPHIWAT, /* mi_hiwat : High water mark */ 344 FCIPLOWAT /* mi_lowat : Low water mark */ 345 }; 346 347 /* 348 * The qinit structres contain the module put, service. open and close 349 * procedure pointers. All modules and drivers with the same streamtab 350 * file (i.e same fmodsw or cdevsw entry points) point to the same 351 * upstream (read) and downstream (write) qinit structs. 352 */ 353 static struct qinit fcip_rinit = { 354 NULL, /* qi_putp */ 355 NULL, /* qi_srvp */ 356 fcip_open, /* qi_qopen */ 357 fcip_close, /* qi_qclose */ 358 NULL, /* qi_qadmin */ 359 &fcipminfo, /* qi_minfo */ 360 NULL /* qi_mstat */ 361 }; 362 363 static struct qinit fcip_winit = { 364 fcip_wput, /* qi_putp */ 365 fcip_wsrv, /* qi_srvp */ 366 NULL, /* qi_qopen */ 367 NULL, /* qi_qclose */ 368 NULL, /* qi_qadmin */ 369 &fcipminfo, /* qi_minfo */ 370 NULL /* qi_mstat */ 371 }; 372 373 /* 374 * streamtab contains pointers to the read and write qinit structures 375 */ 376 377 static struct streamtab fcip_info = { 378 &fcip_rinit, /* st_rdinit */ 379 &fcip_winit, /* st_wrinit */ 380 NULL, /* st_muxrinit */ 381 NULL, /* st_muxwrinit */ 382 }; 383 384 static struct cb_ops fcip_cb_ops = { 385 nodev, /* open */ 386 nodev, /* close */ 387 nodev, /* strategy */ 388 nodev, /* print */ 389 nodev, /* dump */ 390 nodev, /* read */ 391 nodev, /* write */ 392 nodev, /* ioctl */ 393 nodev, /* devmap */ 394 nodev, /* mmap */ 395 nodev, /* segmap */ 396 nochpoll, /* poll */ 397 ddi_prop_op, /* cb_prop_op */ 398 &fcip_info, /* streamtab */ 399 D_MP | D_HOTPLUG, /* Driver compatibility flag */ 400 CB_REV, /* rev */ 401 nodev, /* int (*cb_aread)() */ 402 nodev /* int (*cb_awrite)() */ 403 }; 404 405 /* 406 * autoconfiguration routines. 407 */ 408 static struct dev_ops fcip_ops = { 409 DEVO_REV, /* devo_rev, */ 410 0, /* refcnt */ 411 fcip_getinfo, /* info */ 412 nulldev, /* identify */ 413 nulldev, /* probe */ 414 fcip_attach, /* attach */ 415 fcip_detach, /* detach */ 416 nodev, /* RESET */ 417 &fcip_cb_ops, /* driver operations */ 418 NULL, /* bus operations */ 419 ddi_power /* power management */ 420 }; 421 422 #define FCIP_VERSION "1.61" 423 #define FCIP_NAME "SunFC FCIP v" FCIP_VERSION 424 425 #define PORT_DRIVER "fp" 426 427 #define GETSTRUCT(struct, number) \ 428 ((struct *)kmem_zalloc((size_t)(sizeof (struct) * (number)), \ 429 KM_SLEEP)) 430 431 static struct modldrv modldrv = { 432 &mod_driverops, /* Type of module - driver */ 433 FCIP_NAME, /* Name of module */ 434 &fcip_ops, /* driver ops */ 435 }; 436 437 static struct modlinkage modlinkage = { 438 MODREV_1, (void *)&modldrv, NULL 439 }; 440 441 442 /* 443 * Now for some global statics 444 */ 445 static uint32_t fcip_ub_nbufs = FCIP_UB_NBUFS; 446 static uint32_t fcip_ub_size = FCIP_UB_SIZE; 447 static int fcip_pkt_ttl_ticks = FCIP_PKT_TTL; 448 static int fcip_tick_incr = 1; 449 static int fcip_wait_cmds = FCIP_WAIT_CMDS; 450 static int fcip_num_attaching = 0; 451 static int fcip_port_attach_pending = 0; 452 static int fcip_create_nodes_on_demand = 1; /* keep it similar to fcp */ 453 static int fcip_cache_on_arp_broadcast = 0; 454 static int fcip_farp_supported = 0; 455 static int fcip_minor_node_created = 0; 456 457 /* 458 * Supported FCAs 459 */ 460 #define QLC_PORT_1_ID_BITS 0x100 461 #define QLC_PORT_2_ID_BITS 0x101 462 #define QLC_PORT_NAA 0x2 463 #define QLC_MODULE_NAME "qlc" 464 #define IS_QLC_PORT(port_dip) \ 465 (strcmp(ddi_driver_name(ddi_get_parent((port_dip))),\ 466 QLC_MODULE_NAME) == 0) 467 468 469 /* 470 * fcip softstate structures head. 471 */ 472 473 static void *fcip_softp = NULL; 474 475 /* 476 * linked list of active (inuse) driver streams 477 */ 478 479 static int fcip_num_instances = 0; 480 static dev_info_t *fcip_module_dip = (dev_info_t *)0; 481 482 483 /* 484 * Ethernet broadcast address: Broadcast addressing in IP over fibre 485 * channel should be the IEEE ULA (also the low 6 bytes of the Port WWN). 486 * 487 * The broadcast addressing varies for differing topologies a node may be in: 488 * - On a private loop the ARP broadcast is a class 3 sequence sent 489 * using OPNfr (Open Broadcast Replicate primitive) followed by 490 * the ARP frame to D_ID 0xFFFFFF 491 * 492 * - On a public Loop the broadcast sequence is sent to AL_PA 0x00 493 * (no OPNfr primitive). 494 * 495 * - For direct attach and point to point topologies we just send 496 * the frame to D_ID 0xFFFFFF 497 * 498 * For public loop the handling would probably be different - for now 499 * I'll just declare this struct - It can be deleted if not necessary. 500 * 501 */ 502 503 504 /* 505 * DL_INFO_ACK template for the fcip module. The dl_info_ack_t structure is 506 * returned as a part of an DL_INFO_ACK message which is a M_PCPROTO message 507 * returned in response to a DL_INFO_REQ message sent to us from a DLS user 508 * Let us fake an ether header as much as possible. 509 * 510 * dl_addr_length is the Provider's DLSAP addr which is SAP addr + 511 * Physical addr of the provider. We set this to 512 * ushort_t + sizeof (la_wwn_t) for Fibre Channel ports. 513 * dl_mac_type Lets just use DL_ETHER - we can try using DL_IPFC, a new 514 * dlpi.h define later. 515 * dl_sap_length -2 indicating the SAP address follows the Physical addr 516 * component in the DLSAP addr. 517 * dl_service_mode: DLCLDS - connectionless data link service. 518 * 519 */ 520 521 static dl_info_ack_t fcip_infoack = { 522 DL_INFO_ACK, /* dl_primitive */ 523 FCIPMTU, /* dl_max_sdu */ 524 0, /* dl_min_sdu */ 525 FCIPADDRL, /* dl_addr_length */ 526 DL_ETHER, /* dl_mac_type */ 527 0, /* dl_reserved */ 528 0, /* dl_current_state */ 529 -2, /* dl_sap_length */ 530 DL_CLDLS, /* dl_service_mode */ 531 0, /* dl_qos_length */ 532 0, /* dl_qos_offset */ 533 0, /* dl_range_length */ 534 0, /* dl_range_offset */ 535 DL_STYLE2, /* dl_provider_style */ 536 sizeof (dl_info_ack_t), /* dl_addr_offset */ 537 DL_VERSION_2, /* dl_version */ 538 ETHERADDRL, /* dl_brdcst_addr_length */ 539 sizeof (dl_info_ack_t) + FCIPADDRL, /* dl_brdcst_addr_offset */ 540 0 /* dl_growth */ 541 }; 542 543 /* 544 * FCIP broadcast address definition. 545 */ 546 static struct ether_addr fcipnhbroadcastaddr = { 547 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 548 }; 549 550 /* 551 * RFC2625 requires the broadcast ARP address in the ARP data payload to 552 * be set to 0x00 00 00 00 00 00 for ARP broadcast packets 553 */ 554 static struct ether_addr fcip_arpbroadcast_addr = { 555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 556 }; 557 558 559 #define ether_bcopy(src, dest) bcopy((src), (dest), ETHERADDRL); 560 561 /* 562 * global kernel locks 563 */ 564 static kcondvar_t fcip_global_cv; 565 static kmutex_t fcip_global_mutex; 566 567 /* 568 * fctl external defines 569 */ 570 extern int fc_ulp_add(fc_ulp_modinfo_t *); 571 572 /* 573 * fctl data structures 574 */ 575 576 #define FCIP_REV 0x07 577 578 /* linked list of port info structures */ 579 static fcip_port_info_t *fcip_port_head = NULL; 580 581 /* linked list of fcip structures */ 582 static struct fcipstr *fcipstrup = NULL; 583 static krwlock_t fcipstruplock; 584 585 586 /* 587 * Module information structure. This structure gives the FC Transport modules 588 * information about an ULP that registers with it. 589 */ 590 static fc_ulp_modinfo_t fcip_modinfo = { 591 0, /* for xref checks? */ 592 FCTL_ULP_MODREV_4, /* FCIP revision */ 593 FC_TYPE_IS8802_SNAP, /* type 5 for SNAP encapsulated datagrams */ 594 FCIP_NAME, /* module name as in the modldrv struct */ 595 0x0, /* get all statec callbacks for now */ 596 fcip_port_attach, /* port attach callback */ 597 fcip_port_detach, /* port detach callback */ 598 fcip_port_ioctl, /* port ioctl callback */ 599 fcip_els_cb, /* els callback */ 600 fcip_data_cb, /* data callback */ 601 fcip_statec_cb /* state change callback */ 602 }; 603 604 605 /* 606 * Solaris 9 and up, the /kernel/drv/fp.conf file will have the following entry 607 * 608 * ddi-forceattach=1; 609 * 610 * This will ensure that fp is loaded at bootup. No additional checks are needed 611 */ 612 int 613 _init(void) 614 { 615 int rval; 616 617 FCIP_TNF_LOAD(); 618 619 /* 620 * Initialize the mutexs used by port attach and other callbacks. 621 * The transport can call back into our port_attach_callback 622 * routine even before _init() completes and bad things can happen. 623 */ 624 mutex_init(&fcip_global_mutex, NULL, MUTEX_DRIVER, NULL); 625 cv_init(&fcip_global_cv, NULL, CV_DRIVER, NULL); 626 rw_init(&fcipstruplock, NULL, RW_DRIVER, NULL); 627 628 mutex_enter(&fcip_global_mutex); 629 fcip_port_attach_pending = 1; 630 mutex_exit(&fcip_global_mutex); 631 632 /* 633 * Now attempt to register fcip with the transport. 634 * If fc_ulp_add fails, fcip module will not be loaded. 635 */ 636 rval = fc_ulp_add(&fcip_modinfo); 637 if (rval != FC_SUCCESS) { 638 mutex_destroy(&fcip_global_mutex); 639 cv_destroy(&fcip_global_cv); 640 rw_destroy(&fcipstruplock); 641 switch (rval) { 642 case FC_ULP_SAMEMODULE: 643 FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN, 644 "!fcip: module is already registered with" 645 " transport")); 646 rval = EEXIST; 647 break; 648 case FC_ULP_SAMETYPE: 649 FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN, 650 "!fcip: Another module of the same ULP type 0x%x" 651 " is already registered with the transport", 652 fcip_modinfo.ulp_type)); 653 rval = EEXIST; 654 break; 655 case FC_BADULP: 656 FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN, 657 "!fcip: Current fcip version 0x%x does not match" 658 " fctl version", 659 fcip_modinfo.ulp_rev)); 660 rval = ENODEV; 661 break; 662 default: 663 FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN, 664 "!fcip: fc_ulp_add failed with status 0x%x", rval)); 665 rval = ENODEV; 666 break; 667 } 668 FCIP_TNF_UNLOAD(&modlinkage); 669 return (rval); 670 } 671 672 if ((rval = ddi_soft_state_init(&fcip_softp, sizeof (struct fcip), 673 FCIP_NUM_INSTANCES)) != 0) { 674 mutex_destroy(&fcip_global_mutex); 675 cv_destroy(&fcip_global_cv); 676 rw_destroy(&fcipstruplock); 677 (void) fc_ulp_remove(&fcip_modinfo); 678 FCIP_TNF_UNLOAD(&modlinkage); 679 return (rval); 680 } 681 682 if ((rval = mod_install(&modlinkage)) != 0) { 683 FCIP_TNF_UNLOAD(&modlinkage); 684 (void) fc_ulp_remove(&fcip_modinfo); 685 mutex_destroy(&fcip_global_mutex); 686 cv_destroy(&fcip_global_cv); 687 rw_destroy(&fcipstruplock); 688 ddi_soft_state_fini(&fcip_softp); 689 } 690 return (rval); 691 } 692 693 /* 694 * Unload the port driver if this was the only ULP loaded and then 695 * deregister with the transport. 696 */ 697 int 698 _fini(void) 699 { 700 int rval; 701 int rval1; 702 703 /* 704 * Do not permit the module to be unloaded before a port 705 * attach callback has happened. 706 */ 707 mutex_enter(&fcip_global_mutex); 708 if (fcip_num_attaching || fcip_port_attach_pending) { 709 mutex_exit(&fcip_global_mutex); 710 return (EBUSY); 711 } 712 mutex_exit(&fcip_global_mutex); 713 714 if ((rval = mod_remove(&modlinkage)) != 0) { 715 return (rval); 716 } 717 718 /* 719 * unregister with the transport layer 720 */ 721 rval1 = fc_ulp_remove(&fcip_modinfo); 722 723 /* 724 * If the ULP was not registered with the transport, init should 725 * have failed. If transport has no knowledge of our existence 726 * we should simply bail out and succeed 727 */ 728 #ifdef DEBUG 729 if (rval1 == FC_BADULP) { 730 FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN, 731 "fcip: ULP was never registered with the transport")); 732 rval = ENODEV; 733 } else if (rval1 == FC_BADTYPE) { 734 FCIP_DEBUG(FCIP_DEBUG_DEFAULT, (CE_WARN, 735 "fcip: No ULP of this type 0x%x was registered with " 736 "transport", fcip_modinfo.ulp_type)); 737 rval = ENODEV; 738 } 739 #endif /* DEBUG */ 740 741 mutex_destroy(&fcip_global_mutex); 742 rw_destroy(&fcipstruplock); 743 cv_destroy(&fcip_global_cv); 744 ddi_soft_state_fini(&fcip_softp); 745 746 FCIP_TNF_UNLOAD(&modlinkage); 747 748 return (rval); 749 } 750 751 /* 752 * Info about this loadable module 753 */ 754 int 755 _info(struct modinfo *modinfop) 756 { 757 return (mod_info(&modlinkage, modinfop)); 758 } 759 760 /* 761 * The port attach callback is invoked by the port driver when a FCA 762 * port comes online and binds with the transport layer. The transport 763 * then callsback into all ULP modules registered with it. The Port attach 764 * call back will also provide the ULP module with the Port's WWN and S_ID 765 */ 766 /* ARGSUSED */ 767 static int 768 fcip_port_attach(opaque_t ulp_handle, fc_ulp_port_info_t *port_info, 769 fc_attach_cmd_t cmd, uint32_t sid) 770 { 771 int rval = FC_FAILURE; 772 int instance; 773 struct fcip *fptr; 774 fcip_port_info_t *fport = NULL; 775 fcip_port_info_t *cur_fport; 776 fc_portid_t src_id; 777 778 switch (cmd) { 779 case FC_CMD_ATTACH: { 780 la_wwn_t *ww_pn = NULL; 781 /* 782 * It was determined that, as per spec, the lower 48 bits of 783 * the port-WWN will always be unique. This will make the MAC 784 * address (i.e the lower 48 bits of the WWN), that IP/ARP 785 * depend on, unique too. Hence we should be able to remove the 786 * restriction of attaching to only one of the ports of 787 * multi port FCAs. 788 * 789 * Earlier, fcip used to attach only to qlc module and fail 790 * silently for attach failures resulting from unknown FCAs or 791 * unsupported FCA ports. Now, we'll do no such checks. 792 */ 793 ww_pn = &port_info->port_pwwn; 794 795 FCIP_TNF_PROBE_2((fcip_port_attach, "fcip io", /* CSTYLED */, 796 tnf_string, msg, "port id bits", 797 tnf_opaque, nport_id, ww_pn->w.nport_id)); 798 FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_NOTE, 799 "port id bits: 0x%x", ww_pn->w.nport_id)); 800 /* 801 * A port has come online 802 */ 803 mutex_enter(&fcip_global_mutex); 804 fcip_num_instances++; 805 fcip_num_attaching++; 806 807 if (fcip_port_head == NULL) { 808 /* OK to sleep here ? */ 809 fport = kmem_zalloc(sizeof (fcip_port_info_t), 810 KM_NOSLEEP); 811 if (fport == NULL) { 812 fcip_num_instances--; 813 fcip_num_attaching--; 814 ASSERT(fcip_num_attaching >= 0); 815 mutex_exit(&fcip_global_mutex); 816 rval = FC_FAILURE; 817 cmn_err(CE_WARN, "!fcip(%d): port attach " 818 "failed: alloc failed", 819 ddi_get_instance(port_info->port_dip)); 820 goto done; 821 } 822 fcip_port_head = fport; 823 } else { 824 /* 825 * traverse the port list and also check for 826 * duplicate port attaches - Nothing wrong in being 827 * paranoid Heh Heh. 828 */ 829 cur_fport = fcip_port_head; 830 while (cur_fport != NULL) { 831 if (cur_fport->fcipp_handle == 832 port_info->port_handle) { 833 fcip_num_instances--; 834 fcip_num_attaching--; 835 ASSERT(fcip_num_attaching >= 0); 836 mutex_exit(&fcip_global_mutex); 837 FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_WARN, 838 "!fcip(%d): port already " 839 "attached!!", ddi_get_instance( 840 port_info->port_dip))); 841 rval = FC_FAILURE; 842 goto done; 843 } 844 cur_fport = cur_fport->fcipp_next; 845 } 846 fport = kmem_zalloc(sizeof (fcip_port_info_t), 847 KM_NOSLEEP); 848 if (fport == NULL) { 849 rval = FC_FAILURE; 850 fcip_num_instances--; 851 fcip_num_attaching--; 852 ASSERT(fcip_num_attaching >= 0); 853 mutex_exit(&fcip_global_mutex); 854 cmn_err(CE_WARN, "!fcip(%d): port attach " 855 "failed: alloc failed", 856 ddi_get_instance(port_info->port_dip)); 857 goto done; 858 } 859 fport->fcipp_next = fcip_port_head; 860 fcip_port_head = fport; 861 } 862 863 mutex_exit(&fcip_global_mutex); 864 865 /* 866 * now fill in the details about the port itself 867 */ 868 fport->fcipp_linkage = *port_info->port_linkage; 869 fport->fcipp_handle = port_info->port_handle; 870 fport->fcipp_dip = port_info->port_dip; 871 fport->fcipp_topology = port_info->port_flags; 872 fport->fcipp_pstate = port_info->port_state; 873 fport->fcipp_naa = port_info->port_pwwn.w.naa_id; 874 bcopy(&port_info->port_pwwn, &fport->fcipp_pwwn, 875 sizeof (la_wwn_t)); 876 bcopy(&port_info->port_nwwn, &fport->fcipp_nwwn, 877 sizeof (la_wwn_t)); 878 fport->fcipp_fca_pkt_size = port_info->port_fca_pkt_size; 879 fport->fcipp_cmd_dma_attr = *port_info->port_cmd_dma_attr; 880 fport->fcipp_resp_dma_attr = *port_info->port_resp_dma_attr; 881 fport->fcipp_fca_acc_attr = *port_info->port_acc_attr; 882 src_id.port_id = sid; 883 src_id.priv_lilp_posit = 0; 884 fport->fcipp_sid = src_id; 885 886 /* 887 * allocate soft state for this instance 888 */ 889 instance = ddi_get_instance(fport->fcipp_dip); 890 if (ddi_soft_state_zalloc(fcip_softp, 891 instance) != DDI_SUCCESS) { 892 rval = FC_FAILURE; 893 cmn_err(CE_WARN, "!fcip(%d): port attach failed: " 894 "soft state alloc failed", instance); 895 goto failure; 896 } 897 898 fptr = ddi_get_soft_state(fcip_softp, instance); 899 900 if (fptr == NULL) { 901 rval = FC_FAILURE; 902 cmn_err(CE_WARN, "!fcip(%d): port attach failed: " 903 "failure to get soft state", instance); 904 goto failure; 905 } 906 907 /* 908 * initialize all mutexes and locks required for this module 909 */ 910 mutex_init(&fptr->fcip_mutex, NULL, MUTEX_DRIVER, NULL); 911 mutex_init(&fptr->fcip_ub_mutex, NULL, MUTEX_DRIVER, NULL); 912 mutex_init(&fptr->fcip_rt_mutex, NULL, MUTEX_DRIVER, NULL); 913 mutex_init(&fptr->fcip_dest_mutex, NULL, MUTEX_DRIVER, NULL); 914 mutex_init(&fptr->fcip_sendup_mutex, NULL, MUTEX_DRIVER, NULL); 915 cv_init(&fptr->fcip_farp_cv, NULL, CV_DRIVER, NULL); 916 cv_init(&fptr->fcip_sendup_cv, NULL, CV_DRIVER, NULL); 917 cv_init(&fptr->fcip_ub_cv, NULL, CV_DRIVER, NULL); 918 919 mutex_enter(&fptr->fcip_mutex); 920 921 fptr->fcip_dip = fport->fcipp_dip; /* parent's dip */ 922 fptr->fcip_instance = instance; 923 fptr->fcip_ub_upstream = 0; 924 925 if (FC_PORT_STATE_MASK(port_info->port_state) == 926 FC_STATE_ONLINE) { 927 fptr->fcip_port_state = FCIP_PORT_ONLINE; 928 if (fptr->fcip_flags & FCIP_LINK_DOWN) { 929 fptr->fcip_flags &= ~FCIP_LINK_DOWN; 930 } 931 } else { 932 fptr->fcip_port_state = FCIP_PORT_OFFLINE; 933 } 934 935 fptr->fcip_flags |= FCIP_ATTACHING; 936 fptr->fcip_port_info = fport; 937 938 /* 939 * Extract our MAC addr from our port's WWN. The lower 48 940 * bits will be our MAC address 941 */ 942 wwn_to_ether(&fport->fcipp_nwwn, &fptr->fcip_macaddr); 943 944 fport->fcipp_fcip = fptr; 945 946 FCIP_DEBUG(FCIP_DEBUG_ATTACH, 947 (CE_NOTE, "fcipdest : 0x%lx, rtable : 0x%lx", 948 (long)(sizeof (fptr->fcip_dest)), 949 (long)(sizeof (fptr->fcip_rtable)))); 950 951 bzero(fptr->fcip_dest, sizeof (fptr->fcip_dest)); 952 bzero(fptr->fcip_rtable, sizeof (fptr->fcip_rtable)); 953 954 /* 955 * create a taskq to handle sundry jobs for the driver 956 * This way we can have jobs run in parallel 957 */ 958 fptr->fcip_tq = taskq_create("fcip_tasks", 959 FCIP_NUM_THREADS, MINCLSYSPRI, FCIP_MIN_TASKS, 960 FCIP_MAX_TASKS, TASKQ_PREPOPULATE); 961 962 mutex_exit(&fptr->fcip_mutex); 963 964 /* 965 * create a separate thread to handle all unsolicited 966 * callback handling. This is because unsolicited_callback 967 * can happen from an interrupt context and the upstream 968 * modules can put new messages right back in the same 969 * thread context. This usually works fine, but sometimes 970 * we may have to block to obtain the dest struct entries 971 * for some remote ports. 972 */ 973 mutex_enter(&fptr->fcip_sendup_mutex); 974 if (thread_create(NULL, DEFAULTSTKSZ, 975 (void (*)())fcip_sendup_thr, (caddr_t)fptr, 0, &p0, 976 TS_RUN, minclsyspri) == NULL) { 977 mutex_exit(&fptr->fcip_sendup_mutex); 978 cmn_err(CE_WARN, 979 "!unable to create fcip sendup thread for " 980 " instance: 0x%x", instance); 981 rval = FC_FAILURE; 982 goto done; 983 } 984 fptr->fcip_sendup_thr_initted = 1; 985 fptr->fcip_sendup_head = fptr->fcip_sendup_tail = NULL; 986 mutex_exit(&fptr->fcip_sendup_mutex); 987 988 989 /* Let the attach handler do the rest */ 990 if (fcip_port_attach_handler(fptr) != FC_SUCCESS) { 991 /* 992 * We have already cleaned up so return 993 */ 994 rval = FC_FAILURE; 995 cmn_err(CE_WARN, "!fcip(%d): port attach failed", 996 instance); 997 goto done; 998 } 999 1000 FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_CONT, 1001 "!fcip attach for port instance (0x%x) successful", 1002 instance)); 1003 1004 rval = FC_SUCCESS; 1005 goto done; 1006 } 1007 case FC_CMD_POWER_UP: 1008 /* FALLTHROUGH */ 1009 case FC_CMD_RESUME: 1010 mutex_enter(&fcip_global_mutex); 1011 fport = fcip_port_head; 1012 while (fport != NULL) { 1013 if (fport->fcipp_handle == port_info->port_handle) { 1014 break; 1015 } 1016 fport = fport->fcipp_next; 1017 } 1018 if (fport == NULL) { 1019 rval = FC_SUCCESS; 1020 mutex_exit(&fcip_global_mutex); 1021 goto done; 1022 } 1023 rval = fcip_handle_resume(fport, port_info, cmd); 1024 mutex_exit(&fcip_global_mutex); 1025 goto done; 1026 1027 default: 1028 FCIP_TNF_PROBE_2((fcip_port_attach, "fcip io", /* CSTYLED */, 1029 tnf_string, msg, "unknown command type", 1030 tnf_uint, cmd, cmd)); 1031 FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_WARN, 1032 "unknown cmd type 0x%x in port_attach", cmd)); 1033 rval = FC_FAILURE; 1034 goto done; 1035 } 1036 1037 failure: 1038 if (fport) { 1039 mutex_enter(&fcip_global_mutex); 1040 fcip_num_attaching--; 1041 ASSERT(fcip_num_attaching >= 0); 1042 (void) fcip_softstate_free(fport); 1043 fcip_port_attach_pending = 0; 1044 mutex_exit(&fcip_global_mutex); 1045 } 1046 return (rval); 1047 1048 done: 1049 mutex_enter(&fcip_global_mutex); 1050 fcip_port_attach_pending = 0; 1051 mutex_exit(&fcip_global_mutex); 1052 return (rval); 1053 } 1054 1055 /* 1056 * fcip_port_attach_handler : Completes the port attach operation after 1057 * the ulp_port_attach routine has completed its ground work. The job 1058 * of this function among other things is to obtain and handle topology 1059 * specifics, initialize a port, setup broadcast address entries in 1060 * the fcip tables etc. This routine cleans up behind itself on failures. 1061 * Returns FC_SUCCESS or FC_FAILURE. 1062 */ 1063 static int 1064 fcip_port_attach_handler(struct fcip *fptr) 1065 { 1066 fcip_port_info_t *fport = fptr->fcip_port_info; 1067 int rval = FC_FAILURE; 1068 1069 ASSERT(fport != NULL); 1070 1071 mutex_enter(&fcip_global_mutex); 1072 1073 FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_NOTE, 1074 "fcip module dip: %p instance: %d", 1075 (void *)fcip_module_dip, ddi_get_instance(fptr->fcip_dip))); 1076 1077 if (fcip_module_dip == NULL) { 1078 clock_t fcip_lbolt; 1079 1080 fcip_lbolt = ddi_get_lbolt(); 1081 /* 1082 * we need to use the fcip devinfo for creating 1083 * the clone device node, but the fcip attach 1084 * (from its conf file entry claiming to be a 1085 * child of pseudo) may not have happened yet. 1086 * wait here for 10 seconds and fail port attach 1087 * if the fcip devinfo is not attached yet 1088 */ 1089 fcip_lbolt += drv_usectohz(FCIP_INIT_DELAY); 1090 1091 FCIP_DEBUG(FCIP_DEBUG_ATTACH, 1092 (CE_WARN, "cv_timedwait lbolt %lx", fcip_lbolt)); 1093 1094 (void) cv_timedwait(&fcip_global_cv, &fcip_global_mutex, 1095 fcip_lbolt); 1096 1097 if (fcip_module_dip == NULL) { 1098 mutex_exit(&fcip_global_mutex); 1099 1100 FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_WARN, 1101 "fcip attach did not happen")); 1102 goto port_attach_cleanup; 1103 } 1104 } 1105 1106 if ((!fcip_minor_node_created) && 1107 fcip_is_supported_fc_topology(fport->fcipp_topology)) { 1108 /* 1109 * Checking for same topologies which are considered valid 1110 * by fcip_handle_topology(). Dont create a minor node if 1111 * nothing is hanging off the FC port. 1112 */ 1113 if (ddi_create_minor_node(fcip_module_dip, "fcip", S_IFCHR, 1114 ddi_get_instance(fptr->fcip_dip), DDI_PSEUDO, 1115 CLONE_DEV) == DDI_FAILURE) { 1116 mutex_exit(&fcip_global_mutex); 1117 FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_WARN, 1118 "failed to create minor node for fcip(%d)", 1119 ddi_get_instance(fptr->fcip_dip))); 1120 goto port_attach_cleanup; 1121 } 1122 fcip_minor_node_created++; 1123 } 1124 mutex_exit(&fcip_global_mutex); 1125 1126 /* 1127 * initialize port for traffic 1128 */ 1129 if (fcip_init_port(fptr) != FC_SUCCESS) { 1130 /* fcip_init_port has already cleaned up its stuff */ 1131 1132 mutex_enter(&fcip_global_mutex); 1133 1134 if ((fcip_num_instances == 1) && 1135 (fcip_minor_node_created == 1)) { 1136 /* Remove minor node iff this is the last instance */ 1137 ddi_remove_minor_node(fcip_module_dip, NULL); 1138 } 1139 1140 mutex_exit(&fcip_global_mutex); 1141 1142 goto port_attach_cleanup; 1143 } 1144 1145 mutex_enter(&fptr->fcip_mutex); 1146 fptr->fcip_flags &= ~FCIP_ATTACHING; 1147 fptr->fcip_flags |= FCIP_INITED; 1148 fptr->fcip_timeout_ticks = 0; 1149 1150 /* 1151 * start the timeout threads 1152 */ 1153 fptr->fcip_timeout_id = timeout(fcip_timeout, fptr, 1154 drv_usectohz(1000000)); 1155 1156 mutex_exit(&fptr->fcip_mutex); 1157 mutex_enter(&fcip_global_mutex); 1158 fcip_num_attaching--; 1159 ASSERT(fcip_num_attaching >= 0); 1160 mutex_exit(&fcip_global_mutex); 1161 rval = FC_SUCCESS; 1162 return (rval); 1163 1164 port_attach_cleanup: 1165 mutex_enter(&fcip_global_mutex); 1166 (void) fcip_softstate_free(fport); 1167 fcip_num_attaching--; 1168 ASSERT(fcip_num_attaching >= 0); 1169 mutex_exit(&fcip_global_mutex); 1170 rval = FC_FAILURE; 1171 return (rval); 1172 } 1173 1174 1175 /* 1176 * Handler for DDI_RESUME operations. Port must be ready to restart IP 1177 * traffic on resume 1178 */ 1179 static int 1180 fcip_handle_resume(fcip_port_info_t *fport, fc_ulp_port_info_t *port_info, 1181 fc_attach_cmd_t cmd) 1182 { 1183 int rval = FC_SUCCESS; 1184 struct fcip *fptr = fport->fcipp_fcip; 1185 struct fcipstr *tslp; 1186 int index; 1187 1188 1189 ASSERT(fptr != NULL); 1190 1191 mutex_enter(&fptr->fcip_mutex); 1192 1193 if (cmd == FC_CMD_POWER_UP) { 1194 fptr->fcip_flags &= ~(FCIP_POWER_DOWN); 1195 if (fptr->fcip_flags & FCIP_SUSPENDED) { 1196 mutex_exit(&fptr->fcip_mutex); 1197 return (FC_SUCCESS); 1198 } 1199 } else if (cmd == FC_CMD_RESUME) { 1200 fptr->fcip_flags &= ~(FCIP_SUSPENDED); 1201 } else { 1202 mutex_exit(&fptr->fcip_mutex); 1203 return (FC_FAILURE); 1204 } 1205 1206 /* 1207 * set the current port state and topology 1208 */ 1209 fport->fcipp_topology = port_info->port_flags; 1210 fport->fcipp_pstate = port_info->port_state; 1211 1212 rw_enter(&fcipstruplock, RW_READER); 1213 for (tslp = fcipstrup; tslp; tslp = tslp->sl_nextp) { 1214 if (tslp->sl_fcip == fptr) { 1215 break; 1216 } 1217 } 1218 rw_exit(&fcipstruplock); 1219 1220 /* 1221 * No active streams on this port 1222 */ 1223 if (tslp == NULL) { 1224 rval = FC_SUCCESS; 1225 goto done; 1226 } 1227 1228 mutex_enter(&fptr->fcip_rt_mutex); 1229 for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) { 1230 struct fcip_routing_table *frp; 1231 1232 frp = fptr->fcip_rtable[index]; 1233 while (frp) { 1234 uint32_t did; 1235 /* 1236 * Mark the broadcast RTE available again. It 1237 * was marked SUSPENDED during SUSPEND. 1238 */ 1239 did = fcip_get_broadcast_did(fptr); 1240 if (frp->fcipr_d_id.port_id == did) { 1241 frp->fcipr_state = 0; 1242 index = FCIP_RT_HASH_ELEMS; 1243 break; 1244 } 1245 frp = frp->fcipr_next; 1246 } 1247 } 1248 mutex_exit(&fptr->fcip_rt_mutex); 1249 1250 /* 1251 * fcip_handle_topology will update the port entries in the 1252 * routing table. 1253 * fcip_handle_topology also takes care of resetting the 1254 * fcipr_state field in the routing table structure. The entries 1255 * were set to RT_INVALID during suspend. 1256 */ 1257 fcip_handle_topology(fptr); 1258 1259 done: 1260 /* 1261 * Restart the timeout thread 1262 */ 1263 fptr->fcip_timeout_id = timeout(fcip_timeout, fptr, 1264 drv_usectohz(1000000)); 1265 mutex_exit(&fptr->fcip_mutex); 1266 return (rval); 1267 } 1268 1269 1270 /* 1271 * Insert a destination port entry into the routing table for 1272 * this port 1273 */ 1274 static void 1275 fcip_rt_update(struct fcip *fptr, fc_portmap_t *devlist, uint32_t listlen) 1276 { 1277 struct fcip_routing_table *frp; 1278 fcip_port_info_t *fport = fptr->fcip_port_info; 1279 int hash_bucket, i; 1280 fc_portmap_t *pmap; 1281 char wwn_buf[20]; 1282 1283 FCIP_TNF_PROBE_2((fcip_rt_update, "fcip io", /* CSTYLED */, 1284 tnf_string, msg, "enter", 1285 tnf_int, listlen, listlen)); 1286 1287 ASSERT(!mutex_owned(&fptr->fcip_mutex)); 1288 mutex_enter(&fptr->fcip_rt_mutex); 1289 1290 for (i = 0; i < listlen; i++) { 1291 pmap = &(devlist[i]); 1292 1293 frp = fcip_lookup_rtable(fptr, &(pmap->map_pwwn), 1294 FCIP_COMPARE_PWWN); 1295 /* 1296 * If an entry for a port in the devlist exists in the 1297 * in the per port routing table, make sure the data 1298 * is current. We need to do this irrespective of the 1299 * underlying port topology. 1300 */ 1301 switch (pmap->map_type) { 1302 /* FALLTHROUGH */ 1303 case PORT_DEVICE_NOCHANGE: 1304 /* FALLTHROUGH */ 1305 case PORT_DEVICE_USER_LOGIN: 1306 /* FALLTHROUGH */ 1307 case PORT_DEVICE_CHANGED: 1308 /* FALLTHROUGH */ 1309 case PORT_DEVICE_NEW: 1310 if (frp == NULL) { 1311 goto add_new_entry; 1312 } else if (frp) { 1313 goto update_entry; 1314 } else { 1315 continue; 1316 } 1317 1318 case PORT_DEVICE_OLD: 1319 /* FALLTHROUGH */ 1320 case PORT_DEVICE_USER_LOGOUT: 1321 /* 1322 * Mark entry for removal from Routing Table if 1323 * one exists. Let the timeout thread actually 1324 * remove the entry after we've given up hopes 1325 * of the port ever showing up. 1326 */ 1327 if (frp) { 1328 uint32_t did; 1329 1330 /* 1331 * Mark the routing table as invalid to bail 1332 * the packets early that are in transit 1333 */ 1334 did = fptr->fcip_broadcast_did; 1335 if (frp->fcipr_d_id.port_id != did) { 1336 frp->fcipr_pd = NULL; 1337 frp->fcipr_state = FCIP_RT_INVALID; 1338 frp->fcipr_invalid_timeout = 1339 fptr->fcip_timeout_ticks + 1340 FCIP_RTE_TIMEOUT; 1341 } 1342 } 1343 continue; 1344 1345 default: 1346 FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_WARN, 1347 "unknown map flags in rt_update")); 1348 continue; 1349 } 1350 add_new_entry: 1351 ASSERT(frp == NULL); 1352 hash_bucket = FCIP_RT_HASH(pmap->map_pwwn.raw_wwn); 1353 1354 ASSERT(hash_bucket < FCIP_RT_HASH_ELEMS); 1355 1356 FCIP_TNF_PROBE_2((fcip_rt_update, "cfip io", /* CSTYLED */, 1357 tnf_string, msg, 1358 "add new entry", 1359 tnf_int, hashbucket, hash_bucket)); 1360 1361 frp = (struct fcip_routing_table *) 1362 kmem_zalloc(sizeof (struct fcip_routing_table), KM_SLEEP); 1363 /* insert at beginning of hash bucket */ 1364 frp->fcipr_next = fptr->fcip_rtable[hash_bucket]; 1365 fptr->fcip_rtable[hash_bucket] = frp; 1366 fc_wwn_to_str(&pmap->map_pwwn, wwn_buf); 1367 FCIP_DEBUG(FCIP_DEBUG_ATTACH, (CE_NOTE, 1368 "added entry for pwwn %s and d_id 0x%x", 1369 wwn_buf, pmap->map_did.port_id)); 1370 update_entry: 1371 bcopy((void *)&pmap->map_pwwn, 1372 (void *)&frp->fcipr_pwwn, sizeof (la_wwn_t)); 1373 bcopy((void *)&pmap->map_nwwn, (void *)&frp->fcipr_nwwn, 1374 sizeof (la_wwn_t)); 1375 frp->fcipr_d_id = pmap->map_did; 1376 frp->fcipr_state = pmap->map_state; 1377 frp->fcipr_pd = pmap->map_pd; 1378 1379 /* 1380 * If there is no pd for a destination port that is not 1381 * a broadcast entry, the port is pretty much unusable - so 1382 * mark the port for removal so we can try adding back the 1383 * entry again. 1384 */ 1385 if ((frp->fcipr_pd == NULL) && 1386 (frp->fcipr_d_id.port_id != fptr->fcip_broadcast_did)) { 1387 frp->fcipr_state = PORT_DEVICE_INVALID; 1388 frp->fcipr_invalid_timeout = fptr->fcip_timeout_ticks + 1389 (FCIP_RTE_TIMEOUT / 2); 1390 } 1391 frp->fcipr_fca_dev = 1392 fc_ulp_get_fca_device(fport->fcipp_handle, pmap->map_did); 1393 1394 /* 1395 * login to the remote port. Don't worry about 1396 * plogi failures for now 1397 */ 1398 if (pmap->map_pd != NULL) { 1399 (void) fcip_do_plogi(fptr, frp); 1400 } else if (FC_TOP_EXTERNAL(fport->fcipp_topology)) { 1401 fc_wwn_to_str(&frp->fcipr_pwwn, wwn_buf); 1402 FCIP_DEBUG(FCIP_DEBUG_MISC, (CE_NOTE, 1403 "logging into pwwn %s, d_id 0x%x", 1404 wwn_buf, frp->fcipr_d_id.port_id)); 1405 (void) fcip_do_plogi(fptr, frp); 1406 } 1407 1408 FCIP_TNF_BYTE_ARRAY(fcip_rt_update, "fcip io", "detail", 1409 "new wwn in rt", pwwn, 1410 &frp->fcipr_pwwn, sizeof (la_wwn_t)); 1411 } 1412 mutex_exit(&fptr->fcip_rt_mutex); 1413 } 1414 1415 1416 /* 1417 * return a matching routing table entry for a given fcip instance 1418 */ 1419 struct fcip_routing_table * 1420 fcip_lookup_rtable(struct fcip *fptr, la_wwn_t *wwn, int matchflag) 1421 { 1422 struct fcip_routing_table *frp = NULL; 1423 int hash_bucket; 1424 1425 1426 FCIP_TNF_PROBE_1((fcip_lookup_rtable, "fcip io", /* CSTYLED */, 1427 tnf_string, msg, "enter")); 1428 FCIP_TNF_BYTE_ARRAY(fcip_lookup_rtable, "fcip io", "detail", 1429 "rtable lookup for", wwn, 1430 &wwn->raw_wwn, sizeof (la_wwn_t)); 1431 FCIP_TNF_PROBE_2((fcip_lookup_rtable, "fcip io", /* CSTYLED */, 1432 tnf_string, msg, "match by", 1433 tnf_int, matchflag, matchflag)); 1434 1435 ASSERT(mutex_owned(&fptr->fcip_rt_mutex)); 1436 1437 hash_bucket = FCIP_RT_HASH(wwn->raw_wwn); 1438 frp = fptr->fcip_rtable[hash_bucket]; 1439 while (frp != NULL) { 1440 1441 FCIP_TNF_BYTE_ARRAY(fcip_lookup_rtable, "fcip io", "detail", 1442 "rtable entry", nwwn, 1443 &(frp->fcipr_nwwn.raw_wwn), sizeof (la_wwn_t)); 1444 1445 if (fcip_wwn_compare(&frp->fcipr_pwwn, wwn, matchflag) == 0) { 1446 break; 1447 } 1448 1449 frp = frp->fcipr_next; 1450 } 1451 FCIP_TNF_PROBE_2((fcip_lookup_rtable, "fcip io", /* CSTYLED */, 1452 tnf_string, msg, "lookup result", 1453 tnf_opaque, frp, frp)); 1454 return (frp); 1455 } 1456 1457 /* 1458 * Attach of fcip under pseudo. The actual setup of the interface 1459 * actually happens in fcip_port_attach on a callback from the 1460 * transport. The port_attach callback however can proceed only 1461 * after the devinfo for fcip has been created under pseudo 1462 */ 1463 static int 1464 fcip_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1465 { 1466 switch ((int)cmd) { 1467 1468 case DDI_ATTACH: { 1469 ASSERT(fcip_module_dip == NULL); 1470 fcip_module_dip = dip; 1471 1472 /* 1473 * this call originates as a result of fcip's conf 1474 * file entry and will result in a fcip instance being 1475 * a child of pseudo. We should ensure here that the port 1476 * driver (fp) has been loaded and initted since we would 1477 * never get a port attach callback without fp being loaded. 1478 * If we are unable to succesfully load and initalize fp - 1479 * just fail this attach. 1480 */ 1481 mutex_enter(&fcip_global_mutex); 1482 1483 FCIP_DEBUG(FCIP_DEBUG_ATTACH, 1484 (CE_WARN, "global cv - signaling")); 1485 1486 cv_signal(&fcip_global_cv); 1487 1488 FCIP_DEBUG(FCIP_DEBUG_ATTACH, 1489 (CE_WARN, "global cv - signaled")); 1490 mutex_exit(&fcip_global_mutex); 1491 return (DDI_SUCCESS); 1492 } 1493 case DDI_RESUME: 1494 /* 1495 * Resume appears trickier 1496 */ 1497 return (DDI_SUCCESS); 1498 default: 1499 return (DDI_FAILURE); 1500 } 1501 } 1502 1503 1504 /* 1505 * The detach entry point to permit unloading fcip. We make sure 1506 * there are no active streams before we proceed with the detach 1507 */ 1508 /* ARGSUSED */ 1509 static int 1510 fcip_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1511 { 1512 struct fcip *fptr; 1513 fcip_port_info_t *fport; 1514 int detached; 1515 1516 switch (cmd) { 1517 case DDI_DETACH: { 1518 /* 1519 * If we got here, any active streams should have been 1520 * unplumbed but check anyway 1521 */ 1522 mutex_enter(&fcip_global_mutex); 1523 if (fcipstrup != NULL) { 1524 mutex_exit(&fcip_global_mutex); 1525 return (DDI_FAILURE); 1526 } 1527 1528 if (fcip_port_head != NULL) { 1529 /* 1530 * Check to see if we have unattached/unbound 1531 * ports. If all the ports are unattached/unbound go 1532 * ahead and unregister with the transport 1533 */ 1534 fport = fcip_port_head; 1535 while (fport != NULL) { 1536 fptr = fport->fcipp_fcip; 1537 if (fptr == NULL) { 1538 continue; 1539 } 1540 mutex_enter(&fptr->fcip_mutex); 1541 fptr->fcip_flags |= FCIP_DETACHING; 1542 if (fptr->fcip_ipq || 1543 fptr->fcip_flags & (FCIP_IN_TIMEOUT | 1544 FCIP_IN_CALLBACK | FCIP_ATTACHING | 1545 FCIP_SUSPENDED | FCIP_POWER_DOWN | 1546 FCIP_REG_INPROGRESS)) { 1547 FCIP_TNF_PROBE_1((fcip_detach, 1548 "fcip io", /* CSTYLED */, 1549 tnf_string, msg, 1550 "fcip instance busy")); 1551 1552 mutex_exit(&fptr->fcip_mutex); 1553 FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_WARN, 1554 "fcip instance busy")); 1555 break; 1556 } 1557 /* 1558 * Check for any outstanding pkts. If yes 1559 * fail the detach 1560 */ 1561 mutex_enter(&fptr->fcip_dest_mutex); 1562 if (fcip_port_get_num_pkts(fptr) > 0) { 1563 mutex_exit(&fptr->fcip_dest_mutex); 1564 mutex_exit(&fptr->fcip_mutex); 1565 FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_WARN, 1566 "fcip instance busy - pkts " 1567 "pending")); 1568 break; 1569 } 1570 mutex_exit(&fptr->fcip_dest_mutex); 1571 1572 mutex_enter(&fptr->fcip_rt_mutex); 1573 if (fcip_plogi_in_progress(fptr)) { 1574 mutex_exit(&fptr->fcip_rt_mutex); 1575 mutex_exit(&fptr->fcip_mutex); 1576 FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_WARN, 1577 "fcip instance busy - plogi in " 1578 "progress")); 1579 break; 1580 } 1581 mutex_exit(&fptr->fcip_rt_mutex); 1582 1583 mutex_exit(&fptr->fcip_mutex); 1584 fport = fport->fcipp_next; 1585 } 1586 /* 1587 * if fport is non NULL - we have active ports 1588 */ 1589 if (fport != NULL) { 1590 /* 1591 * Remove the DETACHING flags on the ports 1592 */ 1593 fport = fcip_port_head; 1594 while (fport != NULL) { 1595 fptr = fport->fcipp_fcip; 1596 mutex_enter(&fptr->fcip_mutex); 1597 fptr->fcip_flags &= ~(FCIP_DETACHING); 1598 mutex_exit(&fptr->fcip_mutex); 1599 fport = fport->fcipp_next; 1600 } 1601 mutex_exit(&fcip_global_mutex); 1602 return (DDI_FAILURE); 1603 } 1604 } 1605 1606 /* 1607 * free up all softstate structures 1608 */ 1609 fport = fcip_port_head; 1610 while (fport != NULL) { 1611 detached = 1; 1612 1613 fptr = fport->fcipp_fcip; 1614 if (fptr) { 1615 mutex_enter(&fptr->fcip_mutex); 1616 /* 1617 * Check to see if somebody beat us to the 1618 * punch 1619 */ 1620 detached = fptr->fcip_flags & FCIP_DETACHED; 1621 fptr->fcip_flags &= ~(FCIP_DETACHING); 1622 fptr->fcip_flags |= FCIP_DETACHED; 1623 mutex_exit(&fptr->fcip_mutex); 1624 } 1625 1626 if (!detached) { 1627 fport = fcip_softstate_free(fport); 1628 } else { 1629 /* 1630 * If the port was marked as detached 1631 * but it was still in the list, that 1632 * means another thread has marked it 1633 * but we got in while it released the 1634 * fcip_global_mutex in softstate_free. 1635 * Given that, we're still safe to use 1636 * fport->fcipp_next to find out what 1637 * the next port on the list is. 1638 */ 1639 fport = fport->fcipp_next; 1640 } 1641 1642 FCIP_DEBUG(FCIP_DEBUG_DETACH, 1643 (CE_NOTE, "detaching port")); 1644 1645 FCIP_TNF_PROBE_1((fcip_detach, 1646 "fcip io", /* CSTYLED */, tnf_string, 1647 msg, "detaching port")); 1648 } 1649 1650 /* 1651 * If we haven't removed all the port structures, we 1652 * aren't yet ready to be detached. 1653 */ 1654 if (fcip_port_head != NULL) { 1655 mutex_exit(&fcip_global_mutex); 1656 return (DDI_FAILURE); 1657 } 1658 1659 fcip_num_instances = 0; 1660 mutex_exit(&fcip_global_mutex); 1661 fcip_module_dip = NULL; 1662 return (DDI_SUCCESS); 1663 } 1664 case DDI_SUSPEND: 1665 return (DDI_SUCCESS); 1666 default: 1667 return (DDI_FAILURE); 1668 } 1669 } 1670 1671 /* 1672 * The port_detach callback is called from the transport when a 1673 * FC port is being removed from the transport's control. This routine 1674 * provides fcip with an opportunity to cleanup all activities and 1675 * structures on the port marked for removal. 1676 */ 1677 /* ARGSUSED */ 1678 static int 1679 fcip_port_detach(opaque_t ulp_handle, fc_ulp_port_info_t *port_info, 1680 fc_detach_cmd_t cmd) 1681 { 1682 int rval = FC_FAILURE; 1683 fcip_port_info_t *fport; 1684 struct fcip *fptr; 1685 struct fcipstr *strp; 1686 1687 switch (cmd) { 1688 case FC_CMD_DETACH: { 1689 mutex_enter(&fcip_global_mutex); 1690 1691 if (fcip_port_head == NULL) { 1692 /* 1693 * we are all done but our fini has not been 1694 * called yet!! Let's hope we have no active 1695 * fcip instances here. - strange secnario but 1696 * no harm in having this return a success. 1697 */ 1698 fcip_check_remove_minor_node(); 1699 1700 mutex_exit(&fcip_global_mutex); 1701 return (FC_SUCCESS); 1702 } else { 1703 /* 1704 * traverse the port list 1705 */ 1706 fport = fcip_port_head; 1707 while (fport != NULL) { 1708 if (fport->fcipp_handle == 1709 port_info->port_handle) { 1710 fptr = fport->fcipp_fcip; 1711 1712 /* 1713 * Fail the port detach if there is 1714 * still an attached, bound stream on 1715 * this interface. 1716 */ 1717 1718 rw_enter(&fcipstruplock, RW_READER); 1719 1720 for (strp = fcipstrup; strp != NULL; 1721 strp = strp->sl_nextp) { 1722 if (strp->sl_fcip == fptr) { 1723 rw_exit(&fcipstruplock); 1724 mutex_exit( 1725 &fcip_global_mutex); 1726 return (FC_FAILURE); 1727 } 1728 } 1729 1730 rw_exit(&fcipstruplock); 1731 1732 /* 1733 * fail port detach if we are in 1734 * the middle of a deferred port attach 1735 * or if the port has outstanding pkts 1736 */ 1737 if (fptr != NULL) { 1738 mutex_enter(&fptr->fcip_mutex); 1739 if (fcip_check_port_busy 1740 (fptr) || 1741 (fptr->fcip_flags & 1742 FCIP_DETACHED)) { 1743 mutex_exit( 1744 &fptr->fcip_mutex); 1745 mutex_exit( 1746 &fcip_global_mutex); 1747 return (FC_FAILURE); 1748 } 1749 1750 fptr->fcip_flags |= 1751 FCIP_DETACHED; 1752 mutex_exit(&fptr->fcip_mutex); 1753 } 1754 (void) fcip_softstate_free(fport); 1755 1756 fcip_check_remove_minor_node(); 1757 mutex_exit(&fcip_global_mutex); 1758 return (FC_SUCCESS); 1759 } 1760 fport = fport->fcipp_next; 1761 } 1762 ASSERT(fport == NULL); 1763 } 1764 mutex_exit(&fcip_global_mutex); 1765 break; 1766 } 1767 case FC_CMD_POWER_DOWN: 1768 /* FALLTHROUGH */ 1769 case FC_CMD_SUSPEND: 1770 mutex_enter(&fcip_global_mutex); 1771 fport = fcip_port_head; 1772 while (fport != NULL) { 1773 if (fport->fcipp_handle == port_info->port_handle) { 1774 break; 1775 } 1776 fport = fport->fcipp_next; 1777 } 1778 if (fport == NULL) { 1779 mutex_exit(&fcip_global_mutex); 1780 break; 1781 } 1782 rval = fcip_handle_suspend(fport, cmd); 1783 mutex_exit(&fcip_global_mutex); 1784 break; 1785 default: 1786 FCIP_DEBUG(FCIP_DEBUG_DETACH, 1787 (CE_WARN, "unknown port detach command!!")); 1788 break; 1789 } 1790 return (rval); 1791 } 1792 1793 1794 /* 1795 * Returns 0 if the port is not busy, else returns non zero. 1796 */ 1797 static int 1798 fcip_check_port_busy(struct fcip *fptr) 1799 { 1800 int rval = 0, num_pkts = 0; 1801 1802 ASSERT(fptr != NULL); 1803 ASSERT(MUTEX_HELD(&fptr->fcip_mutex)); 1804 1805 mutex_enter(&fptr->fcip_dest_mutex); 1806 1807 if (fptr->fcip_flags & FCIP_PORT_BUSY || 1808 ((num_pkts = fcip_port_get_num_pkts(fptr)) > 0) || 1809 fptr->fcip_num_ipkts_pending) { 1810 rval = 1; 1811 FCIP_DEBUG(FCIP_DEBUG_DETACH, 1812 (CE_NOTE, "!fcip_check_port_busy: port is busy " 1813 "fcip_flags: 0x%x, num_pkts: 0x%x, ipkts_pending: 0x%lx!", 1814 fptr->fcip_flags, num_pkts, fptr->fcip_num_ipkts_pending)); 1815 } 1816 1817 mutex_exit(&fptr->fcip_dest_mutex); 1818 return (rval); 1819 } 1820 1821 /* 1822 * Helper routine to remove fcip's minor node 1823 * There is one minor node per system and it should be removed if there are no 1824 * other fcip instances (which has a 1:1 mapping for fp instances) present 1825 */ 1826 static void 1827 fcip_check_remove_minor_node(void) 1828 { 1829 ASSERT(MUTEX_HELD(&fcip_global_mutex)); 1830 1831 /* 1832 * If there are no more fcip (fp) instances, remove the 1833 * minor node for fcip. 1834 * Reset fcip_minor_node_created to invalidate it. 1835 */ 1836 if (fcip_num_instances == 0 && (fcip_module_dip != NULL)) { 1837 ddi_remove_minor_node(fcip_module_dip, NULL); 1838 fcip_minor_node_created = 0; 1839 } 1840 } 1841 1842 /* 1843 * This routine permits the suspend operation during a CPR/System 1844 * power management operation. The routine basically quiesces I/Os 1845 * on all active interfaces 1846 */ 1847 static int 1848 fcip_handle_suspend(fcip_port_info_t *fport, fc_detach_cmd_t cmd) 1849 { 1850 struct fcip *fptr = fport->fcipp_fcip; 1851 timeout_id_t tid; 1852 int index; 1853 int tryagain = 0; 1854 int count; 1855 struct fcipstr *tslp; 1856 1857 1858 ASSERT(fptr != NULL); 1859 mutex_enter(&fptr->fcip_mutex); 1860 1861 /* 1862 * Fail if we are in the middle of a callback. Don't use delay during 1863 * suspend since clock intrs are not available so busy wait 1864 */ 1865 count = 0; 1866 while (count++ < 15 && 1867 ((fptr->fcip_flags & FCIP_IN_CALLBACK) || 1868 (fptr->fcip_flags & FCIP_IN_TIMEOUT))) { 1869 mutex_exit(&fptr->fcip_mutex); 1870 drv_usecwait(1000000); 1871 mutex_enter(&fptr->fcip_mutex); 1872 } 1873 1874 if (fptr->fcip_flags & FCIP_IN_CALLBACK || 1875 fptr->fcip_flags & FCIP_IN_TIMEOUT) { 1876 mutex_exit(&fptr->fcip_mutex); 1877 return (FC_FAILURE); 1878 } 1879 1880 if (cmd == FC_CMD_POWER_DOWN) { 1881 if (fptr->fcip_flags & FCIP_SUSPENDED) { 1882 fptr->fcip_flags |= FCIP_POWER_DOWN; 1883 mutex_exit(&fptr->fcip_mutex); 1884 goto success; 1885 } else { 1886 fptr->fcip_flags |= FCIP_POWER_DOWN; 1887 } 1888 } else if (cmd == FC_CMD_SUSPEND) { 1889 fptr->fcip_flags |= FCIP_SUSPENDED; 1890 } else { 1891 mutex_exit(&fptr->fcip_mutex); 1892 return (FC_FAILURE); 1893 } 1894 1895 mutex_exit(&fptr->fcip_mutex); 1896 /* 1897 * If no streams are plumbed - its the easiest case - Just 1898 * bail out without having to do much 1899 */ 1900 1901 rw_enter(&fcipstruplock, RW_READER); 1902 for (tslp = fcipstrup; tslp; tslp = tslp->sl_nextp) { 1903 if (tslp->sl_fcip == fptr) { 1904 break; 1905 } 1906 } 1907 rw_exit(&fcipstruplock); 1908 1909 /* 1910 * No active streams on this port 1911 */ 1912 if (tslp == NULL) { 1913 goto success; 1914 } 1915 1916 /* 1917 * Walk through each Routing table structure and check if 1918 * the destination table has any outstanding commands. If yes 1919 * wait for the commands to drain. Since we go through each 1920 * routing table entry in succession, it may be wise to wait 1921 * only a few seconds for each entry. 1922 */ 1923 mutex_enter(&fptr->fcip_rt_mutex); 1924 while (!tryagain) { 1925 1926 tryagain = 0; 1927 for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) { 1928 struct fcip_routing_table *frp; 1929 struct fcip_dest *fdestp; 1930 la_wwn_t *pwwn; 1931 int hash_bucket; 1932 1933 frp = fptr->fcip_rtable[index]; 1934 while (frp) { 1935 /* 1936 * Mark the routing table as SUSPENDED. Even 1937 * mark the broadcast entry SUSPENDED to 1938 * prevent any ARP or other broadcasts. We 1939 * can reset the state of the broadcast 1940 * RTE when we resume. 1941 */ 1942 frp->fcipr_state = FCIP_RT_SUSPENDED; 1943 pwwn = &frp->fcipr_pwwn; 1944 1945 /* 1946 * Get hold of destination pointer 1947 */ 1948 mutex_enter(&fptr->fcip_dest_mutex); 1949 1950 hash_bucket = FCIP_DEST_HASH(pwwn->raw_wwn); 1951 ASSERT(hash_bucket < FCIP_DEST_HASH_ELEMS); 1952 1953 fdestp = fptr->fcip_dest[hash_bucket]; 1954 while (fdestp != NULL) { 1955 mutex_enter(&fdestp->fcipd_mutex); 1956 if (fdestp->fcipd_rtable) { 1957 if (fcip_wwn_compare(pwwn, 1958 &fdestp->fcipd_pwwn, 1959 FCIP_COMPARE_PWWN) == 0) { 1960 mutex_exit( 1961 &fdestp->fcipd_mutex); 1962 break; 1963 } 1964 } 1965 mutex_exit(&fdestp->fcipd_mutex); 1966 fdestp = fdestp->fcipd_next; 1967 } 1968 1969 mutex_exit(&fptr->fcip_dest_mutex); 1970 if (fdestp == NULL) { 1971 frp = frp->fcipr_next; 1972 continue; 1973 } 1974 1975 /* 1976 * Wait for fcip_wait_cmds seconds for 1977 * the commands to drain. 1978 */ 1979 count = 0; 1980 mutex_enter(&fdestp->fcipd_mutex); 1981 while (fdestp->fcipd_ncmds && 1982 count < fcip_wait_cmds) { 1983 mutex_exit(&fdestp->fcipd_mutex); 1984 mutex_exit(&fptr->fcip_rt_mutex); 1985 drv_usecwait(1000000); 1986 mutex_enter(&fptr->fcip_rt_mutex); 1987 mutex_enter(&fdestp->fcipd_mutex); 1988 count++; 1989 } 1990 /* 1991 * Check if we were able to drain all cmds 1992 * successfully. Else continue with other 1993 * ports and try during the second pass 1994 */ 1995 if (fdestp->fcipd_ncmds) { 1996 tryagain++; 1997 } 1998 mutex_exit(&fdestp->fcipd_mutex); 1999 2000 frp = frp->fcipr_next; 2001 } 2002 } 2003 if (tryagain == 0) { 2004 break; 2005 } 2006 } 2007 mutex_exit(&fptr->fcip_rt_mutex); 2008 2009 if (tryagain) { 2010 mutex_enter(&fptr->fcip_mutex); 2011 fptr->fcip_flags &= ~(FCIP_SUSPENDED | FCIP_POWER_DOWN); 2012 mutex_exit(&fptr->fcip_mutex); 2013 return (FC_FAILURE); 2014 } 2015 2016 success: 2017 mutex_enter(&fptr->fcip_mutex); 2018 tid = fptr->fcip_timeout_id; 2019 fptr->fcip_timeout_id = NULL; 2020 mutex_exit(&fptr->fcip_mutex); 2021 2022 (void) untimeout(tid); 2023 2024 return (FC_SUCCESS); 2025 } 2026 2027 /* 2028 * the getinfo(9E) entry point 2029 */ 2030 /* ARGSUSED */ 2031 static int 2032 fcip_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 2033 { 2034 int rval = DDI_FAILURE; 2035 2036 switch (cmd) { 2037 case DDI_INFO_DEVT2DEVINFO: 2038 *result = fcip_module_dip; 2039 if (*result) 2040 rval = DDI_SUCCESS; 2041 break; 2042 2043 case DDI_INFO_DEVT2INSTANCE: 2044 *result = (void *)0; 2045 rval = DDI_SUCCESS; 2046 break; 2047 default: 2048 break; 2049 } 2050 2051 return (rval); 2052 } 2053 2054 /* 2055 * called from fcip_attach to initialize kstats for the link 2056 */ 2057 /* ARGSUSED */ 2058 static void 2059 fcip_kstat_init(struct fcip *fptr) 2060 { 2061 int instance; 2062 char buf[16]; 2063 struct fcipstat *fcipstatp; 2064 2065 ASSERT(mutex_owned(&fptr->fcip_mutex)); 2066 2067 instance = ddi_get_instance(fptr->fcip_dip); 2068 (void) sprintf(buf, "fcip%d", instance); 2069 2070 #ifdef kstat 2071 fptr->fcip_kstatp = kstat_create("fcip", instance, buf, "net", 2072 KSTAT_TYPE_NAMED, 2073 (sizeof (struct fcipstat)/ sizeof (kstat_named_t)), 2074 KSTAT_FLAG_PERSISTENT); 2075 #else 2076 fptr->fcip_kstatp = kstat_create("fcip", instance, buf, "net", 2077 KSTAT_TYPE_NAMED, 2078 (sizeof (struct fcipstat)/ sizeof (kstat_named_t)), 0); 2079 #endif 2080 if (fptr->fcip_kstatp == NULL) { 2081 FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_WARN, "kstat created failed")); 2082 return; 2083 } 2084 2085 fcipstatp = (struct fcipstat *)fptr->fcip_kstatp->ks_data; 2086 kstat_named_init(&fcipstatp->fcips_ipackets, "ipackets", 2087 KSTAT_DATA_ULONG); 2088 kstat_named_init(&fcipstatp->fcips_ierrors, "ierrors", 2089 KSTAT_DATA_ULONG); 2090 kstat_named_init(&fcipstatp->fcips_opackets, "opackets", 2091 KSTAT_DATA_ULONG); 2092 kstat_named_init(&fcipstatp->fcips_oerrors, "oerrors", 2093 KSTAT_DATA_ULONG); 2094 kstat_named_init(&fcipstatp->fcips_collisions, "collisions", 2095 KSTAT_DATA_ULONG); 2096 kstat_named_init(&fcipstatp->fcips_nocanput, "nocanput", 2097 KSTAT_DATA_ULONG); 2098 kstat_named_init(&fcipstatp->fcips_allocbfail, "allocbfail", 2099 KSTAT_DATA_ULONG); 2100 2101 kstat_named_init(&fcipstatp->fcips_defer, "defer", 2102 KSTAT_DATA_ULONG); 2103 kstat_named_init(&fcipstatp->fcips_fram, "fram", 2104 KSTAT_DATA_ULONG); 2105 kstat_named_init(&fcipstatp->fcips_crc, "crc", 2106 KSTAT_DATA_ULONG); 2107 kstat_named_init(&fcipstatp->fcips_oflo, "oflo", 2108 KSTAT_DATA_ULONG); 2109 kstat_named_init(&fcipstatp->fcips_uflo, "uflo", 2110 KSTAT_DATA_ULONG); 2111 kstat_named_init(&fcipstatp->fcips_missed, "missed", 2112 KSTAT_DATA_ULONG); 2113 kstat_named_init(&fcipstatp->fcips_tlcol, "tlcol", 2114 KSTAT_DATA_ULONG); 2115 kstat_named_init(&fcipstatp->fcips_trtry, "trtry", 2116 KSTAT_DATA_ULONG); 2117 kstat_named_init(&fcipstatp->fcips_tnocar, "tnocar", 2118 KSTAT_DATA_ULONG); 2119 kstat_named_init(&fcipstatp->fcips_inits, "inits", 2120 KSTAT_DATA_ULONG); 2121 kstat_named_init(&fcipstatp->fcips_notbufs, "notbufs", 2122 KSTAT_DATA_ULONG); 2123 kstat_named_init(&fcipstatp->fcips_norbufs, "norbufs", 2124 KSTAT_DATA_ULONG); 2125 kstat_named_init(&fcipstatp->fcips_allocbfail, "allocbfail", 2126 KSTAT_DATA_ULONG); 2127 2128 /* 2129 * required by kstat for MIB II objects(RFC 1213) 2130 */ 2131 kstat_named_init(&fcipstatp->fcips_rcvbytes, "fcips_rcvbytes", 2132 KSTAT_DATA_ULONG); /* # octets received */ 2133 /* MIB - ifInOctets */ 2134 kstat_named_init(&fcipstatp->fcips_xmtbytes, "fcips_xmtbytes", 2135 KSTAT_DATA_ULONG); /* # octets xmitted */ 2136 /* MIB - ifOutOctets */ 2137 kstat_named_init(&fcipstatp->fcips_multircv, "fcips_multircv", 2138 KSTAT_DATA_ULONG); /* # multicast packets */ 2139 /* delivered to upper layer */ 2140 /* MIB - ifInNUcastPkts */ 2141 kstat_named_init(&fcipstatp->fcips_multixmt, "fcips_multixmt", 2142 KSTAT_DATA_ULONG); /* # multicast packets */ 2143 /* requested to be sent */ 2144 /* MIB - ifOutNUcastPkts */ 2145 kstat_named_init(&fcipstatp->fcips_brdcstrcv, "fcips_brdcstrcv", 2146 KSTAT_DATA_ULONG); /* # broadcast packets */ 2147 /* delivered to upper layer */ 2148 /* MIB - ifInNUcastPkts */ 2149 kstat_named_init(&fcipstatp->fcips_brdcstxmt, "fcips_brdcstxmt", 2150 KSTAT_DATA_ULONG); /* # broadcast packets */ 2151 /* requested to be sent */ 2152 /* MIB - ifOutNUcastPkts */ 2153 kstat_named_init(&fcipstatp->fcips_norcvbuf, "fcips_norcvbuf", 2154 KSTAT_DATA_ULONG); /* # rcv packets discarded */ 2155 /* MIB - ifInDiscards */ 2156 kstat_named_init(&fcipstatp->fcips_noxmtbuf, "fcips_noxmtbuf", 2157 KSTAT_DATA_ULONG); /* # xmt packets discarded */ 2158 2159 fptr->fcip_kstatp->ks_update = fcip_stat_update; 2160 fptr->fcip_kstatp->ks_private = (void *) fptr; 2161 kstat_install(fptr->fcip_kstatp); 2162 } 2163 2164 /* 2165 * Update the defined kstats for netstat et al to use 2166 */ 2167 /* ARGSUSED */ 2168 static int 2169 fcip_stat_update(kstat_t *fcip_statp, int val) 2170 { 2171 struct fcipstat *fcipstatp; 2172 struct fcip *fptr; 2173 2174 fptr = (struct fcip *)fcip_statp->ks_private; 2175 fcipstatp = (struct fcipstat *)fcip_statp->ks_data; 2176 2177 if (val == KSTAT_WRITE) { 2178 fptr->fcip_ipackets = fcipstatp->fcips_ipackets.value.ul; 2179 fptr->fcip_ierrors = fcipstatp->fcips_ierrors.value.ul; 2180 fptr->fcip_opackets = fcipstatp->fcips_opackets.value.ul; 2181 fptr->fcip_oerrors = fcipstatp->fcips_oerrors.value.ul; 2182 fptr->fcip_collisions = fcipstatp->fcips_collisions.value.ul; 2183 fptr->fcip_defer = fcipstatp->fcips_defer.value.ul; 2184 fptr->fcip_fram = fcipstatp->fcips_fram.value.ul; 2185 fptr->fcip_crc = fcipstatp->fcips_crc.value.ul; 2186 fptr->fcip_oflo = fcipstatp->fcips_oflo.value.ul; 2187 fptr->fcip_uflo = fcipstatp->fcips_uflo.value.ul; 2188 fptr->fcip_missed = fcipstatp->fcips_missed.value.ul; 2189 fptr->fcip_tlcol = fcipstatp->fcips_tlcol.value.ul; 2190 fptr->fcip_trtry = fcipstatp->fcips_trtry.value.ul; 2191 fptr->fcip_tnocar = fcipstatp->fcips_tnocar.value.ul; 2192 fptr->fcip_inits = fcipstatp->fcips_inits.value.ul; 2193 fptr->fcip_notbufs = fcipstatp->fcips_notbufs.value.ul; 2194 fptr->fcip_norbufs = fcipstatp->fcips_norbufs.value.ul; 2195 fptr->fcip_nocanput = fcipstatp->fcips_nocanput.value.ul; 2196 fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul; 2197 fptr->fcip_rcvbytes = fcipstatp->fcips_rcvbytes.value.ul; 2198 fptr->fcip_xmtbytes = fcipstatp->fcips_xmtbytes.value.ul; 2199 fptr->fcip_multircv = fcipstatp->fcips_multircv.value.ul; 2200 fptr->fcip_multixmt = fcipstatp->fcips_multixmt.value.ul; 2201 fptr->fcip_brdcstrcv = fcipstatp->fcips_brdcstrcv.value.ul; 2202 fptr->fcip_norcvbuf = fcipstatp->fcips_norcvbuf.value.ul; 2203 fptr->fcip_noxmtbuf = fcipstatp->fcips_noxmtbuf.value.ul; 2204 fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul; 2205 fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul; 2206 fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul; 2207 fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul; 2208 fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul; 2209 fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul; 2210 fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul; 2211 fptr->fcip_allocbfail = fcipstatp->fcips_allocbfail.value.ul; 2212 2213 } else { 2214 fcipstatp->fcips_ipackets.value.ul = fptr->fcip_ipackets; 2215 fcipstatp->fcips_ierrors.value.ul = fptr->fcip_ierrors; 2216 fcipstatp->fcips_opackets.value.ul = fptr->fcip_opackets; 2217 fcipstatp->fcips_oerrors.value.ul = fptr->fcip_oerrors; 2218 fcipstatp->fcips_collisions.value.ul = fptr->fcip_collisions; 2219 fcipstatp->fcips_nocanput.value.ul = fptr->fcip_nocanput; 2220 fcipstatp->fcips_allocbfail.value.ul = fptr->fcip_allocbfail; 2221 fcipstatp->fcips_defer.value.ul = fptr->fcip_defer; 2222 fcipstatp->fcips_fram.value.ul = fptr->fcip_fram; 2223 fcipstatp->fcips_crc.value.ul = fptr->fcip_crc; 2224 fcipstatp->fcips_oflo.value.ul = fptr->fcip_oflo; 2225 fcipstatp->fcips_uflo.value.ul = fptr->fcip_uflo; 2226 fcipstatp->fcips_missed.value.ul = fptr->fcip_missed; 2227 fcipstatp->fcips_tlcol.value.ul = fptr->fcip_tlcol; 2228 fcipstatp->fcips_trtry.value.ul = fptr->fcip_trtry; 2229 fcipstatp->fcips_tnocar.value.ul = fptr->fcip_tnocar; 2230 fcipstatp->fcips_inits.value.ul = fptr->fcip_inits; 2231 fcipstatp->fcips_norbufs.value.ul = fptr->fcip_norbufs; 2232 fcipstatp->fcips_notbufs.value.ul = fptr->fcip_notbufs; 2233 fcipstatp->fcips_rcvbytes.value.ul = fptr->fcip_rcvbytes; 2234 fcipstatp->fcips_xmtbytes.value.ul = fptr->fcip_xmtbytes; 2235 fcipstatp->fcips_multircv.value.ul = fptr->fcip_multircv; 2236 fcipstatp->fcips_multixmt.value.ul = fptr->fcip_multixmt; 2237 fcipstatp->fcips_brdcstrcv.value.ul = fptr->fcip_brdcstrcv; 2238 fcipstatp->fcips_brdcstxmt.value.ul = fptr->fcip_brdcstxmt; 2239 fcipstatp->fcips_norcvbuf.value.ul = fptr->fcip_norcvbuf; 2240 fcipstatp->fcips_noxmtbuf.value.ul = fptr->fcip_noxmtbuf; 2241 2242 } 2243 return (0); 2244 } 2245 2246 2247 /* 2248 * fcip_statec_cb: handles all required state change callback notifications 2249 * it receives from the transport 2250 */ 2251 /* ARGSUSED */ 2252 static void 2253 fcip_statec_cb(opaque_t ulp_handle, opaque_t phandle, 2254 uint32_t port_state, uint32_t port_top, fc_portmap_t changelist[], 2255 uint32_t listlen, uint32_t sid) 2256 { 2257 fcip_port_info_t *fport; 2258 struct fcip *fptr; 2259 struct fcipstr *slp; 2260 queue_t *wrq; 2261 int instance; 2262 int index; 2263 struct fcip_routing_table *frtp; 2264 2265 fport = fcip_get_port(phandle); 2266 2267 if (fport == NULL) { 2268 return; 2269 } 2270 2271 fptr = fport->fcipp_fcip; 2272 ASSERT(fptr != NULL); 2273 2274 if (fptr == NULL) { 2275 return; 2276 } 2277 2278 instance = ddi_get_instance(fport->fcipp_dip); 2279 2280 FCIP_TNF_PROBE_4((fcip_statec_cb, "fcip io", /* CSTYLED */, 2281 tnf_string, msg, "state change callback", 2282 tnf_uint, instance, instance, 2283 tnf_uint, S_ID, sid, 2284 tnf_int, count, listlen)); 2285 FCIP_DEBUG(FCIP_DEBUG_ELS, 2286 (CE_NOTE, "fcip%d, state change callback: state:0x%x, " 2287 "S_ID:0x%x, count:0x%x", instance, port_state, sid, listlen)); 2288 2289 mutex_enter(&fptr->fcip_mutex); 2290 2291 if ((fptr->fcip_flags & (FCIP_DETACHING | FCIP_DETACHED)) || 2292 (fptr->fcip_flags & (FCIP_SUSPENDED | FCIP_POWER_DOWN))) { 2293 mutex_exit(&fptr->fcip_mutex); 2294 return; 2295 } 2296 2297 /* 2298 * set fcip flags to indicate we are in the middle of a 2299 * state change callback so we can wait till the statechange 2300 * is handled before succeeding/failing the SUSPEND/POWER DOWN. 2301 */ 2302 fptr->fcip_flags |= FCIP_IN_SC_CB; 2303 2304 fport->fcipp_pstate = port_state; 2305 2306 /* 2307 * Check if topology changed. If Yes - Modify the broadcast 2308 * RTE entries to understand the new broadcast D_IDs 2309 */ 2310 if (fport->fcipp_topology != port_top && 2311 (port_top != FC_TOP_UNKNOWN)) { 2312 /* REMOVE later */ 2313 FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_NOTE, 2314 "topology changed: Old topology: 0x%x New topology 0x%x", 2315 fport->fcipp_topology, port_top)); 2316 /* 2317 * If topology changed - attempt a rediscovery of 2318 * devices. Helps specially in Fabric/Public loops 2319 * and if on_demand_node_creation is disabled 2320 */ 2321 fport->fcipp_topology = port_top; 2322 fcip_handle_topology(fptr); 2323 } 2324 2325 mutex_exit(&fptr->fcip_mutex); 2326 2327 switch (FC_PORT_STATE_MASK(port_state)) { 2328 case FC_STATE_ONLINE: 2329 /* FALLTHROUGH */ 2330 case FC_STATE_LIP: 2331 /* FALLTHROUGH */ 2332 case FC_STATE_LIP_LBIT_SET: 2333 2334 /* 2335 * nothing to do here actually other than if we 2336 * were actually logged onto a port in the devlist 2337 * (which indicates active communication between 2338 * the host port and the port in the changelist). 2339 * If however we are in a private loop or point to 2340 * point mode, we need to check for any IP capable 2341 * ports and update our routing table. 2342 */ 2343 switch (port_top) { 2344 case FC_TOP_FABRIC: 2345 /* 2346 * This indicates a fabric port with a NameServer. 2347 * Check the devlist to see if we are in active 2348 * communication with a port on the devlist. 2349 */ 2350 FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_NOTE, 2351 "Statec_cb: fabric topology")); 2352 fcip_rt_update(fptr, changelist, listlen); 2353 break; 2354 case FC_TOP_NO_NS: 2355 /* 2356 * No nameserver - so treat it like a Private loop 2357 * or point to point topology and get a map of 2358 * devices on the link and get IP capable ports to 2359 * to update the routing table. 2360 */ 2361 FCIP_DEBUG(FCIP_DEBUG_ELS, 2362 (CE_NOTE, "Statec_cb: NO_NS topology")); 2363 /* FALLTHROUGH */ 2364 case FC_TOP_PRIVATE_LOOP: 2365 FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_NOTE, 2366 "Statec_cb: Pvt_Loop topology")); 2367 /* FALLTHROUGH */ 2368 case FC_TOP_PT_PT: 2369 /* 2370 * call get_port_map() and update routing table 2371 */ 2372 fcip_rt_update(fptr, changelist, listlen); 2373 break; 2374 default: 2375 FCIP_DEBUG(FCIP_DEBUG_ELS, 2376 (CE_NOTE, "Statec_cb: Unknown topology")); 2377 } 2378 2379 /* 2380 * We should now enable the Queues and permit I/Os 2381 * to flow through downstream. The update of routing 2382 * table should have flushed out any port entries that 2383 * don't exist or are not available after the state change 2384 */ 2385 mutex_enter(&fptr->fcip_mutex); 2386 fptr->fcip_port_state = FCIP_PORT_ONLINE; 2387 if (fptr->fcip_flags & FCIP_LINK_DOWN) { 2388 fptr->fcip_flags &= ~FCIP_LINK_DOWN; 2389 } 2390 mutex_exit(&fptr->fcip_mutex); 2391 2392 /* 2393 * Enable write queues 2394 */ 2395 rw_enter(&fcipstruplock, RW_READER); 2396 for (slp = fcipstrup; slp != NULL; slp = slp->sl_nextp) { 2397 if (slp && slp->sl_fcip == fptr) { 2398 wrq = WR(slp->sl_rq); 2399 if (wrq->q_flag & QFULL) { 2400 qenable(wrq); 2401 } 2402 } 2403 } 2404 rw_exit(&fcipstruplock); 2405 break; 2406 case FC_STATE_OFFLINE: 2407 /* 2408 * mark the port_state OFFLINE and wait for it to 2409 * become online. Any new messages in this state will 2410 * simply be queued back up. If the port does not 2411 * come online in a short while, we can begin failing 2412 * messages and flush the routing table 2413 */ 2414 mutex_enter(&fptr->fcip_mutex); 2415 fptr->fcip_mark_offline = fptr->fcip_timeout_ticks + 2416 FCIP_OFFLINE_TIMEOUT; 2417 fptr->fcip_port_state = FCIP_PORT_OFFLINE; 2418 mutex_exit(&fptr->fcip_mutex); 2419 2420 /* 2421 * Mark all Routing table entries as invalid to prevent 2422 * any commands from trickling through to ports that 2423 * have disappeared from under us 2424 */ 2425 mutex_enter(&fptr->fcip_rt_mutex); 2426 for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) { 2427 frtp = fptr->fcip_rtable[index]; 2428 while (frtp) { 2429 frtp->fcipr_state = PORT_DEVICE_INVALID; 2430 frtp = frtp->fcipr_next; 2431 } 2432 } 2433 mutex_exit(&fptr->fcip_rt_mutex); 2434 2435 break; 2436 2437 case FC_STATE_RESET_REQUESTED: 2438 /* 2439 * Release all Unsolicited buffers back to transport/FCA. 2440 * This also means the port state is marked offline - so 2441 * we may have to do what OFFLINE state requires us to do. 2442 * Care must be taken to wait for any active unsolicited 2443 * buffer with the other Streams modules - so wait for 2444 * a freeb if the unsolicited buffer is passed back all 2445 * the way upstream. 2446 */ 2447 mutex_enter(&fptr->fcip_mutex); 2448 2449 #ifdef FCIP_ESBALLOC 2450 while (fptr->fcip_ub_upstream) { 2451 cv_wait(&fptr->fcip_ub_cv, &fptr->fcip_mutex); 2452 } 2453 #endif /* FCIP_ESBALLOC */ 2454 2455 fptr->fcip_mark_offline = fptr->fcip_timeout_ticks + 2456 FCIP_OFFLINE_TIMEOUT; 2457 fptr->fcip_port_state = FCIP_PORT_OFFLINE; 2458 mutex_exit(&fptr->fcip_mutex); 2459 break; 2460 2461 case FC_STATE_DEVICE_CHANGE: 2462 if (listlen) { 2463 fcip_rt_update(fptr, changelist, listlen); 2464 } 2465 break; 2466 case FC_STATE_RESET: 2467 /* 2468 * Not much to do I guess - wait for port to become 2469 * ONLINE. If the port doesn't become online in a short 2470 * while, the upper layers abort any request themselves. 2471 * We can just putback the messages in the streams queues 2472 * if the link is offline 2473 */ 2474 break; 2475 } 2476 mutex_enter(&fptr->fcip_mutex); 2477 fptr->fcip_flags &= ~(FCIP_IN_SC_CB); 2478 mutex_exit(&fptr->fcip_mutex); 2479 } 2480 2481 /* 2482 * Given a port handle, return the fcip_port_info structure corresponding 2483 * to that port handle. The transport allocates and communicates with 2484 * ULPs using port handles 2485 */ 2486 static fcip_port_info_t * 2487 fcip_get_port(opaque_t phandle) 2488 { 2489 fcip_port_info_t *fport; 2490 2491 ASSERT(phandle != NULL); 2492 2493 mutex_enter(&fcip_global_mutex); 2494 fport = fcip_port_head; 2495 2496 while (fport != NULL) { 2497 if (fport->fcipp_handle == phandle) { 2498 /* found */ 2499 break; 2500 } 2501 fport = fport->fcipp_next; 2502 } 2503 2504 mutex_exit(&fcip_global_mutex); 2505 2506 return (fport); 2507 } 2508 2509 /* 2510 * Handle inbound ELS requests received by the transport. We are only 2511 * intereseted in FARP/InARP mostly. 2512 */ 2513 /* ARGSUSED */ 2514 static int 2515 fcip_els_cb(opaque_t ulp_handle, opaque_t phandle, 2516 fc_unsol_buf_t *buf, uint32_t claimed) 2517 { 2518 fcip_port_info_t *fport; 2519 struct fcip *fptr; 2520 int instance; 2521 uchar_t r_ctl; 2522 uchar_t ls_code; 2523 la_els_farp_t farp_cmd; 2524 la_els_farp_t *fcmd; 2525 int rval = FC_UNCLAIMED; 2526 2527 fport = fcip_get_port(phandle); 2528 if (fport == NULL) { 2529 return (FC_UNCLAIMED); 2530 } 2531 2532 fptr = fport->fcipp_fcip; 2533 ASSERT(fptr != NULL); 2534 if (fptr == NULL) { 2535 return (FC_UNCLAIMED); 2536 } 2537 2538 instance = ddi_get_instance(fport->fcipp_dip); 2539 2540 mutex_enter(&fptr->fcip_mutex); 2541 if ((fptr->fcip_flags & (FCIP_DETACHING | FCIP_DETACHED)) || 2542 (fptr->fcip_flags & (FCIP_SUSPENDED | FCIP_POWER_DOWN))) { 2543 mutex_exit(&fptr->fcip_mutex); 2544 return (FC_UNCLAIMED); 2545 } 2546 2547 /* 2548 * set fcip flags to indicate we are in the middle of a 2549 * ELS callback so we can wait till the statechange 2550 * is handled before succeeding/failing the SUSPEND/POWER DOWN. 2551 */ 2552 fptr->fcip_flags |= FCIP_IN_ELS_CB; 2553 mutex_exit(&fptr->fcip_mutex); 2554 2555 FCIP_TNF_PROBE_2((fcip_els_cb, "fcip io", /* CSTYLED */, 2556 tnf_string, msg, "ELS callback", 2557 tnf_uint, instance, instance)); 2558 2559 FCIP_DEBUG(FCIP_DEBUG_ELS, 2560 (CE_NOTE, "fcip%d, ELS callback , ", instance)); 2561 2562 r_ctl = buf->ub_frame.r_ctl; 2563 switch (r_ctl & R_CTL_ROUTING) { 2564 case R_CTL_EXTENDED_SVC: 2565 if (r_ctl == R_CTL_ELS_REQ) { 2566 ls_code = buf->ub_buffer[0]; 2567 if (ls_code == LA_ELS_FARP_REQ) { 2568 /* 2569 * Inbound FARP broadcast request 2570 */ 2571 if (buf->ub_bufsize != sizeof (la_els_farp_t)) { 2572 FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN, 2573 "Invalid FARP req buffer size " 2574 "expected 0x%lx, got 0x%x", 2575 (long)(sizeof (la_els_farp_t)), 2576 buf->ub_bufsize)); 2577 rval = FC_UNCLAIMED; 2578 goto els_cb_done; 2579 } 2580 fcmd = (la_els_farp_t *)buf; 2581 if (fcip_wwn_compare(&fcmd->resp_nwwn, 2582 &fport->fcipp_nwwn, 2583 FCIP_COMPARE_NWWN) != 0) { 2584 rval = FC_UNCLAIMED; 2585 goto els_cb_done; 2586 } 2587 /* 2588 * copy the FARP request and release the 2589 * unsolicited buffer 2590 */ 2591 fcmd = &farp_cmd; 2592 bcopy((void *)buf, (void *)fcmd, 2593 sizeof (la_els_farp_t)); 2594 (void) fc_ulp_ubrelease(fport->fcipp_handle, 1, 2595 &buf->ub_token); 2596 2597 if (fcip_farp_supported && 2598 fcip_handle_farp_request(fptr, fcmd) == 2599 FC_SUCCESS) { 2600 /* 2601 * We successfully sent out a FARP 2602 * reply to the requesting port 2603 */ 2604 rval = FC_SUCCESS; 2605 goto els_cb_done; 2606 } else { 2607 rval = FC_UNCLAIMED; 2608 goto els_cb_done; 2609 } 2610 } 2611 } else if (r_ctl == R_CTL_ELS_RSP) { 2612 ls_code = buf->ub_buffer[0]; 2613 if (ls_code == LA_ELS_FARP_REPLY) { 2614 /* 2615 * We received a REPLY to our FARP request 2616 */ 2617 if (buf->ub_bufsize != sizeof (la_els_farp_t)) { 2618 FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN, 2619 "Invalid FARP req buffer size " 2620 "expected 0x%lx, got 0x%x", 2621 (long)(sizeof (la_els_farp_t)), 2622 buf->ub_bufsize)); 2623 rval = FC_UNCLAIMED; 2624 goto els_cb_done; 2625 } 2626 fcmd = &farp_cmd; 2627 bcopy((void *)buf, (void *)fcmd, 2628 sizeof (la_els_farp_t)); 2629 (void) fc_ulp_ubrelease(fport->fcipp_handle, 1, 2630 &buf->ub_token); 2631 if (fcip_farp_supported && 2632 fcip_handle_farp_response(fptr, fcmd) == 2633 FC_SUCCESS) { 2634 FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_NOTE, 2635 "Successfully recevied a FARP " 2636 "response")); 2637 mutex_enter(&fptr->fcip_mutex); 2638 fptr->fcip_farp_rsp_flag = 1; 2639 cv_signal(&fptr->fcip_farp_cv); 2640 mutex_exit(&fptr->fcip_mutex); 2641 rval = FC_SUCCESS; 2642 goto els_cb_done; 2643 } else { 2644 FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN, 2645 "Unable to handle a FARP response " 2646 "receive")); 2647 rval = FC_UNCLAIMED; 2648 goto els_cb_done; 2649 } 2650 } 2651 } 2652 break; 2653 default: 2654 break; 2655 } 2656 els_cb_done: 2657 mutex_enter(&fptr->fcip_mutex); 2658 fptr->fcip_flags &= ~(FCIP_IN_ELS_CB); 2659 mutex_exit(&fptr->fcip_mutex); 2660 return (rval); 2661 } 2662 2663 2664 /* 2665 * Handle inbound FARP requests 2666 */ 2667 static int 2668 fcip_handle_farp_request(struct fcip *fptr, la_els_farp_t *fcmd) 2669 { 2670 fcip_pkt_t *fcip_pkt; 2671 fc_packet_t *fc_pkt; 2672 fcip_port_info_t *fport = fptr->fcip_port_info; 2673 int rval = FC_FAILURE; 2674 opaque_t fca_dev; 2675 fc_portmap_t map; 2676 struct fcip_routing_table *frp; 2677 struct fcip_dest *fdestp; 2678 2679 /* 2680 * Add an entry for the remote port into our routing and destination 2681 * tables. 2682 */ 2683 map.map_did = fcmd->req_id; 2684 map.map_hard_addr.hard_addr = fcmd->req_id.port_id; 2685 map.map_state = PORT_DEVICE_VALID; 2686 map.map_type = PORT_DEVICE_NEW; 2687 map.map_flags = 0; 2688 map.map_pd = NULL; 2689 bcopy((void *)&fcmd->req_pwwn, (void *)&map.map_pwwn, 2690 sizeof (la_wwn_t)); 2691 bcopy((void *)&fcmd->req_nwwn, (void *)&map.map_nwwn, 2692 sizeof (la_wwn_t)); 2693 fcip_rt_update(fptr, &map, 1); 2694 mutex_enter(&fptr->fcip_rt_mutex); 2695 frp = fcip_lookup_rtable(fptr, &fcmd->req_pwwn, FCIP_COMPARE_NWWN); 2696 mutex_exit(&fptr->fcip_rt_mutex); 2697 2698 fdestp = fcip_add_dest(fptr, frp); 2699 2700 fcip_pkt = fcip_ipkt_alloc(fptr, sizeof (la_els_farp_t), 2701 sizeof (la_els_farp_t), NULL, KM_SLEEP); 2702 if (fcip_pkt == NULL) { 2703 rval = FC_FAILURE; 2704 goto farp_done; 2705 } 2706 /* 2707 * Fill in our port's PWWN and NWWN 2708 */ 2709 fcmd->resp_pwwn = fport->fcipp_pwwn; 2710 fcmd->resp_nwwn = fport->fcipp_nwwn; 2711 2712 fcip_init_unicast_pkt(fcip_pkt, fport->fcipp_sid, 2713 fcmd->req_id, NULL); 2714 2715 fca_dev = 2716 fc_ulp_get_fca_device(fport->fcipp_handle, fcmd->req_id); 2717 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 2718 fc_pkt->pkt_cmd_fhdr.r_ctl = R_CTL_ELS_RSP; 2719 fc_pkt->pkt_fca_device = fca_dev; 2720 fcip_pkt->fcip_pkt_dest = fdestp; 2721 2722 /* 2723 * Attempt a PLOGI again 2724 */ 2725 if (fcmd->resp_flags & FARP_INIT_P_LOGI) { 2726 if (fcip_do_plogi(fptr, frp) != FC_SUCCESS) { 2727 /* 2728 * Login to the remote port failed. There is no 2729 * point continuing with the FARP request further 2730 * so bail out here. 2731 */ 2732 frp->fcipr_state = PORT_DEVICE_INVALID; 2733 rval = FC_FAILURE; 2734 goto farp_done; 2735 } 2736 } 2737 2738 FCIP_CP_OUT(fcmd, fc_pkt->pkt_cmd, fc_pkt->pkt_cmd_acc, 2739 sizeof (la_els_farp_t)); 2740 2741 rval = fc_ulp_issue_els(fport->fcipp_handle, fc_pkt); 2742 if (rval != FC_SUCCESS) { 2743 FCIP_TNF_PROBE_2((fcip_handle_farp_request, "fcip io", 2744 /* CSTYLED */, tnf_string, msg, 2745 "fcip_transport of farp reply failed", 2746 tnf_uint, rval, rval)); 2747 FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN, 2748 "fcip_transport of farp reply failed 0x%x", rval)); 2749 } 2750 2751 farp_done: 2752 return (rval); 2753 } 2754 2755 2756 /* 2757 * Handle FARP responses to our FARP requests. When we receive a FARP 2758 * reply, we need to add the entry for the Port that replied into our 2759 * routing and destination hash tables. It is possible that the remote 2760 * port did not login into us (FARP responses can be received without 2761 * a PLOGI) 2762 */ 2763 static int 2764 fcip_handle_farp_response(struct fcip *fptr, la_els_farp_t *fcmd) 2765 { 2766 int rval = FC_FAILURE; 2767 fc_portmap_t map; 2768 struct fcip_routing_table *frp; 2769 struct fcip_dest *fdestp; 2770 2771 /* 2772 * Add an entry for the remote port into our routing and destination 2773 * tables. 2774 */ 2775 map.map_did = fcmd->dest_id; 2776 map.map_hard_addr.hard_addr = fcmd->dest_id.port_id; 2777 map.map_state = PORT_DEVICE_VALID; 2778 map.map_type = PORT_DEVICE_NEW; 2779 map.map_flags = 0; 2780 map.map_pd = NULL; 2781 bcopy((void *)&fcmd->resp_pwwn, (void *)&map.map_pwwn, 2782 sizeof (la_wwn_t)); 2783 bcopy((void *)&fcmd->resp_nwwn, (void *)&map.map_nwwn, 2784 sizeof (la_wwn_t)); 2785 fcip_rt_update(fptr, &map, 1); 2786 mutex_enter(&fptr->fcip_rt_mutex); 2787 frp = fcip_lookup_rtable(fptr, &fcmd->resp_pwwn, FCIP_COMPARE_NWWN); 2788 mutex_exit(&fptr->fcip_rt_mutex); 2789 2790 fdestp = fcip_add_dest(fptr, frp); 2791 2792 if (fdestp != NULL) { 2793 rval = FC_SUCCESS; 2794 } 2795 return (rval); 2796 } 2797 2798 2799 #define FCIP_HDRS_LENGTH \ 2800 sizeof (fcph_network_hdr_t)+sizeof (llc_snap_hdr_t)+sizeof (ipha_t) 2801 2802 /* 2803 * fcip_data_cb is the heart of most IP operations. This routine is called 2804 * by the transport when any unsolicited IP data arrives at a port (which 2805 * is almost all IP data). This routine then strips off the Network header 2806 * from the payload (after authenticating the received payload ofcourse), 2807 * creates a message blk and sends the data upstream. You will see ugly 2808 * #defines because of problems with using esballoc() as opposed to 2809 * allocb to prevent an extra copy of data. We should probably move to 2810 * esballoc entirely when the MTU eventually will be larger than 1500 bytes 2811 * since copies will get more expensive then. At 1500 byte MTUs, there is 2812 * no noticable difference between using allocb and esballoc. The other 2813 * caveat is that the qlc firmware still cannot tell us accurately the 2814 * no. of valid bytes in the unsol buffer it DMA'ed so we have to resort 2815 * to looking into the IP header and hoping that the no. of bytes speficified 2816 * in the header was actually received. 2817 */ 2818 /* ARGSUSED */ 2819 static int 2820 fcip_data_cb(opaque_t ulp_handle, opaque_t phandle, 2821 fc_unsol_buf_t *buf, uint32_t claimed) 2822 { 2823 fcip_port_info_t *fport; 2824 struct fcip *fptr; 2825 fcph_network_hdr_t *nhdr; 2826 llc_snap_hdr_t *snaphdr; 2827 mblk_t *bp; 2828 uint32_t len; 2829 uint32_t hdrlen; 2830 ushort_t type; 2831 ipha_t *iphdr; 2832 int rval; 2833 2834 #ifdef FCIP_ESBALLOC 2835 frtn_t *free_ubuf; 2836 struct fcip_esballoc_arg *fesb_argp; 2837 #endif /* FCIP_ESBALLOC */ 2838 2839 fport = fcip_get_port(phandle); 2840 if (fport == NULL) { 2841 return (FC_UNCLAIMED); 2842 } 2843 2844 fptr = fport->fcipp_fcip; 2845 ASSERT(fptr != NULL); 2846 2847 if (fptr == NULL) { 2848 return (FC_UNCLAIMED); 2849 } 2850 2851 mutex_enter(&fptr->fcip_mutex); 2852 if ((fptr->fcip_flags & (FCIP_DETACHING | FCIP_DETACHED)) || 2853 (fptr->fcip_flags & (FCIP_SUSPENDED | FCIP_POWER_DOWN))) { 2854 mutex_exit(&fptr->fcip_mutex); 2855 rval = FC_UNCLAIMED; 2856 goto data_cb_done; 2857 } 2858 2859 /* 2860 * set fcip flags to indicate we are in the middle of a 2861 * data callback so we can wait till the statechange 2862 * is handled before succeeding/failing the SUSPEND/POWER DOWN. 2863 */ 2864 fptr->fcip_flags |= FCIP_IN_DATA_CB; 2865 mutex_exit(&fptr->fcip_mutex); 2866 2867 FCIP_TNF_PROBE_2((fcip_data_cb, "fcip io", /* CSTYLED */, 2868 tnf_string, msg, "data callback", 2869 tnf_int, instance, ddi_get_instance(fport->fcipp_dip))); 2870 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 2871 (CE_NOTE, "fcip%d, data callback", 2872 ddi_get_instance(fport->fcipp_dip))); 2873 2874 /* 2875 * get to the network and snap headers in the payload 2876 */ 2877 nhdr = (fcph_network_hdr_t *)buf->ub_buffer; 2878 snaphdr = (llc_snap_hdr_t *)(buf->ub_buffer + 2879 sizeof (fcph_network_hdr_t)); 2880 2881 hdrlen = sizeof (fcph_network_hdr_t) + sizeof (llc_snap_hdr_t); 2882 2883 /* 2884 * get the IP header to obtain the no. of bytes we need to read 2885 * off from the unsol buffer. This obviously is because not all 2886 * data fills up the unsol buffer completely and the firmware 2887 * doesn't tell us how many valid bytes are in there as well 2888 */ 2889 iphdr = (ipha_t *)(buf->ub_buffer + hdrlen); 2890 snaphdr->pid = BE_16(snaphdr->pid); 2891 type = snaphdr->pid; 2892 2893 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 2894 (CE_CONT, "SNAPHDR: dsap %x, ssap %x, ctrl %x\n", 2895 snaphdr->dsap, snaphdr->ssap, snaphdr->ctrl)); 2896 2897 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 2898 (CE_CONT, "oui[0] 0x%x oui[1] 0x%x oui[2] 0x%x pid 0x%x\n", 2899 snaphdr->oui[0], snaphdr->oui[1], snaphdr->oui[2], snaphdr->pid)); 2900 2901 /* Authneticate, Authenticate */ 2902 if (type == ETHERTYPE_IP) { 2903 len = hdrlen + BE_16(iphdr->ipha_length); 2904 } else if (type == ETHERTYPE_ARP) { 2905 len = hdrlen + 28; 2906 } else { 2907 len = buf->ub_bufsize; 2908 } 2909 2910 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 2911 (CE_CONT, "effective packet length is %d bytes.\n", len)); 2912 2913 if (len < hdrlen || len > FCIP_UB_SIZE) { 2914 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 2915 (CE_NOTE, "Incorrect buffer size %d bytes", len)); 2916 rval = FC_UNCLAIMED; 2917 goto data_cb_done; 2918 } 2919 2920 if (buf->ub_frame.type != FC_TYPE_IS8802_SNAP) { 2921 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, (CE_NOTE, "Not IP/ARP data")); 2922 rval = FC_UNCLAIMED; 2923 goto data_cb_done; 2924 } 2925 2926 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, (CE_NOTE, "checking wwn")); 2927 2928 if ((fcip_wwn_compare(&nhdr->net_dest_addr, &fport->fcipp_pwwn, 2929 FCIP_COMPARE_NWWN) != 0) && 2930 (!IS_BROADCAST_ADDR(&nhdr->net_dest_addr))) { 2931 rval = FC_UNCLAIMED; 2932 goto data_cb_done; 2933 } else if (fcip_cache_on_arp_broadcast && 2934 IS_BROADCAST_ADDR(&nhdr->net_dest_addr)) { 2935 fcip_cache_arp_broadcast(fptr, buf); 2936 } 2937 2938 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, (CE_NOTE, "Allocate streams block")); 2939 2940 /* 2941 * Using esballoc instead of allocb should be faster, atleast at 2942 * larger MTUs than 1500 bytes. Someday we'll get there :) 2943 */ 2944 #if defined(FCIP_ESBALLOC) 2945 /* 2946 * allocate memory for the frtn function arg. The Function 2947 * (fcip_ubfree) arg is a struct fcip_esballoc_arg type 2948 * which contains pointers to the unsol buffer and the 2949 * opaque port handle for releasing the unsol buffer back to 2950 * the FCA for reuse 2951 */ 2952 fesb_argp = (struct fcip_esballoc_arg *) 2953 kmem_zalloc(sizeof (struct fcip_esballoc_arg), KM_NOSLEEP); 2954 2955 if (fesb_argp == NULL) { 2956 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 2957 (CE_WARN, "esballoc of mblk failed in data_cb")); 2958 rval = FC_UNCLAIMED; 2959 goto data_cb_done; 2960 } 2961 /* 2962 * Check with KM_NOSLEEP 2963 */ 2964 free_ubuf = (frtn_t *)kmem_zalloc(sizeof (frtn_t), KM_NOSLEEP); 2965 if (free_ubuf == NULL) { 2966 kmem_free(fesb_argp, sizeof (struct fcip_esballoc_arg)); 2967 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 2968 (CE_WARN, "esballoc of mblk failed in data_cb")); 2969 rval = FC_UNCLAIMED; 2970 goto data_cb_done; 2971 } 2972 2973 fesb_argp->frtnp = free_ubuf; 2974 fesb_argp->buf = buf; 2975 fesb_argp->phandle = phandle; 2976 free_ubuf->free_func = fcip_ubfree; 2977 free_ubuf->free_arg = (char *)fesb_argp; 2978 if ((bp = (mblk_t *)esballoc((unsigned char *)buf->ub_buffer, 2979 len, BPRI_MED, free_ubuf)) == NULL) { 2980 kmem_free(fesb_argp, sizeof (struct fcip_esballoc_arg)); 2981 kmem_free(free_ubuf, sizeof (frtn_t)); 2982 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 2983 (CE_WARN, "esballoc of mblk failed in data_cb")); 2984 rval = FC_UNCLAIMED; 2985 goto data_cb_done; 2986 } 2987 #elif !defined(FCIP_ESBALLOC) 2988 /* 2989 * allocate streams mblk and copy the contents of the 2990 * unsolicited buffer into this newly alloc'ed mblk 2991 */ 2992 if ((bp = (mblk_t *)fcip_allocb((size_t)len, BPRI_LO)) == NULL) { 2993 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 2994 (CE_WARN, "alloc of mblk failed in data_cb")); 2995 rval = FC_UNCLAIMED; 2996 goto data_cb_done; 2997 } 2998 2999 /* 3000 * Unsolicited buffers handed up to us from the FCA must be 3001 * endian clean so just bcopy the data into our mblk. Else 3002 * we may have to either copy the data byte by byte or 3003 * use the ddi_rep_get* routines to do the copy for us. 3004 */ 3005 bcopy(buf->ub_buffer, bp->b_rptr, len); 3006 3007 /* 3008 * for esballoc'ed mblks - free the UB in the frtn function 3009 * along with the memory allocated for the function arg. 3010 * for allocb'ed mblk - release the unsolicited buffer here 3011 */ 3012 (void) fc_ulp_ubrelease(phandle, 1, &buf->ub_token); 3013 3014 #endif /* FCIP_ESBALLOC */ 3015 3016 bp->b_wptr = bp->b_rptr + len; 3017 fptr->fcip_ipackets++; 3018 3019 if (type == ETHERTYPE_IP) { 3020 mutex_enter(&fptr->fcip_mutex); 3021 fptr->fcip_ub_upstream++; 3022 mutex_exit(&fptr->fcip_mutex); 3023 bp->b_rptr += hdrlen; 3024 3025 /* 3026 * Check if ipq is valid in the sendup thread 3027 */ 3028 if (fcip_sendup_alloc_enque(fptr, bp, NULL) != FC_SUCCESS) { 3029 freemsg(bp); 3030 } 3031 } else { 3032 /* 3033 * We won't get ethernet 802.3 packets in FCIP but we may get 3034 * types other than ETHERTYPE_IP, such as ETHERTYPE_ARP. Let 3035 * fcip_sendup() do the matching. 3036 */ 3037 mutex_enter(&fptr->fcip_mutex); 3038 fptr->fcip_ub_upstream++; 3039 mutex_exit(&fptr->fcip_mutex); 3040 if (fcip_sendup_alloc_enque(fptr, bp, 3041 fcip_accept) != FC_SUCCESS) { 3042 freemsg(bp); 3043 } 3044 } 3045 3046 rval = FC_SUCCESS; 3047 3048 /* 3049 * Unset fcip_flags to indicate we are out of callback and return 3050 */ 3051 data_cb_done: 3052 mutex_enter(&fptr->fcip_mutex); 3053 fptr->fcip_flags &= ~(FCIP_IN_DATA_CB); 3054 mutex_exit(&fptr->fcip_mutex); 3055 return (rval); 3056 } 3057 3058 #if !defined(FCIP_ESBALLOC) 3059 /* 3060 * Allocate a message block for the inbound data to be sent upstream. 3061 */ 3062 static void * 3063 fcip_allocb(size_t size, uint_t pri) 3064 { 3065 mblk_t *mp; 3066 3067 if ((mp = allocb(size, pri)) == NULL) { 3068 return (NULL); 3069 } 3070 return (mp); 3071 } 3072 3073 #endif 3074 3075 /* 3076 * This helper routine kmem cache alloc's a sendup element for enquing 3077 * into the sendup list for callbacks upstream from the dedicated sendup 3078 * thread. We enque the msg buf into the sendup list and cv_signal the 3079 * sendup thread to finish the callback for us. 3080 */ 3081 static int 3082 fcip_sendup_alloc_enque(struct fcip *fptr, mblk_t *mp, struct fcipstr *(*f)()) 3083 { 3084 struct fcip_sendup_elem *msg_elem; 3085 int rval = FC_FAILURE; 3086 3087 FCIP_TNF_PROBE_1((fcip_sendup_alloc_enque, "fcip io", /* CSTYLED */, 3088 tnf_string, msg, "sendup msg enque")); 3089 msg_elem = kmem_cache_alloc(fptr->fcip_sendup_cache, KM_NOSLEEP); 3090 if (msg_elem == NULL) { 3091 /* drop pkt to floor - update stats */ 3092 rval = FC_FAILURE; 3093 goto sendup_alloc_done; 3094 } 3095 msg_elem->fcipsu_mp = mp; 3096 msg_elem->fcipsu_func = f; 3097 3098 mutex_enter(&fptr->fcip_sendup_mutex); 3099 if (fptr->fcip_sendup_head == NULL) { 3100 fptr->fcip_sendup_head = fptr->fcip_sendup_tail = msg_elem; 3101 } else { 3102 fptr->fcip_sendup_tail->fcipsu_next = msg_elem; 3103 fptr->fcip_sendup_tail = msg_elem; 3104 } 3105 fptr->fcip_sendup_cnt++; 3106 cv_signal(&fptr->fcip_sendup_cv); 3107 mutex_exit(&fptr->fcip_sendup_mutex); 3108 rval = FC_SUCCESS; 3109 3110 sendup_alloc_done: 3111 return (rval); 3112 } 3113 3114 /* 3115 * One of the ways of performing the WWN to D_ID mapping required for 3116 * IPFC data is to cache the unsolicited ARP broadcast messages received 3117 * and update the routing table to add entry for the destination port 3118 * if we are the intended recipient of the ARP broadcast message. This is 3119 * one of the methods recommended in the rfc to obtain the WWN to D_ID mapping 3120 * but is not typically used unless enabled. The driver prefers to use the 3121 * nameserver/lilp map to obtain this mapping. 3122 */ 3123 static void 3124 fcip_cache_arp_broadcast(struct fcip *fptr, fc_unsol_buf_t *buf) 3125 { 3126 fcip_port_info_t *fport; 3127 fcph_network_hdr_t *nhdr; 3128 struct fcip_routing_table *frp; 3129 fc_portmap_t map; 3130 3131 fport = fptr->fcip_port_info; 3132 if (fport == NULL) { 3133 return; 3134 } 3135 ASSERT(fport != NULL); 3136 3137 nhdr = (fcph_network_hdr_t *)buf->ub_buffer; 3138 3139 mutex_enter(&fptr->fcip_rt_mutex); 3140 frp = fcip_lookup_rtable(fptr, &nhdr->net_src_addr, FCIP_COMPARE_NWWN); 3141 mutex_exit(&fptr->fcip_rt_mutex); 3142 if (frp == NULL) { 3143 map.map_did.port_id = buf->ub_frame.s_id; 3144 map.map_hard_addr.hard_addr = buf->ub_frame.s_id; 3145 map.map_state = PORT_DEVICE_VALID; 3146 map.map_type = PORT_DEVICE_NEW; 3147 map.map_flags = 0; 3148 map.map_pd = NULL; 3149 bcopy((void *)&nhdr->net_src_addr, (void *)&map.map_pwwn, 3150 sizeof (la_wwn_t)); 3151 bcopy((void *)&nhdr->net_src_addr, (void *)&map.map_nwwn, 3152 sizeof (la_wwn_t)); 3153 fcip_rt_update(fptr, &map, 1); 3154 mutex_enter(&fptr->fcip_rt_mutex); 3155 frp = fcip_lookup_rtable(fptr, &nhdr->net_src_addr, 3156 FCIP_COMPARE_NWWN); 3157 mutex_exit(&fptr->fcip_rt_mutex); 3158 3159 (void) fcip_add_dest(fptr, frp); 3160 } 3161 3162 } 3163 3164 /* 3165 * This is a dedicated thread to do callbacks from fcip's data callback 3166 * routines into the modules upstream. The reason for this thread is 3167 * the data callback function can be called from an interrupt context and 3168 * the upstream modules *can* make calls downstream in the same thread 3169 * context. If the call is to a fabric port which is not yet in our 3170 * routing tables, we may have to query the nameserver/fabric for the 3171 * MAC addr to Port_ID mapping which may be blocking calls. 3172 */ 3173 static void 3174 fcip_sendup_thr(void *arg) 3175 { 3176 struct fcip *fptr = (struct fcip *)arg; 3177 struct fcip_sendup_elem *msg_elem; 3178 queue_t *ip4q = NULL; 3179 3180 CALLB_CPR_INIT(&fptr->fcip_cpr_info, &fptr->fcip_sendup_mutex, 3181 callb_generic_cpr, "fcip_sendup_thr"); 3182 3183 mutex_enter(&fptr->fcip_sendup_mutex); 3184 for (;;) { 3185 3186 while (fptr->fcip_sendup_thr_initted && 3187 fptr->fcip_sendup_head == NULL) { 3188 CALLB_CPR_SAFE_BEGIN(&fptr->fcip_cpr_info); 3189 cv_wait(&fptr->fcip_sendup_cv, 3190 &fptr->fcip_sendup_mutex); 3191 CALLB_CPR_SAFE_END(&fptr->fcip_cpr_info, 3192 &fptr->fcip_sendup_mutex); 3193 } 3194 3195 if (fptr->fcip_sendup_thr_initted == 0) { 3196 break; 3197 } 3198 3199 FCIP_TNF_PROBE_1((fcip_sendup_thr, "fcip io", /* CSTYLED */, 3200 tnf_string, msg, "fcip sendup thr - new msg")); 3201 3202 msg_elem = fptr->fcip_sendup_head; 3203 fptr->fcip_sendup_head = msg_elem->fcipsu_next; 3204 msg_elem->fcipsu_next = NULL; 3205 mutex_exit(&fptr->fcip_sendup_mutex); 3206 3207 if (msg_elem->fcipsu_func == NULL) { 3208 /* 3209 * Message for ipq. Check to see if the ipq is 3210 * is still valid. Since the thread is asynchronous, 3211 * there could have been a close on the stream 3212 */ 3213 mutex_enter(&fptr->fcip_mutex); 3214 if (fptr->fcip_ipq && canputnext(fptr->fcip_ipq)) { 3215 ip4q = fptr->fcip_ipq; 3216 mutex_exit(&fptr->fcip_mutex); 3217 putnext(ip4q, msg_elem->fcipsu_mp); 3218 } else { 3219 mutex_exit(&fptr->fcip_mutex); 3220 freemsg(msg_elem->fcipsu_mp); 3221 } 3222 } else { 3223 fcip_sendup(fptr, msg_elem->fcipsu_mp, 3224 msg_elem->fcipsu_func); 3225 } 3226 3227 #if !defined(FCIP_ESBALLOC) 3228 /* 3229 * for allocb'ed mblk - decrement upstream count here 3230 */ 3231 mutex_enter(&fptr->fcip_mutex); 3232 ASSERT(fptr->fcip_ub_upstream > 0); 3233 fptr->fcip_ub_upstream--; 3234 mutex_exit(&fptr->fcip_mutex); 3235 #endif /* FCIP_ESBALLOC */ 3236 3237 kmem_cache_free(fptr->fcip_sendup_cache, (void *)msg_elem); 3238 mutex_enter(&fptr->fcip_sendup_mutex); 3239 fptr->fcip_sendup_cnt--; 3240 } 3241 3242 3243 #ifndef __lock_lint 3244 CALLB_CPR_EXIT(&fptr->fcip_cpr_info); 3245 #else 3246 mutex_exit(&fptr->fcip_sendup_mutex); 3247 #endif /* __lock_lint */ 3248 3249 /* Wake up fcip detach thread by the end */ 3250 cv_signal(&fptr->fcip_sendup_cv); 3251 3252 thread_exit(); 3253 } 3254 3255 #ifdef FCIP_ESBALLOC 3256 3257 /* 3258 * called from the stream head when it is done using an unsolicited buffer. 3259 * We release this buffer then to the FCA for reuse. 3260 */ 3261 static void 3262 fcip_ubfree(char *arg) 3263 { 3264 struct fcip_esballoc_arg *fesb_argp = (struct fcip_esballoc_arg *)arg; 3265 fc_unsol_buf_t *ubuf; 3266 frtn_t *frtnp; 3267 fcip_port_info_t *fport; 3268 struct fcip *fptr; 3269 3270 3271 fport = fcip_get_port(fesb_argp->phandle); 3272 fptr = fport->fcipp_fcip; 3273 3274 ASSERT(fesb_argp != NULL); 3275 ubuf = fesb_argp->buf; 3276 frtnp = fesb_argp->frtnp; 3277 3278 3279 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, 3280 (CE_WARN, "freeing ubuf after esballoc in fcip_ubfree")); 3281 (void) fc_ulp_ubrelease(fesb_argp->phandle, 1, &ubuf->ub_token); 3282 3283 mutex_enter(&fptr->fcip_mutex); 3284 ASSERT(fptr->fcip_ub_upstream > 0); 3285 fptr->fcip_ub_upstream--; 3286 cv_signal(&fptr->fcip_ub_cv); 3287 mutex_exit(&fptr->fcip_mutex); 3288 3289 kmem_free(frtnp, sizeof (frtn_t)); 3290 kmem_free(fesb_argp, sizeof (struct fcip_esballoc_arg)); 3291 } 3292 3293 #endif /* FCIP_ESBALLOC */ 3294 3295 /* 3296 * handle data other than that of type ETHERTYPE_IP and send it on its 3297 * way upstream to the right streams module to handle 3298 */ 3299 static void 3300 fcip_sendup(struct fcip *fptr, mblk_t *mp, struct fcipstr *(*acceptfunc)()) 3301 { 3302 struct fcipstr *slp, *nslp; 3303 la_wwn_t *dhostp; 3304 mblk_t *nmp; 3305 uint32_t isgroupaddr; 3306 int type; 3307 uint32_t hdrlen; 3308 fcph_network_hdr_t *nhdr; 3309 llc_snap_hdr_t *snaphdr; 3310 3311 FCIP_TNF_PROBE_1((fcip_sendup, "fcip io", /* CSTYLED */, 3312 tnf_string, msg, "fcip sendup")); 3313 nhdr = (fcph_network_hdr_t *)mp->b_rptr; 3314 snaphdr = 3315 (llc_snap_hdr_t *)(mp->b_rptr + sizeof (fcph_network_hdr_t)); 3316 dhostp = &nhdr->net_dest_addr; 3317 type = snaphdr->pid; 3318 hdrlen = sizeof (fcph_network_hdr_t) + sizeof (llc_snap_hdr_t); 3319 3320 /* No group address with fibre channel */ 3321 isgroupaddr = 0; 3322 3323 /* 3324 * While holding a reader lock on the linked list of streams structures, 3325 * attempt to match the address criteria for each stream 3326 * and pass up the raw M_DATA ("fastpath") or a DL_UNITDATA_IND. 3327 */ 3328 3329 rw_enter(&fcipstruplock, RW_READER); 3330 3331 if ((slp = (*acceptfunc)(fcipstrup, fptr, type, dhostp)) == NULL) { 3332 rw_exit(&fcipstruplock); 3333 FCIP_TNF_PROBE_1((fcip_sendup, "fcip io", /* CSTYLED */, 3334 tnf_string, msg, "fcip sendup - no slp")); 3335 freemsg(mp); 3336 return; 3337 } 3338 3339 /* 3340 * Loop on matching open streams until (*acceptfunc)() returns NULL. 3341 */ 3342 for (; nslp = (*acceptfunc)(slp->sl_nextp, fptr, type, dhostp); 3343 slp = nslp) { 3344 if (canputnext(slp->sl_rq)) { 3345 if (nmp = dupmsg(mp)) { 3346 if ((slp->sl_flags & FCIP_SLFAST) && 3347 !isgroupaddr) { 3348 nmp->b_rptr += hdrlen; 3349 putnext(slp->sl_rq, nmp); 3350 } else if (slp->sl_flags & FCIP_SLRAW) { 3351 /* No headers when FCIP_SLRAW is set */ 3352 putnext(slp->sl_rq, nmp); 3353 } else if ((nmp = fcip_addudind(fptr, nmp, 3354 nhdr, type))) { 3355 putnext(slp->sl_rq, nmp); 3356 } 3357 } 3358 } 3359 } 3360 3361 /* 3362 * Do the last one. 3363 */ 3364 if (canputnext(slp->sl_rq)) { 3365 if (slp->sl_flags & FCIP_SLFAST) { 3366 mp->b_rptr += hdrlen; 3367 putnext(slp->sl_rq, mp); 3368 } else if (slp->sl_flags & FCIP_SLRAW) { 3369 putnext(slp->sl_rq, mp); 3370 } else if ((mp = fcip_addudind(fptr, mp, nhdr, type))) { 3371 putnext(slp->sl_rq, mp); 3372 } 3373 } else { 3374 freemsg(mp); 3375 } 3376 FCIP_TNF_PROBE_1((fcip_sendup, "fcip io", /* CSTYLED */, 3377 tnf_string, msg, "fcip sendup done")); 3378 3379 rw_exit(&fcipstruplock); 3380 } 3381 3382 /* 3383 * Match the stream based on type and wwn if necessary. 3384 * Destination wwn dhostp is passed to this routine is reserved 3385 * for future usage. We don't need to use it right now since port 3386 * to fcip instance mapping is unique and wwn is already validated when 3387 * packet comes to fcip. 3388 */ 3389 /* ARGSUSED */ 3390 static struct fcipstr * 3391 fcip_accept(struct fcipstr *slp, struct fcip *fptr, int type, la_wwn_t *dhostp) 3392 { 3393 t_uscalar_t sap; 3394 3395 FCIP_TNF_PROBE_1((fcip_accept, "fcip io", /* CSTYLED */, 3396 tnf_string, msg, "fcip accept")); 3397 3398 for (; slp; slp = slp->sl_nextp) { 3399 sap = slp->sl_sap; 3400 FCIP_DEBUG(FCIP_DEBUG_UPSTREAM, (CE_CONT, 3401 "fcip_accept: checking next sap = %x, type = %x", 3402 sap, type)); 3403 3404 if ((slp->sl_fcip == fptr) && (type == sap)) { 3405 return (slp); 3406 } 3407 } 3408 return (NULL); 3409 } 3410 3411 /* 3412 * Handle DL_UNITDATA_IND messages 3413 */ 3414 static mblk_t * 3415 fcip_addudind(struct fcip *fptr, mblk_t *mp, fcph_network_hdr_t *nhdr, 3416 int type) 3417 { 3418 dl_unitdata_ind_t *dludindp; 3419 struct fcipdladdr *dlap; 3420 mblk_t *nmp; 3421 int size; 3422 uint32_t hdrlen; 3423 struct ether_addr src_addr; 3424 struct ether_addr dest_addr; 3425 3426 3427 hdrlen = (sizeof (llc_snap_hdr_t) + sizeof (fcph_network_hdr_t)); 3428 mp->b_rptr += hdrlen; 3429 3430 FCIP_TNF_PROBE_1((fcip_addudind, "fcip io", /* CSTYLED */, 3431 tnf_string, msg, "fcip addudind")); 3432 3433 /* 3434 * Allocate an M_PROTO mblk for the DL_UNITDATA_IND. 3435 */ 3436 size = sizeof (dl_unitdata_ind_t) + FCIPADDRL + FCIPADDRL; 3437 if ((nmp = allocb(size, BPRI_LO)) == NULL) { 3438 fptr->fcip_allocbfail++; 3439 freemsg(mp); 3440 return (NULL); 3441 } 3442 DB_TYPE(nmp) = M_PROTO; 3443 nmp->b_wptr = nmp->b_datap->db_lim; 3444 nmp->b_rptr = nmp->b_wptr - size; 3445 3446 /* 3447 * Construct a DL_UNITDATA_IND primitive. 3448 */ 3449 dludindp = (dl_unitdata_ind_t *)nmp->b_rptr; 3450 dludindp->dl_primitive = DL_UNITDATA_IND; 3451 dludindp->dl_dest_addr_length = FCIPADDRL; 3452 dludindp->dl_dest_addr_offset = sizeof (dl_unitdata_ind_t); 3453 dludindp->dl_src_addr_length = FCIPADDRL; 3454 dludindp->dl_src_addr_offset = sizeof (dl_unitdata_ind_t) + FCIPADDRL; 3455 dludindp->dl_group_address = 0; /* not DL_MULTI */ 3456 3457 dlap = (struct fcipdladdr *)(nmp->b_rptr + sizeof (dl_unitdata_ind_t)); 3458 wwn_to_ether(&nhdr->net_dest_addr, &dest_addr); 3459 ether_bcopy(&dest_addr, &dlap->dl_phys); 3460 dlap->dl_sap = (uint16_t)type; 3461 3462 dlap = (struct fcipdladdr *)(nmp->b_rptr + sizeof (dl_unitdata_ind_t) 3463 + FCIPADDRL); 3464 wwn_to_ether(&nhdr->net_src_addr, &src_addr); 3465 ether_bcopy(&src_addr, &dlap->dl_phys); 3466 dlap->dl_sap = (uint16_t)type; 3467 3468 /* 3469 * Link the M_PROTO and M_DATA together. 3470 */ 3471 nmp->b_cont = mp; 3472 return (nmp); 3473 } 3474 3475 3476 /* 3477 * The open routine. For clone opens, we return the next available minor 3478 * no. for the stream to use 3479 */ 3480 /* ARGSUSED */ 3481 static int 3482 fcip_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp) 3483 { 3484 struct fcipstr *slp; 3485 struct fcipstr **prevslp; 3486 minor_t minor; 3487 3488 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "in fcip_open")); 3489 FCIP_TNF_PROBE_1((fcip_open, "fcip io", /* CSTYLED */, 3490 tnf_string, msg, "enter")); 3491 /* 3492 * We need to ensure that the port driver is loaded before 3493 * we proceed 3494 */ 3495 if (ddi_hold_installed_driver(ddi_name_to_major(PORT_DRIVER)) == NULL) { 3496 /* no port driver instances found */ 3497 FCIP_DEBUG(FCIP_DEBUG_STARTUP, (CE_WARN, 3498 "!ddi_hold_installed_driver of fp failed\n")); 3499 return (ENXIO); 3500 } 3501 /* serialize opens */ 3502 rw_enter(&fcipstruplock, RW_WRITER); 3503 3504 prevslp = &fcipstrup; 3505 if (sflag == CLONEOPEN) { 3506 minor = 0; 3507 for (; (slp = *prevslp) != NULL; prevslp = &slp->sl_nextp) { 3508 if (minor < slp->sl_minor) { 3509 break; 3510 } 3511 minor ++; 3512 } 3513 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, 3514 "getmajor returns 0x%x", getmajor(*devp))); 3515 *devp = makedevice(getmajor(*devp), minor); 3516 } else { 3517 minor = getminor(*devp); 3518 } 3519 3520 /* 3521 * check if our qp's private area is already initialized. If yes 3522 * the stream is already open - just return 3523 */ 3524 if (rq->q_ptr) { 3525 goto done; 3526 } 3527 3528 slp = GETSTRUCT(struct fcipstr, 1); 3529 slp->sl_minor = minor; 3530 slp->sl_rq = rq; 3531 slp->sl_sap = 0; 3532 slp->sl_flags = 0; 3533 slp->sl_state = DL_UNATTACHED; 3534 slp->sl_fcip = NULL; 3535 3536 mutex_init(&slp->sl_lock, NULL, MUTEX_DRIVER, NULL); 3537 3538 /* 3539 * link this new stream entry into list of active streams 3540 */ 3541 slp->sl_nextp = *prevslp; 3542 *prevslp = slp; 3543 3544 rq->q_ptr = WR(rq)->q_ptr = (char *)slp; 3545 3546 /* 3547 * Disable automatic enabling of our write service procedures 3548 * we need to control this explicitly. This will prevent 3549 * anyone scheduling of our write service procedures. 3550 */ 3551 noenable(WR(rq)); 3552 3553 done: 3554 rw_exit(&fcipstruplock); 3555 /* 3556 * enable our put and service routines on the read side 3557 */ 3558 qprocson(rq); 3559 3560 /* 3561 * There is only one instance of fcip (instance = 0) 3562 * for multiple instances of hardware 3563 */ 3564 (void) qassociate(rq, 0); /* don't allow drcompat to be pushed */ 3565 return (0); 3566 } 3567 3568 /* 3569 * close an opened stream. The minor no. will then be available for 3570 * future opens. 3571 */ 3572 /* ARGSUSED */ 3573 static int 3574 fcip_close(queue_t *rq, int flag, cred_t *credp) 3575 { 3576 struct fcipstr *slp; 3577 struct fcipstr **prevslp; 3578 3579 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "in fcip_close")); 3580 FCIP_TNF_PROBE_1((fcip_close, "fcip io", /* CSTYLED */, 3581 tnf_string, msg, "enter")); 3582 ASSERT(rq); 3583 /* we should also have the active stream pointer in q_ptr */ 3584 ASSERT(rq->q_ptr); 3585 3586 ddi_rele_driver(ddi_name_to_major(PORT_DRIVER)); 3587 /* 3588 * disable our put and service procedures. We had enabled them 3589 * on open 3590 */ 3591 qprocsoff(rq); 3592 slp = (struct fcipstr *)rq->q_ptr; 3593 3594 /* 3595 * Implicitly detach stream a stream from an interface. 3596 */ 3597 if (slp->sl_fcip) { 3598 fcip_dodetach(slp); 3599 } 3600 3601 (void) qassociate(rq, -1); /* undo association in open */ 3602 3603 rw_enter(&fcipstruplock, RW_WRITER); 3604 3605 /* 3606 * unlink this stream from the active stream list and free it 3607 */ 3608 for (prevslp = &fcipstrup; (slp = *prevslp) != NULL; 3609 prevslp = &slp->sl_nextp) { 3610 if (slp == (struct fcipstr *)rq->q_ptr) { 3611 break; 3612 } 3613 } 3614 3615 /* we should have found slp */ 3616 ASSERT(slp); 3617 3618 *prevslp = slp->sl_nextp; 3619 mutex_destroy(&slp->sl_lock); 3620 kmem_free(slp, sizeof (struct fcipstr)); 3621 rq->q_ptr = WR(rq)->q_ptr = NULL; 3622 3623 rw_exit(&fcipstruplock); 3624 return (0); 3625 } 3626 3627 /* 3628 * This is not an extension of the DDI_DETACH request. This routine 3629 * only detaches a stream from an interface 3630 */ 3631 static void 3632 fcip_dodetach(struct fcipstr *slp) 3633 { 3634 struct fcipstr *tslp; 3635 struct fcip *fptr; 3636 3637 FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_NOTE, "in fcip_dodetach")); 3638 FCIP_TNF_PROBE_1((fcip_dodetach, "fcip io", /* CSTYLED */, 3639 tnf_string, msg, "enter")); 3640 ASSERT(slp->sl_fcip != NULL); 3641 3642 fptr = slp->sl_fcip; 3643 slp->sl_fcip = NULL; 3644 3645 /* 3646 * we don't support promiscuous mode currently but check 3647 * for and disable any promiscuous mode operation 3648 */ 3649 if (slp->sl_flags & SLALLPHYS) { 3650 slp->sl_flags &= ~SLALLPHYS; 3651 } 3652 3653 /* 3654 * disable ALLMULTI mode if all mulitcast addr are ON 3655 */ 3656 if (slp->sl_flags & SLALLMULTI) { 3657 slp->sl_flags &= ~SLALLMULTI; 3658 } 3659 3660 /* 3661 * we are most likely going to perform multicast by 3662 * broadcasting to the well known addr (D_ID) 0xFFFFFF or 3663 * ALPA 0x00 in case of public loops 3664 */ 3665 3666 3667 /* 3668 * detach unit from device structure. 3669 */ 3670 for (tslp = fcipstrup; tslp != NULL; tslp = tslp->sl_nextp) { 3671 if (tslp->sl_fcip == fptr) { 3672 break; 3673 } 3674 } 3675 if (tslp == NULL) { 3676 FCIP_DEBUG(FCIP_DEBUG_DETACH, (CE_WARN, 3677 "fcip_dodeatch - active stream struct not found")); 3678 3679 /* unregister with Fabric nameserver?? */ 3680 } 3681 slp->sl_state = DL_UNATTACHED; 3682 3683 fcip_setipq(fptr); 3684 } 3685 3686 3687 /* 3688 * Set or clear device ipq pointer. 3689 * Walk thru all the streams on this device, if a ETHERTYPE_IP 3690 * stream is found, assign device ipq to its sl_rq. 3691 */ 3692 static void 3693 fcip_setipq(struct fcip *fptr) 3694 { 3695 struct fcipstr *slp; 3696 int ok = 1; 3697 queue_t *ipq = NULL; 3698 3699 FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE, "entered fcip_setipq")); 3700 3701 rw_enter(&fcipstruplock, RW_READER); 3702 3703 for (slp = fcipstrup; slp != NULL; slp = slp->sl_nextp) { 3704 if (slp->sl_fcip == fptr) { 3705 if (slp->sl_flags & (SLALLPHYS|SLALLSAP)) { 3706 ok = 0; 3707 } 3708 if (slp->sl_sap == ETHERTYPE_IP) { 3709 if (ipq == NULL) { 3710 ipq = slp->sl_rq; 3711 } else { 3712 ok = 0; 3713 } 3714 } 3715 } 3716 } 3717 3718 rw_exit(&fcipstruplock); 3719 3720 if (fcip_check_port_exists(fptr)) { 3721 /* fptr passed to us is stale */ 3722 return; 3723 } 3724 3725 mutex_enter(&fptr->fcip_mutex); 3726 if (ok) { 3727 fptr->fcip_ipq = ipq; 3728 } else { 3729 fptr->fcip_ipq = NULL; 3730 } 3731 mutex_exit(&fptr->fcip_mutex); 3732 } 3733 3734 3735 /* ARGSUSED */ 3736 static void 3737 fcip_ioctl(queue_t *wq, mblk_t *mp) 3738 { 3739 struct iocblk *iocp = (struct iocblk *)mp->b_rptr; 3740 struct fcipstr *slp = (struct fcipstr *)wq->q_ptr; 3741 3742 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 3743 (CE_NOTE, "in fcip ioctl : %d", iocp->ioc_cmd)); 3744 FCIP_TNF_PROBE_1((fcip_ioctl, "fcip io", /* CSTYLED */, 3745 tnf_string, msg, "enter")); 3746 3747 switch (iocp->ioc_cmd) { 3748 case DLIOCRAW: 3749 slp->sl_flags |= FCIP_SLRAW; 3750 miocack(wq, mp, 0, 0); 3751 break; 3752 3753 case DL_IOC_HDR_INFO: 3754 fcip_dl_ioc_hdr_info(wq, mp); 3755 break; 3756 3757 default: 3758 miocnak(wq, mp, 0, EINVAL); 3759 break; 3760 } 3761 } 3762 3763 /* 3764 * The streams 'Put' routine. 3765 */ 3766 /* ARGSUSED */ 3767 static int 3768 fcip_wput(queue_t *wq, mblk_t *mp) 3769 { 3770 struct fcipstr *slp = (struct fcipstr *)wq->q_ptr; 3771 struct fcip *fptr; 3772 struct fcip_dest *fdestp; 3773 fcph_network_hdr_t *headerp; 3774 3775 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 3776 (CE_NOTE, "in fcip_wput :: type:%x", DB_TYPE(mp))); 3777 3778 switch (DB_TYPE(mp)) { 3779 case M_DATA: { 3780 3781 fptr = slp->sl_fcip; 3782 3783 if (((slp->sl_flags & (FCIP_SLFAST|FCIP_SLRAW)) == 0) || 3784 (slp->sl_state != DL_IDLE) || 3785 (fptr == NULL)) { 3786 /* 3787 * set error in the message block and send a reply 3788 * back upstream. Sun's merror routine does this 3789 * for us more cleanly. 3790 */ 3791 merror(wq, mp, EPROTO); 3792 break; 3793 } 3794 3795 /* 3796 * if any messages are already enqueued or if the interface 3797 * is in promiscuous mode, causing the packets to loop back 3798 * up, then enqueue the message. Otherwise just transmit 3799 * the message. putq() puts the message on fcip's 3800 * write queue and qenable() puts the queue (wq) on 3801 * the list of queues to be called by the streams scheduler. 3802 */ 3803 if (wq->q_first) { 3804 (void) putq(wq, mp); 3805 fptr->fcip_wantw = 1; 3806 qenable(wq); 3807 } else if (fptr->fcip_flags & FCIP_PROMISC) { 3808 /* 3809 * Promiscous mode not supported but add this code in 3810 * case it will be supported in future. 3811 */ 3812 (void) putq(wq, mp); 3813 qenable(wq); 3814 } else { 3815 3816 headerp = (fcph_network_hdr_t *)mp->b_rptr; 3817 fdestp = fcip_get_dest(fptr, &headerp->net_dest_addr); 3818 3819 if (fdestp == NULL) { 3820 merror(wq, mp, EPROTO); 3821 break; 3822 } 3823 3824 ASSERT(fdestp != NULL); 3825 3826 (void) fcip_start(wq, mp, fptr, fdestp, KM_SLEEP); 3827 } 3828 break; 3829 } 3830 case M_PROTO: 3831 case M_PCPROTO: 3832 /* 3833 * to prevent recursive calls into fcip_proto 3834 * (PROTO and PCPROTO messages are handled by fcip_proto) 3835 * let the service procedure handle these messages by 3836 * calling putq here. 3837 */ 3838 (void) putq(wq, mp); 3839 qenable(wq); 3840 break; 3841 3842 case M_IOCTL: 3843 fcip_ioctl(wq, mp); 3844 break; 3845 3846 case M_FLUSH: 3847 if (*mp->b_rptr & FLUSHW) { 3848 flushq(wq, FLUSHALL); 3849 *mp->b_rptr &= ~FLUSHW; 3850 } 3851 /* 3852 * we have both FLUSHW and FLUSHR set with FLUSHRW 3853 */ 3854 if (*mp->b_rptr & FLUSHR) { 3855 /* 3856 * send msg back upstream. qreply() takes care 3857 * of using the RD(wq) queue on its reply 3858 */ 3859 qreply(wq, mp); 3860 } else { 3861 freemsg(mp); 3862 } 3863 break; 3864 3865 default: 3866 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 3867 (CE_NOTE, "default msg type: %x", DB_TYPE(mp))); 3868 freemsg(mp); 3869 break; 3870 } 3871 return (0); 3872 } 3873 3874 3875 /* 3876 * Handle M_PROTO and M_PCPROTO messages 3877 */ 3878 /* ARGSUSED */ 3879 static void 3880 fcip_proto(queue_t *wq, mblk_t *mp) 3881 { 3882 union DL_primitives *dlp; 3883 struct fcipstr *slp; 3884 t_uscalar_t prim; 3885 3886 slp = (struct fcipstr *)wq->q_ptr; 3887 dlp = (union DL_primitives *)mp->b_rptr; 3888 prim = dlp->dl_primitive; /* the DLPI command */ 3889 3890 FCIP_TNF_PROBE_5((fcip_proto, "fcip io", /* CSTYLED */, 3891 tnf_string, msg, "enter", 3892 tnf_opaque, wq, wq, 3893 tnf_opaque, mp, mp, 3894 tnf_opaque, MP_DB_TYPE, DB_TYPE(mp), 3895 tnf_opaque, dl_primitive, dlp->dl_primitive)); 3896 3897 FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE, "dl_primitve : %x", prim)); 3898 3899 mutex_enter(&slp->sl_lock); 3900 3901 switch (prim) { 3902 case DL_UNITDATA_REQ: 3903 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3904 tnf_string, msg, "unit data request")); 3905 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "unit data request")); 3906 fcip_udreq(wq, mp); 3907 break; 3908 3909 case DL_ATTACH_REQ: 3910 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3911 tnf_string, msg, "Attach request")); 3912 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "Attach request")); 3913 fcip_areq(wq, mp); 3914 break; 3915 3916 case DL_DETACH_REQ: 3917 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3918 tnf_string, msg, "Detach request")); 3919 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "Detach request")); 3920 fcip_dreq(wq, mp); 3921 break; 3922 3923 case DL_BIND_REQ: 3924 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "Bind request")); 3925 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3926 tnf_string, msg, "Bind request")); 3927 fcip_breq(wq, mp); 3928 break; 3929 3930 case DL_UNBIND_REQ: 3931 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3932 tnf_string, msg, "unbind request")); 3933 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "unbind request")); 3934 fcip_ubreq(wq, mp); 3935 break; 3936 3937 case DL_INFO_REQ: 3938 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3939 tnf_string, msg, "Info request")); 3940 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "Info request")); 3941 fcip_ireq(wq, mp); 3942 break; 3943 3944 case DL_SET_PHYS_ADDR_REQ: 3945 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3946 tnf_string, msg, "set phy addr request")); 3947 FCIP_DEBUG(FCIP_DEBUG_DLPI, 3948 (CE_NOTE, "set phy addr request")); 3949 fcip_spareq(wq, mp); 3950 break; 3951 3952 case DL_PHYS_ADDR_REQ: 3953 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3954 tnf_string, msg, "phy addr request")); 3955 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "phy addr request")); 3956 fcip_pareq(wq, mp); 3957 break; 3958 3959 case DL_ENABMULTI_REQ: 3960 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3961 tnf_string, msg, "Enable Multicast request")); 3962 FCIP_DEBUG(FCIP_DEBUG_DLPI, 3963 (CE_NOTE, "Enable Multicast request")); 3964 dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0); 3965 break; 3966 3967 case DL_DISABMULTI_REQ: 3968 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3969 tnf_string, msg, "Disable Multicast request")); 3970 FCIP_DEBUG(FCIP_DEBUG_DLPI, 3971 (CE_NOTE, "Disable Multicast request")); 3972 dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0); 3973 break; 3974 3975 case DL_PROMISCON_REQ: 3976 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3977 tnf_string, msg, "Promiscuous mode ON request")); 3978 FCIP_DEBUG(FCIP_DEBUG_DLPI, 3979 (CE_NOTE, "Promiscuous mode ON request")); 3980 dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0); 3981 break; 3982 3983 case DL_PROMISCOFF_REQ: 3984 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3985 tnf_string, msg, "Promiscuous mode OFF request")); 3986 FCIP_DEBUG(FCIP_DEBUG_DLPI, 3987 (CE_NOTE, "Promiscuous mode OFF request")); 3988 dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0); 3989 break; 3990 3991 default: 3992 FCIP_TNF_PROBE_1((fcip_proto, "fcip io", /* CSTYLED */, 3993 tnf_string, msg, "Unsupported request")); 3994 dlerrorack(wq, mp, prim, DL_UNSUPPORTED, 0); 3995 break; 3996 } 3997 mutex_exit(&slp->sl_lock); 3998 } 3999 4000 /* 4001 * Always enqueue M_PROTO and M_PCPROTO messages pn the wq and M_DATA 4002 * messages sometimes. Processing of M_PROTO and M_PCPROTO messages 4003 * require us to hold fcip's internal locks across (upstream) putnext 4004 * calls. Specifically fcip_intr could hold fcip_intrlock and fcipstruplock 4005 * when it calls putnext(). That thread could loop back around to call 4006 * fcip_wput and eventually fcip_init() to cause a recursive mutex panic 4007 * 4008 * M_DATA messages are enqueued only if we are out of xmit resources. Once 4009 * the transmit resources are available the service procedure is enabled 4010 * and an attempt is made to xmit all messages on the wq. 4011 */ 4012 /* ARGSUSED */ 4013 static int 4014 fcip_wsrv(queue_t *wq) 4015 { 4016 mblk_t *mp; 4017 struct fcipstr *slp; 4018 struct fcip *fptr; 4019 struct fcip_dest *fdestp; 4020 fcph_network_hdr_t *headerp; 4021 4022 slp = (struct fcipstr *)wq->q_ptr; 4023 fptr = slp->sl_fcip; 4024 4025 FCIP_TNF_PROBE_2((fcip_wsrv, "fcip io", /* CSTYLED */, 4026 tnf_string, msg, "enter", 4027 tnf_opaque, wq, wq)); 4028 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "fcip wsrv")); 4029 4030 while (mp = getq(wq)) { 4031 switch (DB_TYPE(mp)) { 4032 case M_DATA: 4033 if (fptr && mp) { 4034 headerp = (fcph_network_hdr_t *)mp->b_rptr; 4035 fdestp = fcip_get_dest(fptr, 4036 &headerp->net_dest_addr); 4037 if (fdestp == NULL) { 4038 freemsg(mp); 4039 goto done; 4040 } 4041 if (fcip_start(wq, mp, fptr, fdestp, 4042 KM_SLEEP)) { 4043 goto done; 4044 } 4045 } else { 4046 freemsg(mp); 4047 } 4048 break; 4049 4050 case M_PROTO: 4051 case M_PCPROTO: 4052 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 4053 (CE_NOTE, "PROT msg in wsrv")); 4054 fcip_proto(wq, mp); 4055 break; 4056 default: 4057 break; 4058 } 4059 } 4060 done: 4061 return (0); 4062 } 4063 4064 4065 /* 4066 * This routine is called from fcip_wsrv to send a message downstream 4067 * on the fibre towards its destination. This routine performs the 4068 * actual WWN to D_ID mapping by looking up the routing and destination 4069 * tables. 4070 */ 4071 /* ARGSUSED */ 4072 static int 4073 fcip_start(queue_t *wq, mblk_t *mp, struct fcip *fptr, 4074 struct fcip_dest *fdestp, int flags) 4075 { 4076 int rval; 4077 int free; 4078 fcip_pkt_t *fcip_pkt; 4079 fc_packet_t *fc_pkt; 4080 fcip_port_info_t *fport = fptr->fcip_port_info; 4081 size_t datalen; 4082 4083 FCIP_TNF_PROBE_4((fcip_start, "fcip io", /* CSTYLED */, 4084 tnf_string, msg, "enter", tnf_opaque, wq, wq, 4085 tnf_opaque, mp, mp, 4086 tnf_opaque, MP_DB_TYPE, DB_TYPE(mp))); 4087 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "in fcipstart")); 4088 4089 ASSERT(fdestp != NULL); 4090 4091 /* 4092 * Only return if port has gone offline and not come back online 4093 * in a while 4094 */ 4095 if (fptr->fcip_flags & FCIP_LINK_DOWN) { 4096 freemsg(mp); 4097 return (0); 4098 } 4099 4100 /* 4101 * The message block coming in here already has the network and 4102 * llc_snap hdr stuffed in 4103 */ 4104 /* 4105 * Traditionally ethernet drivers at sun handle 3 cases here - 4106 * 1. messages with one mblk 4107 * 2. messages with 2 mblks 4108 * 3. messages with >2 mblks 4109 * For now lets handle all the 3 cases in a single case where we 4110 * put them together in one mblk that has all the data 4111 */ 4112 4113 if (mp->b_cont != NULL) { 4114 if (!pullupmsg(mp, -1)) { 4115 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 4116 (CE_WARN, "failed to concat message")); 4117 freemsg(mp); 4118 return (1); 4119 } 4120 } 4121 4122 datalen = msgsize(mp); 4123 4124 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, 4125 "msgsize with nhdr & llcsnap hdr in fcip_pkt_alloc 0x%lx", 4126 datalen)); 4127 4128 /* 4129 * We cannot have requests larger than FCIPMTU+Headers 4130 */ 4131 if (datalen > (FCIPMTU + sizeof (llc_snap_hdr_t) + 4132 sizeof (fcph_network_hdr_t))) { 4133 freemsg(mp); 4134 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, 4135 "fcip_pkt_alloc: datalen is larger than " 4136 "max possible size.")); 4137 return (1); 4138 } 4139 4140 fcip_pkt = fcip_pkt_alloc(fptr, mp, flags, datalen); 4141 if (fcip_pkt == NULL) { 4142 (void) putbq(wq, mp); 4143 return (1); 4144 } 4145 4146 fcip_pkt->fcip_pkt_mp = mp; 4147 fcip_pkt->fcip_pkt_wq = wq; 4148 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 4149 4150 mutex_enter(&fdestp->fcipd_mutex); 4151 /* 4152 * If the device dynamically disappeared, just fail the request. 4153 */ 4154 if (fdestp->fcipd_rtable == NULL) { 4155 mutex_exit(&fdestp->fcipd_mutex); 4156 fcip_pkt_free(fcip_pkt, 1); 4157 return (1); 4158 } 4159 4160 /* 4161 * Now that we've assigned pkt_pd, we can call fc_ulp_init_packet 4162 */ 4163 4164 fc_pkt->pkt_pd = fdestp->fcipd_pd; 4165 4166 if (fc_ulp_init_packet((opaque_t)fport->fcipp_handle, 4167 fc_pkt, flags) != FC_SUCCESS) { 4168 mutex_exit(&fdestp->fcipd_mutex); 4169 fcip_pkt_free(fcip_pkt, 1); 4170 return (1); 4171 } 4172 4173 fcip_fdestp_enqueue_pkt(fdestp, fcip_pkt); 4174 fcip_pkt->fcip_pkt_dest = fdestp; 4175 fc_pkt->pkt_fca_device = fdestp->fcipd_fca_dev; 4176 4177 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, 4178 "setting cmdlen to 0x%x: rsp 0x%x : data 0x%x", 4179 fc_pkt->pkt_cmdlen, fc_pkt->pkt_rsplen, fc_pkt->pkt_datalen)); 4180 4181 fcip_init_unicast_pkt(fcip_pkt, fport->fcipp_sid, 4182 fdestp->fcipd_did, fcip_pkt_callback); 4183 4184 fdestp->fcipd_ncmds++; 4185 4186 mutex_exit(&fdestp->fcipd_mutex); 4187 if ((rval = fcip_transport(fcip_pkt)) == FC_SUCCESS) { 4188 fptr->fcip_opackets++; 4189 return (0); 4190 } 4191 4192 free = (rval == FC_STATEC_BUSY || rval == FC_OFFLINE || 4193 rval == FC_TRAN_BUSY) ? 0 : 1; 4194 4195 mutex_enter(&fdestp->fcipd_mutex); 4196 rval = fcip_fdestp_dequeue_pkt(fdestp, fcip_pkt); 4197 4198 if (!rval) { 4199 fcip_pkt = NULL; 4200 } else { 4201 fdestp->fcipd_ncmds--; 4202 } 4203 mutex_exit(&fdestp->fcipd_mutex); 4204 4205 if (fcip_pkt != NULL) { 4206 fcip_pkt_free(fcip_pkt, free); 4207 } 4208 4209 if (!free) { 4210 (void) putbq(wq, mp); 4211 } 4212 4213 return (1); 4214 } 4215 4216 4217 /* 4218 * This routine enqueus a packet marked to be issued to the 4219 * transport in the dest structure. This enables us to timeout any 4220 * request stuck with the FCA/transport for long periods of time 4221 * without a response. fcip_pkt_timeout will attempt to clean up 4222 * any packets hung in this state of limbo. 4223 */ 4224 static void 4225 fcip_fdestp_enqueue_pkt(struct fcip_dest *fdestp, fcip_pkt_t *fcip_pkt) 4226 { 4227 ASSERT(mutex_owned(&fdestp->fcipd_mutex)); 4228 FCIP_TNF_PROBE_1((fcip_fdestp_enqueue_pkt, "fcip io", /* CSTYLED */, 4229 tnf_string, msg, "destp enq pkt")); 4230 4231 /* 4232 * Just hang it off the head of packet list 4233 */ 4234 fcip_pkt->fcip_pkt_next = fdestp->fcipd_head; 4235 fcip_pkt->fcip_pkt_prev = NULL; 4236 fcip_pkt->fcip_pkt_flags |= FCIP_PKT_IN_LIST; 4237 4238 if (fdestp->fcipd_head != NULL) { 4239 ASSERT(fdestp->fcipd_head->fcip_pkt_prev == NULL); 4240 fdestp->fcipd_head->fcip_pkt_prev = fcip_pkt; 4241 } 4242 4243 fdestp->fcipd_head = fcip_pkt; 4244 } 4245 4246 4247 /* 4248 * dequeues any packets after the transport/FCA tells us it has 4249 * been successfully sent on its way. Ofcourse it doesn't mean that 4250 * the packet will actually reach its destination but its atleast 4251 * a step closer in that direction 4252 */ 4253 static int 4254 fcip_fdestp_dequeue_pkt(struct fcip_dest *fdestp, fcip_pkt_t *fcip_pkt) 4255 { 4256 fcip_pkt_t *fcipd_pkt; 4257 4258 ASSERT(mutex_owned(&fdestp->fcipd_mutex)); 4259 if (fcip_pkt->fcip_pkt_flags & FCIP_PKT_IN_TIMEOUT) { 4260 fcipd_pkt = fdestp->fcipd_head; 4261 while (fcipd_pkt) { 4262 if (fcipd_pkt == fcip_pkt) { 4263 fcip_pkt_t *pptr = NULL; 4264 4265 if (fcipd_pkt == fdestp->fcipd_head) { 4266 ASSERT(fcipd_pkt->fcip_pkt_prev == 4267 NULL); 4268 fdestp->fcipd_head = 4269 fcipd_pkt->fcip_pkt_next; 4270 } else { 4271 pptr = fcipd_pkt->fcip_pkt_prev; 4272 ASSERT(pptr != NULL); 4273 pptr->fcip_pkt_next = 4274 fcipd_pkt->fcip_pkt_next; 4275 } 4276 if (fcipd_pkt->fcip_pkt_next) { 4277 pptr = fcipd_pkt->fcip_pkt_next; 4278 pptr->fcip_pkt_prev = 4279 fcipd_pkt->fcip_pkt_prev; 4280 } 4281 fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_LIST; 4282 break; 4283 } 4284 fcipd_pkt = fcipd_pkt->fcip_pkt_next; 4285 } 4286 } else { 4287 if (fcip_pkt->fcip_pkt_prev == NULL) { 4288 ASSERT(fdestp->fcipd_head == fcip_pkt); 4289 fdestp->fcipd_head = fcip_pkt->fcip_pkt_next; 4290 } else { 4291 fcip_pkt->fcip_pkt_prev->fcip_pkt_next = 4292 fcip_pkt->fcip_pkt_next; 4293 } 4294 4295 if (fcip_pkt->fcip_pkt_next) { 4296 fcip_pkt->fcip_pkt_next->fcip_pkt_prev = 4297 fcip_pkt->fcip_pkt_prev; 4298 } 4299 4300 fcipd_pkt = fcip_pkt; 4301 fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_LIST; 4302 } 4303 4304 return (fcipd_pkt == fcip_pkt); 4305 } 4306 4307 /* 4308 * The transport routine - this is the routine that actually calls 4309 * into the FCA driver (through the transport ofcourse) to transmit a 4310 * datagram on the fibre. The dest struct assoicated with the port to 4311 * which the data is intended is already bound to the packet, this routine 4312 * only takes care of marking the packet a broadcast packet if it is 4313 * intended to be a broadcast request. This permits the transport to send 4314 * the packet down on the wire even if it doesn't have an entry for the 4315 * D_ID in its d_id hash tables. 4316 */ 4317 static int 4318 fcip_transport(fcip_pkt_t *fcip_pkt) 4319 { 4320 struct fcip *fptr; 4321 fc_packet_t *fc_pkt; 4322 fcip_port_info_t *fport; 4323 struct fcip_dest *fdestp; 4324 uint32_t did; 4325 int rval = FC_FAILURE; 4326 struct fcip_routing_table *frp = NULL; 4327 4328 FCIP_TNF_PROBE_1((fcip_transport, "fcip io", /* CSTYLED */, 4329 tnf_string, msg, "enter")); 4330 4331 fptr = fcip_pkt->fcip_pkt_fptr; 4332 fport = fptr->fcip_port_info; 4333 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 4334 fdestp = fcip_pkt->fcip_pkt_dest; 4335 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_WARN, "fcip_transport called")); 4336 4337 did = fptr->fcip_broadcast_did; 4338 if (fc_pkt->pkt_cmd_fhdr.d_id == did && 4339 fc_pkt->pkt_tran_type != FC_PKT_BROADCAST) { 4340 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 4341 (CE_NOTE, "trantype set to BROADCAST")); 4342 fc_pkt->pkt_tran_type = FC_PKT_BROADCAST; 4343 } 4344 4345 mutex_enter(&fptr->fcip_mutex); 4346 if ((fc_pkt->pkt_tran_type != FC_PKT_BROADCAST) && 4347 (fc_pkt->pkt_pd == NULL)) { 4348 mutex_exit(&fptr->fcip_mutex); 4349 FCIP_TNF_PROBE_1((fcip_transport, "fcip io", /* CSTYLED */, 4350 tnf_string, msg, "fcip transport no pd")); 4351 return (rval); 4352 } else if (fptr->fcip_port_state == FCIP_PORT_OFFLINE) { 4353 mutex_exit(&fptr->fcip_mutex); 4354 FCIP_TNF_PROBE_1((fcip_transport, "fcip io", /* CSTYLED */, 4355 tnf_string, msg, "fcip transport port offline")); 4356 return (FC_TRAN_BUSY); 4357 } 4358 mutex_exit(&fptr->fcip_mutex); 4359 4360 if (fdestp) { 4361 struct fcip_routing_table *frp; 4362 4363 frp = fdestp->fcipd_rtable; 4364 mutex_enter(&fptr->fcip_rt_mutex); 4365 mutex_enter(&fdestp->fcipd_mutex); 4366 if (fc_pkt->pkt_pd != NULL) { 4367 if ((frp == NULL) || 4368 (frp && FCIP_RTE_UNAVAIL(frp->fcipr_state))) { 4369 mutex_exit(&fdestp->fcipd_mutex); 4370 mutex_exit(&fptr->fcip_rt_mutex); 4371 if (frp && 4372 (frp->fcipr_state == FCIP_RT_INVALID)) { 4373 FCIP_TNF_PROBE_1((fcip_transport, 4374 "fcip io", /* CSTYLED */, 4375 tnf_string, msg, 4376 "fcip transport - TRANBUSY")); 4377 return (FC_TRAN_BUSY); 4378 } else { 4379 FCIP_TNF_PROBE_1((fcip_transport, 4380 "fcip io", /* CSTYLED */, 4381 tnf_string, msg, 4382 "fcip transport: frp unavailable")); 4383 return (rval); 4384 } 4385 } 4386 } 4387 mutex_exit(&fdestp->fcipd_mutex); 4388 mutex_exit(&fptr->fcip_rt_mutex); 4389 ASSERT(fcip_pkt->fcip_pkt_flags & FCIP_PKT_IN_LIST); 4390 } 4391 4392 /* Explicitly invalidate this field till fcip decides to use it */ 4393 fc_pkt->pkt_ulp_rscn_infop = NULL; 4394 4395 rval = fc_ulp_transport(fport->fcipp_handle, fc_pkt); 4396 if (rval == FC_STATEC_BUSY || rval == FC_OFFLINE) { 4397 /* 4398 * Need to queue up the command for retry 4399 */ 4400 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 4401 (CE_WARN, "ulp_transport failed: 0x%x", rval)); 4402 } else if (rval == FC_LOGINREQ && (frp != NULL)) { 4403 (void) fcip_do_plogi(fptr, frp); 4404 } else if (rval == FC_BADPACKET && (frp != NULL)) { 4405 /* 4406 * There is a distinct possiblity in our scheme of things 4407 * that we have a routing table entry with a NULL pd struct. 4408 * Mark the routing table entry for removal if it is not a 4409 * broadcast entry 4410 */ 4411 if ((frp->fcipr_d_id.port_id != 0x0) && 4412 (frp->fcipr_d_id.port_id != 0xffffff)) { 4413 mutex_enter(&fptr->fcip_rt_mutex); 4414 frp->fcipr_pd = NULL; 4415 frp->fcipr_state = PORT_DEVICE_INVALID; 4416 mutex_exit(&fptr->fcip_rt_mutex); 4417 } 4418 } 4419 4420 FCIP_TNF_PROBE_1((fcip_transport, "fcip io", /* CSTYLED */, 4421 tnf_string, msg, "fcip transport done")); 4422 return (rval); 4423 } 4424 4425 /* 4426 * Call back routine. Called by the FCA/transport when the messages 4427 * has been put onto the wire towards its intended destination. We can 4428 * now free the fc_packet associated with the message 4429 */ 4430 static void 4431 fcip_pkt_callback(fc_packet_t *fc_pkt) 4432 { 4433 int rval; 4434 fcip_pkt_t *fcip_pkt; 4435 struct fcip_dest *fdestp; 4436 4437 fcip_pkt = (fcip_pkt_t *)fc_pkt->pkt_ulp_private; 4438 fdestp = fcip_pkt->fcip_pkt_dest; 4439 4440 /* 4441 * take the lock early so that we don't have a race condition 4442 * with fcip_timeout 4443 * 4444 * fdestp->fcipd_mutex isn't really intended to lock per 4445 * packet struct - see bug 5105592 for permanent solution 4446 */ 4447 mutex_enter(&fdestp->fcipd_mutex); 4448 4449 fcip_pkt->fcip_pkt_flags |= FCIP_PKT_RETURNED; 4450 fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_ABORT; 4451 if (fcip_pkt->fcip_pkt_flags & FCIP_PKT_IN_TIMEOUT) { 4452 mutex_exit(&fdestp->fcipd_mutex); 4453 return; 4454 } 4455 4456 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "pkt callback")); 4457 4458 ASSERT(fdestp->fcipd_rtable != NULL); 4459 ASSERT(fcip_pkt->fcip_pkt_flags & FCIP_PKT_IN_LIST); 4460 rval = fcip_fdestp_dequeue_pkt(fdestp, fcip_pkt); 4461 fdestp->fcipd_ncmds--; 4462 mutex_exit(&fdestp->fcipd_mutex); 4463 4464 if (rval) { 4465 fcip_pkt_free(fcip_pkt, 1); 4466 } 4467 4468 FCIP_TNF_PROBE_1((fcip_pkt_callback, "fcip io", /* CSTYLED */, 4469 tnf_string, msg, "pkt callback done")); 4470 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_NOTE, "pkt callback done")); 4471 } 4472 4473 /* 4474 * Return 1 if the topology is supported, else return 0. 4475 * Topology support is consistent with what the whole 4476 * stack supports together. 4477 */ 4478 static int 4479 fcip_is_supported_fc_topology(int fc_topology) 4480 { 4481 switch (fc_topology) { 4482 4483 case FC_TOP_PRIVATE_LOOP : 4484 case FC_TOP_PUBLIC_LOOP : 4485 case FC_TOP_FABRIC : 4486 case FC_TOP_NO_NS : 4487 return (1); 4488 default : 4489 return (0); 4490 } 4491 } 4492 4493 /* 4494 * handle any topology specific initializations here 4495 * this routine must be called while holding fcip_mutex 4496 */ 4497 /* ARGSUSED */ 4498 static void 4499 fcip_handle_topology(struct fcip *fptr) 4500 { 4501 4502 fcip_port_info_t *fport = fptr->fcip_port_info; 4503 4504 ASSERT(mutex_owned(&fptr->fcip_mutex)); 4505 4506 /* 4507 * Since we know the port's topology - handle topology 4508 * specific details here. In Point to Point and Private Loop 4509 * topologies - we would probably not have a name server 4510 */ 4511 4512 FCIP_TNF_PROBE_3((fcip_handle_topology, "fcip io", /* CSTYLED */, 4513 tnf_string, msg, "enter", 4514 tnf_uint, port_state, fport->fcipp_pstate, 4515 tnf_uint, topology, fport->fcipp_topology)); 4516 FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE, "port state: %x, topology %x", 4517 fport->fcipp_pstate, fport->fcipp_topology)); 4518 4519 fptr->fcip_broadcast_did = fcip_get_broadcast_did(fptr); 4520 mutex_exit(&fptr->fcip_mutex); 4521 (void) fcip_dest_add_broadcast_entry(fptr, 0); 4522 mutex_enter(&fptr->fcip_mutex); 4523 4524 if (!fcip_is_supported_fc_topology(fport->fcipp_topology)) { 4525 FCIP_DEBUG(FCIP_DEBUG_INIT, 4526 (CE_WARN, "fcip(0x%x): Unsupported port topology (0x%x)", 4527 fptr->fcip_instance, fport->fcipp_topology)); 4528 return; 4529 } 4530 4531 switch (fport->fcipp_topology) { 4532 case FC_TOP_PRIVATE_LOOP: { 4533 4534 fc_portmap_t *port_map; 4535 uint32_t listlen, alloclen; 4536 /* 4537 * we may have to maintain routing. Get a list of 4538 * all devices on this port that the transport layer is 4539 * aware of. Check if any of them is a IS8802 type port, 4540 * if yes get its WWN and DID mapping and cache it in 4541 * the purport routing table. Since there is no 4542 * State Change notification for private loop/point_point 4543 * topologies - this table may not be accurate. The static 4544 * routing table is updated on a state change callback. 4545 */ 4546 FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_WARN, "port state valid!!")); 4547 fptr->fcip_port_state = FCIP_PORT_ONLINE; 4548 listlen = alloclen = FCIP_MAX_PORTS; 4549 port_map = (fc_portmap_t *) 4550 kmem_zalloc((FCIP_MAX_PORTS * sizeof (fc_portmap_t)), 4551 KM_SLEEP); 4552 if (fc_ulp_getportmap(fport->fcipp_handle, &port_map, 4553 &listlen, FC_ULP_PLOGI_PRESERVE) == FC_SUCCESS) { 4554 mutex_exit(&fptr->fcip_mutex); 4555 fcip_rt_update(fptr, port_map, listlen); 4556 mutex_enter(&fptr->fcip_mutex); 4557 } 4558 if (listlen > alloclen) { 4559 alloclen = listlen; 4560 } 4561 kmem_free(port_map, (alloclen * sizeof (fc_portmap_t))); 4562 /* 4563 * Now fall through and register with the transport 4564 * that this port is IP capable 4565 */ 4566 } 4567 /* FALLTHROUGH */ 4568 case FC_TOP_NO_NS: 4569 /* 4570 * If we don't have a nameserver, lets wait until we 4571 * have to send out a packet to a remote port and then 4572 * try and discover the port using ARP/FARP. 4573 */ 4574 /* FALLTHROUGH */ 4575 case FC_TOP_PUBLIC_LOOP: 4576 case FC_TOP_FABRIC: { 4577 fc_portmap_t *port_map; 4578 uint32_t listlen, alloclen; 4579 4580 /* FC_TYPE of 0x05 goes to word 0, LSB */ 4581 fptr->fcip_port_state = FCIP_PORT_ONLINE; 4582 4583 if (!(fptr->fcip_flags & FCIP_REG_INPROGRESS)) { 4584 fptr->fcip_flags |= FCIP_REG_INPROGRESS; 4585 if (taskq_dispatch(fptr->fcip_tq, fcip_port_ns, 4586 fptr, KM_NOSLEEP) == 0) { 4587 fptr->fcip_flags &= ~FCIP_REG_INPROGRESS; 4588 } 4589 } 4590 4591 /* 4592 * If fcip_create_nodes_on_demand is overridden to force 4593 * discovery of all nodes in Fabric/Public loop topologies 4594 * we need to query for and obtain all nodes and log into 4595 * them as with private loop devices 4596 */ 4597 if (!fcip_create_nodes_on_demand) { 4598 fptr->fcip_port_state = FCIP_PORT_ONLINE; 4599 listlen = alloclen = FCIP_MAX_PORTS; 4600 port_map = (fc_portmap_t *) 4601 kmem_zalloc((FCIP_MAX_PORTS * 4602 sizeof (fc_portmap_t)), KM_SLEEP); 4603 if (fc_ulp_getportmap(fport->fcipp_handle, &port_map, 4604 &listlen, FC_ULP_PLOGI_PRESERVE) == FC_SUCCESS) { 4605 mutex_exit(&fptr->fcip_mutex); 4606 fcip_rt_update(fptr, port_map, listlen); 4607 mutex_enter(&fptr->fcip_mutex); 4608 } 4609 if (listlen > alloclen) { 4610 alloclen = listlen; 4611 } 4612 kmem_free(port_map, 4613 (alloclen * sizeof (fc_portmap_t))); 4614 } 4615 break; 4616 } 4617 4618 default: 4619 break; 4620 } 4621 } 4622 4623 static void 4624 fcip_port_ns(void *arg) 4625 { 4626 struct fcip *fptr = (struct fcip *)arg; 4627 fcip_port_info_t *fport = fptr->fcip_port_info; 4628 fc_ns_cmd_t ns_cmd; 4629 uint32_t types[8]; 4630 ns_rfc_type_t rfc; 4631 4632 mutex_enter(&fptr->fcip_mutex); 4633 if ((fptr->fcip_flags & (FCIP_DETACHING | FCIP_DETACHED)) || 4634 (fptr->fcip_flags & (FCIP_SUSPENDED | FCIP_POWER_DOWN))) { 4635 fptr->fcip_flags &= ~FCIP_REG_INPROGRESS; 4636 mutex_exit(&fptr->fcip_mutex); 4637 return; 4638 } 4639 mutex_exit(&fptr->fcip_mutex); 4640 4641 /* 4642 * Prepare the Name server structure to 4643 * register with the transport in case of 4644 * Fabric configuration. 4645 */ 4646 bzero(&rfc, sizeof (rfc)); 4647 bzero(types, sizeof (types)); 4648 4649 types[FC4_TYPE_WORD_POS(FC_TYPE_IS8802_SNAP)] = (1 << 4650 FC4_TYPE_BIT_POS(FC_TYPE_IS8802_SNAP)); 4651 4652 rfc.rfc_port_id.port_id = fport->fcipp_sid.port_id; 4653 bcopy(types, rfc.rfc_types, sizeof (types)); 4654 4655 ns_cmd.ns_flags = 0; 4656 ns_cmd.ns_cmd = NS_RFT_ID; 4657 ns_cmd.ns_req_len = sizeof (rfc); 4658 ns_cmd.ns_req_payload = (caddr_t)&rfc; 4659 ns_cmd.ns_resp_len = 0; 4660 ns_cmd.ns_resp_payload = NULL; 4661 4662 /* 4663 * Perform the Name Server Registration for FC IS8802_SNAP Type. 4664 * We don't expect a reply for registering port type 4665 */ 4666 (void) fc_ulp_port_ns(fptr->fcip_port_info->fcipp_handle, 4667 (opaque_t)0, &ns_cmd); 4668 4669 mutex_enter(&fptr->fcip_mutex); 4670 fptr->fcip_flags &= ~FCIP_REG_INPROGRESS; 4671 mutex_exit(&fptr->fcip_mutex); 4672 } 4673 4674 /* 4675 * setup this instance of fcip. This routine inits kstats, allocates 4676 * unsolicited buffers, determines' this port's siblings and handles 4677 * topology specific details which includes registering with the name 4678 * server and also setting up the routing table for this port for 4679 * private loops and point to point topologies 4680 */ 4681 static int 4682 fcip_init_port(struct fcip *fptr) 4683 { 4684 int rval = FC_SUCCESS; 4685 fcip_port_info_t *fport = fptr->fcip_port_info; 4686 static char buf[64]; 4687 size_t tok_buf_size = 0; 4688 4689 ASSERT(fport != NULL); 4690 4691 FCIP_TNF_PROBE_1((fcip_init_port, "fcip io", /* CSTYLED */, 4692 tnf_string, msg, "enter")); 4693 mutex_enter(&fptr->fcip_mutex); 4694 4695 /* 4696 * setup mac address for this port. Don't be too worried if 4697 * the WWN is zero, there is probably nothing attached to 4698 * to the port. There is no point allocating unsolicited buffers 4699 * for an unused port so return success if we don't have a MAC 4700 * address. Do the port init on a state change notification. 4701 */ 4702 if (fcip_setup_mac_addr(fptr) == FCIP_INVALID_WWN) { 4703 fptr->fcip_port_state = FCIP_PORT_OFFLINE; 4704 rval = FC_SUCCESS; 4705 goto done; 4706 } 4707 4708 /* 4709 * clear routing table hash list for this port 4710 */ 4711 fcip_rt_flush(fptr); 4712 4713 /* 4714 * init kstats for this instance 4715 */ 4716 fcip_kstat_init(fptr); 4717 4718 /* 4719 * Allocate unsolicited buffers 4720 */ 4721 fptr->fcip_ub_nbufs = fcip_ub_nbufs; 4722 tok_buf_size = sizeof (*fptr->fcip_ub_tokens) * fcip_ub_nbufs; 4723 4724 FCIP_TNF_PROBE_2((fcip_init_port, "fcip io", /* CSTYLED */, 4725 tnf_string, msg, "debug", 4726 tnf_int, tokBufsize, tok_buf_size)); 4727 4728 FCIP_DEBUG(FCIP_DEBUG_INIT, 4729 (CE_WARN, "tokBufsize: 0x%lx", tok_buf_size)); 4730 4731 fptr->fcip_ub_tokens = kmem_zalloc(tok_buf_size, KM_SLEEP); 4732 4733 if (fptr->fcip_ub_tokens == NULL) { 4734 rval = FC_FAILURE; 4735 FCIP_DEBUG(FCIP_DEBUG_INIT, 4736 (CE_WARN, "fcip(%d): failed to allocate unsol buf", 4737 fptr->fcip_instance)); 4738 goto done; 4739 } 4740 rval = fc_ulp_uballoc(fport->fcipp_handle, &fptr->fcip_ub_nbufs, 4741 fcip_ub_size, FC_TYPE_IS8802_SNAP, fptr->fcip_ub_tokens); 4742 4743 if (rval != FC_SUCCESS) { 4744 FCIP_DEBUG(FCIP_DEBUG_INIT, 4745 (CE_WARN, "fcip(%d): fc_ulp_uballoc failed with 0x%x!!", 4746 fptr->fcip_instance, rval)); 4747 } 4748 4749 switch (rval) { 4750 case FC_SUCCESS: 4751 break; 4752 4753 case FC_OFFLINE: 4754 fptr->fcip_port_state = FCIP_PORT_OFFLINE; 4755 rval = FC_FAILURE; 4756 goto done; 4757 4758 case FC_UB_ERROR: 4759 FCIP_TNF_PROBE_1((fcip_init_port, "fcip io", /* CSTYLED */, 4760 tnf_string, msg, "invalid ub alloc request")); 4761 FCIP_DEBUG(FCIP_DEBUG_INIT, 4762 (CE_WARN, "invalid ub alloc request !!")); 4763 rval = FC_FAILURE; 4764 goto done; 4765 4766 case FC_FAILURE: 4767 /* 4768 * requested bytes could not be alloced 4769 */ 4770 if (fptr->fcip_ub_nbufs != fcip_ub_nbufs) { 4771 cmn_err(CE_WARN, 4772 "!fcip(0x%x): Failed to alloc unsolicited bufs", 4773 ddi_get_instance(fport->fcipp_dip)); 4774 rval = FC_FAILURE; 4775 goto done; 4776 } 4777 break; 4778 4779 default: 4780 rval = FC_FAILURE; 4781 break; 4782 } 4783 4784 /* 4785 * Preallocate a Cache of fcip packets for transmit and receive 4786 * We don't want to be holding on to unsolicited buffers while 4787 * we transmit the message upstream 4788 */ 4789 FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE, "allocating fcip_pkt cache")); 4790 4791 (void) sprintf(buf, "fcip%d_cache", fptr->fcip_instance); 4792 fptr->fcip_xmit_cache = kmem_cache_create(buf, 4793 (fport->fcipp_fca_pkt_size + sizeof (fcip_pkt_t)), 4794 8, fcip_cache_constructor, fcip_cache_destructor, 4795 NULL, (void *)fport, NULL, 0); 4796 4797 (void) sprintf(buf, "fcip%d_sendup_cache", fptr->fcip_instance); 4798 fptr->fcip_sendup_cache = kmem_cache_create(buf, 4799 sizeof (struct fcip_sendup_elem), 4800 8, fcip_sendup_constructor, NULL, NULL, (void *)fport, NULL, 0); 4801 4802 if (fptr->fcip_xmit_cache == NULL) { 4803 FCIP_TNF_PROBE_2((fcip_init_port, "fcip io", /* CSTYLED */, 4804 tnf_string, msg, "unable to allocate xmit cache", 4805 tnf_int, instance, fptr->fcip_instance)); 4806 FCIP_DEBUG(FCIP_DEBUG_INIT, 4807 (CE_WARN, "fcip%d unable to allocate xmit cache", 4808 fptr->fcip_instance)); 4809 rval = FC_FAILURE; 4810 goto done; 4811 } 4812 4813 /* 4814 * We may need to handle routing tables for point to point and 4815 * fcal topologies and register with NameServer for Fabric 4816 * topologies. 4817 */ 4818 fcip_handle_topology(fptr); 4819 mutex_exit(&fptr->fcip_mutex); 4820 if (fcip_dest_add_broadcast_entry(fptr, 1) != FC_SUCCESS) { 4821 FCIP_DEBUG(FCIP_DEBUG_INIT, 4822 (CE_WARN, "fcip(0x%x):add broadcast entry failed!!", 4823 fptr->fcip_instance)); 4824 mutex_enter(&fptr->fcip_mutex); 4825 rval = FC_FAILURE; 4826 goto done; 4827 } 4828 4829 rval = FC_SUCCESS; 4830 return (rval); 4831 4832 done: 4833 /* 4834 * we don't always come here from port_attach - so cleanup 4835 * anything done in the init_port routine 4836 */ 4837 if (fptr->fcip_kstatp) { 4838 kstat_delete(fptr->fcip_kstatp); 4839 fptr->fcip_kstatp = NULL; 4840 } 4841 4842 if (fptr->fcip_xmit_cache) { 4843 kmem_cache_destroy(fptr->fcip_xmit_cache); 4844 fptr->fcip_xmit_cache = NULL; 4845 } 4846 4847 if (fptr->fcip_sendup_cache) { 4848 kmem_cache_destroy(fptr->fcip_sendup_cache); 4849 fptr->fcip_sendup_cache = NULL; 4850 } 4851 4852 /* release unsolicited buffers */ 4853 if (fptr->fcip_ub_tokens) { 4854 uint64_t *tokens = fptr->fcip_ub_tokens; 4855 fptr->fcip_ub_tokens = NULL; 4856 4857 mutex_exit(&fptr->fcip_mutex); 4858 (void) fc_ulp_ubfree(fport->fcipp_handle, fptr->fcip_ub_nbufs, 4859 tokens); 4860 kmem_free(tokens, tok_buf_size); 4861 4862 } else { 4863 mutex_exit(&fptr->fcip_mutex); 4864 } 4865 4866 return (rval); 4867 } 4868 4869 /* 4870 * Sets up a port's MAC address from its WWN 4871 */ 4872 static int 4873 fcip_setup_mac_addr(struct fcip *fptr) 4874 { 4875 fcip_port_info_t *fport = fptr->fcip_port_info; 4876 4877 ASSERT(mutex_owned(&fptr->fcip_mutex)); 4878 4879 fptr->fcip_addrflags = 0; 4880 4881 /* 4882 * we cannot choose a MAC address for our interface - we have 4883 * to live with whatever node WWN we get (minus the top two 4884 * MSbytes for the MAC address) from the transport layer. We will 4885 * treat the WWN as our factory MAC address. 4886 */ 4887 4888 if ((fport->fcipp_nwwn.w.wwn_hi != 0) || 4889 (fport->fcipp_nwwn.w.wwn_lo != 0)) { 4890 char etherstr[ETHERSTRL]; 4891 4892 wwn_to_ether(&fport->fcipp_nwwn, &fptr->fcip_macaddr); 4893 fcip_ether_to_str(&fptr->fcip_macaddr, etherstr); 4894 FCIP_DEBUG(FCIP_DEBUG_INIT, 4895 (CE_NOTE, "setupmacaddr ouraddr %s", etherstr)); 4896 4897 fptr->fcip_addrflags = (FCIP_FACTADDR_PRESENT | 4898 FCIP_FACTADDR_USE); 4899 } else { 4900 /* 4901 * No WWN - just return failure - there's not much 4902 * we can do since we cannot set the WWN. 4903 */ 4904 FCIP_DEBUG(FCIP_DEBUG_INIT, 4905 (CE_WARN, "Port does not have a valid WWN")); 4906 return (FCIP_INVALID_WWN); 4907 } 4908 return (FC_SUCCESS); 4909 } 4910 4911 4912 /* 4913 * flush routing table entries 4914 */ 4915 static void 4916 fcip_rt_flush(struct fcip *fptr) 4917 { 4918 int index; 4919 4920 mutex_enter(&fptr->fcip_rt_mutex); 4921 for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) { 4922 struct fcip_routing_table *frtp, *frtp_next; 4923 frtp = fptr->fcip_rtable[index]; 4924 while (frtp) { 4925 frtp_next = frtp->fcipr_next; 4926 kmem_free(frtp, sizeof (struct fcip_routing_table)); 4927 frtp = frtp_next; 4928 } 4929 fptr->fcip_rtable[index] = NULL; 4930 } 4931 mutex_exit(&fptr->fcip_rt_mutex); 4932 } 4933 4934 /* 4935 * Free up the fcip softstate and all allocated resources for the 4936 * fcip instance assoicated with a given port driver instance 4937 * 4938 * Given that the list of structures pointed to by fcip_port_head, 4939 * this function is called from multiple sources, and the 4940 * fcip_global_mutex that protects fcip_port_head must be dropped, 4941 * our best solution is to return a value that indicates the next 4942 * port in the list. This way the caller doesn't need to worry 4943 * about the race condition where it saves off a pointer to the 4944 * next structure in the list and by the time this routine returns, 4945 * that next structure has already been freed. 4946 */ 4947 static fcip_port_info_t * 4948 fcip_softstate_free(fcip_port_info_t *fport) 4949 { 4950 struct fcip *fptr = NULL; 4951 int instance; 4952 timeout_id_t tid; 4953 opaque_t phandle = NULL; 4954 fcip_port_info_t *prev_fport, *cur_fport, *next_fport = NULL; 4955 4956 ASSERT(MUTEX_HELD(&fcip_global_mutex)); 4957 4958 if (fport) { 4959 phandle = fport->fcipp_handle; 4960 fptr = fport->fcipp_fcip; 4961 } else { 4962 return (next_fport); 4963 } 4964 4965 if (fptr) { 4966 mutex_enter(&fptr->fcip_mutex); 4967 instance = ddi_get_instance(fptr->fcip_dip); 4968 4969 /* 4970 * dismantle timeout thread for this instance of fcip 4971 */ 4972 tid = fptr->fcip_timeout_id; 4973 fptr->fcip_timeout_id = NULL; 4974 4975 mutex_exit(&fptr->fcip_mutex); 4976 (void) untimeout(tid); 4977 mutex_enter(&fptr->fcip_mutex); 4978 4979 ASSERT(fcip_num_instances >= 0); 4980 fcip_num_instances--; 4981 4982 /* 4983 * stop sendup thread 4984 */ 4985 mutex_enter(&fptr->fcip_sendup_mutex); 4986 if (fptr->fcip_sendup_thr_initted) { 4987 fptr->fcip_sendup_thr_initted = 0; 4988 cv_signal(&fptr->fcip_sendup_cv); 4989 cv_wait(&fptr->fcip_sendup_cv, 4990 &fptr->fcip_sendup_mutex); 4991 } 4992 ASSERT(fptr->fcip_sendup_head == NULL); 4993 fptr->fcip_sendup_head = fptr->fcip_sendup_tail = NULL; 4994 mutex_exit(&fptr->fcip_sendup_mutex); 4995 4996 /* 4997 * dismantle taskq 4998 */ 4999 if (fptr->fcip_tq) { 5000 taskq_t *tq = fptr->fcip_tq; 5001 5002 fptr->fcip_tq = NULL; 5003 5004 mutex_exit(&fptr->fcip_mutex); 5005 taskq_destroy(tq); 5006 mutex_enter(&fptr->fcip_mutex); 5007 } 5008 5009 if (fptr->fcip_kstatp) { 5010 kstat_delete(fptr->fcip_kstatp); 5011 fptr->fcip_kstatp = NULL; 5012 } 5013 5014 /* flush the routing table entries */ 5015 fcip_rt_flush(fptr); 5016 5017 if (fptr->fcip_xmit_cache) { 5018 kmem_cache_destroy(fptr->fcip_xmit_cache); 5019 fptr->fcip_xmit_cache = NULL; 5020 } 5021 5022 if (fptr->fcip_sendup_cache) { 5023 kmem_cache_destroy(fptr->fcip_sendup_cache); 5024 fptr->fcip_sendup_cache = NULL; 5025 } 5026 5027 fcip_cleanup_dest(fptr); 5028 5029 /* release unsolicited buffers */ 5030 if (fptr->fcip_ub_tokens) { 5031 uint64_t *tokens = fptr->fcip_ub_tokens; 5032 5033 fptr->fcip_ub_tokens = NULL; 5034 mutex_exit(&fptr->fcip_mutex); 5035 if (phandle) { 5036 /* 5037 * release the global mutex here to 5038 * permit any data pending callbacks to 5039 * complete. Else we will deadlock in the 5040 * FCA waiting for all unsol buffers to be 5041 * returned. 5042 */ 5043 mutex_exit(&fcip_global_mutex); 5044 (void) fc_ulp_ubfree(phandle, 5045 fptr->fcip_ub_nbufs, tokens); 5046 mutex_enter(&fcip_global_mutex); 5047 } 5048 kmem_free(tokens, (sizeof (*tokens) * fcip_ub_nbufs)); 5049 } else { 5050 mutex_exit(&fptr->fcip_mutex); 5051 } 5052 5053 mutex_destroy(&fptr->fcip_mutex); 5054 mutex_destroy(&fptr->fcip_ub_mutex); 5055 mutex_destroy(&fptr->fcip_rt_mutex); 5056 mutex_destroy(&fptr->fcip_dest_mutex); 5057 mutex_destroy(&fptr->fcip_sendup_mutex); 5058 cv_destroy(&fptr->fcip_farp_cv); 5059 cv_destroy(&fptr->fcip_sendup_cv); 5060 cv_destroy(&fptr->fcip_ub_cv); 5061 5062 ddi_soft_state_free(fcip_softp, instance); 5063 } 5064 5065 /* 5066 * Now dequeue the fcip_port_info from the port list 5067 */ 5068 cur_fport = fcip_port_head; 5069 prev_fport = NULL; 5070 while (cur_fport != NULL) { 5071 if (cur_fport == fport) { 5072 break; 5073 } 5074 prev_fport = cur_fport; 5075 cur_fport = cur_fport->fcipp_next; 5076 } 5077 5078 /* 5079 * Assert that we found a port in our port list 5080 */ 5081 ASSERT(cur_fport == fport); 5082 5083 if (prev_fport) { 5084 /* 5085 * Not the first port in the port list 5086 */ 5087 prev_fport->fcipp_next = fport->fcipp_next; 5088 } else { 5089 /* 5090 * first port 5091 */ 5092 fcip_port_head = fport->fcipp_next; 5093 } 5094 next_fport = fport->fcipp_next; 5095 kmem_free(fport, sizeof (fcip_port_info_t)); 5096 5097 return (next_fport); 5098 } 5099 5100 5101 /* 5102 * This is called by transport for any ioctl operations performed 5103 * on the devctl or other transport minor nodes. It is currently 5104 * unused for fcip 5105 */ 5106 /* ARGSUSED */ 5107 static int 5108 fcip_port_ioctl(opaque_t ulp_handle, opaque_t port_handle, dev_t dev, 5109 int cmd, intptr_t data, int mode, cred_t *credp, int *rval, 5110 uint32_t claimed) 5111 { 5112 return (FC_UNCLAIMED); 5113 } 5114 5115 /* 5116 * DL_INFO_REQ - returns information about the DLPI stream to the DLS user 5117 * requesting information about this interface 5118 */ 5119 static void 5120 fcip_ireq(queue_t *wq, mblk_t *mp) 5121 { 5122 struct fcipstr *slp; 5123 struct fcip *fptr; 5124 dl_info_ack_t *dlip; 5125 struct fcipdladdr *dlap; 5126 la_wwn_t *ep; 5127 int size; 5128 char etherstr[ETHERSTRL]; 5129 5130 slp = (struct fcipstr *)wq->q_ptr; 5131 5132 fptr = slp->sl_fcip; 5133 5134 FCIP_DEBUG(FCIP_DEBUG_DLPI, 5135 (CE_NOTE, "fcip_ireq: info request req rcvd")); 5136 5137 FCIP_TNF_PROBE_1((fcip_ireq, "fcip io", /* CSTYLED */, 5138 tnf_string, msg, "fcip ireq entered")); 5139 5140 if (MBLKL(mp) < DL_INFO_REQ_SIZE) { 5141 dlerrorack(wq, mp, DL_INFO_REQ, DL_BADPRIM, 0); 5142 return; 5143 } 5144 5145 /* 5146 * Exchange current message for a DL_INFO_ACK 5147 */ 5148 size = sizeof (dl_info_ack_t) + FCIPADDRL + ETHERADDRL; 5149 if ((mp = mexchange(wq, mp, size, M_PCPROTO, DL_INFO_ACK)) == NULL) { 5150 return; 5151 } 5152 5153 /* 5154 * FILL in the DL_INFO_ACK fields and reply 5155 */ 5156 dlip = (dl_info_ack_t *)mp->b_rptr; 5157 *dlip = fcip_infoack; 5158 dlip->dl_current_state = slp->sl_state; 5159 dlap = (struct fcipdladdr *)(mp->b_rptr + dlip->dl_addr_offset); 5160 dlap->dl_sap = slp->sl_sap; 5161 5162 5163 if (fptr) { 5164 fcip_ether_to_str(&fptr->fcip_macaddr, etherstr); 5165 FCIP_DEBUG(FCIP_DEBUG_DLPI, 5166 (CE_NOTE, "ireq - our mac: %s", etherstr)); 5167 ether_bcopy(&fptr->fcip_macaddr, &dlap->dl_phys); 5168 } else { 5169 bzero((caddr_t)&dlap->dl_phys, ETHERADDRL); 5170 } 5171 5172 ep = (la_wwn_t *)(mp->b_rptr + dlip->dl_brdcst_addr_offset); 5173 ether_bcopy(&fcip_arpbroadcast_addr, ep); 5174 5175 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "sending back info req..")); 5176 qreply(wq, mp); 5177 } 5178 5179 5180 /* 5181 * To handle DL_UNITDATA_REQ requests. 5182 */ 5183 5184 static void 5185 fcip_udreq(queue_t *wq, mblk_t *mp) 5186 { 5187 struct fcipstr *slp; 5188 struct fcip *fptr; 5189 fcip_port_info_t *fport; 5190 dl_unitdata_req_t *dludp; 5191 mblk_t *nmp; 5192 struct fcipdladdr *dlap; 5193 fcph_network_hdr_t *headerp; 5194 llc_snap_hdr_t *lsnap; 5195 t_uscalar_t off, len; 5196 struct fcip_dest *fdestp; 5197 la_wwn_t wwn; 5198 int hdr_size; 5199 5200 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "inside fcip_udreq")); 5201 5202 FCIP_TNF_PROBE_1((fcip_udreq, "fcip io", /* CSTYLED */, 5203 tnf_string, msg, "fcip udreq entered")); 5204 5205 slp = (struct fcipstr *)wq->q_ptr; 5206 5207 if (slp->sl_state != DL_IDLE) { 5208 dlerrorack(wq, mp, DL_UNITDATA_REQ, DL_OUTSTATE, 0); 5209 return; 5210 } 5211 5212 fptr = slp->sl_fcip; 5213 5214 if (fptr == NULL) { 5215 dlerrorack(wq, mp, DL_UNITDATA_REQ, DL_OUTSTATE, 0); 5216 return; 5217 } 5218 5219 fport = fptr->fcip_port_info; 5220 5221 dludp = (dl_unitdata_req_t *)mp->b_rptr; 5222 off = dludp->dl_dest_addr_offset; 5223 len = dludp->dl_dest_addr_length; 5224 5225 /* 5226 * Validate destination address format 5227 */ 5228 if (!MBLKIN(mp, off, len) || (len != FCIPADDRL)) { 5229 dluderrorind(wq, mp, (mp->b_rptr + off), len, DL_BADADDR, 0); 5230 return; 5231 } 5232 5233 /* 5234 * Error if no M_DATA follows 5235 */ 5236 nmp = mp->b_cont; 5237 if (nmp == NULL) { 5238 dluderrorind(wq, mp, (mp->b_rptr + off), len, DL_BADDATA, 0); 5239 return; 5240 } 5241 dlap = (struct fcipdladdr *)(mp->b_rptr + off); 5242 5243 /* 5244 * Now get the destination structure for the remote NPORT 5245 */ 5246 ether_to_wwn(&dlap->dl_phys, &wwn); 5247 fdestp = fcip_get_dest(fptr, &wwn); 5248 5249 if (fdestp == NULL) { 5250 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, 5251 "udreq - couldn't find dest struct for remote port")); 5252 dluderrorind(wq, mp, (mp->b_rptr + off), len, DL_BADDATA, 0); 5253 return; 5254 } 5255 5256 /* 5257 * Network header + SAP 5258 */ 5259 hdr_size = sizeof (fcph_network_hdr_t) + sizeof (llc_snap_hdr_t); 5260 5261 /* DB_REF gives the no. of msgs pointing to this block */ 5262 if ((DB_REF(nmp) == 1) && 5263 (MBLKHEAD(nmp) >= hdr_size) && 5264 (((uintptr_t)mp->b_rptr & 0x1) == 0)) { 5265 la_wwn_t wwn; 5266 nmp->b_rptr -= hdr_size; 5267 5268 /* first put the network header */ 5269 headerp = (fcph_network_hdr_t *)nmp->b_rptr; 5270 if (ether_cmp(&dlap->dl_phys, &fcip_arpbroadcast_addr) == 0) { 5271 ether_to_wwn(&fcipnhbroadcastaddr, &wwn); 5272 } else { 5273 ether_to_wwn(&dlap->dl_phys, &wwn); 5274 } 5275 bcopy(&wwn, &headerp->net_dest_addr, sizeof (la_wwn_t)); 5276 ether_to_wwn(&fptr->fcip_macaddr, &wwn); 5277 bcopy(&wwn, &headerp->net_src_addr, sizeof (la_wwn_t)); 5278 5279 /* Now the snap header */ 5280 lsnap = (llc_snap_hdr_t *)(nmp->b_rptr + 5281 sizeof (fcph_network_hdr_t)); 5282 lsnap->dsap = 0xAA; 5283 lsnap->ssap = 0xAA; 5284 lsnap->ctrl = 0x03; 5285 lsnap->oui[0] = 0x00; 5286 lsnap->oui[1] = 0x00; /* 80 */ 5287 lsnap->oui[2] = 0x00; /* C2 */ 5288 lsnap->pid = BE_16((dlap->dl_sap)); 5289 5290 freeb(mp); 5291 mp = nmp; 5292 5293 } else { 5294 la_wwn_t wwn; 5295 5296 DB_TYPE(mp) = M_DATA; 5297 headerp = (fcph_network_hdr_t *)mp->b_rptr; 5298 5299 /* 5300 * Only fill in the low 48bits of WWN for now - we can 5301 * fill in the NAA_ID after we find the port in the 5302 * routing tables 5303 */ 5304 if (ether_cmp(&dlap->dl_phys, &fcip_arpbroadcast_addr) == 0) { 5305 ether_to_wwn(&fcipnhbroadcastaddr, &wwn); 5306 } else { 5307 ether_to_wwn(&dlap->dl_phys, &wwn); 5308 } 5309 bcopy(&wwn, &headerp->net_dest_addr, sizeof (la_wwn_t)); 5310 /* need to send our PWWN */ 5311 bcopy(&fport->fcipp_pwwn, &headerp->net_src_addr, 5312 sizeof (la_wwn_t)); 5313 5314 lsnap = (llc_snap_hdr_t *)(nmp->b_rptr + 5315 sizeof (fcph_network_hdr_t)); 5316 lsnap->dsap = 0xAA; 5317 lsnap->ssap = 0xAA; 5318 lsnap->ctrl = 0x03; 5319 lsnap->oui[0] = 0x00; 5320 lsnap->oui[1] = 0x00; 5321 lsnap->oui[2] = 0x00; 5322 lsnap->pid = BE_16(dlap->dl_sap); 5323 5324 mp->b_wptr = mp->b_rptr + hdr_size; 5325 } 5326 5327 /* 5328 * Ethernet drivers have a lot of gunk here to put the Type 5329 * information (for Ethernet encapsulation (RFC 894) or the 5330 * Length (for 802.2/802.3) - I guess we'll just ignore that 5331 * here. 5332 */ 5333 5334 /* 5335 * Start the I/O on this port. If fcip_start failed for some reason 5336 * we call putbq in fcip_start so we don't need to check the 5337 * return value from fcip_start 5338 */ 5339 (void) fcip_start(wq, mp, fptr, fdestp, KM_SLEEP); 5340 } 5341 5342 /* 5343 * DL_ATTACH_REQ: attaches a PPA with a stream. ATTACH requets are needed 5344 * for style 2 DLS providers to identify the physical medium through which 5345 * the streams communication will happen 5346 */ 5347 static void 5348 fcip_areq(queue_t *wq, mblk_t *mp) 5349 { 5350 struct fcipstr *slp; 5351 union DL_primitives *dlp; 5352 fcip_port_info_t *fport; 5353 struct fcip *fptr; 5354 int ppa; 5355 5356 slp = (struct fcipstr *)wq->q_ptr; 5357 dlp = (union DL_primitives *)mp->b_rptr; 5358 5359 if (MBLKL(mp) < DL_ATTACH_REQ_SIZE) { 5360 dlerrorack(wq, mp, DL_ATTACH_REQ, DL_BADPRIM, 0); 5361 return; 5362 } 5363 5364 if (slp->sl_state != DL_UNATTACHED) { 5365 dlerrorack(wq, mp, DL_ATTACH_REQ, DL_OUTSTATE, 0); 5366 return; 5367 } 5368 5369 ppa = dlp->attach_req.dl_ppa; 5370 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "attach req: ppa %x", ppa)); 5371 5372 /* 5373 * check if the PPA is valid 5374 */ 5375 5376 mutex_enter(&fcip_global_mutex); 5377 5378 for (fport = fcip_port_head; fport; fport = fport->fcipp_next) { 5379 if ((fptr = fport->fcipp_fcip) == NULL) { 5380 continue; 5381 } 5382 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "ppa %x, inst %x", ppa, 5383 ddi_get_instance(fptr->fcip_dip))); 5384 5385 if (ppa == ddi_get_instance(fptr->fcip_dip)) { 5386 FCIP_DEBUG(FCIP_DEBUG_DLPI, 5387 (CE_NOTE, "ppa found %x", ppa)); 5388 break; 5389 } 5390 } 5391 5392 if (fport == NULL) { 5393 FCIP_DEBUG(FCIP_DEBUG_DLPI, 5394 (CE_NOTE, "dlerrorack coz fport==NULL")); 5395 5396 mutex_exit(&fcip_global_mutex); 5397 5398 if (fc_ulp_get_port_handle(ppa) == NULL) { 5399 dlerrorack(wq, mp, DL_ATTACH_REQ, DL_BADPPA, 0); 5400 return; 5401 } 5402 5403 /* 5404 * Wait for Port attach callback to trigger. If port_detach 5405 * got in while we were waiting, then ddi_get_soft_state 5406 * will return NULL, and we'll return error. 5407 */ 5408 5409 delay(drv_usectohz(FCIP_INIT_DELAY)); 5410 mutex_enter(&fcip_global_mutex); 5411 5412 fptr = ddi_get_soft_state(fcip_softp, ppa); 5413 if (fptr == NULL) { 5414 mutex_exit(&fcip_global_mutex); 5415 dlerrorack(wq, mp, DL_ATTACH_REQ, DL_BADPPA, 0); 5416 return; 5417 } 5418 } 5419 5420 /* 5421 * set link to device and update our state 5422 */ 5423 slp->sl_fcip = fptr; 5424 slp->sl_state = DL_UNBOUND; 5425 5426 mutex_exit(&fcip_global_mutex); 5427 5428 #ifdef DEBUG 5429 mutex_enter(&fptr->fcip_mutex); 5430 if (fptr->fcip_flags & FCIP_LINK_DOWN) { 5431 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_WARN, "port not online yet")); 5432 } 5433 mutex_exit(&fptr->fcip_mutex); 5434 #endif 5435 5436 dlokack(wq, mp, DL_ATTACH_REQ); 5437 } 5438 5439 5440 /* 5441 * DL_DETACH request - detaches a PPA from a stream 5442 */ 5443 static void 5444 fcip_dreq(queue_t *wq, mblk_t *mp) 5445 { 5446 struct fcipstr *slp; 5447 5448 slp = (struct fcipstr *)wq->q_ptr; 5449 5450 if (MBLKL(mp) < DL_DETACH_REQ_SIZE) { 5451 dlerrorack(wq, mp, DL_DETACH_REQ, DL_BADPRIM, 0); 5452 return; 5453 } 5454 5455 if (slp->sl_state != DL_UNBOUND) { 5456 dlerrorack(wq, mp, DL_DETACH_REQ, DL_OUTSTATE, 0); 5457 return; 5458 } 5459 5460 fcip_dodetach(slp); 5461 dlokack(wq, mp, DL_DETACH_REQ); 5462 } 5463 5464 /* 5465 * DL_BIND request: requests a DLS provider to bind a DLSAP to the stream. 5466 * DLS users communicate with a physical interface through DLSAPs. Multiple 5467 * DLSAPs can be bound to the same stream (PPA) 5468 */ 5469 static void 5470 fcip_breq(queue_t *wq, mblk_t *mp) 5471 { 5472 struct fcipstr *slp; 5473 union DL_primitives *dlp; 5474 struct fcip *fptr; 5475 struct fcipdladdr fcipaddr; 5476 t_uscalar_t sap; 5477 int xidtest; 5478 5479 slp = (struct fcipstr *)wq->q_ptr; 5480 5481 if (MBLKL(mp) < DL_BIND_REQ_SIZE) { 5482 dlerrorack(wq, mp, DL_BIND_REQ, DL_BADPRIM, 0); 5483 return; 5484 } 5485 5486 if (slp->sl_state != DL_UNBOUND) { 5487 dlerrorack(wq, mp, DL_BIND_REQ, DL_OUTSTATE, 0); 5488 return; 5489 } 5490 5491 dlp = (union DL_primitives *)mp->b_rptr; 5492 fptr = slp->sl_fcip; 5493 5494 if (fptr == NULL) { 5495 dlerrorack(wq, mp, DL_BIND_REQ, DL_OUTSTATE, 0); 5496 return; 5497 } 5498 5499 sap = dlp->bind_req.dl_sap; 5500 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "fcip_breq - sap: %x", sap)); 5501 xidtest = dlp->bind_req.dl_xidtest_flg; 5502 5503 if (xidtest) { 5504 dlerrorack(wq, mp, DL_BIND_REQ, DL_NOAUTO, 0); 5505 return; 5506 } 5507 5508 FCIP_DEBUG(FCIP_DEBUG_DLPI, (CE_NOTE, "DLBIND: sap : %x", sap)); 5509 5510 if (sap > ETHERTYPE_MAX) { 5511 dlerrorack(wq, mp, dlp->dl_primitive, DL_BADSAP, 0); 5512 return; 5513 } 5514 /* 5515 * save SAP for this stream and change the link state 5516 */ 5517 slp->sl_sap = sap; 5518 slp->sl_state = DL_IDLE; 5519 5520 fcipaddr.dl_sap = sap; 5521 ether_bcopy(&fptr->fcip_macaddr, &fcipaddr.dl_phys); 5522 dlbindack(wq, mp, sap, &fcipaddr, FCIPADDRL, 0, 0); 5523 5524 fcip_setipq(fptr); 5525 } 5526 5527 /* 5528 * DL_UNBIND request to unbind a previously bound DLSAP, from this stream 5529 */ 5530 static void 5531 fcip_ubreq(queue_t *wq, mblk_t *mp) 5532 { 5533 struct fcipstr *slp; 5534 5535 slp = (struct fcipstr *)wq->q_ptr; 5536 5537 if (MBLKL(mp) < DL_UNBIND_REQ_SIZE) { 5538 dlerrorack(wq, mp, DL_UNBIND_REQ, DL_BADPRIM, 0); 5539 return; 5540 } 5541 5542 if (slp->sl_state != DL_IDLE) { 5543 dlerrorack(wq, mp, DL_UNBIND_REQ, DL_OUTSTATE, 0); 5544 return; 5545 } 5546 5547 slp->sl_state = DL_UNBOUND; 5548 slp->sl_sap = 0; 5549 5550 (void) putnextctl1(RD(wq), M_FLUSH, FLUSHRW); 5551 dlokack(wq, mp, DL_UNBIND_REQ); 5552 5553 fcip_setipq(slp->sl_fcip); 5554 } 5555 5556 /* 5557 * Return our physical address 5558 */ 5559 static void 5560 fcip_pareq(queue_t *wq, mblk_t *mp) 5561 { 5562 struct fcipstr *slp; 5563 union DL_primitives *dlp; 5564 int type; 5565 struct fcip *fptr; 5566 fcip_port_info_t *fport; 5567 struct ether_addr addr; 5568 5569 slp = (struct fcipstr *)wq->q_ptr; 5570 5571 if (MBLKL(mp) < DL_PHYS_ADDR_REQ_SIZE) { 5572 dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_BADPRIM, 0); 5573 return; 5574 } 5575 5576 dlp = (union DL_primitives *)mp->b_rptr; 5577 type = dlp->physaddr_req.dl_addr_type; 5578 fptr = slp->sl_fcip; 5579 5580 if (fptr == NULL) { 5581 dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_OUTSTATE, 0); 5582 return; 5583 } 5584 5585 fport = fptr->fcip_port_info; 5586 5587 switch (type) { 5588 case DL_FACT_PHYS_ADDR: 5589 FCIP_DEBUG(FCIP_DEBUG_DLPI, 5590 (CE_NOTE, "returning factory phys addr")); 5591 wwn_to_ether(&fport->fcipp_pwwn, &addr); 5592 break; 5593 5594 case DL_CURR_PHYS_ADDR: 5595 FCIP_DEBUG(FCIP_DEBUG_DLPI, 5596 (CE_NOTE, "returning current phys addr")); 5597 ether_bcopy(&fptr->fcip_macaddr, &addr); 5598 break; 5599 5600 default: 5601 FCIP_DEBUG(FCIP_DEBUG_DLPI, 5602 (CE_NOTE, "Not known cmd type in phys addr")); 5603 dlerrorack(wq, mp, DL_PHYS_ADDR_REQ, DL_NOTSUPPORTED, 0); 5604 return; 5605 } 5606 dlphysaddrack(wq, mp, &addr, ETHERADDRL); 5607 } 5608 5609 /* 5610 * Set physical address DLPI request 5611 */ 5612 static void 5613 fcip_spareq(queue_t *wq, mblk_t *mp) 5614 { 5615 struct fcipstr *slp; 5616 union DL_primitives *dlp; 5617 t_uscalar_t off, len; 5618 struct ether_addr *addrp; 5619 la_wwn_t wwn; 5620 struct fcip *fptr; 5621 fc_ns_cmd_t fcip_ns_cmd; 5622 5623 slp = (struct fcipstr *)wq->q_ptr; 5624 5625 if (MBLKL(mp) < DL_SET_PHYS_ADDR_REQ_SIZE) { 5626 dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0); 5627 return; 5628 } 5629 5630 dlp = (union DL_primitives *)mp->b_rptr; 5631 len = dlp->set_physaddr_req.dl_addr_length; 5632 off = dlp->set_physaddr_req.dl_addr_offset; 5633 5634 if (!MBLKIN(mp, off, len)) { 5635 dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0); 5636 return; 5637 } 5638 5639 addrp = (struct ether_addr *)(mp->b_rptr + off); 5640 5641 /* 5642 * If the length of physical address is not correct or address 5643 * specified is a broadcast address or multicast addr - 5644 * return an error. 5645 */ 5646 if ((len != ETHERADDRL) || 5647 ((addrp->ether_addr_octet[0] & 01) == 1) || 5648 (ether_cmp(addrp, &fcip_arpbroadcast_addr) == 0)) { 5649 dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADADDR, 0); 5650 return; 5651 } 5652 5653 /* 5654 * check if a stream is attached to this device. Else return an error 5655 */ 5656 if ((fptr = slp->sl_fcip) == NULL) { 5657 dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_OUTSTATE, 0); 5658 return; 5659 } 5660 5661 /* 5662 * set the new interface local address. We request the transport 5663 * layer to change the Port WWN for this device - return an error 5664 * if we don't succeed. 5665 */ 5666 5667 ether_to_wwn(addrp, &wwn); 5668 if (fcip_set_wwn(&wwn) == FC_SUCCESS) { 5669 FCIP_DEBUG(FCIP_DEBUG_DLPI, 5670 (CE_WARN, "WWN changed in spareq")); 5671 } else { 5672 dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADADDR, 0); 5673 } 5674 5675 /* 5676 * register The new Port WWN and Node WWN with the transport 5677 * and Nameserver. Hope the transport ensures all current I/O 5678 * has stopped before actually attempting to register a new 5679 * port and Node WWN else we are hosed. Maybe a Link reset 5680 * will get everyone's attention. 5681 */ 5682 fcip_ns_cmd.ns_flags = 0; 5683 fcip_ns_cmd.ns_cmd = NS_RPN_ID; 5684 fcip_ns_cmd.ns_req_len = sizeof (la_wwn_t); 5685 fcip_ns_cmd.ns_req_payload = (caddr_t)&wwn.raw_wwn[0]; 5686 fcip_ns_cmd.ns_resp_len = 0; 5687 fcip_ns_cmd.ns_resp_payload = (caddr_t)0; 5688 if (fc_ulp_port_ns(fptr->fcip_port_info->fcipp_handle, 5689 (opaque_t)0, &fcip_ns_cmd) != FC_SUCCESS) { 5690 FCIP_DEBUG(FCIP_DEBUG_DLPI, 5691 (CE_WARN, "setting Port WWN failed")); 5692 dlerrorack(wq, mp, DL_SET_PHYS_ADDR_REQ, DL_BADPRIM, 0); 5693 return; 5694 } 5695 5696 dlokack(wq, mp, DL_SET_PHYS_ADDR_REQ); 5697 } 5698 5699 /* 5700 * change our port's WWN if permitted by hardware 5701 */ 5702 /* ARGSUSED */ 5703 static int 5704 fcip_set_wwn(la_wwn_t *pwwn) 5705 { 5706 /* 5707 * We're usually not allowed to change the WWN of adapters 5708 * but some adapters do permit us to change the WWN - don't 5709 * permit setting of WWNs (yet?) - This behavior could be 5710 * modified if needed 5711 */ 5712 return (FC_FAILURE); 5713 } 5714 5715 5716 /* 5717 * This routine fills in the header for fastpath data requests. What this 5718 * does in simple terms is, instead of sending all data through the Unitdata 5719 * request dlpi code paths (which will then append the protocol specific 5720 * header - network and snap headers in our case), the upper layers issue 5721 * a M_IOCTL with a DL_IOC_HDR_INFO request and ask the streams endpoint 5722 * driver to give the header it needs appended and the upper layer 5723 * allocates and fills in the header and calls our put routine 5724 */ 5725 static void 5726 fcip_dl_ioc_hdr_info(queue_t *wq, mblk_t *mp) 5727 { 5728 mblk_t *nmp; 5729 struct fcipstr *slp; 5730 struct fcipdladdr *dlap; 5731 dl_unitdata_req_t *dlup; 5732 fcph_network_hdr_t *headerp; 5733 la_wwn_t wwn; 5734 llc_snap_hdr_t *lsnap; 5735 struct fcip *fptr; 5736 fcip_port_info_t *fport; 5737 t_uscalar_t off, len; 5738 size_t hdrlen; 5739 int error; 5740 5741 slp = (struct fcipstr *)wq->q_ptr; 5742 fptr = slp->sl_fcip; 5743 if (fptr == NULL) { 5744 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 5745 (CE_NOTE, "dliochdr : returns EINVAL1")); 5746 miocnak(wq, mp, 0, EINVAL); 5747 return; 5748 } 5749 5750 error = miocpullup(mp, sizeof (dl_unitdata_req_t) + FCIPADDRL); 5751 if (error != 0) { 5752 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 5753 (CE_NOTE, "dliochdr : returns %d", error)); 5754 miocnak(wq, mp, 0, error); 5755 return; 5756 } 5757 5758 fport = fptr->fcip_port_info; 5759 5760 /* 5761 * check if the DL_UNITDATA_REQ destination addr has valid offset 5762 * and length values 5763 */ 5764 dlup = (dl_unitdata_req_t *)mp->b_cont->b_rptr; 5765 off = dlup->dl_dest_addr_offset; 5766 len = dlup->dl_dest_addr_length; 5767 if (dlup->dl_primitive != DL_UNITDATA_REQ || 5768 !MBLKIN(mp->b_cont, off, len) || (len != FCIPADDRL)) { 5769 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 5770 (CE_NOTE, "dliochdr : returns EINVAL2")); 5771 miocnak(wq, mp, 0, EINVAL); 5772 return; 5773 } 5774 5775 dlap = (struct fcipdladdr *)(mp->b_cont->b_rptr + off); 5776 5777 /* 5778 * Allocate a new mblk to hold the ether header 5779 */ 5780 5781 /* 5782 * setup space for network header 5783 */ 5784 hdrlen = (sizeof (llc_snap_hdr_t) + sizeof (fcph_network_hdr_t)); 5785 if ((nmp = allocb(hdrlen, BPRI_MED)) == NULL) { 5786 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 5787 (CE_NOTE, "dliochdr : returns ENOMEM")); 5788 miocnak(wq, mp, 0, ENOMEM); 5789 return; 5790 } 5791 nmp->b_wptr += hdrlen; 5792 5793 /* 5794 * Fill in the Network Hdr and LLC SNAP header; 5795 */ 5796 headerp = (fcph_network_hdr_t *)nmp->b_rptr; 5797 /* 5798 * just fill in the Node WWN here - we can fill in the NAA_ID when 5799 * we search the routing table 5800 */ 5801 if (ether_cmp(&dlap->dl_phys, &fcip_arpbroadcast_addr) == 0) { 5802 ether_to_wwn(&fcipnhbroadcastaddr, &wwn); 5803 } else { 5804 ether_to_wwn(&dlap->dl_phys, &wwn); 5805 } 5806 bcopy(&wwn, &headerp->net_dest_addr, sizeof (la_wwn_t)); 5807 bcopy(&fport->fcipp_pwwn, &headerp->net_src_addr, sizeof (la_wwn_t)); 5808 lsnap = (llc_snap_hdr_t *)(nmp->b_rptr + sizeof (fcph_network_hdr_t)); 5809 lsnap->dsap = 0xAA; 5810 lsnap->ssap = 0xAA; 5811 lsnap->ctrl = 0x03; 5812 lsnap->oui[0] = 0x00; 5813 lsnap->oui[1] = 0x00; 5814 lsnap->oui[2] = 0x00; 5815 lsnap->pid = BE_16(dlap->dl_sap); 5816 5817 /* 5818 * Link new mblk in after the "request" mblks. 5819 */ 5820 linkb(mp, nmp); 5821 5822 slp->sl_flags |= FCIP_SLFAST; 5823 5824 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 5825 (CE_NOTE, "dliochdr : returns success ")); 5826 miocack(wq, mp, msgsize(mp->b_cont), 0); 5827 } 5828 5829 5830 /* 5831 * Establish a kmem cache for fcip packets 5832 */ 5833 static int 5834 fcip_cache_constructor(void *buf, void *arg, int flags) 5835 { 5836 fcip_pkt_t *fcip_pkt = buf; 5837 fc_packet_t *fc_pkt; 5838 fcip_port_info_t *fport = (fcip_port_info_t *)arg; 5839 int (*cb) (caddr_t); 5840 struct fcip *fptr; 5841 5842 cb = (flags == KM_SLEEP) ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT; 5843 5844 ASSERT(fport != NULL); 5845 5846 fptr = fport->fcipp_fcip; 5847 5848 /* 5849 * we allocated space for our private area at the end of the 5850 * fc packet. Make sure we point to it correctly. Ideally we 5851 * should just push fc_packet_private to the beginning or end 5852 * of the fc_packet structure 5853 */ 5854 fcip_pkt->fcip_pkt_next = NULL; 5855 fcip_pkt->fcip_pkt_prev = NULL; 5856 fcip_pkt->fcip_pkt_dest = NULL; 5857 fcip_pkt->fcip_pkt_state = 0; 5858 fcip_pkt->fcip_pkt_reason = 0; 5859 fcip_pkt->fcip_pkt_flags = 0; 5860 fcip_pkt->fcip_pkt_fptr = fptr; 5861 fcip_pkt->fcip_pkt_dma_flags = 0; 5862 5863 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 5864 fc_pkt->pkt_ulp_rscn_infop = NULL; 5865 5866 /* 5867 * We use pkt_cmd_dma for OUTBOUND requests. We don't expect 5868 * any responses for outbound IP data so no need to setup 5869 * response or data dma handles. 5870 */ 5871 if (ddi_dma_alloc_handle(fport->fcipp_dip, 5872 &fport->fcipp_cmd_dma_attr, cb, NULL, 5873 &fc_pkt->pkt_cmd_dma) != DDI_SUCCESS) { 5874 return (FCIP_FAILURE); 5875 } 5876 5877 fc_pkt->pkt_cmd_acc = fc_pkt->pkt_resp_acc = NULL; 5878 fc_pkt->pkt_fca_private = (opaque_t)((caddr_t)buf + 5879 sizeof (fcip_pkt_t)); 5880 fc_pkt->pkt_ulp_private = (opaque_t)fcip_pkt; 5881 5882 fc_pkt->pkt_cmd_cookie_cnt = fc_pkt->pkt_resp_cookie_cnt = 5883 fc_pkt->pkt_data_cookie_cnt = 0; 5884 fc_pkt->pkt_cmd_cookie = fc_pkt->pkt_resp_cookie = 5885 fc_pkt->pkt_data_cookie = NULL; 5886 5887 return (FCIP_SUCCESS); 5888 } 5889 5890 /* 5891 * destroy the fcip kmem cache 5892 */ 5893 static void 5894 fcip_cache_destructor(void *buf, void *arg) 5895 { 5896 fcip_pkt_t *fcip_pkt = (fcip_pkt_t *)buf; 5897 fc_packet_t *fc_pkt; 5898 fcip_port_info_t *fport = (fcip_port_info_t *)arg; 5899 struct fcip *fptr; 5900 5901 ASSERT(fport != NULL); 5902 5903 fptr = fport->fcipp_fcip; 5904 5905 ASSERT(fptr == fcip_pkt->fcip_pkt_fptr); 5906 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 5907 5908 if (fc_pkt->pkt_cmd_dma) { 5909 ddi_dma_free_handle(&fc_pkt->pkt_cmd_dma); 5910 } 5911 } 5912 5913 /* 5914 * the fcip destination structure is hashed on Node WWN assuming 5915 * a NAA_ID of 0x1 (IEEE) 5916 */ 5917 static struct fcip_dest * 5918 fcip_get_dest(struct fcip *fptr, la_wwn_t *pwwn) 5919 { 5920 struct fcip_dest *fdestp = NULL; 5921 fcip_port_info_t *fport; 5922 int hash_bucket; 5923 opaque_t pd; 5924 int rval; 5925 struct fcip_routing_table *frp; 5926 la_wwn_t twwn; 5927 uint32_t *twwnp = (uint32_t *)&twwn; 5928 5929 hash_bucket = FCIP_DEST_HASH(pwwn->raw_wwn); 5930 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 5931 (CE_NOTE, "get dest hashbucket : 0x%x", hash_bucket)); 5932 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 5933 (CE_NOTE, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x", 5934 pwwn->raw_wwn[2], pwwn->raw_wwn[3], pwwn->raw_wwn[4], 5935 pwwn->raw_wwn[5], pwwn->raw_wwn[6], pwwn->raw_wwn[7])); 5936 5937 ASSERT(hash_bucket < FCIP_DEST_HASH_ELEMS); 5938 5939 if (fcip_check_port_exists(fptr)) { 5940 /* fptr is stale, return fdestp */ 5941 return (fdestp); 5942 } 5943 fport = fptr->fcip_port_info; 5944 5945 /* 5946 * First check if we have active I/Os going on with the 5947 * destination port (an entry would exist in fcip_dest hash table) 5948 */ 5949 mutex_enter(&fptr->fcip_dest_mutex); 5950 fdestp = fptr->fcip_dest[hash_bucket]; 5951 while (fdestp != NULL) { 5952 mutex_enter(&fdestp->fcipd_mutex); 5953 if (fdestp->fcipd_rtable) { 5954 if (fcip_wwn_compare(pwwn, &fdestp->fcipd_pwwn, 5955 FCIP_COMPARE_NWWN) == 0) { 5956 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 5957 (CE_NOTE, "found fdestp")); 5958 mutex_exit(&fdestp->fcipd_mutex); 5959 mutex_exit(&fptr->fcip_dest_mutex); 5960 return (fdestp); 5961 } 5962 } 5963 mutex_exit(&fdestp->fcipd_mutex); 5964 fdestp = fdestp->fcipd_next; 5965 } 5966 mutex_exit(&fptr->fcip_dest_mutex); 5967 5968 /* 5969 * We did not find the destination port information in our 5970 * active port list so search for an entry in our routing 5971 * table. 5972 */ 5973 mutex_enter(&fptr->fcip_rt_mutex); 5974 frp = fcip_lookup_rtable(fptr, pwwn, FCIP_COMPARE_NWWN); 5975 mutex_exit(&fptr->fcip_rt_mutex); 5976 5977 if (frp == NULL || (frp && (!FCIP_RTE_UNAVAIL(frp->fcipr_state)) && 5978 frp->fcipr_state != PORT_DEVICE_LOGGED_IN) || 5979 (frp && frp->fcipr_pd == NULL)) { 5980 /* 5981 * No entry for the destination port in our routing 5982 * table too. First query the transport to see if it 5983 * already has structures for the destination port in 5984 * its hash tables. This must be done for all topologies 5985 * since we could have retired entries in the hash tables 5986 * which may have to be re-added without a statechange 5987 * callback happening. Its better to try and get an entry 5988 * for the destination port rather than simply failing a 5989 * request though it may be an overkill in private loop 5990 * topologies. 5991 * If a entry for the remote port exists in the transport's 5992 * hash tables, we are fine and can add the entry to our 5993 * routing and dest hash lists, Else for fabric configs we 5994 * query the nameserver if one exists or issue FARP ELS. 5995 */ 5996 5997 /* 5998 * We need to do a PortName based Nameserver 5999 * query operation. So get the right PortWWN 6000 * for the adapter. 6001 */ 6002 bcopy(pwwn, &twwn, sizeof (la_wwn_t)); 6003 6004 /* 6005 * Try IEEE Name (Format 1) first, this is the default and 6006 * Emulex uses this format. 6007 */ 6008 pd = fc_ulp_get_remote_port(fport->fcipp_handle, 6009 &twwn, &rval, 1); 6010 6011 if (rval != FC_SUCCESS) { 6012 /* 6013 * If IEEE Name (Format 1) query failed, try IEEE 6014 * Extended Name (Format 2) which Qlogic uses. 6015 * And try port 1 on Qlogic FC-HBA first. 6016 * Note: On x86, we need to byte swap the 32-bit 6017 * word first, after the modification, swap it back. 6018 */ 6019 *twwnp = BE_32(*twwnp); 6020 twwn.w.nport_id = QLC_PORT_1_ID_BITS; 6021 twwn.w.naa_id = QLC_PORT_NAA; 6022 *twwnp = BE_32(*twwnp); 6023 pd = fc_ulp_get_remote_port(fport->fcipp_handle, 6024 &twwn, &rval, 1); 6025 } 6026 6027 if (rval != FC_SUCCESS) { 6028 /* If still failed, try port 2 on Qlogic FC-HBA. */ 6029 *twwnp = BE_32(*twwnp); 6030 twwn.w.nport_id = QLC_PORT_2_ID_BITS; 6031 *twwnp = BE_32(*twwnp); 6032 pd = fc_ulp_get_remote_port(fport->fcipp_handle, 6033 &twwn, &rval, 1); 6034 } 6035 6036 if (rval == FC_SUCCESS) { 6037 fc_portmap_t map; 6038 /* 6039 * Add the newly found destination structure 6040 * to our routing table. Create a map with 6041 * the device we found. We could ask the 6042 * transport to give us the list of all 6043 * devices connected to our port but we 6044 * probably don't need to know all the devices 6045 * so let us just constuct a list with only 6046 * one device instead. 6047 */ 6048 6049 fc_ulp_copy_portmap(&map, pd); 6050 fcip_rt_update(fptr, &map, 1); 6051 6052 mutex_enter(&fptr->fcip_rt_mutex); 6053 frp = fcip_lookup_rtable(fptr, pwwn, 6054 FCIP_COMPARE_NWWN); 6055 mutex_exit(&fptr->fcip_rt_mutex); 6056 6057 fdestp = fcip_add_dest(fptr, frp); 6058 } else if (fcip_farp_supported && 6059 (FC_TOP_EXTERNAL(fport->fcipp_topology) || 6060 (fport->fcipp_topology == FC_TOP_PT_PT))) { 6061 /* 6062 * The Name server request failed so 6063 * issue an FARP 6064 */ 6065 fdestp = fcip_do_farp(fptr, pwwn, NULL, 6066 0, 0); 6067 } else { 6068 fdestp = NULL; 6069 } 6070 } else if (frp && frp->fcipr_state == PORT_DEVICE_LOGGED_IN) { 6071 /* 6072 * Prepare a dest structure to return to caller 6073 */ 6074 fdestp = fcip_add_dest(fptr, frp); 6075 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 6076 (CE_NOTE, "in fcip get dest non fabric")); 6077 } 6078 return (fdestp); 6079 } 6080 6081 6082 /* 6083 * Endian clean WWN compare. 6084 * Returns 0 if they compare OK, else return non zero value. 6085 * flag can be bitwise OR of FCIP_COMPARE_NWWN, FCIP_COMPARE_PWWN, 6086 * FCIP_COMPARE_BROADCAST. 6087 */ 6088 static int 6089 fcip_wwn_compare(la_wwn_t *wwn1, la_wwn_t *wwn2, int flag) 6090 { 6091 int rval = 0; 6092 if ((wwn1->raw_wwn[2] != wwn2->raw_wwn[2]) || 6093 (wwn1->raw_wwn[3] != wwn2->raw_wwn[3]) || 6094 (wwn1->raw_wwn[4] != wwn2->raw_wwn[4]) || 6095 (wwn1->raw_wwn[5] != wwn2->raw_wwn[5]) || 6096 (wwn1->raw_wwn[6] != wwn2->raw_wwn[6]) || 6097 (wwn1->raw_wwn[7] != wwn2->raw_wwn[7])) { 6098 rval = 1; 6099 } else if ((flag == FCIP_COMPARE_PWWN) && 6100 (((wwn1->raw_wwn[0] & 0xf0) != (wwn2->raw_wwn[0] & 0xf0)) || 6101 (wwn1->raw_wwn[1] != wwn2->raw_wwn[1]))) { 6102 rval = 1; 6103 } 6104 return (rval); 6105 } 6106 6107 6108 /* 6109 * Add an entry for a remote port in the dest hash table. Dest hash table 6110 * has entries for ports in the routing hash table with which we decide 6111 * to establish IP communication with. The no. of entries in the dest hash 6112 * table must always be less than or equal to the entries in the routing 6113 * hash table. Every entry in the dest hash table ofcourse must have a 6114 * corresponding entry in the routing hash table 6115 */ 6116 static struct fcip_dest * 6117 fcip_add_dest(struct fcip *fptr, struct fcip_routing_table *frp) 6118 { 6119 struct fcip_dest *fdestp = NULL; 6120 la_wwn_t *pwwn; 6121 int hash_bucket; 6122 struct fcip_dest *fdest_new; 6123 6124 if (frp == NULL) { 6125 return (fdestp); 6126 } 6127 6128 pwwn = &frp->fcipr_pwwn; 6129 mutex_enter(&fptr->fcip_dest_mutex); 6130 hash_bucket = FCIP_DEST_HASH(pwwn->raw_wwn); 6131 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 6132 (CE_NOTE, "add dest hash_bucket: 0x%x", hash_bucket)); 6133 6134 ASSERT(hash_bucket < FCIP_DEST_HASH_ELEMS); 6135 6136 fdestp = fptr->fcip_dest[hash_bucket]; 6137 while (fdestp != NULL) { 6138 mutex_enter(&fdestp->fcipd_mutex); 6139 if (fdestp->fcipd_rtable) { 6140 if (fcip_wwn_compare(pwwn, &fdestp->fcipd_pwwn, 6141 FCIP_COMPARE_PWWN) == 0) { 6142 mutex_exit(&fdestp->fcipd_mutex); 6143 mutex_exit(&fptr->fcip_dest_mutex); 6144 return (fdestp); 6145 } 6146 } 6147 mutex_exit(&fdestp->fcipd_mutex); 6148 fdestp = fdestp->fcipd_next; 6149 } 6150 6151 ASSERT(fdestp == NULL); 6152 6153 fdest_new = (struct fcip_dest *) 6154 kmem_zalloc(sizeof (struct fcip_dest), KM_SLEEP); 6155 6156 mutex_init(&fdest_new->fcipd_mutex, NULL, MUTEX_DRIVER, NULL); 6157 fdest_new->fcipd_next = fptr->fcip_dest[hash_bucket]; 6158 fdest_new->fcipd_refcnt = 0; 6159 fdest_new->fcipd_rtable = frp; 6160 fdest_new->fcipd_ncmds = 0; 6161 fptr->fcip_dest[hash_bucket] = fdest_new; 6162 fdest_new->fcipd_flags = FCIP_PORT_NOTLOGGED; 6163 6164 mutex_exit(&fptr->fcip_dest_mutex); 6165 return (fdest_new); 6166 } 6167 6168 /* 6169 * Cleanup the dest hash table and remove all entries 6170 */ 6171 static void 6172 fcip_cleanup_dest(struct fcip *fptr) 6173 { 6174 struct fcip_dest *fdestp = NULL; 6175 struct fcip_dest *fdest_delp = NULL; 6176 int i; 6177 6178 mutex_enter(&fptr->fcip_dest_mutex); 6179 6180 for (i = 0; i < FCIP_DEST_HASH_ELEMS; i++) { 6181 fdestp = fptr->fcip_dest[i]; 6182 while (fdestp != NULL) { 6183 mutex_destroy(&fdestp->fcipd_mutex); 6184 fdest_delp = fdestp; 6185 fdestp = fdestp->fcipd_next; 6186 kmem_free(fdest_delp, sizeof (struct fcip_dest)); 6187 fptr->fcip_dest[i] = NULL; 6188 } 6189 } 6190 mutex_exit(&fptr->fcip_dest_mutex); 6191 } 6192 6193 6194 /* 6195 * Send FARP requests for Fabric ports when we don't have the port 6196 * we wish to talk to in our routing hash table. FARP is specially required 6197 * to talk to FC switches for inband switch management. Most FC switches 6198 * today have a switch FC IP address for IP over FC inband switch management 6199 * but the WWN and Port_ID for this traffic is not available through the 6200 * Nameservers since the switch themeselves are transparent. 6201 */ 6202 /* ARGSUSED */ 6203 static struct fcip_dest * 6204 fcip_do_farp(struct fcip *fptr, la_wwn_t *pwwn, char *ip_addr, 6205 size_t ip_addr_len, int flags) 6206 { 6207 fcip_pkt_t *fcip_pkt; 6208 fc_packet_t *fc_pkt; 6209 fcip_port_info_t *fport = fptr->fcip_port_info; 6210 la_els_farp_t farp_cmd; 6211 la_els_farp_t *fcmd; 6212 struct fcip_dest *fdestp = NULL; 6213 int rval; 6214 clock_t farp_lbolt; 6215 la_wwn_t broadcast_wwn; 6216 struct fcip_dest *bdestp; 6217 struct fcip_routing_table *frp; 6218 6219 bdestp = fcip_get_dest(fptr, &broadcast_wwn); 6220 6221 if (bdestp == NULL) { 6222 return (fdestp); 6223 } 6224 6225 fcip_pkt = fcip_ipkt_alloc(fptr, sizeof (la_els_farp_t), 6226 sizeof (la_els_farp_t), bdestp->fcipd_pd, KM_SLEEP); 6227 6228 if (fcip_pkt == NULL) { 6229 return (fdestp); 6230 } 6231 6232 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 6233 ether_to_wwn(&fcip_arpbroadcast_addr, &broadcast_wwn); 6234 6235 mutex_enter(&bdestp->fcipd_mutex); 6236 if (bdestp->fcipd_rtable == NULL) { 6237 mutex_exit(&bdestp->fcipd_mutex); 6238 fcip_ipkt_free(fcip_pkt); 6239 return (fdestp); 6240 } 6241 6242 fcip_pkt->fcip_pkt_dest = bdestp; 6243 fc_pkt->pkt_fca_device = bdestp->fcipd_fca_dev; 6244 6245 bdestp->fcipd_ncmds++; 6246 mutex_exit(&bdestp->fcipd_mutex); 6247 6248 fcip_init_broadcast_pkt(fcip_pkt, NULL, 1); 6249 fcip_pkt->fcip_pkt_flags |= FCIP_PKT_IN_LIST; 6250 6251 /* 6252 * Now initialize the FARP payload itself 6253 */ 6254 fcmd = &farp_cmd; 6255 fcmd->ls_code.ls_code = LA_ELS_FARP_REQ; 6256 fcmd->ls_code.mbz = 0; 6257 /* 6258 * for now just match the Port WWN since the other match addr 6259 * code points are optional. We can explore matching the IP address 6260 * if needed 6261 */ 6262 if (ip_addr) { 6263 fcmd->match_addr = FARP_MATCH_WW_PN_IPv4; 6264 } else { 6265 fcmd->match_addr = FARP_MATCH_WW_PN; 6266 } 6267 6268 /* 6269 * Request the responder port to log into us - that way 6270 * the Transport is aware of the remote port when we create 6271 * an entry for it in our tables 6272 */ 6273 fcmd->resp_flags = FARP_INIT_REPLY | FARP_INIT_P_LOGI; 6274 fcmd->req_id = fport->fcipp_sid; 6275 fcmd->dest_id.port_id = fc_pkt->pkt_cmd_fhdr.d_id; 6276 bcopy(&fport->fcipp_pwwn, &fcmd->req_pwwn, sizeof (la_wwn_t)); 6277 bcopy(&fport->fcipp_nwwn, &fcmd->req_nwwn, sizeof (la_wwn_t)); 6278 bcopy(pwwn, &fcmd->resp_pwwn, sizeof (la_wwn_t)); 6279 /* 6280 * copy in source IP address if we get to know it 6281 */ 6282 if (ip_addr) { 6283 bcopy(ip_addr, fcmd->resp_ip, ip_addr_len); 6284 } 6285 6286 fc_pkt->pkt_cmdlen = sizeof (la_els_farp_t); 6287 fc_pkt->pkt_rsplen = sizeof (la_els_farp_t); 6288 fc_pkt->pkt_tran_type = FC_PKT_EXCHANGE; 6289 fc_pkt->pkt_ulp_private = (opaque_t)fcip_pkt; 6290 6291 /* 6292 * Endian safe copy 6293 */ 6294 FCIP_CP_OUT(fcmd, fc_pkt->pkt_cmd, fc_pkt->pkt_cmd_acc, 6295 sizeof (la_els_farp_t)); 6296 6297 /* 6298 * send the packet in polled mode. 6299 */ 6300 rval = fc_ulp_issue_els(fport->fcipp_handle, fc_pkt); 6301 if (rval != FC_SUCCESS) { 6302 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_WARN, 6303 "fcip_transport of farp pkt failed 0x%x", rval)); 6304 fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_LIST; 6305 fcip_ipkt_free(fcip_pkt); 6306 6307 mutex_enter(&bdestp->fcipd_mutex); 6308 bdestp->fcipd_ncmds--; 6309 mutex_exit(&bdestp->fcipd_mutex); 6310 6311 return (fdestp); 6312 } 6313 6314 farp_lbolt = ddi_get_lbolt(); 6315 farp_lbolt += drv_usectohz(FCIP_FARP_TIMEOUT); 6316 6317 mutex_enter(&fptr->fcip_mutex); 6318 fptr->fcip_farp_rsp_flag = 0; 6319 while (!fptr->fcip_farp_rsp_flag) { 6320 if (cv_timedwait(&fptr->fcip_farp_cv, &fptr->fcip_mutex, 6321 farp_lbolt) == -1) { 6322 /* 6323 * No FARP response from any destination port 6324 * so bail out. 6325 */ 6326 fptr->fcip_farp_rsp_flag = 1; 6327 } else { 6328 /* 6329 * We received a FARP response - check to see if the 6330 * response was in reply to our FARP request. 6331 */ 6332 6333 mutex_enter(&fptr->fcip_rt_mutex); 6334 frp = fcip_lookup_rtable(fptr, pwwn, FCIP_COMPARE_NWWN); 6335 mutex_exit(&fptr->fcip_rt_mutex); 6336 6337 if ((frp != NULL) && 6338 !FCIP_RTE_UNAVAIL(frp->fcipr_state)) { 6339 fdestp = fcip_get_dest(fptr, pwwn); 6340 } else { 6341 /* 6342 * Not our FARP response so go back and wait 6343 * again till FARP_TIMEOUT expires 6344 */ 6345 fptr->fcip_farp_rsp_flag = 0; 6346 } 6347 } 6348 } 6349 mutex_exit(&fptr->fcip_mutex); 6350 6351 fcip_pkt->fcip_pkt_flags |= FCIP_PKT_IN_LIST; 6352 fcip_ipkt_free(fcip_pkt); 6353 mutex_enter(&bdestp->fcipd_mutex); 6354 bdestp->fcipd_ncmds--; 6355 mutex_exit(&bdestp->fcipd_mutex); 6356 return (fdestp); 6357 } 6358 6359 6360 6361 /* 6362 * Helper routine to PLOGI to a remote port we wish to talk to. 6363 * This may not be required since the port driver does logins anyway, 6364 * but this can be required in fabric cases since FARP requests/responses 6365 * don't require you to be logged in? 6366 */ 6367 6368 /* ARGSUSED */ 6369 static int 6370 fcip_do_plogi(struct fcip *fptr, struct fcip_routing_table *frp) 6371 { 6372 fcip_pkt_t *fcip_pkt; 6373 fc_packet_t *fc_pkt; 6374 fcip_port_info_t *fport = fptr->fcip_port_info; 6375 la_els_logi_t logi; 6376 int rval; 6377 fc_frame_hdr_t *fr_hdr; 6378 6379 /* 6380 * Don't bother to login for broadcast RTE entries 6381 */ 6382 if ((frp->fcipr_d_id.port_id == 0x0) || 6383 (frp->fcipr_d_id.port_id == 0xffffff)) { 6384 return (FC_FAILURE); 6385 } 6386 6387 /* 6388 * We shouldn't pound in too many logins here 6389 * 6390 */ 6391 if (frp->fcipr_state == FCIP_RT_LOGIN_PROGRESS || 6392 frp->fcipr_state == PORT_DEVICE_LOGGED_IN) { 6393 return (FC_SUCCESS); 6394 } 6395 6396 fcip_pkt = fcip_ipkt_alloc(fptr, sizeof (la_els_logi_t), 6397 sizeof (la_els_logi_t), frp->fcipr_pd, KM_SLEEP); 6398 6399 if (fcip_pkt == NULL) { 6400 return (FC_FAILURE); 6401 } 6402 6403 /* 6404 * Update back pointer for login state update 6405 */ 6406 fcip_pkt->fcip_pkt_frp = frp; 6407 frp->fcipr_state = FCIP_RT_LOGIN_PROGRESS; 6408 6409 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 6410 6411 /* 6412 * Initialize frame header for ELS 6413 */ 6414 fr_hdr = &fc_pkt->pkt_cmd_fhdr; 6415 fr_hdr->r_ctl = R_CTL_ELS_REQ; 6416 fr_hdr->type = FC_TYPE_EXTENDED_LS; 6417 fr_hdr->f_ctl = F_CTL_SEQ_INITIATIVE | F_CTL_FIRST_SEQ; 6418 fr_hdr->df_ctl = 0; 6419 fr_hdr->s_id = fport->fcipp_sid.port_id; 6420 fr_hdr->d_id = frp->fcipr_d_id.port_id; 6421 fr_hdr->seq_cnt = 0; 6422 fr_hdr->ox_id = 0xffff; 6423 fr_hdr->rx_id = 0xffff; 6424 fr_hdr->ro = 0; 6425 6426 fc_pkt->pkt_rsplen = sizeof (la_els_logi_t); 6427 fc_pkt->pkt_comp = fcip_ipkt_callback; 6428 fc_pkt->pkt_tran_type = FC_PKT_EXCHANGE; 6429 fc_pkt->pkt_timeout = 10; /* 10 seconds */ 6430 fcip_pkt->fcip_pkt_ttl = fptr->fcip_timeout_ticks + fc_pkt->pkt_timeout; 6431 fc_pkt->pkt_ulp_private = (opaque_t)fcip_pkt; 6432 6433 /* 6434 * Everybody does class 3, so let's just set it. If the transport 6435 * knows better, it will deal with the class appropriately. 6436 */ 6437 6438 fc_pkt->pkt_tran_flags = FC_TRAN_INTR | FC_TRAN_CLASS3; 6439 6440 /* 6441 * we need only fill in the ls_code and the cmd frame header 6442 */ 6443 bzero((void *)&logi, sizeof (la_els_logi_t)); 6444 logi.ls_code.ls_code = LA_ELS_PLOGI; 6445 logi.ls_code.mbz = 0; 6446 6447 FCIP_CP_OUT((uint8_t *)&logi, fc_pkt->pkt_cmd, fc_pkt->pkt_cmd_acc, 6448 sizeof (la_els_logi_t)); 6449 6450 rval = fc_ulp_login(fport->fcipp_handle, &fc_pkt, 1); 6451 if (rval != FC_SUCCESS) { 6452 cmn_err(CE_WARN, 6453 "!fc_ulp_login failed for d_id: 0x%x, rval: 0x%x", 6454 frp->fcipr_d_id.port_id, rval); 6455 fcip_ipkt_free(fcip_pkt); 6456 } 6457 return (rval); 6458 } 6459 6460 /* 6461 * The packet callback routine - called from the transport/FCA after 6462 * it is done DMA'ing/sending out the packet contents on the wire so 6463 * that the alloc'ed packet can be freed 6464 */ 6465 static void 6466 fcip_ipkt_callback(fc_packet_t *fc_pkt) 6467 { 6468 ls_code_t logi_req; 6469 ls_code_t logi_resp; 6470 fcip_pkt_t *fcip_pkt; 6471 fc_frame_hdr_t *fr_hdr; 6472 struct fcip *fptr; 6473 fcip_port_info_t *fport; 6474 struct fcip_routing_table *frp; 6475 6476 fr_hdr = &fc_pkt->pkt_cmd_fhdr; 6477 6478 FCIP_CP_IN(fc_pkt->pkt_resp, (uint8_t *)&logi_resp, 6479 fc_pkt->pkt_resp_acc, sizeof (logi_resp)); 6480 6481 FCIP_CP_IN(fc_pkt->pkt_cmd, (uint8_t *)&logi_req, fc_pkt->pkt_cmd_acc, 6482 sizeof (logi_req)); 6483 6484 fcip_pkt = (fcip_pkt_t *)fc_pkt->pkt_ulp_private; 6485 frp = fcip_pkt->fcip_pkt_frp; 6486 fptr = fcip_pkt->fcip_pkt_fptr; 6487 fport = fptr->fcip_port_info; 6488 6489 ASSERT(logi_req.ls_code == LA_ELS_PLOGI); 6490 6491 if (fc_pkt->pkt_state != FC_PKT_SUCCESS || 6492 logi_resp.ls_code != LA_ELS_ACC) { 6493 /* EMPTY */ 6494 6495 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_WARN, 6496 "opcode : 0x%x to d_id: 0x%x failed", 6497 logi_req.ls_code, fr_hdr->d_id)); 6498 6499 mutex_enter(&fptr->fcip_rt_mutex); 6500 frp->fcipr_state = PORT_DEVICE_INVALID; 6501 frp->fcipr_invalid_timeout = fptr->fcip_timeout_ticks + 6502 (FCIP_RTE_TIMEOUT / 2); 6503 mutex_exit(&fptr->fcip_rt_mutex); 6504 } else { 6505 fc_portid_t d_id; 6506 6507 d_id.port_id = fr_hdr->d_id; 6508 d_id.priv_lilp_posit = 0; 6509 6510 /* 6511 * Update PLOGI results; FCA Handle, and Port device handles 6512 */ 6513 mutex_enter(&fptr->fcip_rt_mutex); 6514 frp->fcipr_pd = fc_pkt->pkt_pd; 6515 frp->fcipr_fca_dev = 6516 fc_ulp_get_fca_device(fport->fcipp_handle, d_id); 6517 frp->fcipr_state = PORT_DEVICE_LOGGED_IN; 6518 mutex_exit(&fptr->fcip_rt_mutex); 6519 } 6520 6521 fcip_ipkt_free(fcip_pkt); 6522 } 6523 6524 6525 /* 6526 * pkt_alloc routine for outbound IP datagrams. The cache constructor 6527 * Only initializes the pkt_cmd_dma (which is where the outbound datagram 6528 * is stuffed) since we don't expect response 6529 */ 6530 static fcip_pkt_t * 6531 fcip_pkt_alloc(struct fcip *fptr, mblk_t *bp, int flags, int datalen) 6532 { 6533 fcip_pkt_t *fcip_pkt; 6534 fc_packet_t *fc_pkt; 6535 ddi_dma_cookie_t pkt_cookie; 6536 ddi_dma_cookie_t *cp; 6537 uint32_t cnt; 6538 fcip_port_info_t *fport = fptr->fcip_port_info; 6539 6540 fcip_pkt = kmem_cache_alloc(fptr->fcip_xmit_cache, flags); 6541 if (fcip_pkt == NULL) { 6542 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, (CE_WARN, 6543 "fcip_pkt_alloc: kmem_cache_alloc failed")); 6544 return (NULL); 6545 } 6546 6547 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 6548 fcip_pkt->fcip_pkt_fcpktp = fc_pkt; 6549 fc_pkt->pkt_tran_flags = 0; 6550 fcip_pkt->fcip_pkt_dma_flags = 0; 6551 6552 /* 6553 * the cache constructor has allocated the dma handle 6554 */ 6555 fc_pkt->pkt_cmd = (caddr_t)bp->b_rptr; 6556 if (ddi_dma_addr_bind_handle(fc_pkt->pkt_cmd_dma, NULL, 6557 (caddr_t)bp->b_rptr, datalen, DDI_DMA_WRITE | DDI_DMA_CONSISTENT, 6558 DDI_DMA_DONTWAIT, NULL, &pkt_cookie, 6559 &fc_pkt->pkt_cmd_cookie_cnt) != DDI_DMA_MAPPED) { 6560 goto fail; 6561 } 6562 6563 fcip_pkt->fcip_pkt_dma_flags |= FCIP_CMD_DMA_BOUND; 6564 6565 if (fc_pkt->pkt_cmd_cookie_cnt > 6566 fport->fcipp_cmd_dma_attr.dma_attr_sgllen) { 6567 goto fail; 6568 } 6569 6570 ASSERT(fc_pkt->pkt_cmd_cookie_cnt != 0); 6571 6572 cp = fc_pkt->pkt_cmd_cookie = (ddi_dma_cookie_t *)kmem_alloc( 6573 fc_pkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie), 6574 KM_NOSLEEP); 6575 6576 if (cp == NULL) { 6577 goto fail; 6578 } 6579 6580 *cp = pkt_cookie; 6581 cp++; 6582 for (cnt = 1; cnt < fc_pkt->pkt_cmd_cookie_cnt; cnt++, cp++) { 6583 ddi_dma_nextcookie(fc_pkt->pkt_cmd_dma, &pkt_cookie); 6584 *cp = pkt_cookie; 6585 } 6586 6587 fc_pkt->pkt_cmdlen = datalen; 6588 6589 fcip_pkt->fcip_pkt_mp = NULL; 6590 fcip_pkt->fcip_pkt_wq = NULL; 6591 fcip_pkt->fcip_pkt_dest = NULL; 6592 fcip_pkt->fcip_pkt_next = NULL; 6593 fcip_pkt->fcip_pkt_prev = NULL; 6594 fcip_pkt->fcip_pkt_state = 0; 6595 fcip_pkt->fcip_pkt_reason = 0; 6596 fcip_pkt->fcip_pkt_flags = 0; 6597 fcip_pkt->fcip_pkt_frp = NULL; 6598 6599 return (fcip_pkt); 6600 fail: 6601 if (fcip_pkt) { 6602 fcip_pkt_free(fcip_pkt, 0); 6603 } 6604 return ((fcip_pkt_t *)0); 6605 } 6606 6607 /* 6608 * Free a packet and all its associated resources 6609 */ 6610 static void 6611 fcip_pkt_free(struct fcip_pkt *fcip_pkt, int free_mblk) 6612 { 6613 fc_packet_t *fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 6614 struct fcip *fptr = fcip_pkt->fcip_pkt_fptr; 6615 6616 if (fc_pkt->pkt_cmd_cookie != NULL) { 6617 kmem_free(fc_pkt->pkt_cmd_cookie, fc_pkt->pkt_cmd_cookie_cnt * 6618 sizeof (ddi_dma_cookie_t)); 6619 fc_pkt->pkt_cmd_cookie = NULL; 6620 } 6621 6622 fcip_free_pkt_dma(fcip_pkt); 6623 if (free_mblk && fcip_pkt->fcip_pkt_mp) { 6624 freemsg(fcip_pkt->fcip_pkt_mp); 6625 fcip_pkt->fcip_pkt_mp = NULL; 6626 } 6627 6628 (void) fc_ulp_uninit_packet(fptr->fcip_port_info->fcipp_handle, fc_pkt); 6629 6630 kmem_cache_free(fptr->fcip_xmit_cache, (void *)fcip_pkt); 6631 } 6632 6633 /* 6634 * Allocate a Packet for internal driver use. This is for requests 6635 * that originate from within the driver 6636 */ 6637 static fcip_pkt_t * 6638 fcip_ipkt_alloc(struct fcip *fptr, int cmdlen, int resplen, 6639 opaque_t pd, int flags) 6640 { 6641 fcip_pkt_t *fcip_pkt; 6642 fc_packet_t *fc_pkt; 6643 int (*cb)(caddr_t); 6644 fcip_port_info_t *fport = fptr->fcip_port_info; 6645 size_t real_len; 6646 uint_t held_here = 0; 6647 ddi_dma_cookie_t pkt_cookie; 6648 ddi_dma_cookie_t *cp; 6649 uint32_t cnt; 6650 6651 cb = (flags == KM_SLEEP) ? DDI_DMA_SLEEP : DDI_DMA_DONTWAIT; 6652 6653 fcip_pkt = kmem_zalloc((sizeof (fcip_pkt_t) + 6654 fport->fcipp_fca_pkt_size), flags); 6655 6656 if (fcip_pkt == NULL) { 6657 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 6658 (CE_WARN, "pkt alloc of ineternal pkt failed")); 6659 goto fail; 6660 } 6661 6662 fcip_pkt->fcip_pkt_flags = FCIP_PKT_INTERNAL; 6663 fcip_pkt->fcip_pkt_fptr = fptr; 6664 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 6665 fcip_pkt->fcip_pkt_fcpktp = fc_pkt; 6666 fc_pkt->pkt_tran_flags = 0; 6667 fc_pkt->pkt_cmdlen = 0; 6668 fc_pkt->pkt_rsplen = 0; 6669 fc_pkt->pkt_datalen = 0; 6670 fc_pkt->pkt_fca_private = (opaque_t)((caddr_t)fcip_pkt + 6671 sizeof (fcip_pkt_t)); 6672 fc_pkt->pkt_ulp_private = (opaque_t)fcip_pkt; 6673 6674 if (cmdlen) { 6675 if (ddi_dma_alloc_handle(fptr->fcip_dip, 6676 &fport->fcipp_cmd_dma_attr, cb, NULL, 6677 &fc_pkt->pkt_cmd_dma) != DDI_SUCCESS) { 6678 goto fail; 6679 } 6680 6681 if (ddi_dma_mem_alloc(fc_pkt->pkt_cmd_dma, cmdlen, 6682 &fport->fcipp_fca_acc_attr, DDI_DMA_CONSISTENT, 6683 cb, NULL, (caddr_t *)&fc_pkt->pkt_cmd, 6684 &real_len, &fc_pkt->pkt_cmd_acc) != DDI_SUCCESS) { 6685 goto fail; 6686 } 6687 6688 fcip_pkt->fcip_pkt_dma_flags |= FCIP_CMD_DMA_MEM; 6689 fc_pkt->pkt_cmdlen = cmdlen; 6690 6691 if (real_len < cmdlen) { 6692 goto fail; 6693 } 6694 6695 if (ddi_dma_addr_bind_handle(fc_pkt->pkt_cmd_dma, NULL, 6696 (caddr_t)fc_pkt->pkt_cmd, real_len, 6697 DDI_DMA_WRITE | DDI_DMA_CONSISTENT, cb, NULL, 6698 &pkt_cookie, &fc_pkt->pkt_cmd_cookie_cnt) != 6699 DDI_DMA_MAPPED) { 6700 goto fail; 6701 } 6702 6703 fcip_pkt->fcip_pkt_dma_flags |= FCIP_CMD_DMA_BOUND; 6704 6705 if (fc_pkt->pkt_cmd_cookie_cnt > 6706 fport->fcipp_cmd_dma_attr.dma_attr_sgllen) { 6707 goto fail; 6708 } 6709 6710 ASSERT(fc_pkt->pkt_cmd_cookie_cnt != 0); 6711 6712 cp = fc_pkt->pkt_cmd_cookie = (ddi_dma_cookie_t *)kmem_alloc( 6713 fc_pkt->pkt_cmd_cookie_cnt * sizeof (pkt_cookie), 6714 KM_NOSLEEP); 6715 6716 if (cp == NULL) { 6717 goto fail; 6718 } 6719 6720 *cp = pkt_cookie; 6721 cp++; 6722 for (cnt = 1; cnt < fc_pkt->pkt_cmd_cookie_cnt; cnt++, cp++) { 6723 ddi_dma_nextcookie(fc_pkt->pkt_cmd_dma, &pkt_cookie); 6724 *cp = pkt_cookie; 6725 } 6726 } 6727 6728 if (resplen) { 6729 if (ddi_dma_alloc_handle(fptr->fcip_dip, 6730 &fport->fcipp_resp_dma_attr, cb, NULL, 6731 &fc_pkt->pkt_resp_dma) != DDI_SUCCESS) { 6732 goto fail; 6733 } 6734 6735 if (ddi_dma_mem_alloc(fc_pkt->pkt_resp_dma, resplen, 6736 &fport->fcipp_fca_acc_attr, DDI_DMA_CONSISTENT, 6737 cb, NULL, (caddr_t *)&fc_pkt->pkt_resp, 6738 &real_len, &fc_pkt->pkt_resp_acc) != DDI_SUCCESS) { 6739 goto fail; 6740 } 6741 6742 fcip_pkt->fcip_pkt_dma_flags |= FCIP_RESP_DMA_MEM; 6743 6744 if (real_len < resplen) { 6745 goto fail; 6746 } 6747 6748 if (ddi_dma_addr_bind_handle(fc_pkt->pkt_resp_dma, NULL, 6749 (caddr_t)fc_pkt->pkt_resp, real_len, 6750 DDI_DMA_WRITE | DDI_DMA_CONSISTENT, cb, NULL, 6751 &pkt_cookie, &fc_pkt->pkt_resp_cookie_cnt) != 6752 DDI_DMA_MAPPED) { 6753 goto fail; 6754 } 6755 6756 fcip_pkt->fcip_pkt_dma_flags |= FCIP_RESP_DMA_BOUND; 6757 fc_pkt->pkt_rsplen = resplen; 6758 6759 if (fc_pkt->pkt_resp_cookie_cnt > 6760 fport->fcipp_resp_dma_attr.dma_attr_sgllen) { 6761 goto fail; 6762 } 6763 6764 ASSERT(fc_pkt->pkt_resp_cookie_cnt != 0); 6765 6766 cp = fc_pkt->pkt_resp_cookie = (ddi_dma_cookie_t *)kmem_alloc( 6767 fc_pkt->pkt_resp_cookie_cnt * sizeof (pkt_cookie), 6768 KM_NOSLEEP); 6769 6770 if (cp == NULL) { 6771 goto fail; 6772 } 6773 6774 *cp = pkt_cookie; 6775 cp++; 6776 for (cnt = 1; cnt < fc_pkt->pkt_resp_cookie_cnt; cnt++, cp++) { 6777 ddi_dma_nextcookie(fc_pkt->pkt_resp_dma, &pkt_cookie); 6778 *cp = pkt_cookie; 6779 } 6780 } 6781 6782 /* 6783 * Initialize pkt_pd prior to calling fc_ulp_init_packet 6784 */ 6785 6786 fc_pkt->pkt_pd = pd; 6787 6788 /* 6789 * Ask the FCA to bless the internal packet 6790 */ 6791 if (fc_ulp_init_packet((opaque_t)fport->fcipp_handle, 6792 fc_pkt, flags) != FC_SUCCESS) { 6793 goto fail; 6794 } 6795 6796 /* 6797 * Keep track of # of ipkts alloc-ed 6798 * This function can get called with mutex either held or not. So, we'll 6799 * grab mutex if it is not already held by this thread. 6800 * This has to be cleaned up someday. 6801 */ 6802 if (!MUTEX_HELD(&fptr->fcip_mutex)) { 6803 held_here = 1; 6804 mutex_enter(&fptr->fcip_mutex); 6805 } 6806 6807 fptr->fcip_num_ipkts_pending++; 6808 6809 if (held_here) 6810 mutex_exit(&fptr->fcip_mutex); 6811 6812 return (fcip_pkt); 6813 fail: 6814 if (fcip_pkt) { 6815 fcip_ipkt_free(fcip_pkt); 6816 } 6817 6818 return (NULL); 6819 } 6820 6821 /* 6822 * free up an internal IP packet (like a FARP pkt etc) 6823 */ 6824 static void 6825 fcip_ipkt_free(fcip_pkt_t *fcip_pkt) 6826 { 6827 fc_packet_t *fc_pkt; 6828 struct fcip *fptr = fcip_pkt->fcip_pkt_fptr; 6829 fcip_port_info_t *fport = fptr->fcip_port_info; 6830 6831 ASSERT(fptr != NULL); 6832 ASSERT(!mutex_owned(&fptr->fcip_mutex)); 6833 6834 /* One less ipkt to wait for */ 6835 mutex_enter(&fptr->fcip_mutex); 6836 if (fptr->fcip_num_ipkts_pending) /* Safety check */ 6837 fptr->fcip_num_ipkts_pending--; 6838 mutex_exit(&fptr->fcip_mutex); 6839 6840 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 6841 6842 if (fc_pkt->pkt_cmd_cookie != NULL) { 6843 kmem_free(fc_pkt->pkt_cmd_cookie, fc_pkt->pkt_cmd_cookie_cnt * 6844 sizeof (ddi_dma_cookie_t)); 6845 fc_pkt->pkt_cmd_cookie = NULL; 6846 } 6847 6848 if (fc_pkt->pkt_resp_cookie != NULL) { 6849 kmem_free(fc_pkt->pkt_resp_cookie, fc_pkt->pkt_resp_cookie_cnt * 6850 sizeof (ddi_dma_cookie_t)); 6851 fc_pkt->pkt_resp_cookie = NULL; 6852 } 6853 6854 if (fc_ulp_uninit_packet(fport->fcipp_handle, fc_pkt) != FC_SUCCESS) { 6855 FCIP_DEBUG(FCIP_DEBUG_ELS, (CE_WARN, 6856 "fc_ulp_uninit_pkt failed for internal fc pkt 0x%p", 6857 (void *)fc_pkt)); 6858 } 6859 fcip_free_pkt_dma(fcip_pkt); 6860 kmem_free(fcip_pkt, (sizeof (fcip_pkt_t) + fport->fcipp_fca_pkt_size)); 6861 } 6862 6863 /* 6864 * initialize a unicast request. This is a misnomer because even the 6865 * broadcast requests are initialized with this routine 6866 */ 6867 static void 6868 fcip_init_unicast_pkt(fcip_pkt_t *fcip_pkt, fc_portid_t sid, fc_portid_t did, 6869 void (*comp) ()) 6870 { 6871 fc_packet_t *fc_pkt; 6872 fc_frame_hdr_t *fr_hdr; 6873 struct fcip *fptr = fcip_pkt->fcip_pkt_fptr; 6874 6875 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 6876 fr_hdr = &fc_pkt->pkt_cmd_fhdr; 6877 6878 fr_hdr->r_ctl = R_CTL_DEVICE_DATA | R_CTL_UNSOL_DATA; 6879 fr_hdr->s_id = sid.port_id; 6880 fr_hdr->d_id = did.port_id; 6881 fr_hdr->type = FC_TYPE_IS8802_SNAP; 6882 fr_hdr->f_ctl = F_CTL_FIRST_SEQ | F_CTL_LAST_SEQ; 6883 fr_hdr->df_ctl = DF_CTL_NET_HDR; 6884 fr_hdr->seq_cnt = 0; 6885 fr_hdr->ox_id = 0xffff; 6886 fr_hdr->rx_id = 0xffff; 6887 fr_hdr->ro = 0; 6888 /* 6889 * reset all the length fields 6890 */ 6891 fc_pkt->pkt_rsplen = 0; 6892 fc_pkt->pkt_datalen = 0; 6893 fc_pkt->pkt_comp = comp; 6894 if (comp) { 6895 fc_pkt->pkt_tran_flags |= FC_TRAN_INTR; 6896 } else { 6897 fc_pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 6898 } 6899 fc_pkt->pkt_tran_type = FC_PKT_OUTBOUND | FC_PKT_IP_WRITE; 6900 fc_pkt->pkt_timeout = fcip_pkt_ttl_ticks; 6901 fcip_pkt->fcip_pkt_ttl = fptr->fcip_timeout_ticks + fc_pkt->pkt_timeout; 6902 } 6903 6904 6905 /* 6906 * Initialize a fcip_packet for broadcast data transfers 6907 */ 6908 static void 6909 fcip_init_broadcast_pkt(fcip_pkt_t *fcip_pkt, void (*comp) (), int is_els) 6910 { 6911 fc_packet_t *fc_pkt; 6912 fc_frame_hdr_t *fr_hdr; 6913 struct fcip *fptr = fcip_pkt->fcip_pkt_fptr; 6914 fcip_port_info_t *fport = fptr->fcip_port_info; 6915 uint32_t sid; 6916 uint32_t did; 6917 6918 FCIP_TNF_PROBE_1((fcip_init_broadcast_pkt, "fcip io", /* CSTYLED */, 6919 tnf_string, msg, "enter")); 6920 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 6921 fr_hdr = &fc_pkt->pkt_cmd_fhdr; 6922 sid = fport->fcipp_sid.port_id; 6923 6924 if (is_els) { 6925 fr_hdr->r_ctl = R_CTL_ELS_REQ; 6926 } else { 6927 fr_hdr->r_ctl = R_CTL_DEVICE_DATA | R_CTL_UNSOL_DATA; 6928 } 6929 fr_hdr->s_id = sid; 6930 /* 6931 * The destination broadcast address depends on the topology 6932 * of the underlying port 6933 */ 6934 did = fptr->fcip_broadcast_did; 6935 /* 6936 * mark pkt a broadcast pkt 6937 */ 6938 fc_pkt->pkt_tran_type = FC_PKT_BROADCAST; 6939 6940 fr_hdr->d_id = did; 6941 fr_hdr->type = FC_TYPE_IS8802_SNAP; 6942 fr_hdr->f_ctl = F_CTL_FIRST_SEQ | F_CTL_LAST_SEQ | F_CTL_END_SEQ; 6943 fr_hdr->f_ctl &= ~(F_CTL_SEQ_INITIATIVE); 6944 fr_hdr->df_ctl = DF_CTL_NET_HDR; 6945 fr_hdr->seq_cnt = 0; 6946 fr_hdr->ox_id = 0xffff; 6947 fr_hdr->rx_id = 0xffff; 6948 fr_hdr->ro = 0; 6949 fc_pkt->pkt_comp = comp; 6950 6951 if (comp) { 6952 fc_pkt->pkt_tran_flags |= FC_TRAN_INTR; 6953 } else { 6954 fc_pkt->pkt_tran_flags |= FC_TRAN_NO_INTR; 6955 } 6956 6957 fc_pkt->pkt_tran_type = FC_PKT_BROADCAST; 6958 fc_pkt->pkt_timeout = fcip_pkt_ttl_ticks; 6959 fcip_pkt->fcip_pkt_ttl = fptr->fcip_timeout_ticks + fc_pkt->pkt_timeout; 6960 } 6961 6962 6963 6964 /* 6965 * Free up all DMA resources associated with an allocated packet 6966 */ 6967 static void 6968 fcip_free_pkt_dma(fcip_pkt_t *fcip_pkt) 6969 { 6970 fc_packet_t *fc_pkt; 6971 6972 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 6973 6974 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 6975 (CE_NOTE, "in freepktdma : flags 0x%x", 6976 fcip_pkt->fcip_pkt_dma_flags)); 6977 6978 if (fcip_pkt->fcip_pkt_dma_flags & FCIP_CMD_DMA_BOUND) { 6979 (void) ddi_dma_unbind_handle(fc_pkt->pkt_cmd_dma); 6980 } 6981 if (fcip_pkt->fcip_pkt_dma_flags & FCIP_CMD_DMA_MEM) { 6982 ddi_dma_mem_free(&fc_pkt->pkt_cmd_acc); 6983 } 6984 6985 if (fcip_pkt->fcip_pkt_dma_flags & FCIP_RESP_DMA_BOUND) { 6986 (void) ddi_dma_unbind_handle(fc_pkt->pkt_resp_dma); 6987 } 6988 if (fcip_pkt->fcip_pkt_dma_flags & FCIP_RESP_DMA_MEM) { 6989 ddi_dma_mem_free(&fc_pkt->pkt_resp_acc); 6990 } 6991 /* 6992 * for internal commands, we need to free up the dma handles too. 6993 * This is done in the cache destructor for non internal cmds 6994 */ 6995 if (fcip_pkt->fcip_pkt_flags & FCIP_PKT_INTERNAL) { 6996 if (fc_pkt->pkt_cmd_dma) { 6997 ddi_dma_free_handle(&fc_pkt->pkt_cmd_dma); 6998 } 6999 if (fc_pkt->pkt_resp_dma) { 7000 ddi_dma_free_handle(&fc_pkt->pkt_resp_dma); 7001 } 7002 } 7003 } 7004 7005 7006 /* 7007 * helper routine to generate a string, given an ether addr 7008 */ 7009 static void 7010 fcip_ether_to_str(struct ether_addr *e, caddr_t s) 7011 { 7012 int i; 7013 7014 for (i = 0; i < sizeof (struct ether_addr); i++, s += 2) { 7015 FCIP_DEBUG(FCIP_DEBUG_MISC, 7016 (CE_CONT, "0x%02X:", e->ether_addr_octet[i])); 7017 (void) sprintf(s, "%02X", e->ether_addr_octet[i]); 7018 } 7019 7020 *s = '\0'; 7021 } 7022 7023 /* 7024 * When a broadcast request comes from the upper streams modules, it 7025 * is ugly to look into every datagram to figure out if it is a broadcast 7026 * datagram or a unicast packet. Instead just add the broadcast entries 7027 * into our routing and dest tables and the standard hash table look ups 7028 * will find the entries. It is a lot cleaner this way. Also Solaris ifconfig 7029 * seems to be very ethernet specific and it requires broadcasts to the 7030 * ether broadcast addr of 0xffffffffff to succeed even though we specified 7031 * in the dl_info request that our broadcast MAC addr is 0x0000000000 7032 * (can't figure out why RFC2625 did this though). So add broadcast entries 7033 * for both MAC address 7034 */ 7035 static int 7036 fcip_dest_add_broadcast_entry(struct fcip *fptr, int new_flag) 7037 { 7038 fc_portmap_t map; 7039 struct fcip_routing_table *frp; 7040 uint32_t did; 7041 la_wwn_t broadcast_wwn; 7042 7043 /* 7044 * get port_id of destination for broadcast - this is topology 7045 * dependent 7046 */ 7047 did = fptr->fcip_broadcast_did; 7048 7049 ether_to_wwn(&fcip_arpbroadcast_addr, &broadcast_wwn); 7050 bcopy((void *)&broadcast_wwn, (void *)&map.map_pwwn, sizeof (la_wwn_t)); 7051 bcopy((void *)&broadcast_wwn, (void *)&map.map_nwwn, sizeof (la_wwn_t)); 7052 7053 map.map_did.port_id = did; 7054 map.map_hard_addr.hard_addr = did; 7055 map.map_state = PORT_DEVICE_VALID; 7056 if (new_flag) { 7057 map.map_type = PORT_DEVICE_NEW; 7058 } else { 7059 map.map_type = PORT_DEVICE_CHANGED; 7060 } 7061 map.map_flags = 0; 7062 map.map_pd = NULL; 7063 bzero(&map.map_fc4_types, sizeof (map.map_fc4_types)); 7064 fcip_rt_update(fptr, &map, 1); 7065 mutex_enter(&fptr->fcip_rt_mutex); 7066 frp = fcip_lookup_rtable(fptr, &broadcast_wwn, FCIP_COMPARE_NWWN); 7067 mutex_exit(&fptr->fcip_rt_mutex); 7068 if (frp == NULL) { 7069 return (FC_FAILURE); 7070 } 7071 (void) fcip_add_dest(fptr, frp); 7072 /* 7073 * The Upper IP layers expect the traditional broadcast MAC addr 7074 * of 0xff ff ff ff ff ff to work too if we want to plumb the fcip 7075 * stream through the /etc/hostname.fcipXX file. Instead of checking 7076 * each phys addr for a match with fcip's ARP header broadcast 7077 * addr (0x00 00 00 00 00 00), its simply easier to add another 7078 * broadcast entry for 0xff ff ff ff ff ff. 7079 */ 7080 ether_to_wwn(&fcipnhbroadcastaddr, &broadcast_wwn); 7081 bcopy((void *)&broadcast_wwn, (void *)&map.map_pwwn, sizeof (la_wwn_t)); 7082 bcopy((void *)&broadcast_wwn, (void *)&map.map_nwwn, sizeof (la_wwn_t)); 7083 fcip_rt_update(fptr, &map, 1); 7084 mutex_enter(&fptr->fcip_rt_mutex); 7085 frp = fcip_lookup_rtable(fptr, &broadcast_wwn, FCIP_COMPARE_NWWN); 7086 mutex_exit(&fptr->fcip_rt_mutex); 7087 if (frp == NULL) { 7088 return (FC_FAILURE); 7089 } 7090 (void) fcip_add_dest(fptr, frp); 7091 return (FC_SUCCESS); 7092 } 7093 7094 /* 7095 * We need to obtain the D_ID of the broadcast port for transmitting all 7096 * our broadcast (and multicast) requests. The broadcast D_ID as we know 7097 * is dependent on the link topology 7098 */ 7099 static uint32_t 7100 fcip_get_broadcast_did(struct fcip *fptr) 7101 { 7102 fcip_port_info_t *fport = fptr->fcip_port_info; 7103 uint32_t did = 0; 7104 uint32_t sid; 7105 7106 FCIP_TNF_PROBE_2((fcip_get_broadcast_did, "fcip io", /* CSTYLED */, 7107 tnf_string, msg, "enter", 7108 tnf_opaque, fptr, fptr)); 7109 7110 sid = fport->fcipp_sid.port_id; 7111 7112 switch (fport->fcipp_topology) { 7113 7114 case FC_TOP_PT_PT: { 7115 fc_portmap_t *port_map = NULL; 7116 uint32_t listlen = 0; 7117 7118 if (fc_ulp_getportmap(fport->fcipp_handle, &port_map, 7119 &listlen, FC_ULP_PLOGI_DONTCARE) == FC_SUCCESS) { 7120 FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_NOTE, 7121 "fcip_gpmap: listlen : 0x%x", listlen)); 7122 if (listlen == 1) { 7123 did = port_map->map_did.port_id; 7124 } 7125 } 7126 if (port_map) { 7127 kmem_free(port_map, listlen * sizeof (fc_portmap_t)); 7128 } 7129 if (listlen != 1) { 7130 /* Dummy return value */ 7131 return (0x00FFFFFF); 7132 } 7133 break; 7134 } 7135 7136 case FC_TOP_NO_NS: 7137 /* FALLTHROUGH */ 7138 case FC_TOP_FABRIC: 7139 /* 7140 * The broadcast address is the same whether or not 7141 * the switch/fabric contains a Name service. 7142 */ 7143 did = 0x00FFFFFF; 7144 break; 7145 7146 case FC_TOP_PUBLIC_LOOP: 7147 /* 7148 * The open replicate primitive must not be used. The 7149 * broadcast sequence is simply sent to ALPA 0x00. The 7150 * fabric controller then propagates the broadcast to all 7151 * other ports. The fabric propagates the broadcast by 7152 * using the OPNfr primitive. 7153 */ 7154 did = 0x00; 7155 break; 7156 7157 case FC_TOP_PRIVATE_LOOP: 7158 /* 7159 * The source port for broadcast in private loop mode 7160 * must send an OPN(fr) signal forcing all ports in the 7161 * loop to replicate the frames that they receive. 7162 */ 7163 did = 0x00FFFFFF; 7164 break; 7165 7166 case FC_TOP_UNKNOWN: 7167 /* FALLTHROUGH */ 7168 default: 7169 did = sid; 7170 FCIP_DEBUG(FCIP_DEBUG_INIT, (CE_WARN, 7171 "fcip(0x%x):unknown topology in init_broadcast_pkt", 7172 fptr->fcip_instance)); 7173 break; 7174 } 7175 FCIP_TNF_PROBE_2((fcip_get_broadcast_did, "fcip io", /* CSTYLED */, 7176 tnf_string, msg, "return", 7177 tnf_opaque, did, did)); 7178 7179 return (did); 7180 } 7181 7182 7183 /* 7184 * fcip timeout performs 2 operations: 7185 * 1. timeout any packets sent to the FCA for which a callback hasn't 7186 * happened. If you are wondering why we need a callback since all 7187 * traffic in FCIP is unidirectional, hence all exchanges are unidirectional 7188 * but wait, we can only free up the resources after we know the FCA has 7189 * DMA'ed out the data. pretty obvious eh :) 7190 * 7191 * 2. Retire and routing table entries we marked up for retiring. This is 7192 * to give the link a chance to recover instead of marking a port down 7193 * when we have lost all communication with it after a link transition 7194 */ 7195 static void 7196 fcip_timeout(void *arg) 7197 { 7198 struct fcip *fptr = (struct fcip *)arg; 7199 int i; 7200 fcip_pkt_t *fcip_pkt; 7201 struct fcip_dest *fdestp; 7202 int index; 7203 struct fcip_routing_table *frtp; 7204 int dispatch_rte_removal = 0; 7205 7206 mutex_enter(&fptr->fcip_mutex); 7207 7208 fptr->fcip_flags |= FCIP_IN_TIMEOUT; 7209 fptr->fcip_timeout_ticks += fcip_tick_incr; 7210 7211 if (fptr->fcip_flags & (FCIP_DETACHED | FCIP_DETACHING | \ 7212 FCIP_SUSPENDED | FCIP_POWER_DOWN)) { 7213 fptr->fcip_flags &= ~(FCIP_IN_TIMEOUT); 7214 mutex_exit(&fptr->fcip_mutex); 7215 return; 7216 } 7217 7218 if (fptr->fcip_port_state == FCIP_PORT_OFFLINE) { 7219 if (fptr->fcip_timeout_ticks > fptr->fcip_mark_offline) { 7220 fptr->fcip_flags |= FCIP_LINK_DOWN; 7221 } 7222 } 7223 if (!fptr->fcip_flags & FCIP_RTE_REMOVING) { 7224 dispatch_rte_removal = 1; 7225 } 7226 mutex_exit(&fptr->fcip_mutex); 7227 7228 /* 7229 * Check if we have any Invalid routing table entries in our 7230 * hashtable we have marked off for deferred removal. If any, 7231 * we can spawn a taskq thread to do the cleanup for us. We 7232 * need to avoid cleanup in the timeout thread since we may 7233 * have to wait for outstanding commands to complete before 7234 * we retire a routing table entry. Also dispatch the taskq 7235 * thread only if we are already do not have a taskq thread 7236 * dispatched. 7237 */ 7238 if (dispatch_rte_removal) { 7239 mutex_enter(&fptr->fcip_rt_mutex); 7240 for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) { 7241 frtp = fptr->fcip_rtable[index]; 7242 while (frtp) { 7243 if ((frtp->fcipr_state == FCIP_RT_INVALID) && 7244 (fptr->fcip_timeout_ticks > 7245 frtp->fcipr_invalid_timeout)) { 7246 /* 7247 * If we cannot schedule a task thread 7248 * let us attempt again on the next 7249 * tick rather than call 7250 * fcip_rte_remove_deferred() from here 7251 * directly since the routine can sleep. 7252 */ 7253 frtp->fcipr_state = FCIP_RT_RETIRED; 7254 7255 mutex_enter(&fptr->fcip_mutex); 7256 fptr->fcip_flags |= FCIP_RTE_REMOVING; 7257 mutex_exit(&fptr->fcip_mutex); 7258 7259 if (taskq_dispatch(fptr->fcip_tq, 7260 fcip_rte_remove_deferred, fptr, 7261 KM_NOSLEEP) == 0) { 7262 /* 7263 * failed - so mark the entry 7264 * as invalid again. 7265 */ 7266 frtp->fcipr_state = 7267 FCIP_RT_INVALID; 7268 7269 mutex_enter(&fptr->fcip_mutex); 7270 fptr->fcip_flags &= 7271 ~FCIP_RTE_REMOVING; 7272 mutex_exit(&fptr->fcip_mutex); 7273 } 7274 } 7275 frtp = frtp->fcipr_next; 7276 } 7277 } 7278 mutex_exit(&fptr->fcip_rt_mutex); 7279 } 7280 7281 mutex_enter(&fptr->fcip_dest_mutex); 7282 7283 /* 7284 * Now timeout any packets stuck with the transport/FCA for too long 7285 */ 7286 for (i = 0; i < FCIP_DEST_HASH_ELEMS; i++) { 7287 fdestp = fptr->fcip_dest[i]; 7288 while (fdestp != NULL) { 7289 mutex_enter(&fdestp->fcipd_mutex); 7290 for (fcip_pkt = fdestp->fcipd_head; fcip_pkt != NULL; 7291 fcip_pkt = fcip_pkt->fcip_pkt_next) { 7292 if (fcip_pkt->fcip_pkt_flags & 7293 (FCIP_PKT_RETURNED | FCIP_PKT_IN_TIMEOUT | 7294 FCIP_PKT_IN_ABORT)) { 7295 continue; 7296 } 7297 if (fptr->fcip_timeout_ticks > 7298 fcip_pkt->fcip_pkt_ttl) { 7299 fcip_pkt->fcip_pkt_flags |= 7300 FCIP_PKT_IN_TIMEOUT; 7301 7302 mutex_exit(&fdestp->fcipd_mutex); 7303 if (taskq_dispatch(fptr->fcip_tq, 7304 fcip_pkt_timeout, fcip_pkt, 7305 KM_NOSLEEP) == 0) { 7306 /* 7307 * timeout immediately 7308 */ 7309 fcip_pkt_timeout(fcip_pkt); 7310 } 7311 mutex_enter(&fdestp->fcipd_mutex); 7312 /* 7313 * The linked list is altered because 7314 * of one of the following reasons: 7315 * a. Timeout code dequeued a pkt 7316 * b. Pkt completion happened 7317 * 7318 * So restart the spin starting at 7319 * the head again; This is a bit 7320 * excessive, but okay since 7321 * fcip_timeout_ticks isn't incremented 7322 * for this spin, we will skip the 7323 * not-to-be-timedout packets quickly 7324 */ 7325 fcip_pkt = fdestp->fcipd_head; 7326 if (fcip_pkt == NULL) { 7327 break; 7328 } 7329 } 7330 } 7331 mutex_exit(&fdestp->fcipd_mutex); 7332 fdestp = fdestp->fcipd_next; 7333 } 7334 } 7335 mutex_exit(&fptr->fcip_dest_mutex); 7336 7337 /* 7338 * reschedule the timeout thread 7339 */ 7340 mutex_enter(&fptr->fcip_mutex); 7341 7342 fptr->fcip_timeout_id = timeout(fcip_timeout, fptr, 7343 drv_usectohz(1000000)); 7344 fptr->fcip_flags &= ~(FCIP_IN_TIMEOUT); 7345 mutex_exit(&fptr->fcip_mutex); 7346 } 7347 7348 7349 /* 7350 * This routine is either called from taskq or directly from fcip_timeout 7351 * does the actual job of aborting the packet 7352 */ 7353 static void 7354 fcip_pkt_timeout(void *arg) 7355 { 7356 fcip_pkt_t *fcip_pkt = (fcip_pkt_t *)arg; 7357 struct fcip_dest *fdestp; 7358 struct fcip *fptr; 7359 fc_packet_t *fc_pkt; 7360 fcip_port_info_t *fport; 7361 int rval; 7362 7363 fdestp = fcip_pkt->fcip_pkt_dest; 7364 fptr = fcip_pkt->fcip_pkt_fptr; 7365 fport = fptr->fcip_port_info; 7366 fc_pkt = FCIP_PKT_TO_FC_PKT(fcip_pkt); 7367 7368 /* 7369 * try to abort the pkt 7370 */ 7371 fcip_pkt->fcip_pkt_flags |= FCIP_PKT_IN_ABORT; 7372 rval = fc_ulp_abort(fport->fcipp_handle, fc_pkt, KM_NOSLEEP); 7373 7374 FCIP_DEBUG(FCIP_DEBUG_DOWNSTREAM, 7375 (CE_NOTE, "fc_ulp_abort returns: 0x%x", rval)); 7376 7377 if (rval == FC_SUCCESS) { 7378 ASSERT(fdestp != NULL); 7379 7380 /* 7381 * dequeue the pkt from the dest structure pkt list 7382 */ 7383 fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_ABORT; 7384 mutex_enter(&fdestp->fcipd_mutex); 7385 rval = fcip_fdestp_dequeue_pkt(fdestp, fcip_pkt); 7386 ASSERT(rval == 1); 7387 mutex_exit(&fdestp->fcipd_mutex); 7388 7389 /* 7390 * Now cleanup the pkt and free the mblk 7391 */ 7392 fcip_pkt_free(fcip_pkt, 1); 7393 } else { 7394 /* 7395 * abort failed - just mark the pkt as done and 7396 * wait for it to complete in fcip_pkt_callback since 7397 * the pkt has already been xmitted by the FCA 7398 */ 7399 fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_TIMEOUT; 7400 if (fcip_pkt->fcip_pkt_flags & FCIP_PKT_RETURNED) { 7401 fcip_pkt->fcip_pkt_flags &= ~FCIP_PKT_IN_ABORT; 7402 mutex_enter(&fdestp->fcipd_mutex); 7403 rval = fcip_fdestp_dequeue_pkt(fdestp, fcip_pkt); 7404 ASSERT(rval == 1); 7405 mutex_exit(&fdestp->fcipd_mutex); 7406 7407 fcip_pkt_free(fcip_pkt, 1); 7408 } 7409 return; 7410 } 7411 } 7412 7413 7414 /* 7415 * Remove a routing table entry marked for deferred removal. This routine 7416 * unlike fcip_pkt_timeout, is always called from a taskq context 7417 */ 7418 static void 7419 fcip_rte_remove_deferred(void *arg) 7420 { 7421 struct fcip *fptr = (struct fcip *)arg; 7422 int hash_bucket; 7423 struct fcip_dest *fdestp; 7424 la_wwn_t *pwwn; 7425 int index; 7426 struct fcip_routing_table *frtp, *frtp_next, *frtp_prev; 7427 7428 7429 mutex_enter(&fptr->fcip_rt_mutex); 7430 for (index = 0; index < FCIP_RT_HASH_ELEMS; index++) { 7431 frtp = fptr->fcip_rtable[index]; 7432 frtp_prev = NULL; 7433 while (frtp) { 7434 frtp_next = frtp->fcipr_next; 7435 7436 if (frtp->fcipr_state == FCIP_RT_RETIRED) { 7437 7438 pwwn = &frtp->fcipr_pwwn; 7439 /* 7440 * Get hold of destination pointer 7441 */ 7442 mutex_enter(&fptr->fcip_dest_mutex); 7443 7444 hash_bucket = FCIP_DEST_HASH(pwwn->raw_wwn); 7445 ASSERT(hash_bucket < FCIP_DEST_HASH_ELEMS); 7446 7447 fdestp = fptr->fcip_dest[hash_bucket]; 7448 while (fdestp != NULL) { 7449 mutex_enter(&fdestp->fcipd_mutex); 7450 if (fdestp->fcipd_rtable) { 7451 if (fcip_wwn_compare(pwwn, 7452 &fdestp->fcipd_pwwn, 7453 FCIP_COMPARE_PWWN) == 0) { 7454 mutex_exit( 7455 &fdestp->fcipd_mutex); 7456 break; 7457 } 7458 } 7459 mutex_exit(&fdestp->fcipd_mutex); 7460 fdestp = fdestp->fcipd_next; 7461 } 7462 7463 mutex_exit(&fptr->fcip_dest_mutex); 7464 if (fdestp == NULL) { 7465 frtp_prev = frtp; 7466 frtp = frtp_next; 7467 continue; 7468 } 7469 7470 mutex_enter(&fdestp->fcipd_mutex); 7471 if (fdestp->fcipd_ncmds) { 7472 /* 7473 * Instead of waiting to drain commands 7474 * let us revisit this RT entry in 7475 * the next pass. 7476 */ 7477 mutex_exit(&fdestp->fcipd_mutex); 7478 frtp_prev = frtp; 7479 frtp = frtp_next; 7480 continue; 7481 } 7482 7483 /* 7484 * We are clean, so remove the RTE 7485 */ 7486 fdestp->fcipd_rtable = NULL; 7487 mutex_exit(&fdestp->fcipd_mutex); 7488 7489 FCIP_TNF_PROBE_2((fcip_rte_remove_deferred, 7490 "fcip io", /* CSTYLED */, 7491 tnf_string, msg, 7492 "remove retired routing entry", 7493 tnf_int, index, index)); 7494 7495 if (frtp_prev == NULL) { 7496 /* first element */ 7497 fptr->fcip_rtable[index] = 7498 frtp->fcipr_next; 7499 } else { 7500 frtp_prev->fcipr_next = 7501 frtp->fcipr_next; 7502 } 7503 kmem_free(frtp, 7504 sizeof (struct fcip_routing_table)); 7505 7506 frtp = frtp_next; 7507 } else { 7508 frtp_prev = frtp; 7509 frtp = frtp_next; 7510 } 7511 } 7512 } 7513 mutex_exit(&fptr->fcip_rt_mutex); 7514 /* 7515 * Clear the RTE_REMOVING flag 7516 */ 7517 mutex_enter(&fptr->fcip_mutex); 7518 fptr->fcip_flags &= ~FCIP_RTE_REMOVING; 7519 mutex_exit(&fptr->fcip_mutex); 7520 } 7521 7522 /* 7523 * Walk through all the dest hash table entries and count up the total 7524 * no. of packets outstanding against a given port 7525 */ 7526 static int 7527 fcip_port_get_num_pkts(struct fcip *fptr) 7528 { 7529 int num_cmds = 0; 7530 int i; 7531 struct fcip_dest *fdestp; 7532 7533 ASSERT(mutex_owned(&fptr->fcip_dest_mutex)); 7534 7535 for (i = 0; i < FCIP_DEST_HASH_ELEMS; i++) { 7536 fdestp = fptr->fcip_dest[i]; 7537 while (fdestp != NULL) { 7538 mutex_enter(&fdestp->fcipd_mutex); 7539 7540 ASSERT(fdestp->fcipd_ncmds >= 0); 7541 7542 if (fdestp->fcipd_ncmds > 0) { 7543 num_cmds += fdestp->fcipd_ncmds; 7544 } 7545 mutex_exit(&fdestp->fcipd_mutex); 7546 fdestp = fdestp->fcipd_next; 7547 } 7548 } 7549 7550 return (num_cmds); 7551 } 7552 7553 7554 /* 7555 * Walk through the routing table for this state instance and see if there is a 7556 * PLOGI in progress for any of the entries. Return success even if we find one. 7557 */ 7558 static int 7559 fcip_plogi_in_progress(struct fcip *fptr) 7560 { 7561 int i; 7562 struct fcip_routing_table *frp; 7563 7564 ASSERT(mutex_owned(&fptr->fcip_rt_mutex)); 7565 7566 for (i = 0; i < FCIP_RT_HASH_ELEMS; i++) { 7567 frp = fptr->fcip_rtable[i]; 7568 while (frp) { 7569 if (frp->fcipr_state == FCIP_RT_LOGIN_PROGRESS) { 7570 /* Found an entry where PLOGI is in progress */ 7571 return (1); 7572 } 7573 frp = frp->fcipr_next; 7574 } 7575 } 7576 7577 return (0); 7578 } 7579 7580 /* 7581 * Walk through the fcip port global list and check if the given port exists in 7582 * the list. Returns "0" if port exists and "1" if otherwise. 7583 */ 7584 static int 7585 fcip_check_port_exists(struct fcip *fptr) 7586 { 7587 fcip_port_info_t *cur_fport; 7588 fcip_port_info_t *fport; 7589 7590 mutex_enter(&fcip_global_mutex); 7591 fport = fptr->fcip_port_info; 7592 cur_fport = fcip_port_head; 7593 while (cur_fport != NULL) { 7594 if (cur_fport == fport) { 7595 /* Found */ 7596 mutex_exit(&fcip_global_mutex); 7597 return (0); 7598 } else { 7599 cur_fport = cur_fport->fcipp_next; 7600 } 7601 } 7602 mutex_exit(&fcip_global_mutex); 7603 7604 return (1); 7605 } 7606 7607 /* 7608 * Constructor to initialize the sendup elements for callback into 7609 * modules upstream 7610 */ 7611 7612 /* ARGSUSED */ 7613 static int 7614 fcip_sendup_constructor(void *buf, void *arg, int flags) 7615 { 7616 struct fcip_sendup_elem *msg_elem = (struct fcip_sendup_elem *)buf; 7617 fcip_port_info_t *fport = (fcip_port_info_t *)arg; 7618 7619 ASSERT(fport != NULL); 7620 7621 msg_elem->fcipsu_mp = NULL; 7622 msg_elem->fcipsu_func = NULL; 7623 msg_elem->fcipsu_next = NULL; 7624 7625 return (FCIP_SUCCESS); 7626 } 7627