diff options
| -rw-r--r-- | drivers/net/ethernet/brocade/bna/bfa_defs.h | 98 | ||||
| -rw-r--r-- | drivers/net/ethernet/brocade/bna/bfa_ioc.c | 372 | ||||
| -rw-r--r-- | drivers/net/ethernet/brocade/bna/bfa_ioc.h | 48 | ||||
| -rw-r--r-- | drivers/net/ethernet/brocade/bna/bfi.h | 95 | ||||
| -rw-r--r-- | drivers/net/ethernet/brocade/bna/bna_enet.c | 8 | ||||
| -rw-r--r-- | drivers/net/ethernet/brocade/bna/bna_types.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/brocade/bna/bnad.c | 37 | ||||
| -rw-r--r-- | drivers/net/ethernet/brocade/bna/bnad.h | 9 | ||||
| -rw-r--r-- | drivers/net/ethernet/brocade/bna/bnad_ethtool.c | 142 |
9 files changed, 771 insertions, 39 deletions
diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs.h b/drivers/net/ethernet/brocade/bna/bfa_defs.h index 2f12d68021d5..871c6309334c 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_defs.h +++ b/drivers/net/ethernet/brocade/bna/bfa_defs.h | |||
| @@ -219,41 +219,39 @@ enum { | |||
| 219 | * All numerical fields are in big-endian format. | 219 | * All numerical fields are in big-endian format. |
| 220 | */ | 220 | */ |
| 221 | struct bfa_mfg_block { | 221 | struct bfa_mfg_block { |
| 222 | u8 version; /*!< manufacturing block version */ | 222 | u8 version; /* manufacturing block version */ |
| 223 | u8 mfg_sig[3]; /*!< characters 'M', 'F', 'G' */ | 223 | u8 mfg_sig[3]; /* characters 'M', 'F', 'G' */ |
| 224 | u16 mfgsize; /*!< mfg block size */ | 224 | u16 mfgsize; /* mfg block size */ |
| 225 | u16 u16_chksum; /*!< old u16 checksum */ | 225 | u16 u16_chksum; /* old u16 checksum */ |
| 226 | char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)]; | 226 | char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)]; |
| 227 | char brcd_partnum[STRSZ(BFA_MFG_PARTNUM_SIZE)]; | 227 | char brcd_partnum[STRSZ(BFA_MFG_PARTNUM_SIZE)]; |
| 228 | u8 mfg_day; /*!< manufacturing day */ | 228 | u8 mfg_day; /* manufacturing day */ |
| 229 | u8 mfg_month; /*!< manufacturing month */ | 229 | u8 mfg_month; /* manufacturing month */ |
| 230 | u16 mfg_year; /*!< manufacturing year */ | 230 | u16 mfg_year; /* manufacturing year */ |
| 231 | u64 mfg_wwn; /*!< wwn base for this adapter */ | 231 | u64 mfg_wwn; /* wwn base for this adapter */ |
| 232 | u8 num_wwn; /*!< number of wwns assigned */ | 232 | u8 num_wwn; /* number of wwns assigned */ |
| 233 | u8 mfg_speeds; /*!< speeds allowed for this adapter */ | 233 | u8 mfg_speeds; /* speeds allowed for this adapter */ |
| 234 | u8 rsv[2]; | 234 | u8 rsv[2]; |
| 235 | char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)]; | 235 | char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)]; |
| 236 | char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)]; | 236 | char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)]; |
| 237 | char | 237 | char supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)]; |
| 238 | supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)]; | 238 | char supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)]; |
| 239 | char | 239 | mac_t mfg_mac; /* base mac address */ |
| 240 | supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)]; | 240 | u8 num_mac; /* number of mac addresses */ |
| 241 | mac_t mfg_mac; /*!< mac address */ | 241 | u8 rsv2; |
| 242 | u8 num_mac; /*!< number of mac addresses */ | 242 | u32 card_type; /* card type */ |
| 243 | u8 rsv2; | 243 | char cap_nic; /* capability nic */ |
| 244 | u32 card_type; /*!< card type */ | 244 | char cap_cna; /* capability cna */ |
| 245 | char cap_nic; /*!< capability nic */ | 245 | char cap_hba; /* capability hba */ |
| 246 | char cap_cna; /*!< capability cna */ | 246 | char cap_fc16g; /* capability fc 16g */ |
| 247 | char cap_hba; /*!< capability hba */ | 247 | char cap_sriov; /* capability sriov */ |
| 248 | char cap_fc16g; /*!< capability fc 16g */ | 248 | char cap_mezz; /* capability mezz */ |
| 249 | char cap_sriov; /*!< capability sriov */ | 249 | u8 rsv3; |
| 250 | char cap_mezz; /*!< capability mezz */ | 250 | u8 mfg_nports; /* number of ports */ |
| 251 | u8 rsv3; | 251 | char media[8]; /* xfi/xaui */ |
| 252 | u8 mfg_nports; /*!< number of ports */ | 252 | char initial_mode[8]; /* initial mode: hba/cna/nic */ |
| 253 | char media[8]; /*!< xfi/xaui */ | 253 | u8 rsv4[84]; |
| 254 | char initial_mode[8];/*!< initial mode: hba/cna/nic */ | 254 | u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /* md5 checksum */ |
| 255 | u8 rsv4[84]; | ||
| 256 | u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /*!< md5 checksum */ | ||
| 257 | }; | 255 | }; |
| 258 | 256 | ||
| 259 | #pragma pack() | 257 | #pragma pack() |
| @@ -293,4 +291,34 @@ enum bfa_mode { | |||
| 293 | BFA_MODE_NIC = 3 | 291 | BFA_MODE_NIC = 3 |
| 294 | }; | 292 | }; |
| 295 | 293 | ||
| 294 | /* | ||
| 295 | * Flash module specific | ||
| 296 | */ | ||
| 297 | #define BFA_FLASH_PART_ENTRY_SIZE 32 /* partition entry size */ | ||
| 298 | #define BFA_FLASH_PART_MAX 32 /* maximal # of partitions */ | ||
| 299 | #define BFA_TOTAL_FLASH_SIZE 0x400000 | ||
| 300 | #define BFA_FLASH_PART_MFG 7 | ||
| 301 | |||
| 302 | /* | ||
| 303 | * flash partition attributes | ||
| 304 | */ | ||
| 305 | struct bfa_flash_part_attr { | ||
| 306 | u32 part_type; /* partition type */ | ||
| 307 | u32 part_instance; /* partition instance */ | ||
| 308 | u32 part_off; /* partition offset */ | ||
| 309 | u32 part_size; /* partition size */ | ||
| 310 | u32 part_len; /* partition content length */ | ||
| 311 | u32 part_status; /* partition status */ | ||
| 312 | char rsv[BFA_FLASH_PART_ENTRY_SIZE - 24]; | ||
| 313 | }; | ||
| 314 | |||
| 315 | /* | ||
| 316 | * flash attributes | ||
| 317 | */ | ||
| 318 | struct bfa_flash_attr { | ||
| 319 | u32 status; /* flash overall status */ | ||
| 320 | u32 npart; /* num of partitions */ | ||
| 321 | struct bfa_flash_part_attr part[BFA_FLASH_PART_MAX]; | ||
| 322 | }; | ||
| 323 | |||
| 296 | #endif /* __BFA_DEFS_H__ */ | 324 | #endif /* __BFA_DEFS_H__ */ |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index b0307a00a109..1d130445efbc 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c | |||
| @@ -2172,6 +2172,15 @@ bfa_nw_ioc_is_disabled(struct bfa_ioc *ioc) | |||
| 2172 | } | 2172 | } |
| 2173 | 2173 | ||
| 2174 | /** | 2174 | /** |
| 2175 | * return true if IOC is operational | ||
| 2176 | */ | ||
| 2177 | bool | ||
| 2178 | bfa_nw_ioc_is_operational(struct bfa_ioc *ioc) | ||
| 2179 | { | ||
| 2180 | return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); | ||
| 2181 | } | ||
| 2182 | |||
| 2183 | /** | ||
| 2175 | * Add to IOC heartbeat failure notification queue. To be used by common | 2184 | * Add to IOC heartbeat failure notification queue. To be used by common |
| 2176 | * modules such as cee, port, diag. | 2185 | * modules such as cee, port, diag. |
| 2177 | */ | 2186 | */ |
| @@ -2471,3 +2480,366 @@ bfa_ioc_poll_fwinit(struct bfa_ioc *ioc) | |||
| 2471 | msecs_to_jiffies(BFA_IOC_POLL_TOV)); | 2480 | msecs_to_jiffies(BFA_IOC_POLL_TOV)); |
| 2472 | } | 2481 | } |
| 2473 | } | 2482 | } |
| 2483 | |||
| 2484 | /* | ||
| 2485 | * Flash module specific | ||
| 2486 | */ | ||
| 2487 | |||
| 2488 | /* | ||
| 2489 | * FLASH DMA buffer should be big enough to hold both MFG block and | ||
| 2490 | * asic block(64k) at the same time and also should be 2k aligned to | ||
| 2491 | * avoid write segement to cross sector boundary. | ||
| 2492 | */ | ||
| 2493 | #define BFA_FLASH_SEG_SZ 2048 | ||
| 2494 | #define BFA_FLASH_DMA_BUF_SZ \ | ||
| 2495 | roundup(0x010000 + sizeof(struct bfa_mfg_block), BFA_FLASH_SEG_SZ) | ||
| 2496 | |||
| 2497 | static void | ||
| 2498 | bfa_flash_cb(struct bfa_flash *flash) | ||
| 2499 | { | ||
| 2500 | flash->op_busy = 0; | ||
| 2501 | if (flash->cbfn) | ||
| 2502 | flash->cbfn(flash->cbarg, flash->status); | ||
| 2503 | } | ||
| 2504 | |||
| 2505 | static void | ||
| 2506 | bfa_flash_notify(void *cbarg, enum bfa_ioc_event event) | ||
| 2507 | { | ||
| 2508 | struct bfa_flash *flash = cbarg; | ||
| 2509 | |||
| 2510 | switch (event) { | ||
| 2511 | case BFA_IOC_E_DISABLED: | ||
| 2512 | case BFA_IOC_E_FAILED: | ||
| 2513 | if (flash->op_busy) { | ||
| 2514 | flash->status = BFA_STATUS_IOC_FAILURE; | ||
| 2515 | flash->cbfn(flash->cbarg, flash->status); | ||
| 2516 | flash->op_busy = 0; | ||
| 2517 | } | ||
| 2518 | break; | ||
| 2519 | default: | ||
| 2520 | break; | ||
| 2521 | } | ||
| 2522 | } | ||
| 2523 | |||
| 2524 | /* | ||
| 2525 | * Send flash write request. | ||
| 2526 | * | ||
| 2527 | * @param[in] cbarg - callback argument | ||
| 2528 | */ | ||
| 2529 | static void | ||
| 2530 | bfa_flash_write_send(struct bfa_flash *flash) | ||
| 2531 | { | ||
| 2532 | struct bfi_flash_write_req *msg = | ||
| 2533 | (struct bfi_flash_write_req *) flash->mb.msg; | ||
| 2534 | u32 len; | ||
| 2535 | |||
| 2536 | msg->type = be32_to_cpu(flash->type); | ||
| 2537 | msg->instance = flash->instance; | ||
| 2538 | msg->offset = be32_to_cpu(flash->addr_off + flash->offset); | ||
| 2539 | len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? | ||
| 2540 | flash->residue : BFA_FLASH_DMA_BUF_SZ; | ||
| 2541 | msg->length = be32_to_cpu(len); | ||
| 2542 | |||
| 2543 | /* indicate if it's the last msg of the whole write operation */ | ||
| 2544 | msg->last = (len == flash->residue) ? 1 : 0; | ||
| 2545 | |||
| 2546 | bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_WRITE_REQ, | ||
| 2547 | bfa_ioc_portid(flash->ioc)); | ||
| 2548 | bfa_alen_set(&msg->alen, len, flash->dbuf_pa); | ||
| 2549 | memcpy(flash->dbuf_kva, flash->ubuf + flash->offset, len); | ||
| 2550 | bfa_nw_ioc_mbox_queue(flash->ioc, &flash->mb, NULL, NULL); | ||
| 2551 | |||
| 2552 | flash->residue -= len; | ||
| 2553 | flash->offset += len; | ||
| 2554 | } | ||
| 2555 | |||
| 2556 | /* | ||
| 2557 | * Send flash read request. | ||
| 2558 | * | ||
| 2559 | * @param[in] cbarg - callback argument | ||
| 2560 | */ | ||
| 2561 | static void | ||
| 2562 | bfa_flash_read_send(void *cbarg) | ||
| 2563 | { | ||
| 2564 | struct bfa_flash *flash = cbarg; | ||
| 2565 | struct bfi_flash_read_req *msg = | ||
| 2566 | (struct bfi_flash_read_req *) flash->mb.msg; | ||
| 2567 | u32 len; | ||
| 2568 | |||
| 2569 | msg->type = be32_to_cpu(flash->type); | ||
| 2570 | msg->instance = flash->instance; | ||
| 2571 | msg->offset = be32_to_cpu(flash->addr_off + flash->offset); | ||
| 2572 | len = (flash->residue < BFA_FLASH_DMA_BUF_SZ) ? | ||
| 2573 | flash->residue : BFA_FLASH_DMA_BUF_SZ; | ||
| 2574 | msg->length = be32_to_cpu(len); | ||
| 2575 | bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_READ_REQ, | ||
| 2576 | bfa_ioc_portid(flash->ioc)); | ||
| 2577 | bfa_alen_set(&msg->alen, len, flash->dbuf_pa); | ||
| 2578 | bfa_nw_ioc_mbox_queue(flash->ioc, &flash->mb, NULL, NULL); | ||
| 2579 | } | ||
| 2580 | |||
| 2581 | /* | ||
| 2582 | * Process flash response messages upon receiving interrupts. | ||
| 2583 | * | ||
| 2584 | * @param[in] flasharg - flash structure | ||
| 2585 | * @param[in] msg - message structure | ||
| 2586 | */ | ||
| 2587 | static void | ||
| 2588 | bfa_flash_intr(void *flasharg, struct bfi_mbmsg *msg) | ||
| 2589 | { | ||
| 2590 | struct bfa_flash *flash = flasharg; | ||
| 2591 | u32 status; | ||
| 2592 | |||
| 2593 | union { | ||
| 2594 | struct bfi_flash_query_rsp *query; | ||
| 2595 | struct bfi_flash_write_rsp *write; | ||
| 2596 | struct bfi_flash_read_rsp *read; | ||
| 2597 | struct bfi_mbmsg *msg; | ||
| 2598 | } m; | ||
| 2599 | |||
| 2600 | m.msg = msg; | ||
| 2601 | |||
| 2602 | /* receiving response after ioc failure */ | ||
| 2603 | if (!flash->op_busy && msg->mh.msg_id != BFI_FLASH_I2H_EVENT) | ||
| 2604 | return; | ||
| 2605 | |||
| 2606 | switch (msg->mh.msg_id) { | ||
| 2607 | case BFI_FLASH_I2H_QUERY_RSP: | ||
| 2608 | status = be32_to_cpu(m.query->status); | ||
| 2609 | if (status == BFA_STATUS_OK) { | ||
| 2610 | u32 i; | ||
| 2611 | struct bfa_flash_attr *attr, *f; | ||
| 2612 | |||
| 2613 | attr = (struct bfa_flash_attr *) flash->ubuf; | ||
| 2614 | f = (struct bfa_flash_attr *) flash->dbuf_kva; | ||
| 2615 | attr->status = be32_to_cpu(f->status); | ||
| 2616 | attr->npart = be32_to_cpu(f->npart); | ||
| 2617 | for (i = 0; i < attr->npart; i++) { | ||
| 2618 | attr->part[i].part_type = | ||
| 2619 | be32_to_cpu(f->part[i].part_type); | ||
| 2620 | attr->part[i].part_instance = | ||
| 2621 | be32_to_cpu(f->part[i].part_instance); | ||
| 2622 | attr->part[i].part_off = | ||
| 2623 | be32_to_cpu(f->part[i].part_off); | ||
| 2624 | attr->part[i].part_size = | ||
| 2625 | be32_to_cpu(f->part[i].part_size); | ||
| 2626 | attr->part[i].part_len = | ||
| 2627 | be32_to_cpu(f->part[i].part_len); | ||
| 2628 | attr->part[i].part_status = | ||
| 2629 | be32_to_cpu(f->part[i].part_status); | ||
| 2630 | } | ||
| 2631 | } | ||
| 2632 | flash->status = status; | ||
| 2633 | bfa_flash_cb(flash); | ||
| 2634 | break; | ||
| 2635 | case BFI_FLASH_I2H_WRITE_RSP: | ||
| 2636 | status = be32_to_cpu(m.write->status); | ||
| 2637 | if (status != BFA_STATUS_OK || flash->residue == 0) { | ||
| 2638 | flash->status = status; | ||
| 2639 | bfa_flash_cb(flash); | ||
| 2640 | } else | ||
| 2641 | bfa_flash_write_send(flash); | ||
| 2642 | break; | ||
| 2643 | case BFI_FLASH_I2H_READ_RSP: | ||
| 2644 | status = be32_to_cpu(m.read->status); | ||
| 2645 | if (status != BFA_STATUS_OK) { | ||
| 2646 | flash->status = status; | ||
| 2647 | bfa_flash_cb(flash); | ||
| 2648 | } else { | ||
| 2649 | u32 len = be32_to_cpu(m.read->length); | ||
| 2650 | memcpy(flash->ubuf + flash->offset, | ||
| 2651 | flash->dbuf_kva, len); | ||
| 2652 | flash->residue -= len; | ||
| 2653 | flash->offset += len; | ||
| 2654 | if (flash->residue == 0) { | ||
| 2655 | flash->status = status; | ||
| 2656 | bfa_flash_cb(flash); | ||
| 2657 | } else | ||
| 2658 | bfa_flash_read_send(flash); | ||
| 2659 | } | ||
| 2660 | break; | ||
| 2661 | case BFI_FLASH_I2H_BOOT_VER_RSP: | ||
| 2662 | case BFI_FLASH_I2H_EVENT: | ||
| 2663 | break; | ||
| 2664 | default: | ||
| 2665 | WARN_ON(1); | ||
| 2666 | } | ||
| 2667 | } | ||
| 2668 | |||
| 2669 | /* | ||
| 2670 | * Flash memory info API. | ||
| 2671 | */ | ||
| 2672 | u32 | ||
| 2673 | bfa_nw_flash_meminfo(void) | ||
| 2674 | { | ||
| 2675 | return roundup(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
| 2676 | } | ||
| 2677 | |||
| 2678 | /* | ||
| 2679 | * Flash attach API. | ||
| 2680 | * | ||
| 2681 | * @param[in] flash - flash structure | ||
| 2682 | * @param[in] ioc - ioc structure | ||
| 2683 | * @param[in] dev - device structure | ||
| 2684 | */ | ||
| 2685 | void | ||
| 2686 | bfa_nw_flash_attach(struct bfa_flash *flash, struct bfa_ioc *ioc, void *dev) | ||
| 2687 | { | ||
| 2688 | flash->ioc = ioc; | ||
| 2689 | flash->cbfn = NULL; | ||
| 2690 | flash->cbarg = NULL; | ||
| 2691 | flash->op_busy = 0; | ||
| 2692 | |||
| 2693 | bfa_nw_ioc_mbox_regisr(flash->ioc, BFI_MC_FLASH, bfa_flash_intr, flash); | ||
| 2694 | bfa_q_qe_init(&flash->ioc_notify); | ||
| 2695 | bfa_ioc_notify_init(&flash->ioc_notify, bfa_flash_notify, flash); | ||
| 2696 | list_add_tail(&flash->ioc_notify.qe, &flash->ioc->notify_q); | ||
| 2697 | } | ||
| 2698 | |||
| 2699 | /* | ||
| 2700 | * Claim memory for flash | ||
| 2701 | * | ||
| 2702 | * @param[in] flash - flash structure | ||
| 2703 | * @param[in] dm_kva - pointer to virtual memory address | ||
| 2704 | * @param[in] dm_pa - physical memory address | ||
| 2705 | */ | ||
| 2706 | void | ||
| 2707 | bfa_nw_flash_memclaim(struct bfa_flash *flash, u8 *dm_kva, u64 dm_pa) | ||
| 2708 | { | ||
| 2709 | flash->dbuf_kva = dm_kva; | ||
| 2710 | flash->dbuf_pa = dm_pa; | ||
| 2711 | memset(flash->dbuf_kva, 0, BFA_FLASH_DMA_BUF_SZ); | ||
| 2712 | dm_kva += roundup(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
| 2713 | dm_pa += roundup(BFA_FLASH_DMA_BUF_SZ, BFA_DMA_ALIGN_SZ); | ||
| 2714 | } | ||
| 2715 | |||
| 2716 | /* | ||
| 2717 | * Get flash attribute. | ||
| 2718 | * | ||
| 2719 | * @param[in] flash - flash structure | ||
| 2720 | * @param[in] attr - flash attribute structure | ||
| 2721 | * @param[in] cbfn - callback function | ||
| 2722 | * @param[in] cbarg - callback argument | ||
| 2723 | * | ||
| 2724 | * Return status. | ||
| 2725 | */ | ||
| 2726 | enum bfa_status | ||
| 2727 | bfa_nw_flash_get_attr(struct bfa_flash *flash, struct bfa_flash_attr *attr, | ||
| 2728 | bfa_cb_flash cbfn, void *cbarg) | ||
| 2729 | { | ||
| 2730 | struct bfi_flash_query_req *msg = | ||
| 2731 | (struct bfi_flash_query_req *) flash->mb.msg; | ||
| 2732 | |||
| 2733 | if (!bfa_nw_ioc_is_operational(flash->ioc)) | ||
| 2734 | return BFA_STATUS_IOC_NON_OP; | ||
| 2735 | |||
| 2736 | if (flash->op_busy) | ||
| 2737 | return BFA_STATUS_DEVBUSY; | ||
| 2738 | |||
| 2739 | flash->op_busy = 1; | ||
| 2740 | flash->cbfn = cbfn; | ||
| 2741 | flash->cbarg = cbarg; | ||
| 2742 | flash->ubuf = (u8 *) attr; | ||
| 2743 | |||
| 2744 | bfi_h2i_set(msg->mh, BFI_MC_FLASH, BFI_FLASH_H2I_QUERY_REQ, | ||
| 2745 | bfa_ioc_portid(flash->ioc)); | ||
| 2746 | bfa_alen_set(&msg->alen, sizeof(struct bfa_flash_attr), flash->dbuf_pa); | ||
| 2747 | bfa_nw_ioc_mbox_queue(flash->ioc, &flash->mb, NULL, NULL); | ||
| 2748 | |||
| 2749 | return BFA_STATUS_OK; | ||
| 2750 | } | ||
| 2751 | |||
| 2752 | /* | ||
| 2753 | * Update flash partition. | ||
| 2754 | * | ||
| 2755 | * @param[in] flash - flash structure | ||
| 2756 | * @param[in] type - flash partition type | ||
| 2757 | * @param[in] instance - flash partition instance | ||
| 2758 | * @param[in] buf - update data buffer | ||
| 2759 | * @param[in] len - data buffer length | ||
| 2760 | * @param[in] offset - offset relative to the partition starting address | ||
| 2761 | * @param[in] cbfn - callback function | ||
| 2762 | * @param[in] cbarg - callback argument | ||
| 2763 | * | ||
| 2764 | * Return status. | ||
| 2765 | */ | ||
| 2766 | enum bfa_status | ||
| 2767 | bfa_nw_flash_update_part(struct bfa_flash *flash, u32 type, u8 instance, | ||
| 2768 | void *buf, u32 len, u32 offset, | ||
| 2769 | bfa_cb_flash cbfn, void *cbarg) | ||
| 2770 | { | ||
| 2771 | if (!bfa_nw_ioc_is_operational(flash->ioc)) | ||
| 2772 | return BFA_STATUS_IOC_NON_OP; | ||
| 2773 | |||
| 2774 | /* | ||
| 2775 | * 'len' must be in word (4-byte) boundary | ||
| 2776 | */ | ||
| 2777 | if (!len || (len & 0x03)) | ||
| 2778 | return BFA_STATUS_FLASH_BAD_LEN; | ||
| 2779 | |||
| 2780 | if (type == BFA_FLASH_PART_MFG) | ||
| 2781 | return BFA_STATUS_EINVAL; | ||
| 2782 | |||
| 2783 | if (flash->op_busy) | ||
| 2784 | return BFA_STATUS_DEVBUSY; | ||
| 2785 | |||
| 2786 | flash->op_busy = 1; | ||
| 2787 | flash->cbfn = cbfn; | ||
| 2788 | flash->cbarg = cbarg; | ||
| 2789 | flash->type = type; | ||
| 2790 | flash->instance = instance; | ||
| 2791 | flash->residue = len; | ||
| 2792 | flash->offset = 0; | ||
| 2793 | flash->addr_off = offset; | ||
| 2794 | flash->ubuf = buf; | ||
| 2795 | |||
| 2796 | bfa_flash_write_send(flash); | ||
| 2797 | |||
| 2798 | return BFA_STATUS_OK; | ||
| 2799 | } | ||
| 2800 | |||
| 2801 | /* | ||
| 2802 | * Read flash partition. | ||
| 2803 | * | ||
| 2804 | * @param[in] flash - flash structure | ||
| 2805 | * @param[in] type - flash partition type | ||
| 2806 | * @param[in] instance - flash partition instance | ||
| 2807 | * @param[in] buf - read data buffer | ||
| 2808 | * @param[in] len - data buffer length | ||
| 2809 | * @param[in] offset - offset relative to the partition starting address | ||
| 2810 | * @param[in] cbfn - callback function | ||
| 2811 | * @param[in] cbarg - callback argument | ||
| 2812 | * | ||
| 2813 | * Return status. | ||
| 2814 | */ | ||
| 2815 | enum bfa_status | ||
| 2816 | bfa_nw_flash_read_part(struct bfa_flash *flash, u32 type, u8 instance, | ||
| 2817 | void *buf, u32 len, u32 offset, | ||
| 2818 | bfa_cb_flash cbfn, void *cbarg) | ||
| 2819 | { | ||
| 2820 | if (!bfa_nw_ioc_is_operational(flash->ioc)) | ||
| 2821 | return BFA_STATUS_IOC_NON_OP; | ||
| 2822 | |||
| 2823 | /* | ||
| 2824 | * 'len' must be in word (4-byte) boundary | ||
| 2825 | */ | ||
| 2826 | if (!len || (len & 0x03)) | ||
| 2827 | return BFA_STATUS_FLASH_BAD_LEN; | ||
| 2828 | |||
| 2829 | if (flash->op_busy) | ||
| 2830 | return BFA_STATUS_DEVBUSY; | ||
| 2831 | |||
| 2832 | flash->op_busy = 1; | ||
| 2833 | flash->cbfn = cbfn; | ||
| 2834 | flash->cbarg = cbarg; | ||
| 2835 | flash->type = type; | ||
| 2836 | flash->instance = instance; | ||
| 2837 | flash->residue = len; | ||
| 2838 | flash->offset = 0; | ||
| 2839 | flash->addr_off = offset; | ||
| 2840 | flash->ubuf = buf; | ||
| 2841 | |||
| 2842 | bfa_flash_read_send(flash); | ||
| 2843 | |||
| 2844 | return BFA_STATUS_OK; | ||
| 2845 | } | ||
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.h b/drivers/net/ethernet/brocade/bna/bfa_ioc.h index ca158d1eaef3..fc108c7a735e 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.h +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.h | |||
| @@ -68,6 +68,16 @@ __bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa) | |||
| 68 | dma_addr->a32.addr_hi = (u32) htonl(upper_32_bits(pa)); | 68 | dma_addr->a32.addr_hi = (u32) htonl(upper_32_bits(pa)); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | #define bfa_alen_set(__alen, __len, __pa) \ | ||
| 72 | __bfa_alen_set(__alen, __len, (u64)__pa) | ||
| 73 | |||
| 74 | static inline void | ||
| 75 | __bfa_alen_set(struct bfi_alen *alen, u32 len, u64 pa) | ||
| 76 | { | ||
| 77 | alen->al_len = cpu_to_be32(len); | ||
| 78 | bfa_dma_be_addr_set(alen->al_addr, pa); | ||
| 79 | } | ||
| 80 | |||
| 71 | struct bfa_ioc_regs { | 81 | struct bfa_ioc_regs { |
| 72 | void __iomem *hfn_mbox_cmd; | 82 | void __iomem *hfn_mbox_cmd; |
| 73 | void __iomem *hfn_mbox; | 83 | void __iomem *hfn_mbox; |
| @@ -322,4 +332,42 @@ void bfa_nw_iocpf_sem_timeout(void *ioc); | |||
| 322 | u32 *bfa_cb_image_get_chunk(enum bfi_asic_gen asic_gen, u32 off); | 332 | u32 *bfa_cb_image_get_chunk(enum bfi_asic_gen asic_gen, u32 off); |
| 323 | u32 bfa_cb_image_get_size(enum bfi_asic_gen asic_gen); | 333 | u32 bfa_cb_image_get_size(enum bfi_asic_gen asic_gen); |
| 324 | 334 | ||
| 335 | /* | ||
| 336 | * Flash module specific | ||
| 337 | */ | ||
| 338 | typedef void (*bfa_cb_flash) (void *cbarg, enum bfa_status status); | ||
| 339 | |||
| 340 | struct bfa_flash { | ||
| 341 | struct bfa_ioc *ioc; /* back pointer to ioc */ | ||
| 342 | u32 type; /* partition type */ | ||
| 343 | u8 instance; /* partition instance */ | ||
| 344 | u8 rsv[3]; | ||
| 345 | u32 op_busy; /* operation busy flag */ | ||
| 346 | u32 residue; /* residual length */ | ||
| 347 | u32 offset; /* offset */ | ||
| 348 | enum bfa_status status; /* status */ | ||
| 349 | u8 *dbuf_kva; /* dma buf virtual address */ | ||
| 350 | u64 dbuf_pa; /* dma buf physical address */ | ||
| 351 | bfa_cb_flash cbfn; /* user callback function */ | ||
| 352 | void *cbarg; /* user callback arg */ | ||
| 353 | u8 *ubuf; /* user supplied buffer */ | ||
| 354 | u32 addr_off; /* partition address offset */ | ||
| 355 | struct bfa_mbox_cmd mb; /* mailbox */ | ||
| 356 | struct bfa_ioc_notify ioc_notify; /* ioc event notify */ | ||
| 357 | }; | ||
| 358 | |||
| 359 | enum bfa_status bfa_nw_flash_get_attr(struct bfa_flash *flash, | ||
| 360 | struct bfa_flash_attr *attr, | ||
| 361 | bfa_cb_flash cbfn, void *cbarg); | ||
| 362 | enum bfa_status bfa_nw_flash_update_part(struct bfa_flash *flash, | ||
| 363 | u32 type, u8 instance, void *buf, u32 len, u32 offset, | ||
| 364 | bfa_cb_flash cbfn, void *cbarg); | ||
| 365 | enum bfa_status bfa_nw_flash_read_part(struct bfa_flash *flash, | ||
| 366 | u32 type, u8 instance, void *buf, u32 len, u32 offset, | ||
| 367 | bfa_cb_flash cbfn, void *cbarg); | ||
| 368 | u32 bfa_nw_flash_meminfo(void); | ||
| 369 | void bfa_nw_flash_attach(struct bfa_flash *flash, | ||
| 370 | struct bfa_ioc *ioc, void *dev); | ||
| 371 | void bfa_nw_flash_memclaim(struct bfa_flash *flash, u8 *dm_kva, u64 dm_pa); | ||
| 372 | |||
| 325 | #endif /* __BFA_IOC_H__ */ | 373 | #endif /* __BFA_IOC_H__ */ |
diff --git a/drivers/net/ethernet/brocade/bna/bfi.h b/drivers/net/ethernet/brocade/bna/bfi.h index 7a1393aabd43..8230970ad2d3 100644 --- a/drivers/net/ethernet/brocade/bna/bfi.h +++ b/drivers/net/ethernet/brocade/bna/bfi.h | |||
| @@ -83,6 +83,14 @@ union bfi_addr_u { | |||
| 83 | } a32; | 83 | } a32; |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | /** | ||
| 87 | * Generic DMA addr-len pair. | ||
| 88 | */ | ||
| 89 | struct bfi_alen { | ||
| 90 | union bfi_addr_u al_addr; /* DMA addr of buffer */ | ||
| 91 | u32 al_len; /* length of buffer */ | ||
| 92 | }; | ||
| 93 | |||
| 86 | /* | 94 | /* |
| 87 | * Large Message structure - 128 Bytes size Msgs | 95 | * Large Message structure - 128 Bytes size Msgs |
| 88 | */ | 96 | */ |
| @@ -476,6 +484,93 @@ struct bfi_msgq_i2h_cmdq_copy_req { | |||
| 476 | u16 len; | 484 | u16 len; |
| 477 | }; | 485 | }; |
| 478 | 486 | ||
| 487 | /* | ||
| 488 | * FLASH module specific | ||
| 489 | */ | ||
| 490 | enum bfi_flash_h2i_msgs { | ||
| 491 | BFI_FLASH_H2I_QUERY_REQ = 1, | ||
| 492 | BFI_FLASH_H2I_ERASE_REQ = 2, | ||
| 493 | BFI_FLASH_H2I_WRITE_REQ = 3, | ||
| 494 | BFI_FLASH_H2I_READ_REQ = 4, | ||
| 495 | BFI_FLASH_H2I_BOOT_VER_REQ = 5, | ||
| 496 | }; | ||
| 497 | |||
| 498 | enum bfi_flash_i2h_msgs { | ||
| 499 | BFI_FLASH_I2H_QUERY_RSP = BFA_I2HM(1), | ||
| 500 | BFI_FLASH_I2H_ERASE_RSP = BFA_I2HM(2), | ||
| 501 | BFI_FLASH_I2H_WRITE_RSP = BFA_I2HM(3), | ||
| 502 | BFI_FLASH_I2H_READ_RSP = BFA_I2HM(4), | ||
| 503 | BFI_FLASH_I2H_BOOT_VER_RSP = BFA_I2HM(5), | ||
| 504 | BFI_FLASH_I2H_EVENT = BFA_I2HM(127), | ||
| 505 | }; | ||
| 506 | |||
| 507 | /* | ||
| 508 | * Flash query request | ||
| 509 | */ | ||
| 510 | struct bfi_flash_query_req { | ||
| 511 | struct bfi_mhdr mh; /* Common msg header */ | ||
| 512 | struct bfi_alen alen; | ||
| 513 | }; | ||
| 514 | |||
| 515 | /* | ||
| 516 | * Flash write request | ||
| 517 | */ | ||
| 518 | struct bfi_flash_write_req { | ||
| 519 | struct bfi_mhdr mh; /* Common msg header */ | ||
| 520 | struct bfi_alen alen; | ||
| 521 | u32 type; /* partition type */ | ||
| 522 | u8 instance; /* partition instance */ | ||
| 523 | u8 last; | ||
| 524 | u8 rsv[2]; | ||
| 525 | u32 offset; | ||
| 526 | u32 length; | ||
| 527 | }; | ||
| 528 | |||
| 529 | /* | ||
| 530 | * Flash read request | ||
| 531 | */ | ||
| 532 | struct bfi_flash_read_req { | ||
| 533 | struct bfi_mhdr mh; /* Common msg header */ | ||
| 534 | u32 type; /* partition type */ | ||
| 535 | u8 instance; /* partition instance */ | ||
| 536 | u8 rsv[3]; | ||
| 537 | u32 offset; | ||
| 538 | u32 length; | ||
| 539 | struct bfi_alen alen; | ||
| 540 | }; | ||
| 541 | |||
| 542 | /* | ||
| 543 | * Flash query response | ||
| 544 | */ | ||
| 545 | struct bfi_flash_query_rsp { | ||
| 546 | struct bfi_mhdr mh; /* Common msg header */ | ||
| 547 | u32 status; | ||
| 548 | }; | ||
| 549 | |||
| 550 | /* | ||
| 551 | * Flash read response | ||
| 552 | */ | ||
| 553 | struct bfi_flash_read_rsp { | ||
| 554 | struct bfi_mhdr mh; /* Common msg header */ | ||
| 555 | u32 type; /* partition type */ | ||
| 556 | u8 instance; /* partition instance */ | ||
| 557 | u8 rsv[3]; | ||
| 558 | u32 status; | ||
| 559 | u32 length; | ||
| 560 | }; | ||
| 561 | |||
| 562 | /* | ||
| 563 | * Flash write response | ||
| 564 | */ | ||
| 565 | struct bfi_flash_write_rsp { | ||
| 566 | struct bfi_mhdr mh; /* Common msg header */ | ||
| 567 | u32 type; /* partition type */ | ||
| 568 | u8 instance; /* partition instance */ | ||
| 569 | u8 rsv[3]; | ||
| 570 | u32 status; | ||
| 571 | u32 length; | ||
| 572 | }; | ||
| 573 | |||
| 479 | #pragma pack() | 574 | #pragma pack() |
| 480 | 575 | ||
| 481 | #endif /* __BFI_H__ */ | 576 | #endif /* __BFI_H__ */ |
diff --git a/drivers/net/ethernet/brocade/bna/bna_enet.c b/drivers/net/ethernet/brocade/bna/bna_enet.c index 26f5c5abfd1f..bcfe29676677 100644 --- a/drivers/net/ethernet/brocade/bna/bna_enet.c +++ b/drivers/net/ethernet/brocade/bna/bna_enet.c | |||
| @@ -1740,6 +1740,11 @@ bna_ioceth_init(struct bna_ioceth *ioceth, struct bna *bna, | |||
| 1740 | kva += bfa_nw_cee_meminfo(); | 1740 | kva += bfa_nw_cee_meminfo(); |
| 1741 | dma += bfa_nw_cee_meminfo(); | 1741 | dma += bfa_nw_cee_meminfo(); |
| 1742 | 1742 | ||
| 1743 | bfa_nw_flash_attach(&bna->flash, &ioceth->ioc, bna); | ||
| 1744 | bfa_nw_flash_memclaim(&bna->flash, kva, dma); | ||
| 1745 | kva += bfa_nw_flash_meminfo(); | ||
| 1746 | dma += bfa_nw_flash_meminfo(); | ||
| 1747 | |||
| 1743 | bfa_msgq_attach(&bna->msgq, &ioceth->ioc); | 1748 | bfa_msgq_attach(&bna->msgq, &ioceth->ioc); |
| 1744 | bfa_msgq_memclaim(&bna->msgq, kva, dma); | 1749 | bfa_msgq_memclaim(&bna->msgq, kva, dma); |
| 1745 | bfa_msgq_regisr(&bna->msgq, BFI_MC_ENET, bna_msgq_rsp_handler, bna); | 1750 | bfa_msgq_regisr(&bna->msgq, BFI_MC_ENET, bna_msgq_rsp_handler, bna); |
| @@ -1892,7 +1897,8 @@ bna_res_req(struct bna_res_info *res_info) | |||
| 1892 | res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1; | 1897 | res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1; |
| 1893 | res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN( | 1898 | res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN( |
| 1894 | (bfa_nw_cee_meminfo() + | 1899 | (bfa_nw_cee_meminfo() + |
| 1895 | bfa_msgq_meminfo()), PAGE_SIZE); | 1900 | bfa_nw_flash_meminfo() + |
| 1901 | bfa_msgq_meminfo()), PAGE_SIZE); | ||
| 1896 | 1902 | ||
| 1897 | /* DMA memory for retrieving IOC attributes */ | 1903 | /* DMA memory for retrieving IOC attributes */ |
| 1898 | res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM; | 1904 | res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM; |
diff --git a/drivers/net/ethernet/brocade/bna/bna_types.h b/drivers/net/ethernet/brocade/bna/bna_types.h index d090fbfb12fa..8e57fc5c5868 100644 --- a/drivers/net/ethernet/brocade/bna/bna_types.h +++ b/drivers/net/ethernet/brocade/bna/bna_types.h | |||
| @@ -966,6 +966,7 @@ struct bna { | |||
| 966 | 966 | ||
| 967 | struct bna_ioceth ioceth; | 967 | struct bna_ioceth ioceth; |
| 968 | struct bfa_cee cee; | 968 | struct bfa_cee cee; |
| 969 | struct bfa_flash flash; | ||
| 969 | struct bfa_msgq msgq; | 970 | struct bfa_msgq msgq; |
| 970 | 971 | ||
| 971 | struct bna_ethport ethport; | 972 | struct bna_ethport ethport; |
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 197af04ff1ab..741f2e405006 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c | |||
| @@ -48,7 +48,9 @@ MODULE_PARM_DESC(bnad_ioc_auto_recover, "Enable / Disable auto recovery"); | |||
| 48 | * Global variables | 48 | * Global variables |
| 49 | */ | 49 | */ |
| 50 | u32 bnad_rxqs_per_cq = 2; | 50 | u32 bnad_rxqs_per_cq = 2; |
| 51 | 51 | u32 bna_id; | |
| 52 | struct mutex bnad_list_mutex; | ||
| 53 | LIST_HEAD(bnad_list); | ||
| 52 | static const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | 54 | static const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; |
| 53 | 55 | ||
| 54 | /* | 56 | /* |
| @@ -75,6 +77,23 @@ do { \ | |||
| 75 | 77 | ||
| 76 | #define BNAD_TXRX_SYNC_MDELAY 250 /* 250 msecs */ | 78 | #define BNAD_TXRX_SYNC_MDELAY 250 /* 250 msecs */ |
| 77 | 79 | ||
| 80 | static void | ||
| 81 | bnad_add_to_list(struct bnad *bnad) | ||
| 82 | { | ||
| 83 | mutex_lock(&bnad_list_mutex); | ||
| 84 | list_add_tail(&bnad->list_entry, &bnad_list); | ||
| 85 | bnad->id = bna_id++; | ||
| 86 | mutex_unlock(&bnad_list_mutex); | ||
| 87 | } | ||
| 88 | |||
| 89 | static void | ||
| 90 | bnad_remove_from_list(struct bnad *bnad) | ||
| 91 | { | ||
| 92 | mutex_lock(&bnad_list_mutex); | ||
| 93 | list_del(&bnad->list_entry); | ||
| 94 | mutex_unlock(&bnad_list_mutex); | ||
| 95 | } | ||
| 96 | |||
| 78 | /* | 97 | /* |
| 79 | * Reinitialize completions in CQ, once Rx is taken down | 98 | * Reinitialize completions in CQ, once Rx is taken down |
| 80 | */ | 99 | */ |
| @@ -1084,6 +1103,16 @@ bnad_cb_enet_mtu_set(struct bnad *bnad) | |||
| 1084 | complete(&bnad->bnad_completions.mtu_comp); | 1103 | complete(&bnad->bnad_completions.mtu_comp); |
| 1085 | } | 1104 | } |
| 1086 | 1105 | ||
| 1106 | void | ||
| 1107 | bnad_cb_completion(void *arg, enum bfa_status status) | ||
| 1108 | { | ||
| 1109 | struct bnad_iocmd_comp *iocmd_comp = | ||
| 1110 | (struct bnad_iocmd_comp *)arg; | ||
| 1111 | |||
| 1112 | iocmd_comp->comp_status = (u32) status; | ||
| 1113 | complete(&iocmd_comp->comp); | ||
| 1114 | } | ||
| 1115 | |||
| 1087 | /* Resource allocation, free functions */ | 1116 | /* Resource allocation, free functions */ |
| 1088 | 1117 | ||
| 1089 | static void | 1118 | static void |
| @@ -3167,12 +3196,14 @@ bnad_lock_init(struct bnad *bnad) | |||
| 3167 | { | 3196 | { |
| 3168 | spin_lock_init(&bnad->bna_lock); | 3197 | spin_lock_init(&bnad->bna_lock); |
| 3169 | mutex_init(&bnad->conf_mutex); | 3198 | mutex_init(&bnad->conf_mutex); |
| 3199 | mutex_init(&bnad_list_mutex); | ||
| 3170 | } | 3200 | } |
| 3171 | 3201 | ||
| 3172 | static void | 3202 | static void |
| 3173 | bnad_lock_uninit(struct bnad *bnad) | 3203 | bnad_lock_uninit(struct bnad *bnad) |
| 3174 | { | 3204 | { |
| 3175 | mutex_destroy(&bnad->conf_mutex); | 3205 | mutex_destroy(&bnad->conf_mutex); |
| 3206 | mutex_destroy(&bnad_list_mutex); | ||
| 3176 | } | 3207 | } |
| 3177 | 3208 | ||
| 3178 | /* PCI Initialization */ | 3209 | /* PCI Initialization */ |
| @@ -3253,8 +3284,8 @@ bnad_pci_probe(struct pci_dev *pdev, | |||
| 3253 | return err; | 3284 | return err; |
| 3254 | } | 3285 | } |
| 3255 | bnad = netdev_priv(netdev); | 3286 | bnad = netdev_priv(netdev); |
| 3256 | |||
| 3257 | bnad_lock_init(bnad); | 3287 | bnad_lock_init(bnad); |
| 3288 | bnad_add_to_list(bnad); | ||
| 3258 | 3289 | ||
| 3259 | mutex_lock(&bnad->conf_mutex); | 3290 | mutex_lock(&bnad->conf_mutex); |
| 3260 | /* | 3291 | /* |
| @@ -3407,6 +3438,7 @@ pci_uninit: | |||
| 3407 | bnad_pci_uninit(pdev); | 3438 | bnad_pci_uninit(pdev); |
| 3408 | unlock_mutex: | 3439 | unlock_mutex: |
| 3409 | mutex_unlock(&bnad->conf_mutex); | 3440 | mutex_unlock(&bnad->conf_mutex); |
| 3441 | bnad_remove_from_list(bnad); | ||
| 3410 | bnad_lock_uninit(bnad); | 3442 | bnad_lock_uninit(bnad); |
| 3411 | free_netdev(netdev); | 3443 | free_netdev(netdev); |
| 3412 | return err; | 3444 | return err; |
| @@ -3445,6 +3477,7 @@ bnad_pci_remove(struct pci_dev *pdev) | |||
| 3445 | bnad_disable_msix(bnad); | 3477 | bnad_disable_msix(bnad); |
| 3446 | bnad_pci_uninit(pdev); | 3478 | bnad_pci_uninit(pdev); |
| 3447 | mutex_unlock(&bnad->conf_mutex); | 3479 | mutex_unlock(&bnad->conf_mutex); |
| 3480 | bnad_remove_from_list(bnad); | ||
| 3448 | bnad_lock_uninit(bnad); | 3481 | bnad_lock_uninit(bnad); |
| 3449 | bnad_uninit(bnad); | 3482 | bnad_uninit(bnad); |
| 3450 | free_netdev(netdev); | 3483 | free_netdev(netdev); |
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h index 5487ca42d018..459030c191c5 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.h +++ b/drivers/net/ethernet/brocade/bna/bnad.h | |||
| @@ -124,6 +124,12 @@ enum bnad_link_state { | |||
| 124 | BNAD_LS_UP = 1 | 124 | BNAD_LS_UP = 1 |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | struct bnad_iocmd_comp { | ||
| 128 | struct bnad *bnad; | ||
| 129 | struct completion comp; | ||
| 130 | int comp_status; | ||
| 131 | }; | ||
| 132 | |||
| 127 | struct bnad_completion { | 133 | struct bnad_completion { |
| 128 | struct completion ioc_comp; | 134 | struct completion ioc_comp; |
| 129 | struct completion ucast_comp; | 135 | struct completion ucast_comp; |
| @@ -251,6 +257,8 @@ struct bnad_unmap_q { | |||
| 251 | 257 | ||
| 252 | struct bnad { | 258 | struct bnad { |
| 253 | struct net_device *netdev; | 259 | struct net_device *netdev; |
| 260 | u32 id; | ||
| 261 | struct list_head list_entry; | ||
| 254 | 262 | ||
| 255 | /* Data path */ | 263 | /* Data path */ |
| 256 | struct bnad_tx_info tx_info[BNAD_MAX_TX]; | 264 | struct bnad_tx_info tx_info[BNAD_MAX_TX]; |
| @@ -340,6 +348,7 @@ extern int bnad_mac_addr_set_locked(struct bnad *bnad, u8 *mac_addr); | |||
| 340 | extern int bnad_enable_default_bcast(struct bnad *bnad); | 348 | extern int bnad_enable_default_bcast(struct bnad *bnad); |
| 341 | extern void bnad_restore_vlans(struct bnad *bnad, u32 rx_id); | 349 | extern void bnad_restore_vlans(struct bnad *bnad, u32 rx_id); |
| 342 | extern void bnad_set_ethtool_ops(struct net_device *netdev); | 350 | extern void bnad_set_ethtool_ops(struct net_device *netdev); |
| 351 | extern void bnad_cb_completion(void *arg, enum bfa_status status); | ||
| 343 | 352 | ||
| 344 | /* Configuration & setup */ | 353 | /* Configuration & setup */ |
| 345 | extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad); | 354 | extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad); |
diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c index 38d5c66075f9..5f7be5ac32a1 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c +++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c | |||
| @@ -935,6 +935,143 @@ bnad_get_sset_count(struct net_device *netdev, int sset) | |||
| 935 | } | 935 | } |
| 936 | } | 936 | } |
| 937 | 937 | ||
| 938 | static u32 | ||
| 939 | bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset, | ||
| 940 | u32 *base_offset) | ||
| 941 | { | ||
| 942 | struct bfa_flash_attr *flash_attr; | ||
| 943 | struct bnad_iocmd_comp fcomp; | ||
| 944 | u32 i, flash_part = 0, ret; | ||
| 945 | unsigned long flags = 0; | ||
| 946 | |||
| 947 | flash_attr = kzalloc(sizeof(struct bfa_flash_attr), GFP_KERNEL); | ||
| 948 | if (!flash_attr) | ||
| 949 | return -ENOMEM; | ||
| 950 | |||
| 951 | fcomp.bnad = bnad; | ||
| 952 | fcomp.comp_status = 0; | ||
| 953 | |||
| 954 | init_completion(&fcomp.comp); | ||
| 955 | spin_lock_irqsave(&bnad->bna_lock, flags); | ||
| 956 | ret = bfa_nw_flash_get_attr(&bnad->bna.flash, flash_attr, | ||
| 957 | bnad_cb_completion, &fcomp); | ||
| 958 | if (ret != BFA_STATUS_OK) { | ||
| 959 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
| 960 | kfree(flash_attr); | ||
| 961 | goto out_err; | ||
| 962 | } | ||
| 963 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
| 964 | wait_for_completion(&fcomp.comp); | ||
| 965 | ret = fcomp.comp_status; | ||
| 966 | |||
| 967 | /* Check for the flash type & base offset value */ | ||
| 968 | if (ret == BFA_STATUS_OK) { | ||
| 969 | for (i = 0; i < flash_attr->npart; i++) { | ||
| 970 | if (offset >= flash_attr->part[i].part_off && | ||
| 971 | offset < (flash_attr->part[i].part_off + | ||
| 972 | flash_attr->part[i].part_size)) { | ||
| 973 | flash_part = flash_attr->part[i].part_type; | ||
| 974 | *base_offset = flash_attr->part[i].part_off; | ||
| 975 | break; | ||
| 976 | } | ||
| 977 | } | ||
| 978 | } | ||
| 979 | kfree(flash_attr); | ||
| 980 | return flash_part; | ||
| 981 | out_err: | ||
| 982 | return -EINVAL; | ||
| 983 | } | ||
| 984 | |||
| 985 | static int | ||
| 986 | bnad_get_eeprom_len(struct net_device *netdev) | ||
| 987 | { | ||
| 988 | return BFA_TOTAL_FLASH_SIZE; | ||
| 989 | } | ||
| 990 | |||
| 991 | static int | ||
| 992 | bnad_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, | ||
| 993 | u8 *bytes) | ||
| 994 | { | ||
| 995 | struct bnad *bnad = netdev_priv(netdev); | ||
| 996 | struct bnad_iocmd_comp fcomp; | ||
| 997 | u32 flash_part = 0, base_offset = 0; | ||
| 998 | unsigned long flags = 0; | ||
| 999 | int ret = 0; | ||
| 1000 | |||
| 1001 | /* Check if the flash read request is valid */ | ||
| 1002 | if (eeprom->magic != (bnad->pcidev->vendor | | ||
| 1003 | (bnad->pcidev->device << 16))) | ||
| 1004 | return -EFAULT; | ||
| 1005 | |||
| 1006 | /* Query the flash partition based on the offset */ | ||
| 1007 | flash_part = bnad_get_flash_partition_by_offset(bnad, | ||
| 1008 | eeprom->offset, &base_offset); | ||
| 1009 | if (flash_part <= 0) | ||
| 1010 | return -EFAULT; | ||
| 1011 | |||
| 1012 | fcomp.bnad = bnad; | ||
| 1013 | fcomp.comp_status = 0; | ||
| 1014 | |||
| 1015 | init_completion(&fcomp.comp); | ||
| 1016 | spin_lock_irqsave(&bnad->bna_lock, flags); | ||
| 1017 | ret = bfa_nw_flash_read_part(&bnad->bna.flash, flash_part, | ||
| 1018 | bnad->id, bytes, eeprom->len, | ||
| 1019 | eeprom->offset - base_offset, | ||
| 1020 | bnad_cb_completion, &fcomp); | ||
| 1021 | if (ret != BFA_STATUS_OK) { | ||
| 1022 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
| 1023 | goto done; | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
| 1027 | wait_for_completion(&fcomp.comp); | ||
| 1028 | ret = fcomp.comp_status; | ||
| 1029 | done: | ||
| 1030 | return ret; | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | static int | ||
| 1034 | bnad_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, | ||
| 1035 | u8 *bytes) | ||
| 1036 | { | ||
| 1037 | struct bnad *bnad = netdev_priv(netdev); | ||
| 1038 | struct bnad_iocmd_comp fcomp; | ||
| 1039 | u32 flash_part = 0, base_offset = 0; | ||
| 1040 | unsigned long flags = 0; | ||
| 1041 | int ret = 0; | ||
| 1042 | |||
| 1043 | /* Check if the flash update request is valid */ | ||
| 1044 | if (eeprom->magic != (bnad->pcidev->vendor | | ||
| 1045 | (bnad->pcidev->device << 16))) | ||
| 1046 | return -EINVAL; | ||
| 1047 | |||
| 1048 | /* Query the flash partition based on the offset */ | ||
| 1049 | flash_part = bnad_get_flash_partition_by_offset(bnad, | ||
| 1050 | eeprom->offset, &base_offset); | ||
| 1051 | if (flash_part <= 0) | ||
| 1052 | return -EFAULT; | ||
| 1053 | |||
| 1054 | fcomp.bnad = bnad; | ||
| 1055 | fcomp.comp_status = 0; | ||
| 1056 | |||
| 1057 | init_completion(&fcomp.comp); | ||
| 1058 | spin_lock_irqsave(&bnad->bna_lock, flags); | ||
| 1059 | ret = bfa_nw_flash_update_part(&bnad->bna.flash, flash_part, | ||
| 1060 | bnad->id, bytes, eeprom->len, | ||
| 1061 | eeprom->offset - base_offset, | ||
| 1062 | bnad_cb_completion, &fcomp); | ||
| 1063 | if (ret != BFA_STATUS_OK) { | ||
| 1064 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
| 1065 | goto done; | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
| 1069 | wait_for_completion(&fcomp.comp); | ||
| 1070 | ret = fcomp.comp_status; | ||
| 1071 | done: | ||
| 1072 | return ret; | ||
| 1073 | } | ||
| 1074 | |||
| 938 | static struct ethtool_ops bnad_ethtool_ops = { | 1075 | static struct ethtool_ops bnad_ethtool_ops = { |
| 939 | .get_settings = bnad_get_settings, | 1076 | .get_settings = bnad_get_settings, |
| 940 | .set_settings = bnad_set_settings, | 1077 | .set_settings = bnad_set_settings, |
| @@ -949,7 +1086,10 @@ static struct ethtool_ops bnad_ethtool_ops = { | |||
| 949 | .set_pauseparam = bnad_set_pauseparam, | 1086 | .set_pauseparam = bnad_set_pauseparam, |
| 950 | .get_strings = bnad_get_strings, | 1087 | .get_strings = bnad_get_strings, |
| 951 | .get_ethtool_stats = bnad_get_ethtool_stats, | 1088 | .get_ethtool_stats = bnad_get_ethtool_stats, |
| 952 | .get_sset_count = bnad_get_sset_count | 1089 | .get_sset_count = bnad_get_sset_count, |
| 1090 | .get_eeprom_len = bnad_get_eeprom_len, | ||
| 1091 | .get_eeprom = bnad_get_eeprom, | ||
| 1092 | .set_eeprom = bnad_set_eeprom, | ||
| 953 | }; | 1093 | }; |
| 954 | 1094 | ||
| 955 | void | 1095 | void |
