diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-12-22 08:29:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-23 16:50:58 -0500 |
commit | 72a9730b3f556e18912f3e1b494a7aee7ae3dd91 (patch) | |
tree | 1b589cb530e6cf5145a29c3423c176408c667033 /drivers/net/ethernet/brocade | |
parent | 6fc0d0f2e3bcbb4bfbc22a89c996e5905da4cc43 (diff) |
bna: Added flash sub-module and ethtool eeprom entry points.
Change details:
- The patch adds flash sub-module to the bna driver.
- Added ethtool set_eeprom() and get_eeprom() entry points to
support flash partition read/write operations.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/brocade')
-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 |