18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Linux network driver for QLogic BR-series Converged Network Adapter. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci/* 68c2ecf20Sopenharmony_ci * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. 78c2ecf20Sopenharmony_ci * Copyright (c) 2014-2015 QLogic Corporation 88c2ecf20Sopenharmony_ci * All rights reserved 98c2ecf20Sopenharmony_ci * www.qlogic.com 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci#include "bna.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistatic inline int 148c2ecf20Sopenharmony_ciethport_can_be_up(struct bna_ethport *ethport) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci int ready = 0; 178c2ecf20Sopenharmony_ci if (ethport->bna->enet.type == BNA_ENET_T_REGULAR) 188c2ecf20Sopenharmony_ci ready = ((ethport->flags & BNA_ETHPORT_F_ADMIN_UP) && 198c2ecf20Sopenharmony_ci (ethport->flags & BNA_ETHPORT_F_RX_STARTED) && 208c2ecf20Sopenharmony_ci (ethport->flags & BNA_ETHPORT_F_PORT_ENABLED)); 218c2ecf20Sopenharmony_ci else 228c2ecf20Sopenharmony_ci ready = ((ethport->flags & BNA_ETHPORT_F_ADMIN_UP) && 238c2ecf20Sopenharmony_ci (ethport->flags & BNA_ETHPORT_F_RX_STARTED) && 248c2ecf20Sopenharmony_ci !(ethport->flags & BNA_ETHPORT_F_PORT_ENABLED)); 258c2ecf20Sopenharmony_ci return ready; 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define ethport_is_up ethport_can_be_up 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cienum bna_ethport_event { 318c2ecf20Sopenharmony_ci ETHPORT_E_START = 1, 328c2ecf20Sopenharmony_ci ETHPORT_E_STOP = 2, 338c2ecf20Sopenharmony_ci ETHPORT_E_FAIL = 3, 348c2ecf20Sopenharmony_ci ETHPORT_E_UP = 4, 358c2ecf20Sopenharmony_ci ETHPORT_E_DOWN = 5, 368c2ecf20Sopenharmony_ci ETHPORT_E_FWRESP_UP_OK = 6, 378c2ecf20Sopenharmony_ci ETHPORT_E_FWRESP_DOWN = 7, 388c2ecf20Sopenharmony_ci ETHPORT_E_FWRESP_UP_FAIL = 8, 398c2ecf20Sopenharmony_ci}; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cienum bna_enet_event { 428c2ecf20Sopenharmony_ci ENET_E_START = 1, 438c2ecf20Sopenharmony_ci ENET_E_STOP = 2, 448c2ecf20Sopenharmony_ci ENET_E_FAIL = 3, 458c2ecf20Sopenharmony_ci ENET_E_PAUSE_CFG = 4, 468c2ecf20Sopenharmony_ci ENET_E_MTU_CFG = 5, 478c2ecf20Sopenharmony_ci ENET_E_FWRESP_PAUSE = 6, 488c2ecf20Sopenharmony_ci ENET_E_CHLD_STOPPED = 7, 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cienum bna_ioceth_event { 528c2ecf20Sopenharmony_ci IOCETH_E_ENABLE = 1, 538c2ecf20Sopenharmony_ci IOCETH_E_DISABLE = 2, 548c2ecf20Sopenharmony_ci IOCETH_E_IOC_RESET = 3, 558c2ecf20Sopenharmony_ci IOCETH_E_IOC_FAILED = 4, 568c2ecf20Sopenharmony_ci IOCETH_E_IOC_READY = 5, 578c2ecf20Sopenharmony_ci IOCETH_E_ENET_ATTR_RESP = 6, 588c2ecf20Sopenharmony_ci IOCETH_E_ENET_STOPPED = 7, 598c2ecf20Sopenharmony_ci IOCETH_E_IOC_DISABLED = 8, 608c2ecf20Sopenharmony_ci}; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci#define bna_stats_copy(_name, _type) \ 638c2ecf20Sopenharmony_cido { \ 648c2ecf20Sopenharmony_ci count = sizeof(struct bfi_enet_stats_ ## _type) / sizeof(u64); \ 658c2ecf20Sopenharmony_ci stats_src = (u64 *)&bna->stats.hw_stats_kva->_name ## _stats; \ 668c2ecf20Sopenharmony_ci stats_dst = (u64 *)&bna->stats.hw_stats._name ## _stats; \ 678c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) \ 688c2ecf20Sopenharmony_ci stats_dst[i] = be64_to_cpu(stats_src[i]); \ 698c2ecf20Sopenharmony_ci} while (0) \ 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* 728c2ecf20Sopenharmony_ci * FW response handlers 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic void 768c2ecf20Sopenharmony_cibna_bfi_ethport_enable_aen(struct bna_ethport *ethport, 778c2ecf20Sopenharmony_ci struct bfi_msgq_mhdr *msghdr) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci ethport->flags |= BNA_ETHPORT_F_PORT_ENABLED; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci if (ethport_can_be_up(ethport)) 828c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_UP); 838c2ecf20Sopenharmony_ci} 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic void 868c2ecf20Sopenharmony_cibna_bfi_ethport_disable_aen(struct bna_ethport *ethport, 878c2ecf20Sopenharmony_ci struct bfi_msgq_mhdr *msghdr) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci int ethport_up = ethport_is_up(ethport); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci if (ethport_up) 948c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_DOWN); 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_cistatic void 988c2ecf20Sopenharmony_cibna_bfi_ethport_admin_rsp(struct bna_ethport *ethport, 998c2ecf20Sopenharmony_ci struct bfi_msgq_mhdr *msghdr) 1008c2ecf20Sopenharmony_ci{ 1018c2ecf20Sopenharmony_ci struct bfi_enet_enable_req *admin_req = 1028c2ecf20Sopenharmony_ci ðport->bfi_enet_cmd.admin_req; 1038c2ecf20Sopenharmony_ci struct bfi_enet_rsp *rsp = 1048c2ecf20Sopenharmony_ci container_of(msghdr, struct bfi_enet_rsp, mh); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci switch (admin_req->enable) { 1078c2ecf20Sopenharmony_ci case BNA_STATUS_T_ENABLED: 1088c2ecf20Sopenharmony_ci if (rsp->error == BFI_ENET_CMD_OK) 1098c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_OK); 1108c2ecf20Sopenharmony_ci else { 1118c2ecf20Sopenharmony_ci ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED; 1128c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_FAIL); 1138c2ecf20Sopenharmony_ci } 1148c2ecf20Sopenharmony_ci break; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci case BNA_STATUS_T_DISABLED: 1178c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_DOWN); 1188c2ecf20Sopenharmony_ci ethport->link_status = BNA_LINK_DOWN; 1198c2ecf20Sopenharmony_ci ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN); 1208c2ecf20Sopenharmony_ci break; 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic void 1258c2ecf20Sopenharmony_cibna_bfi_ethport_lpbk_rsp(struct bna_ethport *ethport, 1268c2ecf20Sopenharmony_ci struct bfi_msgq_mhdr *msghdr) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci struct bfi_enet_diag_lb_req *diag_lb_req = 1298c2ecf20Sopenharmony_ci ðport->bfi_enet_cmd.lpbk_req; 1308c2ecf20Sopenharmony_ci struct bfi_enet_rsp *rsp = 1318c2ecf20Sopenharmony_ci container_of(msghdr, struct bfi_enet_rsp, mh); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci switch (diag_lb_req->enable) { 1348c2ecf20Sopenharmony_ci case BNA_STATUS_T_ENABLED: 1358c2ecf20Sopenharmony_ci if (rsp->error == BFI_ENET_CMD_OK) 1368c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_OK); 1378c2ecf20Sopenharmony_ci else { 1388c2ecf20Sopenharmony_ci ethport->flags &= ~BNA_ETHPORT_F_ADMIN_UP; 1398c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_UP_FAIL); 1408c2ecf20Sopenharmony_ci } 1418c2ecf20Sopenharmony_ci break; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci case BNA_STATUS_T_DISABLED: 1448c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_FWRESP_DOWN); 1458c2ecf20Sopenharmony_ci break; 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci} 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_cistatic void 1508c2ecf20Sopenharmony_cibna_bfi_pause_set_rsp(struct bna_enet *enet, struct bfi_msgq_mhdr *msghdr) 1518c2ecf20Sopenharmony_ci{ 1528c2ecf20Sopenharmony_ci bfa_fsm_send_event(enet, ENET_E_FWRESP_PAUSE); 1538c2ecf20Sopenharmony_ci} 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cistatic void 1568c2ecf20Sopenharmony_cibna_bfi_attr_get_rsp(struct bna_ioceth *ioceth, 1578c2ecf20Sopenharmony_ci struct bfi_msgq_mhdr *msghdr) 1588c2ecf20Sopenharmony_ci{ 1598c2ecf20Sopenharmony_ci struct bfi_enet_attr_rsp *rsp = 1608c2ecf20Sopenharmony_ci container_of(msghdr, struct bfi_enet_attr_rsp, mh); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci /** 1638c2ecf20Sopenharmony_ci * Store only if not set earlier, since BNAD can override the HW 1648c2ecf20Sopenharmony_ci * attributes 1658c2ecf20Sopenharmony_ci */ 1668c2ecf20Sopenharmony_ci if (!ioceth->attr.fw_query_complete) { 1678c2ecf20Sopenharmony_ci ioceth->attr.num_txq = ntohl(rsp->max_cfg); 1688c2ecf20Sopenharmony_ci ioceth->attr.num_rxp = ntohl(rsp->max_cfg); 1698c2ecf20Sopenharmony_ci ioceth->attr.num_ucmac = ntohl(rsp->max_ucmac); 1708c2ecf20Sopenharmony_ci ioceth->attr.num_mcmac = BFI_ENET_MAX_MCAM; 1718c2ecf20Sopenharmony_ci ioceth->attr.max_rit_size = ntohl(rsp->rit_size); 1728c2ecf20Sopenharmony_ci ioceth->attr.fw_query_complete = true; 1738c2ecf20Sopenharmony_ci } 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci bfa_fsm_send_event(ioceth, IOCETH_E_ENET_ATTR_RESP); 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic void 1798c2ecf20Sopenharmony_cibna_bfi_stats_get_rsp(struct bna *bna, struct bfi_msgq_mhdr *msghdr) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci struct bfi_enet_stats_req *stats_req = &bna->stats_mod.stats_get; 1828c2ecf20Sopenharmony_ci u64 *stats_src; 1838c2ecf20Sopenharmony_ci u64 *stats_dst; 1848c2ecf20Sopenharmony_ci u32 tx_enet_mask = ntohl(stats_req->tx_enet_mask); 1858c2ecf20Sopenharmony_ci u32 rx_enet_mask = ntohl(stats_req->rx_enet_mask); 1868c2ecf20Sopenharmony_ci int count; 1878c2ecf20Sopenharmony_ci int i; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci bna_stats_copy(mac, mac); 1908c2ecf20Sopenharmony_ci bna_stats_copy(bpc, bpc); 1918c2ecf20Sopenharmony_ci bna_stats_copy(rad, rad); 1928c2ecf20Sopenharmony_ci bna_stats_copy(rlb, rad); 1938c2ecf20Sopenharmony_ci bna_stats_copy(fc_rx, fc_rx); 1948c2ecf20Sopenharmony_ci bna_stats_copy(fc_tx, fc_tx); 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci stats_src = (u64 *)&(bna->stats.hw_stats_kva->rxf_stats[0]); 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci /* Copy Rxf stats to SW area, scatter them while copying */ 1998c2ecf20Sopenharmony_ci for (i = 0; i < BFI_ENET_CFG_MAX; i++) { 2008c2ecf20Sopenharmony_ci stats_dst = (u64 *)&(bna->stats.hw_stats.rxf_stats[i]); 2018c2ecf20Sopenharmony_ci memset(stats_dst, 0, sizeof(struct bfi_enet_stats_rxf)); 2028c2ecf20Sopenharmony_ci if (rx_enet_mask & BIT(i)) { 2038c2ecf20Sopenharmony_ci int k; 2048c2ecf20Sopenharmony_ci count = sizeof(struct bfi_enet_stats_rxf) / 2058c2ecf20Sopenharmony_ci sizeof(u64); 2068c2ecf20Sopenharmony_ci for (k = 0; k < count; k++) { 2078c2ecf20Sopenharmony_ci stats_dst[k] = be64_to_cpu(*stats_src); 2088c2ecf20Sopenharmony_ci stats_src++; 2098c2ecf20Sopenharmony_ci } 2108c2ecf20Sopenharmony_ci } 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci /* Copy Txf stats to SW area, scatter them while copying */ 2148c2ecf20Sopenharmony_ci for (i = 0; i < BFI_ENET_CFG_MAX; i++) { 2158c2ecf20Sopenharmony_ci stats_dst = (u64 *)&(bna->stats.hw_stats.txf_stats[i]); 2168c2ecf20Sopenharmony_ci memset(stats_dst, 0, sizeof(struct bfi_enet_stats_txf)); 2178c2ecf20Sopenharmony_ci if (tx_enet_mask & BIT(i)) { 2188c2ecf20Sopenharmony_ci int k; 2198c2ecf20Sopenharmony_ci count = sizeof(struct bfi_enet_stats_txf) / 2208c2ecf20Sopenharmony_ci sizeof(u64); 2218c2ecf20Sopenharmony_ci for (k = 0; k < count; k++) { 2228c2ecf20Sopenharmony_ci stats_dst[k] = be64_to_cpu(*stats_src); 2238c2ecf20Sopenharmony_ci stats_src++; 2248c2ecf20Sopenharmony_ci } 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci } 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci bna->stats_mod.stats_get_busy = false; 2298c2ecf20Sopenharmony_ci bnad_cb_stats_get(bna->bnad, BNA_CB_SUCCESS, &bna->stats); 2308c2ecf20Sopenharmony_ci} 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_cistatic void 2338c2ecf20Sopenharmony_cibna_bfi_ethport_linkup_aen(struct bna_ethport *ethport, 2348c2ecf20Sopenharmony_ci struct bfi_msgq_mhdr *msghdr) 2358c2ecf20Sopenharmony_ci{ 2368c2ecf20Sopenharmony_ci ethport->link_status = BNA_LINK_UP; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci /* Dispatch events */ 2398c2ecf20Sopenharmony_ci ethport->link_cbfn(ethport->bna->bnad, ethport->link_status); 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic void 2438c2ecf20Sopenharmony_cibna_bfi_ethport_linkdown_aen(struct bna_ethport *ethport, 2448c2ecf20Sopenharmony_ci struct bfi_msgq_mhdr *msghdr) 2458c2ecf20Sopenharmony_ci{ 2468c2ecf20Sopenharmony_ci ethport->link_status = BNA_LINK_DOWN; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci /* Dispatch events */ 2498c2ecf20Sopenharmony_ci ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN); 2508c2ecf20Sopenharmony_ci} 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic void 2538c2ecf20Sopenharmony_cibna_err_handler(struct bna *bna, u32 intr_status) 2548c2ecf20Sopenharmony_ci{ 2558c2ecf20Sopenharmony_ci if (BNA_IS_HALT_INTR(bna, intr_status)) 2568c2ecf20Sopenharmony_ci bna_halt_clear(bna); 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci bfa_nw_ioc_error_isr(&bna->ioceth.ioc); 2598c2ecf20Sopenharmony_ci} 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_civoid 2628c2ecf20Sopenharmony_cibna_mbox_handler(struct bna *bna, u32 intr_status) 2638c2ecf20Sopenharmony_ci{ 2648c2ecf20Sopenharmony_ci if (BNA_IS_ERR_INTR(bna, intr_status)) { 2658c2ecf20Sopenharmony_ci bna_err_handler(bna, intr_status); 2668c2ecf20Sopenharmony_ci return; 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci if (BNA_IS_MBOX_INTR(bna, intr_status)) 2698c2ecf20Sopenharmony_ci bfa_nw_ioc_mbox_isr(&bna->ioceth.ioc); 2708c2ecf20Sopenharmony_ci} 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_cistatic void 2738c2ecf20Sopenharmony_cibna_msgq_rsp_handler(void *arg, struct bfi_msgq_mhdr *msghdr) 2748c2ecf20Sopenharmony_ci{ 2758c2ecf20Sopenharmony_ci struct bna *bna = (struct bna *)arg; 2768c2ecf20Sopenharmony_ci struct bna_tx *tx; 2778c2ecf20Sopenharmony_ci struct bna_rx *rx; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci switch (msghdr->msg_id) { 2808c2ecf20Sopenharmony_ci case BFI_ENET_I2H_RX_CFG_SET_RSP: 2818c2ecf20Sopenharmony_ci bna_rx_from_rid(bna, msghdr->enet_id, rx); 2828c2ecf20Sopenharmony_ci if (rx) 2838c2ecf20Sopenharmony_ci bna_bfi_rx_enet_start_rsp(rx, msghdr); 2848c2ecf20Sopenharmony_ci break; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci case BFI_ENET_I2H_RX_CFG_CLR_RSP: 2878c2ecf20Sopenharmony_ci bna_rx_from_rid(bna, msghdr->enet_id, rx); 2888c2ecf20Sopenharmony_ci if (rx) 2898c2ecf20Sopenharmony_ci bna_bfi_rx_enet_stop_rsp(rx, msghdr); 2908c2ecf20Sopenharmony_ci break; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci case BFI_ENET_I2H_RIT_CFG_RSP: 2938c2ecf20Sopenharmony_ci case BFI_ENET_I2H_RSS_CFG_RSP: 2948c2ecf20Sopenharmony_ci case BFI_ENET_I2H_RSS_ENABLE_RSP: 2958c2ecf20Sopenharmony_ci case BFI_ENET_I2H_RX_PROMISCUOUS_RSP: 2968c2ecf20Sopenharmony_ci case BFI_ENET_I2H_RX_DEFAULT_RSP: 2978c2ecf20Sopenharmony_ci case BFI_ENET_I2H_MAC_UCAST_CLR_RSP: 2988c2ecf20Sopenharmony_ci case BFI_ENET_I2H_MAC_UCAST_ADD_RSP: 2998c2ecf20Sopenharmony_ci case BFI_ENET_I2H_MAC_UCAST_DEL_RSP: 3008c2ecf20Sopenharmony_ci case BFI_ENET_I2H_MAC_MCAST_DEL_RSP: 3018c2ecf20Sopenharmony_ci case BFI_ENET_I2H_MAC_MCAST_FILTER_RSP: 3028c2ecf20Sopenharmony_ci case BFI_ENET_I2H_RX_VLAN_SET_RSP: 3038c2ecf20Sopenharmony_ci case BFI_ENET_I2H_RX_VLAN_STRIP_ENABLE_RSP: 3048c2ecf20Sopenharmony_ci bna_rx_from_rid(bna, msghdr->enet_id, rx); 3058c2ecf20Sopenharmony_ci if (rx) 3068c2ecf20Sopenharmony_ci bna_bfi_rxf_cfg_rsp(&rx->rxf, msghdr); 3078c2ecf20Sopenharmony_ci break; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci case BFI_ENET_I2H_MAC_UCAST_SET_RSP: 3108c2ecf20Sopenharmony_ci bna_rx_from_rid(bna, msghdr->enet_id, rx); 3118c2ecf20Sopenharmony_ci if (rx) 3128c2ecf20Sopenharmony_ci bna_bfi_rxf_ucast_set_rsp(&rx->rxf, msghdr); 3138c2ecf20Sopenharmony_ci break; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci case BFI_ENET_I2H_MAC_MCAST_ADD_RSP: 3168c2ecf20Sopenharmony_ci bna_rx_from_rid(bna, msghdr->enet_id, rx); 3178c2ecf20Sopenharmony_ci if (rx) 3188c2ecf20Sopenharmony_ci bna_bfi_rxf_mcast_add_rsp(&rx->rxf, msghdr); 3198c2ecf20Sopenharmony_ci break; 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci case BFI_ENET_I2H_TX_CFG_SET_RSP: 3228c2ecf20Sopenharmony_ci bna_tx_from_rid(bna, msghdr->enet_id, tx); 3238c2ecf20Sopenharmony_ci if (tx) 3248c2ecf20Sopenharmony_ci bna_bfi_tx_enet_start_rsp(tx, msghdr); 3258c2ecf20Sopenharmony_ci break; 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci case BFI_ENET_I2H_TX_CFG_CLR_RSP: 3288c2ecf20Sopenharmony_ci bna_tx_from_rid(bna, msghdr->enet_id, tx); 3298c2ecf20Sopenharmony_ci if (tx) 3308c2ecf20Sopenharmony_ci bna_bfi_tx_enet_stop_rsp(tx, msghdr); 3318c2ecf20Sopenharmony_ci break; 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci case BFI_ENET_I2H_PORT_ADMIN_RSP: 3348c2ecf20Sopenharmony_ci bna_bfi_ethport_admin_rsp(&bna->ethport, msghdr); 3358c2ecf20Sopenharmony_ci break; 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci case BFI_ENET_I2H_DIAG_LOOPBACK_RSP: 3388c2ecf20Sopenharmony_ci bna_bfi_ethport_lpbk_rsp(&bna->ethport, msghdr); 3398c2ecf20Sopenharmony_ci break; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci case BFI_ENET_I2H_SET_PAUSE_RSP: 3428c2ecf20Sopenharmony_ci bna_bfi_pause_set_rsp(&bna->enet, msghdr); 3438c2ecf20Sopenharmony_ci break; 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci case BFI_ENET_I2H_GET_ATTR_RSP: 3468c2ecf20Sopenharmony_ci bna_bfi_attr_get_rsp(&bna->ioceth, msghdr); 3478c2ecf20Sopenharmony_ci break; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci case BFI_ENET_I2H_STATS_GET_RSP: 3508c2ecf20Sopenharmony_ci bna_bfi_stats_get_rsp(bna, msghdr); 3518c2ecf20Sopenharmony_ci break; 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci case BFI_ENET_I2H_STATS_CLR_RSP: 3548c2ecf20Sopenharmony_ci /* No-op */ 3558c2ecf20Sopenharmony_ci break; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci case BFI_ENET_I2H_LINK_UP_AEN: 3588c2ecf20Sopenharmony_ci bna_bfi_ethport_linkup_aen(&bna->ethport, msghdr); 3598c2ecf20Sopenharmony_ci break; 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci case BFI_ENET_I2H_LINK_DOWN_AEN: 3628c2ecf20Sopenharmony_ci bna_bfi_ethport_linkdown_aen(&bna->ethport, msghdr); 3638c2ecf20Sopenharmony_ci break; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci case BFI_ENET_I2H_PORT_ENABLE_AEN: 3668c2ecf20Sopenharmony_ci bna_bfi_ethport_enable_aen(&bna->ethport, msghdr); 3678c2ecf20Sopenharmony_ci break; 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci case BFI_ENET_I2H_PORT_DISABLE_AEN: 3708c2ecf20Sopenharmony_ci bna_bfi_ethport_disable_aen(&bna->ethport, msghdr); 3718c2ecf20Sopenharmony_ci break; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci case BFI_ENET_I2H_BW_UPDATE_AEN: 3748c2ecf20Sopenharmony_ci bna_bfi_bw_update_aen(&bna->tx_mod); 3758c2ecf20Sopenharmony_ci break; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci default: 3788c2ecf20Sopenharmony_ci break; 3798c2ecf20Sopenharmony_ci } 3808c2ecf20Sopenharmony_ci} 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci/* ETHPORT */ 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci#define call_ethport_stop_cbfn(_ethport) \ 3858c2ecf20Sopenharmony_cido { \ 3868c2ecf20Sopenharmony_ci if ((_ethport)->stop_cbfn) { \ 3878c2ecf20Sopenharmony_ci void (*cbfn)(struct bna_enet *); \ 3888c2ecf20Sopenharmony_ci cbfn = (_ethport)->stop_cbfn; \ 3898c2ecf20Sopenharmony_ci (_ethport)->stop_cbfn = NULL; \ 3908c2ecf20Sopenharmony_ci cbfn(&(_ethport)->bna->enet); \ 3918c2ecf20Sopenharmony_ci } \ 3928c2ecf20Sopenharmony_ci} while (0) 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci#define call_ethport_adminup_cbfn(ethport, status) \ 3958c2ecf20Sopenharmony_cido { \ 3968c2ecf20Sopenharmony_ci if ((ethport)->adminup_cbfn) { \ 3978c2ecf20Sopenharmony_ci void (*cbfn)(struct bnad *, enum bna_cb_status); \ 3988c2ecf20Sopenharmony_ci cbfn = (ethport)->adminup_cbfn; \ 3998c2ecf20Sopenharmony_ci (ethport)->adminup_cbfn = NULL; \ 4008c2ecf20Sopenharmony_ci cbfn((ethport)->bna->bnad, status); \ 4018c2ecf20Sopenharmony_ci } \ 4028c2ecf20Sopenharmony_ci} while (0) 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_cistatic void 4058c2ecf20Sopenharmony_cibna_bfi_ethport_admin_up(struct bna_ethport *ethport) 4068c2ecf20Sopenharmony_ci{ 4078c2ecf20Sopenharmony_ci struct bfi_enet_enable_req *admin_up_req = 4088c2ecf20Sopenharmony_ci ðport->bfi_enet_cmd.admin_req; 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_ci bfi_msgq_mhdr_set(admin_up_req->mh, BFI_MC_ENET, 4118c2ecf20Sopenharmony_ci BFI_ENET_H2I_PORT_ADMIN_UP_REQ, 0, 0); 4128c2ecf20Sopenharmony_ci admin_up_req->mh.num_entries = htons( 4138c2ecf20Sopenharmony_ci bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req))); 4148c2ecf20Sopenharmony_ci admin_up_req->enable = BNA_STATUS_T_ENABLED; 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_ci bfa_msgq_cmd_set(ðport->msgq_cmd, NULL, NULL, 4178c2ecf20Sopenharmony_ci sizeof(struct bfi_enet_enable_req), &admin_up_req->mh); 4188c2ecf20Sopenharmony_ci bfa_msgq_cmd_post(ðport->bna->msgq, ðport->msgq_cmd); 4198c2ecf20Sopenharmony_ci} 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_cistatic void 4228c2ecf20Sopenharmony_cibna_bfi_ethport_admin_down(struct bna_ethport *ethport) 4238c2ecf20Sopenharmony_ci{ 4248c2ecf20Sopenharmony_ci struct bfi_enet_enable_req *admin_down_req = 4258c2ecf20Sopenharmony_ci ðport->bfi_enet_cmd.admin_req; 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci bfi_msgq_mhdr_set(admin_down_req->mh, BFI_MC_ENET, 4288c2ecf20Sopenharmony_ci BFI_ENET_H2I_PORT_ADMIN_UP_REQ, 0, 0); 4298c2ecf20Sopenharmony_ci admin_down_req->mh.num_entries = htons( 4308c2ecf20Sopenharmony_ci bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_enable_req))); 4318c2ecf20Sopenharmony_ci admin_down_req->enable = BNA_STATUS_T_DISABLED; 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci bfa_msgq_cmd_set(ðport->msgq_cmd, NULL, NULL, 4348c2ecf20Sopenharmony_ci sizeof(struct bfi_enet_enable_req), &admin_down_req->mh); 4358c2ecf20Sopenharmony_ci bfa_msgq_cmd_post(ðport->bna->msgq, ðport->msgq_cmd); 4368c2ecf20Sopenharmony_ci} 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_cistatic void 4398c2ecf20Sopenharmony_cibna_bfi_ethport_lpbk_up(struct bna_ethport *ethport) 4408c2ecf20Sopenharmony_ci{ 4418c2ecf20Sopenharmony_ci struct bfi_enet_diag_lb_req *lpbk_up_req = 4428c2ecf20Sopenharmony_ci ðport->bfi_enet_cmd.lpbk_req; 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci bfi_msgq_mhdr_set(lpbk_up_req->mh, BFI_MC_ENET, 4458c2ecf20Sopenharmony_ci BFI_ENET_H2I_DIAG_LOOPBACK_REQ, 0, 0); 4468c2ecf20Sopenharmony_ci lpbk_up_req->mh.num_entries = htons( 4478c2ecf20Sopenharmony_ci bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_diag_lb_req))); 4488c2ecf20Sopenharmony_ci lpbk_up_req->mode = (ethport->bna->enet.type == 4498c2ecf20Sopenharmony_ci BNA_ENET_T_LOOPBACK_INTERNAL) ? 4508c2ecf20Sopenharmony_ci BFI_ENET_DIAG_LB_OPMODE_EXT : 4518c2ecf20Sopenharmony_ci BFI_ENET_DIAG_LB_OPMODE_CBL; 4528c2ecf20Sopenharmony_ci lpbk_up_req->enable = BNA_STATUS_T_ENABLED; 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci bfa_msgq_cmd_set(ðport->msgq_cmd, NULL, NULL, 4558c2ecf20Sopenharmony_ci sizeof(struct bfi_enet_diag_lb_req), &lpbk_up_req->mh); 4568c2ecf20Sopenharmony_ci bfa_msgq_cmd_post(ðport->bna->msgq, ðport->msgq_cmd); 4578c2ecf20Sopenharmony_ci} 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_cistatic void 4608c2ecf20Sopenharmony_cibna_bfi_ethport_lpbk_down(struct bna_ethport *ethport) 4618c2ecf20Sopenharmony_ci{ 4628c2ecf20Sopenharmony_ci struct bfi_enet_diag_lb_req *lpbk_down_req = 4638c2ecf20Sopenharmony_ci ðport->bfi_enet_cmd.lpbk_req; 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci bfi_msgq_mhdr_set(lpbk_down_req->mh, BFI_MC_ENET, 4668c2ecf20Sopenharmony_ci BFI_ENET_H2I_DIAG_LOOPBACK_REQ, 0, 0); 4678c2ecf20Sopenharmony_ci lpbk_down_req->mh.num_entries = htons( 4688c2ecf20Sopenharmony_ci bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_diag_lb_req))); 4698c2ecf20Sopenharmony_ci lpbk_down_req->enable = BNA_STATUS_T_DISABLED; 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci bfa_msgq_cmd_set(ðport->msgq_cmd, NULL, NULL, 4728c2ecf20Sopenharmony_ci sizeof(struct bfi_enet_diag_lb_req), &lpbk_down_req->mh); 4738c2ecf20Sopenharmony_ci bfa_msgq_cmd_post(ðport->bna->msgq, ðport->msgq_cmd); 4748c2ecf20Sopenharmony_ci} 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_cistatic void 4778c2ecf20Sopenharmony_cibna_bfi_ethport_up(struct bna_ethport *ethport) 4788c2ecf20Sopenharmony_ci{ 4798c2ecf20Sopenharmony_ci if (ethport->bna->enet.type == BNA_ENET_T_REGULAR) 4808c2ecf20Sopenharmony_ci bna_bfi_ethport_admin_up(ethport); 4818c2ecf20Sopenharmony_ci else 4828c2ecf20Sopenharmony_ci bna_bfi_ethport_lpbk_up(ethport); 4838c2ecf20Sopenharmony_ci} 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_cistatic void 4868c2ecf20Sopenharmony_cibna_bfi_ethport_down(struct bna_ethport *ethport) 4878c2ecf20Sopenharmony_ci{ 4888c2ecf20Sopenharmony_ci if (ethport->bna->enet.type == BNA_ENET_T_REGULAR) 4898c2ecf20Sopenharmony_ci bna_bfi_ethport_admin_down(ethport); 4908c2ecf20Sopenharmony_ci else 4918c2ecf20Sopenharmony_ci bna_bfi_ethport_lpbk_down(ethport); 4928c2ecf20Sopenharmony_ci} 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ethport, stopped, struct bna_ethport, 4958c2ecf20Sopenharmony_ci enum bna_ethport_event); 4968c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ethport, down, struct bna_ethport, 4978c2ecf20Sopenharmony_ci enum bna_ethport_event); 4988c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ethport, up_resp_wait, struct bna_ethport, 4998c2ecf20Sopenharmony_ci enum bna_ethport_event); 5008c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ethport, down_resp_wait, struct bna_ethport, 5018c2ecf20Sopenharmony_ci enum bna_ethport_event); 5028c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ethport, up, struct bna_ethport, 5038c2ecf20Sopenharmony_ci enum bna_ethport_event); 5048c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ethport, last_resp_wait, struct bna_ethport, 5058c2ecf20Sopenharmony_ci enum bna_ethport_event); 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_cistatic void 5088c2ecf20Sopenharmony_cibna_ethport_sm_stopped_entry(struct bna_ethport *ethport) 5098c2ecf20Sopenharmony_ci{ 5108c2ecf20Sopenharmony_ci call_ethport_stop_cbfn(ethport); 5118c2ecf20Sopenharmony_ci} 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_cistatic void 5148c2ecf20Sopenharmony_cibna_ethport_sm_stopped(struct bna_ethport *ethport, 5158c2ecf20Sopenharmony_ci enum bna_ethport_event event) 5168c2ecf20Sopenharmony_ci{ 5178c2ecf20Sopenharmony_ci switch (event) { 5188c2ecf20Sopenharmony_ci case ETHPORT_E_START: 5198c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_down); 5208c2ecf20Sopenharmony_ci break; 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci case ETHPORT_E_STOP: 5238c2ecf20Sopenharmony_ci call_ethport_stop_cbfn(ethport); 5248c2ecf20Sopenharmony_ci break; 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci case ETHPORT_E_FAIL: 5278c2ecf20Sopenharmony_ci /* No-op */ 5288c2ecf20Sopenharmony_ci break; 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci case ETHPORT_E_DOWN: 5318c2ecf20Sopenharmony_ci /* This event is received due to Rx objects failing */ 5328c2ecf20Sopenharmony_ci /* No-op */ 5338c2ecf20Sopenharmony_ci break; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci default: 5368c2ecf20Sopenharmony_ci bfa_sm_fault(event); 5378c2ecf20Sopenharmony_ci } 5388c2ecf20Sopenharmony_ci} 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_cistatic void 5418c2ecf20Sopenharmony_cibna_ethport_sm_down_entry(struct bna_ethport *ethport) 5428c2ecf20Sopenharmony_ci{ 5438c2ecf20Sopenharmony_ci} 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_cistatic void 5468c2ecf20Sopenharmony_cibna_ethport_sm_down(struct bna_ethport *ethport, 5478c2ecf20Sopenharmony_ci enum bna_ethport_event event) 5488c2ecf20Sopenharmony_ci{ 5498c2ecf20Sopenharmony_ci switch (event) { 5508c2ecf20Sopenharmony_ci case ETHPORT_E_STOP: 5518c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_stopped); 5528c2ecf20Sopenharmony_ci break; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci case ETHPORT_E_FAIL: 5558c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_stopped); 5568c2ecf20Sopenharmony_ci break; 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci case ETHPORT_E_UP: 5598c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_up_resp_wait); 5608c2ecf20Sopenharmony_ci bna_bfi_ethport_up(ethport); 5618c2ecf20Sopenharmony_ci break; 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_ci default: 5648c2ecf20Sopenharmony_ci bfa_sm_fault(event); 5658c2ecf20Sopenharmony_ci } 5668c2ecf20Sopenharmony_ci} 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_cistatic void 5698c2ecf20Sopenharmony_cibna_ethport_sm_up_resp_wait_entry(struct bna_ethport *ethport) 5708c2ecf20Sopenharmony_ci{ 5718c2ecf20Sopenharmony_ci} 5728c2ecf20Sopenharmony_ci 5738c2ecf20Sopenharmony_cistatic void 5748c2ecf20Sopenharmony_cibna_ethport_sm_up_resp_wait(struct bna_ethport *ethport, 5758c2ecf20Sopenharmony_ci enum bna_ethport_event event) 5768c2ecf20Sopenharmony_ci{ 5778c2ecf20Sopenharmony_ci switch (event) { 5788c2ecf20Sopenharmony_ci case ETHPORT_E_STOP: 5798c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait); 5808c2ecf20Sopenharmony_ci break; 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci case ETHPORT_E_FAIL: 5838c2ecf20Sopenharmony_ci call_ethport_adminup_cbfn(ethport, BNA_CB_FAIL); 5848c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_stopped); 5858c2ecf20Sopenharmony_ci break; 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci case ETHPORT_E_DOWN: 5888c2ecf20Sopenharmony_ci call_ethport_adminup_cbfn(ethport, BNA_CB_INTERRUPT); 5898c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_down_resp_wait); 5908c2ecf20Sopenharmony_ci break; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci case ETHPORT_E_FWRESP_UP_OK: 5938c2ecf20Sopenharmony_ci call_ethport_adminup_cbfn(ethport, BNA_CB_SUCCESS); 5948c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_up); 5958c2ecf20Sopenharmony_ci break; 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci case ETHPORT_E_FWRESP_UP_FAIL: 5988c2ecf20Sopenharmony_ci call_ethport_adminup_cbfn(ethport, BNA_CB_FAIL); 5998c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_down); 6008c2ecf20Sopenharmony_ci break; 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci case ETHPORT_E_FWRESP_DOWN: 6038c2ecf20Sopenharmony_ci /* down_resp_wait -> up_resp_wait transition on ETHPORT_E_UP */ 6048c2ecf20Sopenharmony_ci bna_bfi_ethport_up(ethport); 6058c2ecf20Sopenharmony_ci break; 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci default: 6088c2ecf20Sopenharmony_ci bfa_sm_fault(event); 6098c2ecf20Sopenharmony_ci } 6108c2ecf20Sopenharmony_ci} 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_cistatic void 6138c2ecf20Sopenharmony_cibna_ethport_sm_down_resp_wait_entry(struct bna_ethport *ethport) 6148c2ecf20Sopenharmony_ci{ 6158c2ecf20Sopenharmony_ci /** 6168c2ecf20Sopenharmony_ci * NOTE: Do not call bna_bfi_ethport_down() here. That will over step 6178c2ecf20Sopenharmony_ci * mbox due to up_resp_wait -> down_resp_wait transition on event 6188c2ecf20Sopenharmony_ci * ETHPORT_E_DOWN 6198c2ecf20Sopenharmony_ci */ 6208c2ecf20Sopenharmony_ci} 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_cistatic void 6238c2ecf20Sopenharmony_cibna_ethport_sm_down_resp_wait(struct bna_ethport *ethport, 6248c2ecf20Sopenharmony_ci enum bna_ethport_event event) 6258c2ecf20Sopenharmony_ci{ 6268c2ecf20Sopenharmony_ci switch (event) { 6278c2ecf20Sopenharmony_ci case ETHPORT_E_STOP: 6288c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait); 6298c2ecf20Sopenharmony_ci break; 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci case ETHPORT_E_FAIL: 6328c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_stopped); 6338c2ecf20Sopenharmony_ci break; 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci case ETHPORT_E_UP: 6368c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_up_resp_wait); 6378c2ecf20Sopenharmony_ci break; 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci case ETHPORT_E_FWRESP_UP_OK: 6408c2ecf20Sopenharmony_ci /* up_resp_wait->down_resp_wait transition on ETHPORT_E_DOWN */ 6418c2ecf20Sopenharmony_ci bna_bfi_ethport_down(ethport); 6428c2ecf20Sopenharmony_ci break; 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci case ETHPORT_E_FWRESP_UP_FAIL: 6458c2ecf20Sopenharmony_ci case ETHPORT_E_FWRESP_DOWN: 6468c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_down); 6478c2ecf20Sopenharmony_ci break; 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci default: 6508c2ecf20Sopenharmony_ci bfa_sm_fault(event); 6518c2ecf20Sopenharmony_ci } 6528c2ecf20Sopenharmony_ci} 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_cistatic void 6558c2ecf20Sopenharmony_cibna_ethport_sm_up_entry(struct bna_ethport *ethport) 6568c2ecf20Sopenharmony_ci{ 6578c2ecf20Sopenharmony_ci} 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_cistatic void 6608c2ecf20Sopenharmony_cibna_ethport_sm_up(struct bna_ethport *ethport, 6618c2ecf20Sopenharmony_ci enum bna_ethport_event event) 6628c2ecf20Sopenharmony_ci{ 6638c2ecf20Sopenharmony_ci switch (event) { 6648c2ecf20Sopenharmony_ci case ETHPORT_E_STOP: 6658c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_last_resp_wait); 6668c2ecf20Sopenharmony_ci bna_bfi_ethport_down(ethport); 6678c2ecf20Sopenharmony_ci break; 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci case ETHPORT_E_FAIL: 6708c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_stopped); 6718c2ecf20Sopenharmony_ci break; 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ci case ETHPORT_E_DOWN: 6748c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_down_resp_wait); 6758c2ecf20Sopenharmony_ci bna_bfi_ethport_down(ethport); 6768c2ecf20Sopenharmony_ci break; 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ci default: 6798c2ecf20Sopenharmony_ci bfa_sm_fault(event); 6808c2ecf20Sopenharmony_ci } 6818c2ecf20Sopenharmony_ci} 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_cistatic void 6848c2ecf20Sopenharmony_cibna_ethport_sm_last_resp_wait_entry(struct bna_ethport *ethport) 6858c2ecf20Sopenharmony_ci{ 6868c2ecf20Sopenharmony_ci} 6878c2ecf20Sopenharmony_ci 6888c2ecf20Sopenharmony_cistatic void 6898c2ecf20Sopenharmony_cibna_ethport_sm_last_resp_wait(struct bna_ethport *ethport, 6908c2ecf20Sopenharmony_ci enum bna_ethport_event event) 6918c2ecf20Sopenharmony_ci{ 6928c2ecf20Sopenharmony_ci switch (event) { 6938c2ecf20Sopenharmony_ci case ETHPORT_E_FAIL: 6948c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_stopped); 6958c2ecf20Sopenharmony_ci break; 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci case ETHPORT_E_DOWN: 6988c2ecf20Sopenharmony_ci /** 6998c2ecf20Sopenharmony_ci * This event is received due to Rx objects stopping in 7008c2ecf20Sopenharmony_ci * parallel to ethport 7018c2ecf20Sopenharmony_ci */ 7028c2ecf20Sopenharmony_ci /* No-op */ 7038c2ecf20Sopenharmony_ci break; 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci case ETHPORT_E_FWRESP_UP_OK: 7068c2ecf20Sopenharmony_ci /* up_resp_wait->last_resp_wait transition on ETHPORT_T_STOP */ 7078c2ecf20Sopenharmony_ci bna_bfi_ethport_down(ethport); 7088c2ecf20Sopenharmony_ci break; 7098c2ecf20Sopenharmony_ci 7108c2ecf20Sopenharmony_ci case ETHPORT_E_FWRESP_UP_FAIL: 7118c2ecf20Sopenharmony_ci case ETHPORT_E_FWRESP_DOWN: 7128c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_stopped); 7138c2ecf20Sopenharmony_ci break; 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci default: 7168c2ecf20Sopenharmony_ci bfa_sm_fault(event); 7178c2ecf20Sopenharmony_ci } 7188c2ecf20Sopenharmony_ci} 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_cistatic void 7218c2ecf20Sopenharmony_cibna_ethport_init(struct bna_ethport *ethport, struct bna *bna) 7228c2ecf20Sopenharmony_ci{ 7238c2ecf20Sopenharmony_ci ethport->flags |= (BNA_ETHPORT_F_ADMIN_UP | BNA_ETHPORT_F_PORT_ENABLED); 7248c2ecf20Sopenharmony_ci ethport->bna = bna; 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci ethport->link_status = BNA_LINK_DOWN; 7278c2ecf20Sopenharmony_ci ethport->link_cbfn = bnad_cb_ethport_link_status; 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_ci ethport->rx_started_count = 0; 7308c2ecf20Sopenharmony_ci 7318c2ecf20Sopenharmony_ci ethport->stop_cbfn = NULL; 7328c2ecf20Sopenharmony_ci ethport->adminup_cbfn = NULL; 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci bfa_fsm_set_state(ethport, bna_ethport_sm_stopped); 7358c2ecf20Sopenharmony_ci} 7368c2ecf20Sopenharmony_ci 7378c2ecf20Sopenharmony_cistatic void 7388c2ecf20Sopenharmony_cibna_ethport_uninit(struct bna_ethport *ethport) 7398c2ecf20Sopenharmony_ci{ 7408c2ecf20Sopenharmony_ci ethport->flags &= ~BNA_ETHPORT_F_ADMIN_UP; 7418c2ecf20Sopenharmony_ci ethport->flags &= ~BNA_ETHPORT_F_PORT_ENABLED; 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci ethport->bna = NULL; 7448c2ecf20Sopenharmony_ci} 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_cistatic void 7478c2ecf20Sopenharmony_cibna_ethport_start(struct bna_ethport *ethport) 7488c2ecf20Sopenharmony_ci{ 7498c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_START); 7508c2ecf20Sopenharmony_ci} 7518c2ecf20Sopenharmony_ci 7528c2ecf20Sopenharmony_cistatic void 7538c2ecf20Sopenharmony_cibna_enet_cb_ethport_stopped(struct bna_enet *enet) 7548c2ecf20Sopenharmony_ci{ 7558c2ecf20Sopenharmony_ci bfa_wc_down(&enet->chld_stop_wc); 7568c2ecf20Sopenharmony_ci} 7578c2ecf20Sopenharmony_ci 7588c2ecf20Sopenharmony_cistatic void 7598c2ecf20Sopenharmony_cibna_ethport_stop(struct bna_ethport *ethport) 7608c2ecf20Sopenharmony_ci{ 7618c2ecf20Sopenharmony_ci ethport->stop_cbfn = bna_enet_cb_ethport_stopped; 7628c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_STOP); 7638c2ecf20Sopenharmony_ci} 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_cistatic void 7668c2ecf20Sopenharmony_cibna_ethport_fail(struct bna_ethport *ethport) 7678c2ecf20Sopenharmony_ci{ 7688c2ecf20Sopenharmony_ci /* Reset the physical port status to enabled */ 7698c2ecf20Sopenharmony_ci ethport->flags |= BNA_ETHPORT_F_PORT_ENABLED; 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci if (ethport->link_status != BNA_LINK_DOWN) { 7728c2ecf20Sopenharmony_ci ethport->link_status = BNA_LINK_DOWN; 7738c2ecf20Sopenharmony_ci ethport->link_cbfn(ethport->bna->bnad, BNA_LINK_DOWN); 7748c2ecf20Sopenharmony_ci } 7758c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_FAIL); 7768c2ecf20Sopenharmony_ci} 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci/* Should be called only when ethport is disabled */ 7798c2ecf20Sopenharmony_civoid 7808c2ecf20Sopenharmony_cibna_ethport_cb_rx_started(struct bna_ethport *ethport) 7818c2ecf20Sopenharmony_ci{ 7828c2ecf20Sopenharmony_ci ethport->rx_started_count++; 7838c2ecf20Sopenharmony_ci 7848c2ecf20Sopenharmony_ci if (ethport->rx_started_count == 1) { 7858c2ecf20Sopenharmony_ci ethport->flags |= BNA_ETHPORT_F_RX_STARTED; 7868c2ecf20Sopenharmony_ci 7878c2ecf20Sopenharmony_ci if (ethport_can_be_up(ethport)) 7888c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_UP); 7898c2ecf20Sopenharmony_ci } 7908c2ecf20Sopenharmony_ci} 7918c2ecf20Sopenharmony_ci 7928c2ecf20Sopenharmony_civoid 7938c2ecf20Sopenharmony_cibna_ethport_cb_rx_stopped(struct bna_ethport *ethport) 7948c2ecf20Sopenharmony_ci{ 7958c2ecf20Sopenharmony_ci int ethport_up = ethport_is_up(ethport); 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ci ethport->rx_started_count--; 7988c2ecf20Sopenharmony_ci 7998c2ecf20Sopenharmony_ci if (ethport->rx_started_count == 0) { 8008c2ecf20Sopenharmony_ci ethport->flags &= ~BNA_ETHPORT_F_RX_STARTED; 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci if (ethport_up) 8038c2ecf20Sopenharmony_ci bfa_fsm_send_event(ethport, ETHPORT_E_DOWN); 8048c2ecf20Sopenharmony_ci } 8058c2ecf20Sopenharmony_ci} 8068c2ecf20Sopenharmony_ci 8078c2ecf20Sopenharmony_ci/* ENET */ 8088c2ecf20Sopenharmony_ci 8098c2ecf20Sopenharmony_ci#define bna_enet_chld_start(enet) \ 8108c2ecf20Sopenharmony_cido { \ 8118c2ecf20Sopenharmony_ci enum bna_tx_type tx_type = \ 8128c2ecf20Sopenharmony_ci ((enet)->type == BNA_ENET_T_REGULAR) ? \ 8138c2ecf20Sopenharmony_ci BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK; \ 8148c2ecf20Sopenharmony_ci enum bna_rx_type rx_type = \ 8158c2ecf20Sopenharmony_ci ((enet)->type == BNA_ENET_T_REGULAR) ? \ 8168c2ecf20Sopenharmony_ci BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK; \ 8178c2ecf20Sopenharmony_ci bna_ethport_start(&(enet)->bna->ethport); \ 8188c2ecf20Sopenharmony_ci bna_tx_mod_start(&(enet)->bna->tx_mod, tx_type); \ 8198c2ecf20Sopenharmony_ci bna_rx_mod_start(&(enet)->bna->rx_mod, rx_type); \ 8208c2ecf20Sopenharmony_ci} while (0) 8218c2ecf20Sopenharmony_ci 8228c2ecf20Sopenharmony_ci#define bna_enet_chld_stop(enet) \ 8238c2ecf20Sopenharmony_cido { \ 8248c2ecf20Sopenharmony_ci enum bna_tx_type tx_type = \ 8258c2ecf20Sopenharmony_ci ((enet)->type == BNA_ENET_T_REGULAR) ? \ 8268c2ecf20Sopenharmony_ci BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK; \ 8278c2ecf20Sopenharmony_ci enum bna_rx_type rx_type = \ 8288c2ecf20Sopenharmony_ci ((enet)->type == BNA_ENET_T_REGULAR) ? \ 8298c2ecf20Sopenharmony_ci BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK; \ 8308c2ecf20Sopenharmony_ci bfa_wc_init(&(enet)->chld_stop_wc, bna_enet_cb_chld_stopped, (enet));\ 8318c2ecf20Sopenharmony_ci bfa_wc_up(&(enet)->chld_stop_wc); \ 8328c2ecf20Sopenharmony_ci bna_ethport_stop(&(enet)->bna->ethport); \ 8338c2ecf20Sopenharmony_ci bfa_wc_up(&(enet)->chld_stop_wc); \ 8348c2ecf20Sopenharmony_ci bna_tx_mod_stop(&(enet)->bna->tx_mod, tx_type); \ 8358c2ecf20Sopenharmony_ci bfa_wc_up(&(enet)->chld_stop_wc); \ 8368c2ecf20Sopenharmony_ci bna_rx_mod_stop(&(enet)->bna->rx_mod, rx_type); \ 8378c2ecf20Sopenharmony_ci bfa_wc_wait(&(enet)->chld_stop_wc); \ 8388c2ecf20Sopenharmony_ci} while (0) 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci#define bna_enet_chld_fail(enet) \ 8418c2ecf20Sopenharmony_cido { \ 8428c2ecf20Sopenharmony_ci bna_ethport_fail(&(enet)->bna->ethport); \ 8438c2ecf20Sopenharmony_ci bna_tx_mod_fail(&(enet)->bna->tx_mod); \ 8448c2ecf20Sopenharmony_ci bna_rx_mod_fail(&(enet)->bna->rx_mod); \ 8458c2ecf20Sopenharmony_ci} while (0) 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_ci#define bna_enet_rx_start(enet) \ 8488c2ecf20Sopenharmony_cido { \ 8498c2ecf20Sopenharmony_ci enum bna_rx_type rx_type = \ 8508c2ecf20Sopenharmony_ci ((enet)->type == BNA_ENET_T_REGULAR) ? \ 8518c2ecf20Sopenharmony_ci BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK; \ 8528c2ecf20Sopenharmony_ci bna_rx_mod_start(&(enet)->bna->rx_mod, rx_type); \ 8538c2ecf20Sopenharmony_ci} while (0) 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci#define bna_enet_rx_stop(enet) \ 8568c2ecf20Sopenharmony_cido { \ 8578c2ecf20Sopenharmony_ci enum bna_rx_type rx_type = \ 8588c2ecf20Sopenharmony_ci ((enet)->type == BNA_ENET_T_REGULAR) ? \ 8598c2ecf20Sopenharmony_ci BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK; \ 8608c2ecf20Sopenharmony_ci bfa_wc_init(&(enet)->chld_stop_wc, bna_enet_cb_chld_stopped, (enet));\ 8618c2ecf20Sopenharmony_ci bfa_wc_up(&(enet)->chld_stop_wc); \ 8628c2ecf20Sopenharmony_ci bna_rx_mod_stop(&(enet)->bna->rx_mod, rx_type); \ 8638c2ecf20Sopenharmony_ci bfa_wc_wait(&(enet)->chld_stop_wc); \ 8648c2ecf20Sopenharmony_ci} while (0) 8658c2ecf20Sopenharmony_ci 8668c2ecf20Sopenharmony_ci#define call_enet_stop_cbfn(enet) \ 8678c2ecf20Sopenharmony_cido { \ 8688c2ecf20Sopenharmony_ci if ((enet)->stop_cbfn) { \ 8698c2ecf20Sopenharmony_ci void (*cbfn)(void *); \ 8708c2ecf20Sopenharmony_ci void *cbarg; \ 8718c2ecf20Sopenharmony_ci cbfn = (enet)->stop_cbfn; \ 8728c2ecf20Sopenharmony_ci cbarg = (enet)->stop_cbarg; \ 8738c2ecf20Sopenharmony_ci (enet)->stop_cbfn = NULL; \ 8748c2ecf20Sopenharmony_ci (enet)->stop_cbarg = NULL; \ 8758c2ecf20Sopenharmony_ci cbfn(cbarg); \ 8768c2ecf20Sopenharmony_ci } \ 8778c2ecf20Sopenharmony_ci} while (0) 8788c2ecf20Sopenharmony_ci 8798c2ecf20Sopenharmony_ci#define call_enet_mtu_cbfn(enet) \ 8808c2ecf20Sopenharmony_cido { \ 8818c2ecf20Sopenharmony_ci if ((enet)->mtu_cbfn) { \ 8828c2ecf20Sopenharmony_ci void (*cbfn)(struct bnad *); \ 8838c2ecf20Sopenharmony_ci cbfn = (enet)->mtu_cbfn; \ 8848c2ecf20Sopenharmony_ci (enet)->mtu_cbfn = NULL; \ 8858c2ecf20Sopenharmony_ci cbfn((enet)->bna->bnad); \ 8868c2ecf20Sopenharmony_ci } \ 8878c2ecf20Sopenharmony_ci} while (0) 8888c2ecf20Sopenharmony_ci 8898c2ecf20Sopenharmony_cistatic void bna_enet_cb_chld_stopped(void *arg); 8908c2ecf20Sopenharmony_cistatic void bna_bfi_pause_set(struct bna_enet *enet); 8918c2ecf20Sopenharmony_ci 8928c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_enet, stopped, struct bna_enet, 8938c2ecf20Sopenharmony_ci enum bna_enet_event); 8948c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_enet, pause_init_wait, struct bna_enet, 8958c2ecf20Sopenharmony_ci enum bna_enet_event); 8968c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_enet, last_resp_wait, struct bna_enet, 8978c2ecf20Sopenharmony_ci enum bna_enet_event); 8988c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_enet, started, struct bna_enet, 8998c2ecf20Sopenharmony_ci enum bna_enet_event); 9008c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_enet, cfg_wait, struct bna_enet, 9018c2ecf20Sopenharmony_ci enum bna_enet_event); 9028c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_enet, cfg_stop_wait, struct bna_enet, 9038c2ecf20Sopenharmony_ci enum bna_enet_event); 9048c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_enet, chld_stop_wait, struct bna_enet, 9058c2ecf20Sopenharmony_ci enum bna_enet_event); 9068c2ecf20Sopenharmony_ci 9078c2ecf20Sopenharmony_cistatic void 9088c2ecf20Sopenharmony_cibna_enet_sm_stopped_entry(struct bna_enet *enet) 9098c2ecf20Sopenharmony_ci{ 9108c2ecf20Sopenharmony_ci call_enet_mtu_cbfn(enet); 9118c2ecf20Sopenharmony_ci call_enet_stop_cbfn(enet); 9128c2ecf20Sopenharmony_ci} 9138c2ecf20Sopenharmony_ci 9148c2ecf20Sopenharmony_cistatic void 9158c2ecf20Sopenharmony_cibna_enet_sm_stopped(struct bna_enet *enet, enum bna_enet_event event) 9168c2ecf20Sopenharmony_ci{ 9178c2ecf20Sopenharmony_ci switch (event) { 9188c2ecf20Sopenharmony_ci case ENET_E_START: 9198c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_pause_init_wait); 9208c2ecf20Sopenharmony_ci break; 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_ci case ENET_E_STOP: 9238c2ecf20Sopenharmony_ci call_enet_stop_cbfn(enet); 9248c2ecf20Sopenharmony_ci break; 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_ci case ENET_E_FAIL: 9278c2ecf20Sopenharmony_ci /* No-op */ 9288c2ecf20Sopenharmony_ci break; 9298c2ecf20Sopenharmony_ci 9308c2ecf20Sopenharmony_ci case ENET_E_PAUSE_CFG: 9318c2ecf20Sopenharmony_ci break; 9328c2ecf20Sopenharmony_ci 9338c2ecf20Sopenharmony_ci case ENET_E_MTU_CFG: 9348c2ecf20Sopenharmony_ci call_enet_mtu_cbfn(enet); 9358c2ecf20Sopenharmony_ci break; 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ci case ENET_E_CHLD_STOPPED: 9388c2ecf20Sopenharmony_ci /** 9398c2ecf20Sopenharmony_ci * This event is received due to Ethport, Tx and Rx objects 9408c2ecf20Sopenharmony_ci * failing 9418c2ecf20Sopenharmony_ci */ 9428c2ecf20Sopenharmony_ci /* No-op */ 9438c2ecf20Sopenharmony_ci break; 9448c2ecf20Sopenharmony_ci 9458c2ecf20Sopenharmony_ci default: 9468c2ecf20Sopenharmony_ci bfa_sm_fault(event); 9478c2ecf20Sopenharmony_ci } 9488c2ecf20Sopenharmony_ci} 9498c2ecf20Sopenharmony_ci 9508c2ecf20Sopenharmony_cistatic void 9518c2ecf20Sopenharmony_cibna_enet_sm_pause_init_wait_entry(struct bna_enet *enet) 9528c2ecf20Sopenharmony_ci{ 9538c2ecf20Sopenharmony_ci bna_bfi_pause_set(enet); 9548c2ecf20Sopenharmony_ci} 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_cistatic void 9578c2ecf20Sopenharmony_cibna_enet_sm_pause_init_wait(struct bna_enet *enet, 9588c2ecf20Sopenharmony_ci enum bna_enet_event event) 9598c2ecf20Sopenharmony_ci{ 9608c2ecf20Sopenharmony_ci switch (event) { 9618c2ecf20Sopenharmony_ci case ENET_E_STOP: 9628c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED; 9638c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_last_resp_wait); 9648c2ecf20Sopenharmony_ci break; 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci case ENET_E_FAIL: 9678c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED; 9688c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_stopped); 9698c2ecf20Sopenharmony_ci break; 9708c2ecf20Sopenharmony_ci 9718c2ecf20Sopenharmony_ci case ENET_E_PAUSE_CFG: 9728c2ecf20Sopenharmony_ci enet->flags |= BNA_ENET_F_PAUSE_CHANGED; 9738c2ecf20Sopenharmony_ci break; 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_ci case ENET_E_MTU_CFG: 9768c2ecf20Sopenharmony_ci /* No-op */ 9778c2ecf20Sopenharmony_ci break; 9788c2ecf20Sopenharmony_ci 9798c2ecf20Sopenharmony_ci case ENET_E_FWRESP_PAUSE: 9808c2ecf20Sopenharmony_ci if (enet->flags & BNA_ENET_F_PAUSE_CHANGED) { 9818c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED; 9828c2ecf20Sopenharmony_ci bna_bfi_pause_set(enet); 9838c2ecf20Sopenharmony_ci } else { 9848c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_started); 9858c2ecf20Sopenharmony_ci bna_enet_chld_start(enet); 9868c2ecf20Sopenharmony_ci } 9878c2ecf20Sopenharmony_ci break; 9888c2ecf20Sopenharmony_ci 9898c2ecf20Sopenharmony_ci default: 9908c2ecf20Sopenharmony_ci bfa_sm_fault(event); 9918c2ecf20Sopenharmony_ci } 9928c2ecf20Sopenharmony_ci} 9938c2ecf20Sopenharmony_ci 9948c2ecf20Sopenharmony_cistatic void 9958c2ecf20Sopenharmony_cibna_enet_sm_last_resp_wait_entry(struct bna_enet *enet) 9968c2ecf20Sopenharmony_ci{ 9978c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED; 9988c2ecf20Sopenharmony_ci} 9998c2ecf20Sopenharmony_ci 10008c2ecf20Sopenharmony_cistatic void 10018c2ecf20Sopenharmony_cibna_enet_sm_last_resp_wait(struct bna_enet *enet, 10028c2ecf20Sopenharmony_ci enum bna_enet_event event) 10038c2ecf20Sopenharmony_ci{ 10048c2ecf20Sopenharmony_ci switch (event) { 10058c2ecf20Sopenharmony_ci case ENET_E_FAIL: 10068c2ecf20Sopenharmony_ci case ENET_E_FWRESP_PAUSE: 10078c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_stopped); 10088c2ecf20Sopenharmony_ci break; 10098c2ecf20Sopenharmony_ci 10108c2ecf20Sopenharmony_ci default: 10118c2ecf20Sopenharmony_ci bfa_sm_fault(event); 10128c2ecf20Sopenharmony_ci } 10138c2ecf20Sopenharmony_ci} 10148c2ecf20Sopenharmony_ci 10158c2ecf20Sopenharmony_cistatic void 10168c2ecf20Sopenharmony_cibna_enet_sm_started_entry(struct bna_enet *enet) 10178c2ecf20Sopenharmony_ci{ 10188c2ecf20Sopenharmony_ci /** 10198c2ecf20Sopenharmony_ci * NOTE: Do not call bna_enet_chld_start() here, since it will be 10208c2ecf20Sopenharmony_ci * inadvertently called during cfg_wait->started transition as well 10218c2ecf20Sopenharmony_ci */ 10228c2ecf20Sopenharmony_ci call_enet_mtu_cbfn(enet); 10238c2ecf20Sopenharmony_ci} 10248c2ecf20Sopenharmony_ci 10258c2ecf20Sopenharmony_cistatic void 10268c2ecf20Sopenharmony_cibna_enet_sm_started(struct bna_enet *enet, 10278c2ecf20Sopenharmony_ci enum bna_enet_event event) 10288c2ecf20Sopenharmony_ci{ 10298c2ecf20Sopenharmony_ci switch (event) { 10308c2ecf20Sopenharmony_ci case ENET_E_STOP: 10318c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_chld_stop_wait); 10328c2ecf20Sopenharmony_ci break; 10338c2ecf20Sopenharmony_ci 10348c2ecf20Sopenharmony_ci case ENET_E_FAIL: 10358c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_stopped); 10368c2ecf20Sopenharmony_ci bna_enet_chld_fail(enet); 10378c2ecf20Sopenharmony_ci break; 10388c2ecf20Sopenharmony_ci 10398c2ecf20Sopenharmony_ci case ENET_E_PAUSE_CFG: 10408c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_cfg_wait); 10418c2ecf20Sopenharmony_ci bna_bfi_pause_set(enet); 10428c2ecf20Sopenharmony_ci break; 10438c2ecf20Sopenharmony_ci 10448c2ecf20Sopenharmony_ci case ENET_E_MTU_CFG: 10458c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_cfg_wait); 10468c2ecf20Sopenharmony_ci bna_enet_rx_stop(enet); 10478c2ecf20Sopenharmony_ci break; 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_ci default: 10508c2ecf20Sopenharmony_ci bfa_sm_fault(event); 10518c2ecf20Sopenharmony_ci } 10528c2ecf20Sopenharmony_ci} 10538c2ecf20Sopenharmony_ci 10548c2ecf20Sopenharmony_cistatic void 10558c2ecf20Sopenharmony_cibna_enet_sm_cfg_wait_entry(struct bna_enet *enet) 10568c2ecf20Sopenharmony_ci{ 10578c2ecf20Sopenharmony_ci} 10588c2ecf20Sopenharmony_ci 10598c2ecf20Sopenharmony_cistatic void 10608c2ecf20Sopenharmony_cibna_enet_sm_cfg_wait(struct bna_enet *enet, 10618c2ecf20Sopenharmony_ci enum bna_enet_event event) 10628c2ecf20Sopenharmony_ci{ 10638c2ecf20Sopenharmony_ci switch (event) { 10648c2ecf20Sopenharmony_ci case ENET_E_STOP: 10658c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED; 10668c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_MTU_CHANGED; 10678c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_cfg_stop_wait); 10688c2ecf20Sopenharmony_ci break; 10698c2ecf20Sopenharmony_ci 10708c2ecf20Sopenharmony_ci case ENET_E_FAIL: 10718c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED; 10728c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_MTU_CHANGED; 10738c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_stopped); 10748c2ecf20Sopenharmony_ci bna_enet_chld_fail(enet); 10758c2ecf20Sopenharmony_ci break; 10768c2ecf20Sopenharmony_ci 10778c2ecf20Sopenharmony_ci case ENET_E_PAUSE_CFG: 10788c2ecf20Sopenharmony_ci enet->flags |= BNA_ENET_F_PAUSE_CHANGED; 10798c2ecf20Sopenharmony_ci break; 10808c2ecf20Sopenharmony_ci 10818c2ecf20Sopenharmony_ci case ENET_E_MTU_CFG: 10828c2ecf20Sopenharmony_ci enet->flags |= BNA_ENET_F_MTU_CHANGED; 10838c2ecf20Sopenharmony_ci break; 10848c2ecf20Sopenharmony_ci 10858c2ecf20Sopenharmony_ci case ENET_E_CHLD_STOPPED: 10868c2ecf20Sopenharmony_ci bna_enet_rx_start(enet); 10878c2ecf20Sopenharmony_ci fallthrough; 10888c2ecf20Sopenharmony_ci case ENET_E_FWRESP_PAUSE: 10898c2ecf20Sopenharmony_ci if (enet->flags & BNA_ENET_F_PAUSE_CHANGED) { 10908c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED; 10918c2ecf20Sopenharmony_ci bna_bfi_pause_set(enet); 10928c2ecf20Sopenharmony_ci } else if (enet->flags & BNA_ENET_F_MTU_CHANGED) { 10938c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_MTU_CHANGED; 10948c2ecf20Sopenharmony_ci bna_enet_rx_stop(enet); 10958c2ecf20Sopenharmony_ci } else { 10968c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_started); 10978c2ecf20Sopenharmony_ci } 10988c2ecf20Sopenharmony_ci break; 10998c2ecf20Sopenharmony_ci 11008c2ecf20Sopenharmony_ci default: 11018c2ecf20Sopenharmony_ci bfa_sm_fault(event); 11028c2ecf20Sopenharmony_ci } 11038c2ecf20Sopenharmony_ci} 11048c2ecf20Sopenharmony_ci 11058c2ecf20Sopenharmony_cistatic void 11068c2ecf20Sopenharmony_cibna_enet_sm_cfg_stop_wait_entry(struct bna_enet *enet) 11078c2ecf20Sopenharmony_ci{ 11088c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_PAUSE_CHANGED; 11098c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_MTU_CHANGED; 11108c2ecf20Sopenharmony_ci} 11118c2ecf20Sopenharmony_ci 11128c2ecf20Sopenharmony_cistatic void 11138c2ecf20Sopenharmony_cibna_enet_sm_cfg_stop_wait(struct bna_enet *enet, 11148c2ecf20Sopenharmony_ci enum bna_enet_event event) 11158c2ecf20Sopenharmony_ci{ 11168c2ecf20Sopenharmony_ci switch (event) { 11178c2ecf20Sopenharmony_ci case ENET_E_FAIL: 11188c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_stopped); 11198c2ecf20Sopenharmony_ci bna_enet_chld_fail(enet); 11208c2ecf20Sopenharmony_ci break; 11218c2ecf20Sopenharmony_ci 11228c2ecf20Sopenharmony_ci case ENET_E_FWRESP_PAUSE: 11238c2ecf20Sopenharmony_ci case ENET_E_CHLD_STOPPED: 11248c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_chld_stop_wait); 11258c2ecf20Sopenharmony_ci break; 11268c2ecf20Sopenharmony_ci 11278c2ecf20Sopenharmony_ci default: 11288c2ecf20Sopenharmony_ci bfa_sm_fault(event); 11298c2ecf20Sopenharmony_ci } 11308c2ecf20Sopenharmony_ci} 11318c2ecf20Sopenharmony_ci 11328c2ecf20Sopenharmony_cistatic void 11338c2ecf20Sopenharmony_cibna_enet_sm_chld_stop_wait_entry(struct bna_enet *enet) 11348c2ecf20Sopenharmony_ci{ 11358c2ecf20Sopenharmony_ci bna_enet_chld_stop(enet); 11368c2ecf20Sopenharmony_ci} 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_cistatic void 11398c2ecf20Sopenharmony_cibna_enet_sm_chld_stop_wait(struct bna_enet *enet, 11408c2ecf20Sopenharmony_ci enum bna_enet_event event) 11418c2ecf20Sopenharmony_ci{ 11428c2ecf20Sopenharmony_ci switch (event) { 11438c2ecf20Sopenharmony_ci case ENET_E_FAIL: 11448c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_stopped); 11458c2ecf20Sopenharmony_ci bna_enet_chld_fail(enet); 11468c2ecf20Sopenharmony_ci break; 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_ci case ENET_E_CHLD_STOPPED: 11498c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_stopped); 11508c2ecf20Sopenharmony_ci break; 11518c2ecf20Sopenharmony_ci 11528c2ecf20Sopenharmony_ci default: 11538c2ecf20Sopenharmony_ci bfa_sm_fault(event); 11548c2ecf20Sopenharmony_ci } 11558c2ecf20Sopenharmony_ci} 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_cistatic void 11588c2ecf20Sopenharmony_cibna_bfi_pause_set(struct bna_enet *enet) 11598c2ecf20Sopenharmony_ci{ 11608c2ecf20Sopenharmony_ci struct bfi_enet_set_pause_req *pause_req = &enet->pause_req; 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci bfi_msgq_mhdr_set(pause_req->mh, BFI_MC_ENET, 11638c2ecf20Sopenharmony_ci BFI_ENET_H2I_SET_PAUSE_REQ, 0, 0); 11648c2ecf20Sopenharmony_ci pause_req->mh.num_entries = htons( 11658c2ecf20Sopenharmony_ci bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_set_pause_req))); 11668c2ecf20Sopenharmony_ci pause_req->tx_pause = enet->pause_config.tx_pause; 11678c2ecf20Sopenharmony_ci pause_req->rx_pause = enet->pause_config.rx_pause; 11688c2ecf20Sopenharmony_ci 11698c2ecf20Sopenharmony_ci bfa_msgq_cmd_set(&enet->msgq_cmd, NULL, NULL, 11708c2ecf20Sopenharmony_ci sizeof(struct bfi_enet_set_pause_req), &pause_req->mh); 11718c2ecf20Sopenharmony_ci bfa_msgq_cmd_post(&enet->bna->msgq, &enet->msgq_cmd); 11728c2ecf20Sopenharmony_ci} 11738c2ecf20Sopenharmony_ci 11748c2ecf20Sopenharmony_cistatic void 11758c2ecf20Sopenharmony_cibna_enet_cb_chld_stopped(void *arg) 11768c2ecf20Sopenharmony_ci{ 11778c2ecf20Sopenharmony_ci struct bna_enet *enet = (struct bna_enet *)arg; 11788c2ecf20Sopenharmony_ci 11798c2ecf20Sopenharmony_ci bfa_fsm_send_event(enet, ENET_E_CHLD_STOPPED); 11808c2ecf20Sopenharmony_ci} 11818c2ecf20Sopenharmony_ci 11828c2ecf20Sopenharmony_cistatic void 11838c2ecf20Sopenharmony_cibna_enet_init(struct bna_enet *enet, struct bna *bna) 11848c2ecf20Sopenharmony_ci{ 11858c2ecf20Sopenharmony_ci enet->bna = bna; 11868c2ecf20Sopenharmony_ci enet->flags = 0; 11878c2ecf20Sopenharmony_ci enet->mtu = 0; 11888c2ecf20Sopenharmony_ci enet->type = BNA_ENET_T_REGULAR; 11898c2ecf20Sopenharmony_ci 11908c2ecf20Sopenharmony_ci enet->stop_cbfn = NULL; 11918c2ecf20Sopenharmony_ci enet->stop_cbarg = NULL; 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_ci enet->mtu_cbfn = NULL; 11948c2ecf20Sopenharmony_ci 11958c2ecf20Sopenharmony_ci bfa_fsm_set_state(enet, bna_enet_sm_stopped); 11968c2ecf20Sopenharmony_ci} 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_cistatic void 11998c2ecf20Sopenharmony_cibna_enet_uninit(struct bna_enet *enet) 12008c2ecf20Sopenharmony_ci{ 12018c2ecf20Sopenharmony_ci enet->flags = 0; 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_ci enet->bna = NULL; 12048c2ecf20Sopenharmony_ci} 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_cistatic void 12078c2ecf20Sopenharmony_cibna_enet_start(struct bna_enet *enet) 12088c2ecf20Sopenharmony_ci{ 12098c2ecf20Sopenharmony_ci enet->flags |= BNA_ENET_F_IOCETH_READY; 12108c2ecf20Sopenharmony_ci if (enet->flags & BNA_ENET_F_ENABLED) 12118c2ecf20Sopenharmony_ci bfa_fsm_send_event(enet, ENET_E_START); 12128c2ecf20Sopenharmony_ci} 12138c2ecf20Sopenharmony_ci 12148c2ecf20Sopenharmony_cistatic void 12158c2ecf20Sopenharmony_cibna_ioceth_cb_enet_stopped(void *arg) 12168c2ecf20Sopenharmony_ci{ 12178c2ecf20Sopenharmony_ci struct bna_ioceth *ioceth = (struct bna_ioceth *)arg; 12188c2ecf20Sopenharmony_ci 12198c2ecf20Sopenharmony_ci bfa_fsm_send_event(ioceth, IOCETH_E_ENET_STOPPED); 12208c2ecf20Sopenharmony_ci} 12218c2ecf20Sopenharmony_ci 12228c2ecf20Sopenharmony_cistatic void 12238c2ecf20Sopenharmony_cibna_enet_stop(struct bna_enet *enet) 12248c2ecf20Sopenharmony_ci{ 12258c2ecf20Sopenharmony_ci enet->stop_cbfn = bna_ioceth_cb_enet_stopped; 12268c2ecf20Sopenharmony_ci enet->stop_cbarg = &enet->bna->ioceth; 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_IOCETH_READY; 12298c2ecf20Sopenharmony_ci bfa_fsm_send_event(enet, ENET_E_STOP); 12308c2ecf20Sopenharmony_ci} 12318c2ecf20Sopenharmony_ci 12328c2ecf20Sopenharmony_cistatic void 12338c2ecf20Sopenharmony_cibna_enet_fail(struct bna_enet *enet) 12348c2ecf20Sopenharmony_ci{ 12358c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_IOCETH_READY; 12368c2ecf20Sopenharmony_ci bfa_fsm_send_event(enet, ENET_E_FAIL); 12378c2ecf20Sopenharmony_ci} 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_civoid 12408c2ecf20Sopenharmony_cibna_enet_cb_tx_stopped(struct bna_enet *enet) 12418c2ecf20Sopenharmony_ci{ 12428c2ecf20Sopenharmony_ci bfa_wc_down(&enet->chld_stop_wc); 12438c2ecf20Sopenharmony_ci} 12448c2ecf20Sopenharmony_ci 12458c2ecf20Sopenharmony_civoid 12468c2ecf20Sopenharmony_cibna_enet_cb_rx_stopped(struct bna_enet *enet) 12478c2ecf20Sopenharmony_ci{ 12488c2ecf20Sopenharmony_ci bfa_wc_down(&enet->chld_stop_wc); 12498c2ecf20Sopenharmony_ci} 12508c2ecf20Sopenharmony_ci 12518c2ecf20Sopenharmony_ciint 12528c2ecf20Sopenharmony_cibna_enet_mtu_get(struct bna_enet *enet) 12538c2ecf20Sopenharmony_ci{ 12548c2ecf20Sopenharmony_ci return enet->mtu; 12558c2ecf20Sopenharmony_ci} 12568c2ecf20Sopenharmony_ci 12578c2ecf20Sopenharmony_civoid 12588c2ecf20Sopenharmony_cibna_enet_enable(struct bna_enet *enet) 12598c2ecf20Sopenharmony_ci{ 12608c2ecf20Sopenharmony_ci if (enet->fsm != (bfa_sm_t)bna_enet_sm_stopped) 12618c2ecf20Sopenharmony_ci return; 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_ci enet->flags |= BNA_ENET_F_ENABLED; 12648c2ecf20Sopenharmony_ci 12658c2ecf20Sopenharmony_ci if (enet->flags & BNA_ENET_F_IOCETH_READY) 12668c2ecf20Sopenharmony_ci bfa_fsm_send_event(enet, ENET_E_START); 12678c2ecf20Sopenharmony_ci} 12688c2ecf20Sopenharmony_ci 12698c2ecf20Sopenharmony_civoid 12708c2ecf20Sopenharmony_cibna_enet_disable(struct bna_enet *enet, enum bna_cleanup_type type, 12718c2ecf20Sopenharmony_ci void (*cbfn)(void *)) 12728c2ecf20Sopenharmony_ci{ 12738c2ecf20Sopenharmony_ci if (type == BNA_SOFT_CLEANUP) { 12748c2ecf20Sopenharmony_ci (*cbfn)(enet->bna->bnad); 12758c2ecf20Sopenharmony_ci return; 12768c2ecf20Sopenharmony_ci } 12778c2ecf20Sopenharmony_ci 12788c2ecf20Sopenharmony_ci enet->stop_cbfn = cbfn; 12798c2ecf20Sopenharmony_ci enet->stop_cbarg = enet->bna->bnad; 12808c2ecf20Sopenharmony_ci 12818c2ecf20Sopenharmony_ci enet->flags &= ~BNA_ENET_F_ENABLED; 12828c2ecf20Sopenharmony_ci 12838c2ecf20Sopenharmony_ci bfa_fsm_send_event(enet, ENET_E_STOP); 12848c2ecf20Sopenharmony_ci} 12858c2ecf20Sopenharmony_ci 12868c2ecf20Sopenharmony_civoid 12878c2ecf20Sopenharmony_cibna_enet_pause_config(struct bna_enet *enet, 12888c2ecf20Sopenharmony_ci struct bna_pause_config *pause_config) 12898c2ecf20Sopenharmony_ci{ 12908c2ecf20Sopenharmony_ci enet->pause_config = *pause_config; 12918c2ecf20Sopenharmony_ci 12928c2ecf20Sopenharmony_ci bfa_fsm_send_event(enet, ENET_E_PAUSE_CFG); 12938c2ecf20Sopenharmony_ci} 12948c2ecf20Sopenharmony_ci 12958c2ecf20Sopenharmony_civoid 12968c2ecf20Sopenharmony_cibna_enet_mtu_set(struct bna_enet *enet, int mtu, 12978c2ecf20Sopenharmony_ci void (*cbfn)(struct bnad *)) 12988c2ecf20Sopenharmony_ci{ 12998c2ecf20Sopenharmony_ci enet->mtu = mtu; 13008c2ecf20Sopenharmony_ci 13018c2ecf20Sopenharmony_ci enet->mtu_cbfn = cbfn; 13028c2ecf20Sopenharmony_ci 13038c2ecf20Sopenharmony_ci bfa_fsm_send_event(enet, ENET_E_MTU_CFG); 13048c2ecf20Sopenharmony_ci} 13058c2ecf20Sopenharmony_ci 13068c2ecf20Sopenharmony_civoid 13078c2ecf20Sopenharmony_cibna_enet_perm_mac_get(struct bna_enet *enet, u8 *mac) 13088c2ecf20Sopenharmony_ci{ 13098c2ecf20Sopenharmony_ci bfa_nw_ioc_get_mac(&enet->bna->ioceth.ioc, mac); 13108c2ecf20Sopenharmony_ci} 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_ci/* IOCETH */ 13138c2ecf20Sopenharmony_ci 13148c2ecf20Sopenharmony_ci#define enable_mbox_intr(_ioceth) \ 13158c2ecf20Sopenharmony_cido { \ 13168c2ecf20Sopenharmony_ci u32 intr_status; \ 13178c2ecf20Sopenharmony_ci bna_intr_status_get((_ioceth)->bna, intr_status); \ 13188c2ecf20Sopenharmony_ci bnad_cb_mbox_intr_enable((_ioceth)->bna->bnad); \ 13198c2ecf20Sopenharmony_ci bna_mbox_intr_enable((_ioceth)->bna); \ 13208c2ecf20Sopenharmony_ci} while (0) 13218c2ecf20Sopenharmony_ci 13228c2ecf20Sopenharmony_ci#define disable_mbox_intr(_ioceth) \ 13238c2ecf20Sopenharmony_cido { \ 13248c2ecf20Sopenharmony_ci bna_mbox_intr_disable((_ioceth)->bna); \ 13258c2ecf20Sopenharmony_ci bnad_cb_mbox_intr_disable((_ioceth)->bna->bnad); \ 13268c2ecf20Sopenharmony_ci} while (0) 13278c2ecf20Sopenharmony_ci 13288c2ecf20Sopenharmony_ci#define call_ioceth_stop_cbfn(_ioceth) \ 13298c2ecf20Sopenharmony_cido { \ 13308c2ecf20Sopenharmony_ci if ((_ioceth)->stop_cbfn) { \ 13318c2ecf20Sopenharmony_ci void (*cbfn)(struct bnad *); \ 13328c2ecf20Sopenharmony_ci struct bnad *cbarg; \ 13338c2ecf20Sopenharmony_ci cbfn = (_ioceth)->stop_cbfn; \ 13348c2ecf20Sopenharmony_ci cbarg = (_ioceth)->stop_cbarg; \ 13358c2ecf20Sopenharmony_ci (_ioceth)->stop_cbfn = NULL; \ 13368c2ecf20Sopenharmony_ci (_ioceth)->stop_cbarg = NULL; \ 13378c2ecf20Sopenharmony_ci cbfn(cbarg); \ 13388c2ecf20Sopenharmony_ci } \ 13398c2ecf20Sopenharmony_ci} while (0) 13408c2ecf20Sopenharmony_ci 13418c2ecf20Sopenharmony_ci#define bna_stats_mod_uninit(_stats_mod) \ 13428c2ecf20Sopenharmony_cido { \ 13438c2ecf20Sopenharmony_ci} while (0) 13448c2ecf20Sopenharmony_ci 13458c2ecf20Sopenharmony_ci#define bna_stats_mod_start(_stats_mod) \ 13468c2ecf20Sopenharmony_cido { \ 13478c2ecf20Sopenharmony_ci (_stats_mod)->ioc_ready = true; \ 13488c2ecf20Sopenharmony_ci} while (0) 13498c2ecf20Sopenharmony_ci 13508c2ecf20Sopenharmony_ci#define bna_stats_mod_stop(_stats_mod) \ 13518c2ecf20Sopenharmony_cido { \ 13528c2ecf20Sopenharmony_ci (_stats_mod)->ioc_ready = false; \ 13538c2ecf20Sopenharmony_ci} while (0) 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_ci#define bna_stats_mod_fail(_stats_mod) \ 13568c2ecf20Sopenharmony_cido { \ 13578c2ecf20Sopenharmony_ci (_stats_mod)->ioc_ready = false; \ 13588c2ecf20Sopenharmony_ci (_stats_mod)->stats_get_busy = false; \ 13598c2ecf20Sopenharmony_ci (_stats_mod)->stats_clr_busy = false; \ 13608c2ecf20Sopenharmony_ci} while (0) 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_cistatic void bna_bfi_attr_get(struct bna_ioceth *ioceth); 13638c2ecf20Sopenharmony_ci 13648c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, stopped, struct bna_ioceth, 13658c2ecf20Sopenharmony_ci enum bna_ioceth_event); 13668c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, ioc_ready_wait, struct bna_ioceth, 13678c2ecf20Sopenharmony_ci enum bna_ioceth_event); 13688c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, enet_attr_wait, struct bna_ioceth, 13698c2ecf20Sopenharmony_ci enum bna_ioceth_event); 13708c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, ready, struct bna_ioceth, 13718c2ecf20Sopenharmony_ci enum bna_ioceth_event); 13728c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, last_resp_wait, struct bna_ioceth, 13738c2ecf20Sopenharmony_ci enum bna_ioceth_event); 13748c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, enet_stop_wait, struct bna_ioceth, 13758c2ecf20Sopenharmony_ci enum bna_ioceth_event); 13768c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, ioc_disable_wait, struct bna_ioceth, 13778c2ecf20Sopenharmony_ci enum bna_ioceth_event); 13788c2ecf20Sopenharmony_cibfa_fsm_state_decl(bna_ioceth, failed, struct bna_ioceth, 13798c2ecf20Sopenharmony_ci enum bna_ioceth_event); 13808c2ecf20Sopenharmony_ci 13818c2ecf20Sopenharmony_cistatic void 13828c2ecf20Sopenharmony_cibna_ioceth_sm_stopped_entry(struct bna_ioceth *ioceth) 13838c2ecf20Sopenharmony_ci{ 13848c2ecf20Sopenharmony_ci call_ioceth_stop_cbfn(ioceth); 13858c2ecf20Sopenharmony_ci} 13868c2ecf20Sopenharmony_ci 13878c2ecf20Sopenharmony_cistatic void 13888c2ecf20Sopenharmony_cibna_ioceth_sm_stopped(struct bna_ioceth *ioceth, 13898c2ecf20Sopenharmony_ci enum bna_ioceth_event event) 13908c2ecf20Sopenharmony_ci{ 13918c2ecf20Sopenharmony_ci switch (event) { 13928c2ecf20Sopenharmony_ci case IOCETH_E_ENABLE: 13938c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_ready_wait); 13948c2ecf20Sopenharmony_ci bfa_nw_ioc_enable(&ioceth->ioc); 13958c2ecf20Sopenharmony_ci break; 13968c2ecf20Sopenharmony_ci 13978c2ecf20Sopenharmony_ci case IOCETH_E_DISABLE: 13988c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped); 13998c2ecf20Sopenharmony_ci break; 14008c2ecf20Sopenharmony_ci 14018c2ecf20Sopenharmony_ci case IOCETH_E_IOC_RESET: 14028c2ecf20Sopenharmony_ci enable_mbox_intr(ioceth); 14038c2ecf20Sopenharmony_ci break; 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci case IOCETH_E_IOC_FAILED: 14068c2ecf20Sopenharmony_ci disable_mbox_intr(ioceth); 14078c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed); 14088c2ecf20Sopenharmony_ci break; 14098c2ecf20Sopenharmony_ci 14108c2ecf20Sopenharmony_ci default: 14118c2ecf20Sopenharmony_ci bfa_sm_fault(event); 14128c2ecf20Sopenharmony_ci } 14138c2ecf20Sopenharmony_ci} 14148c2ecf20Sopenharmony_ci 14158c2ecf20Sopenharmony_cistatic void 14168c2ecf20Sopenharmony_cibna_ioceth_sm_ioc_ready_wait_entry(struct bna_ioceth *ioceth) 14178c2ecf20Sopenharmony_ci{ 14188c2ecf20Sopenharmony_ci /** 14198c2ecf20Sopenharmony_ci * Do not call bfa_nw_ioc_enable() here. It must be called in the 14208c2ecf20Sopenharmony_ci * previous state due to failed -> ioc_ready_wait transition. 14218c2ecf20Sopenharmony_ci */ 14228c2ecf20Sopenharmony_ci} 14238c2ecf20Sopenharmony_ci 14248c2ecf20Sopenharmony_cistatic void 14258c2ecf20Sopenharmony_cibna_ioceth_sm_ioc_ready_wait(struct bna_ioceth *ioceth, 14268c2ecf20Sopenharmony_ci enum bna_ioceth_event event) 14278c2ecf20Sopenharmony_ci{ 14288c2ecf20Sopenharmony_ci switch (event) { 14298c2ecf20Sopenharmony_ci case IOCETH_E_DISABLE: 14308c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait); 14318c2ecf20Sopenharmony_ci bfa_nw_ioc_disable(&ioceth->ioc); 14328c2ecf20Sopenharmony_ci break; 14338c2ecf20Sopenharmony_ci 14348c2ecf20Sopenharmony_ci case IOCETH_E_IOC_RESET: 14358c2ecf20Sopenharmony_ci enable_mbox_intr(ioceth); 14368c2ecf20Sopenharmony_ci break; 14378c2ecf20Sopenharmony_ci 14388c2ecf20Sopenharmony_ci case IOCETH_E_IOC_FAILED: 14398c2ecf20Sopenharmony_ci disable_mbox_intr(ioceth); 14408c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed); 14418c2ecf20Sopenharmony_ci break; 14428c2ecf20Sopenharmony_ci 14438c2ecf20Sopenharmony_ci case IOCETH_E_IOC_READY: 14448c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_enet_attr_wait); 14458c2ecf20Sopenharmony_ci break; 14468c2ecf20Sopenharmony_ci 14478c2ecf20Sopenharmony_ci default: 14488c2ecf20Sopenharmony_ci bfa_sm_fault(event); 14498c2ecf20Sopenharmony_ci } 14508c2ecf20Sopenharmony_ci} 14518c2ecf20Sopenharmony_ci 14528c2ecf20Sopenharmony_cistatic void 14538c2ecf20Sopenharmony_cibna_ioceth_sm_enet_attr_wait_entry(struct bna_ioceth *ioceth) 14548c2ecf20Sopenharmony_ci{ 14558c2ecf20Sopenharmony_ci bna_bfi_attr_get(ioceth); 14568c2ecf20Sopenharmony_ci} 14578c2ecf20Sopenharmony_ci 14588c2ecf20Sopenharmony_cistatic void 14598c2ecf20Sopenharmony_cibna_ioceth_sm_enet_attr_wait(struct bna_ioceth *ioceth, 14608c2ecf20Sopenharmony_ci enum bna_ioceth_event event) 14618c2ecf20Sopenharmony_ci{ 14628c2ecf20Sopenharmony_ci switch (event) { 14638c2ecf20Sopenharmony_ci case IOCETH_E_DISABLE: 14648c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_last_resp_wait); 14658c2ecf20Sopenharmony_ci break; 14668c2ecf20Sopenharmony_ci 14678c2ecf20Sopenharmony_ci case IOCETH_E_IOC_FAILED: 14688c2ecf20Sopenharmony_ci disable_mbox_intr(ioceth); 14698c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed); 14708c2ecf20Sopenharmony_ci break; 14718c2ecf20Sopenharmony_ci 14728c2ecf20Sopenharmony_ci case IOCETH_E_ENET_ATTR_RESP: 14738c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_ready); 14748c2ecf20Sopenharmony_ci break; 14758c2ecf20Sopenharmony_ci 14768c2ecf20Sopenharmony_ci default: 14778c2ecf20Sopenharmony_ci bfa_sm_fault(event); 14788c2ecf20Sopenharmony_ci } 14798c2ecf20Sopenharmony_ci} 14808c2ecf20Sopenharmony_ci 14818c2ecf20Sopenharmony_cistatic void 14828c2ecf20Sopenharmony_cibna_ioceth_sm_ready_entry(struct bna_ioceth *ioceth) 14838c2ecf20Sopenharmony_ci{ 14848c2ecf20Sopenharmony_ci bna_enet_start(&ioceth->bna->enet); 14858c2ecf20Sopenharmony_ci bna_stats_mod_start(&ioceth->bna->stats_mod); 14868c2ecf20Sopenharmony_ci bnad_cb_ioceth_ready(ioceth->bna->bnad); 14878c2ecf20Sopenharmony_ci} 14888c2ecf20Sopenharmony_ci 14898c2ecf20Sopenharmony_cistatic void 14908c2ecf20Sopenharmony_cibna_ioceth_sm_ready(struct bna_ioceth *ioceth, enum bna_ioceth_event event) 14918c2ecf20Sopenharmony_ci{ 14928c2ecf20Sopenharmony_ci switch (event) { 14938c2ecf20Sopenharmony_ci case IOCETH_E_DISABLE: 14948c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_enet_stop_wait); 14958c2ecf20Sopenharmony_ci break; 14968c2ecf20Sopenharmony_ci 14978c2ecf20Sopenharmony_ci case IOCETH_E_IOC_FAILED: 14988c2ecf20Sopenharmony_ci disable_mbox_intr(ioceth); 14998c2ecf20Sopenharmony_ci bna_enet_fail(&ioceth->bna->enet); 15008c2ecf20Sopenharmony_ci bna_stats_mod_fail(&ioceth->bna->stats_mod); 15018c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_failed); 15028c2ecf20Sopenharmony_ci break; 15038c2ecf20Sopenharmony_ci 15048c2ecf20Sopenharmony_ci default: 15058c2ecf20Sopenharmony_ci bfa_sm_fault(event); 15068c2ecf20Sopenharmony_ci } 15078c2ecf20Sopenharmony_ci} 15088c2ecf20Sopenharmony_ci 15098c2ecf20Sopenharmony_cistatic void 15108c2ecf20Sopenharmony_cibna_ioceth_sm_last_resp_wait_entry(struct bna_ioceth *ioceth) 15118c2ecf20Sopenharmony_ci{ 15128c2ecf20Sopenharmony_ci} 15138c2ecf20Sopenharmony_ci 15148c2ecf20Sopenharmony_cistatic void 15158c2ecf20Sopenharmony_cibna_ioceth_sm_last_resp_wait(struct bna_ioceth *ioceth, 15168c2ecf20Sopenharmony_ci enum bna_ioceth_event event) 15178c2ecf20Sopenharmony_ci{ 15188c2ecf20Sopenharmony_ci switch (event) { 15198c2ecf20Sopenharmony_ci case IOCETH_E_IOC_FAILED: 15208c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait); 15218c2ecf20Sopenharmony_ci disable_mbox_intr(ioceth); 15228c2ecf20Sopenharmony_ci bfa_nw_ioc_disable(&ioceth->ioc); 15238c2ecf20Sopenharmony_ci break; 15248c2ecf20Sopenharmony_ci 15258c2ecf20Sopenharmony_ci case IOCETH_E_ENET_ATTR_RESP: 15268c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait); 15278c2ecf20Sopenharmony_ci bfa_nw_ioc_disable(&ioceth->ioc); 15288c2ecf20Sopenharmony_ci break; 15298c2ecf20Sopenharmony_ci 15308c2ecf20Sopenharmony_ci default: 15318c2ecf20Sopenharmony_ci bfa_sm_fault(event); 15328c2ecf20Sopenharmony_ci } 15338c2ecf20Sopenharmony_ci} 15348c2ecf20Sopenharmony_ci 15358c2ecf20Sopenharmony_cistatic void 15368c2ecf20Sopenharmony_cibna_ioceth_sm_enet_stop_wait_entry(struct bna_ioceth *ioceth) 15378c2ecf20Sopenharmony_ci{ 15388c2ecf20Sopenharmony_ci bna_stats_mod_stop(&ioceth->bna->stats_mod); 15398c2ecf20Sopenharmony_ci bna_enet_stop(&ioceth->bna->enet); 15408c2ecf20Sopenharmony_ci} 15418c2ecf20Sopenharmony_ci 15428c2ecf20Sopenharmony_cistatic void 15438c2ecf20Sopenharmony_cibna_ioceth_sm_enet_stop_wait(struct bna_ioceth *ioceth, 15448c2ecf20Sopenharmony_ci enum bna_ioceth_event event) 15458c2ecf20Sopenharmony_ci{ 15468c2ecf20Sopenharmony_ci switch (event) { 15478c2ecf20Sopenharmony_ci case IOCETH_E_IOC_FAILED: 15488c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait); 15498c2ecf20Sopenharmony_ci disable_mbox_intr(ioceth); 15508c2ecf20Sopenharmony_ci bna_enet_fail(&ioceth->bna->enet); 15518c2ecf20Sopenharmony_ci bna_stats_mod_fail(&ioceth->bna->stats_mod); 15528c2ecf20Sopenharmony_ci bfa_nw_ioc_disable(&ioceth->ioc); 15538c2ecf20Sopenharmony_ci break; 15548c2ecf20Sopenharmony_ci 15558c2ecf20Sopenharmony_ci case IOCETH_E_ENET_STOPPED: 15568c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait); 15578c2ecf20Sopenharmony_ci bfa_nw_ioc_disable(&ioceth->ioc); 15588c2ecf20Sopenharmony_ci break; 15598c2ecf20Sopenharmony_ci 15608c2ecf20Sopenharmony_ci default: 15618c2ecf20Sopenharmony_ci bfa_sm_fault(event); 15628c2ecf20Sopenharmony_ci } 15638c2ecf20Sopenharmony_ci} 15648c2ecf20Sopenharmony_ci 15658c2ecf20Sopenharmony_cistatic void 15668c2ecf20Sopenharmony_cibna_ioceth_sm_ioc_disable_wait_entry(struct bna_ioceth *ioceth) 15678c2ecf20Sopenharmony_ci{ 15688c2ecf20Sopenharmony_ci} 15698c2ecf20Sopenharmony_ci 15708c2ecf20Sopenharmony_cistatic void 15718c2ecf20Sopenharmony_cibna_ioceth_sm_ioc_disable_wait(struct bna_ioceth *ioceth, 15728c2ecf20Sopenharmony_ci enum bna_ioceth_event event) 15738c2ecf20Sopenharmony_ci{ 15748c2ecf20Sopenharmony_ci switch (event) { 15758c2ecf20Sopenharmony_ci case IOCETH_E_IOC_DISABLED: 15768c2ecf20Sopenharmony_ci disable_mbox_intr(ioceth); 15778c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped); 15788c2ecf20Sopenharmony_ci break; 15798c2ecf20Sopenharmony_ci 15808c2ecf20Sopenharmony_ci case IOCETH_E_ENET_STOPPED: 15818c2ecf20Sopenharmony_ci /* This event is received due to enet failing */ 15828c2ecf20Sopenharmony_ci /* No-op */ 15838c2ecf20Sopenharmony_ci break; 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_ci default: 15868c2ecf20Sopenharmony_ci bfa_sm_fault(event); 15878c2ecf20Sopenharmony_ci } 15888c2ecf20Sopenharmony_ci} 15898c2ecf20Sopenharmony_ci 15908c2ecf20Sopenharmony_cistatic void 15918c2ecf20Sopenharmony_cibna_ioceth_sm_failed_entry(struct bna_ioceth *ioceth) 15928c2ecf20Sopenharmony_ci{ 15938c2ecf20Sopenharmony_ci bnad_cb_ioceth_failed(ioceth->bna->bnad); 15948c2ecf20Sopenharmony_ci} 15958c2ecf20Sopenharmony_ci 15968c2ecf20Sopenharmony_cistatic void 15978c2ecf20Sopenharmony_cibna_ioceth_sm_failed(struct bna_ioceth *ioceth, 15988c2ecf20Sopenharmony_ci enum bna_ioceth_event event) 15998c2ecf20Sopenharmony_ci{ 16008c2ecf20Sopenharmony_ci switch (event) { 16018c2ecf20Sopenharmony_ci case IOCETH_E_DISABLE: 16028c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_disable_wait); 16038c2ecf20Sopenharmony_ci bfa_nw_ioc_disable(&ioceth->ioc); 16048c2ecf20Sopenharmony_ci break; 16058c2ecf20Sopenharmony_ci 16068c2ecf20Sopenharmony_ci case IOCETH_E_IOC_RESET: 16078c2ecf20Sopenharmony_ci enable_mbox_intr(ioceth); 16088c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_ioc_ready_wait); 16098c2ecf20Sopenharmony_ci break; 16108c2ecf20Sopenharmony_ci 16118c2ecf20Sopenharmony_ci case IOCETH_E_IOC_FAILED: 16128c2ecf20Sopenharmony_ci break; 16138c2ecf20Sopenharmony_ci 16148c2ecf20Sopenharmony_ci default: 16158c2ecf20Sopenharmony_ci bfa_sm_fault(event); 16168c2ecf20Sopenharmony_ci } 16178c2ecf20Sopenharmony_ci} 16188c2ecf20Sopenharmony_ci 16198c2ecf20Sopenharmony_cistatic void 16208c2ecf20Sopenharmony_cibna_bfi_attr_get(struct bna_ioceth *ioceth) 16218c2ecf20Sopenharmony_ci{ 16228c2ecf20Sopenharmony_ci struct bfi_enet_attr_req *attr_req = &ioceth->attr_req; 16238c2ecf20Sopenharmony_ci 16248c2ecf20Sopenharmony_ci bfi_msgq_mhdr_set(attr_req->mh, BFI_MC_ENET, 16258c2ecf20Sopenharmony_ci BFI_ENET_H2I_GET_ATTR_REQ, 0, 0); 16268c2ecf20Sopenharmony_ci attr_req->mh.num_entries = htons( 16278c2ecf20Sopenharmony_ci bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_attr_req))); 16288c2ecf20Sopenharmony_ci bfa_msgq_cmd_set(&ioceth->msgq_cmd, NULL, NULL, 16298c2ecf20Sopenharmony_ci sizeof(struct bfi_enet_attr_req), &attr_req->mh); 16308c2ecf20Sopenharmony_ci bfa_msgq_cmd_post(&ioceth->bna->msgq, &ioceth->msgq_cmd); 16318c2ecf20Sopenharmony_ci} 16328c2ecf20Sopenharmony_ci 16338c2ecf20Sopenharmony_ci/* IOC callback functions */ 16348c2ecf20Sopenharmony_ci 16358c2ecf20Sopenharmony_cistatic void 16368c2ecf20Sopenharmony_cibna_cb_ioceth_enable(void *arg, enum bfa_status error) 16378c2ecf20Sopenharmony_ci{ 16388c2ecf20Sopenharmony_ci struct bna_ioceth *ioceth = (struct bna_ioceth *)arg; 16398c2ecf20Sopenharmony_ci 16408c2ecf20Sopenharmony_ci if (error) 16418c2ecf20Sopenharmony_ci bfa_fsm_send_event(ioceth, IOCETH_E_IOC_FAILED); 16428c2ecf20Sopenharmony_ci else 16438c2ecf20Sopenharmony_ci bfa_fsm_send_event(ioceth, IOCETH_E_IOC_READY); 16448c2ecf20Sopenharmony_ci} 16458c2ecf20Sopenharmony_ci 16468c2ecf20Sopenharmony_cistatic void 16478c2ecf20Sopenharmony_cibna_cb_ioceth_disable(void *arg) 16488c2ecf20Sopenharmony_ci{ 16498c2ecf20Sopenharmony_ci struct bna_ioceth *ioceth = (struct bna_ioceth *)arg; 16508c2ecf20Sopenharmony_ci 16518c2ecf20Sopenharmony_ci bfa_fsm_send_event(ioceth, IOCETH_E_IOC_DISABLED); 16528c2ecf20Sopenharmony_ci} 16538c2ecf20Sopenharmony_ci 16548c2ecf20Sopenharmony_cistatic void 16558c2ecf20Sopenharmony_cibna_cb_ioceth_hbfail(void *arg) 16568c2ecf20Sopenharmony_ci{ 16578c2ecf20Sopenharmony_ci struct bna_ioceth *ioceth = (struct bna_ioceth *)arg; 16588c2ecf20Sopenharmony_ci 16598c2ecf20Sopenharmony_ci bfa_fsm_send_event(ioceth, IOCETH_E_IOC_FAILED); 16608c2ecf20Sopenharmony_ci} 16618c2ecf20Sopenharmony_ci 16628c2ecf20Sopenharmony_cistatic void 16638c2ecf20Sopenharmony_cibna_cb_ioceth_reset(void *arg) 16648c2ecf20Sopenharmony_ci{ 16658c2ecf20Sopenharmony_ci struct bna_ioceth *ioceth = (struct bna_ioceth *)arg; 16668c2ecf20Sopenharmony_ci 16678c2ecf20Sopenharmony_ci bfa_fsm_send_event(ioceth, IOCETH_E_IOC_RESET); 16688c2ecf20Sopenharmony_ci} 16698c2ecf20Sopenharmony_ci 16708c2ecf20Sopenharmony_cistatic struct bfa_ioc_cbfn bna_ioceth_cbfn = { 16718c2ecf20Sopenharmony_ci .enable_cbfn = bna_cb_ioceth_enable, 16728c2ecf20Sopenharmony_ci .disable_cbfn = bna_cb_ioceth_disable, 16738c2ecf20Sopenharmony_ci .hbfail_cbfn = bna_cb_ioceth_hbfail, 16748c2ecf20Sopenharmony_ci .reset_cbfn = bna_cb_ioceth_reset 16758c2ecf20Sopenharmony_ci}; 16768c2ecf20Sopenharmony_ci 16778c2ecf20Sopenharmony_cistatic void bna_attr_init(struct bna_ioceth *ioceth) 16788c2ecf20Sopenharmony_ci{ 16798c2ecf20Sopenharmony_ci ioceth->attr.num_txq = BFI_ENET_DEF_TXQ; 16808c2ecf20Sopenharmony_ci ioceth->attr.num_rxp = BFI_ENET_DEF_RXP; 16818c2ecf20Sopenharmony_ci ioceth->attr.num_ucmac = BFI_ENET_DEF_UCAM; 16828c2ecf20Sopenharmony_ci ioceth->attr.num_mcmac = BFI_ENET_MAX_MCAM; 16838c2ecf20Sopenharmony_ci ioceth->attr.max_rit_size = BFI_ENET_DEF_RITSZ; 16848c2ecf20Sopenharmony_ci ioceth->attr.fw_query_complete = false; 16858c2ecf20Sopenharmony_ci} 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_cistatic void 16888c2ecf20Sopenharmony_cibna_ioceth_init(struct bna_ioceth *ioceth, struct bna *bna, 16898c2ecf20Sopenharmony_ci struct bna_res_info *res_info) 16908c2ecf20Sopenharmony_ci{ 16918c2ecf20Sopenharmony_ci u64 dma; 16928c2ecf20Sopenharmony_ci u8 *kva; 16938c2ecf20Sopenharmony_ci 16948c2ecf20Sopenharmony_ci ioceth->bna = bna; 16958c2ecf20Sopenharmony_ci 16968c2ecf20Sopenharmony_ci /** 16978c2ecf20Sopenharmony_ci * Attach IOC and claim: 16988c2ecf20Sopenharmony_ci * 1. DMA memory for IOC attributes 16998c2ecf20Sopenharmony_ci * 2. Kernel memory for FW trace 17008c2ecf20Sopenharmony_ci */ 17018c2ecf20Sopenharmony_ci bfa_nw_ioc_attach(&ioceth->ioc, ioceth, &bna_ioceth_cbfn); 17028c2ecf20Sopenharmony_ci bfa_nw_ioc_pci_init(&ioceth->ioc, &bna->pcidev, BFI_PCIFN_CLASS_ETH); 17038c2ecf20Sopenharmony_ci 17048c2ecf20Sopenharmony_ci BNA_GET_DMA_ADDR( 17058c2ecf20Sopenharmony_ci &res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma); 17068c2ecf20Sopenharmony_ci kva = res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva; 17078c2ecf20Sopenharmony_ci bfa_nw_ioc_mem_claim(&ioceth->ioc, kva, dma); 17088c2ecf20Sopenharmony_ci 17098c2ecf20Sopenharmony_ci kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva; 17108c2ecf20Sopenharmony_ci bfa_nw_ioc_debug_memclaim(&ioceth->ioc, kva); 17118c2ecf20Sopenharmony_ci 17128c2ecf20Sopenharmony_ci /** 17138c2ecf20Sopenharmony_ci * Attach common modules (Diag, SFP, CEE, Port) and claim respective 17148c2ecf20Sopenharmony_ci * DMA memory. 17158c2ecf20Sopenharmony_ci */ 17168c2ecf20Sopenharmony_ci BNA_GET_DMA_ADDR( 17178c2ecf20Sopenharmony_ci &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma); 17188c2ecf20Sopenharmony_ci kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva; 17198c2ecf20Sopenharmony_ci bfa_nw_cee_attach(&bna->cee, &ioceth->ioc, bna); 17208c2ecf20Sopenharmony_ci bfa_nw_cee_mem_claim(&bna->cee, kva, dma); 17218c2ecf20Sopenharmony_ci kva += bfa_nw_cee_meminfo(); 17228c2ecf20Sopenharmony_ci dma += bfa_nw_cee_meminfo(); 17238c2ecf20Sopenharmony_ci 17248c2ecf20Sopenharmony_ci bfa_nw_flash_attach(&bna->flash, &ioceth->ioc, bna); 17258c2ecf20Sopenharmony_ci bfa_nw_flash_memclaim(&bna->flash, kva, dma); 17268c2ecf20Sopenharmony_ci kva += bfa_nw_flash_meminfo(); 17278c2ecf20Sopenharmony_ci dma += bfa_nw_flash_meminfo(); 17288c2ecf20Sopenharmony_ci 17298c2ecf20Sopenharmony_ci bfa_msgq_attach(&bna->msgq, &ioceth->ioc); 17308c2ecf20Sopenharmony_ci bfa_msgq_memclaim(&bna->msgq, kva, dma); 17318c2ecf20Sopenharmony_ci bfa_msgq_regisr(&bna->msgq, BFI_MC_ENET, bna_msgq_rsp_handler, bna); 17328c2ecf20Sopenharmony_ci kva += bfa_msgq_meminfo(); 17338c2ecf20Sopenharmony_ci dma += bfa_msgq_meminfo(); 17348c2ecf20Sopenharmony_ci 17358c2ecf20Sopenharmony_ci ioceth->stop_cbfn = NULL; 17368c2ecf20Sopenharmony_ci ioceth->stop_cbarg = NULL; 17378c2ecf20Sopenharmony_ci 17388c2ecf20Sopenharmony_ci bna_attr_init(ioceth); 17398c2ecf20Sopenharmony_ci 17408c2ecf20Sopenharmony_ci bfa_fsm_set_state(ioceth, bna_ioceth_sm_stopped); 17418c2ecf20Sopenharmony_ci} 17428c2ecf20Sopenharmony_ci 17438c2ecf20Sopenharmony_cistatic void 17448c2ecf20Sopenharmony_cibna_ioceth_uninit(struct bna_ioceth *ioceth) 17458c2ecf20Sopenharmony_ci{ 17468c2ecf20Sopenharmony_ci bfa_nw_ioc_detach(&ioceth->ioc); 17478c2ecf20Sopenharmony_ci 17488c2ecf20Sopenharmony_ci ioceth->bna = NULL; 17498c2ecf20Sopenharmony_ci} 17508c2ecf20Sopenharmony_ci 17518c2ecf20Sopenharmony_civoid 17528c2ecf20Sopenharmony_cibna_ioceth_enable(struct bna_ioceth *ioceth) 17538c2ecf20Sopenharmony_ci{ 17548c2ecf20Sopenharmony_ci if (ioceth->fsm == (bfa_fsm_t)bna_ioceth_sm_ready) { 17558c2ecf20Sopenharmony_ci bnad_cb_ioceth_ready(ioceth->bna->bnad); 17568c2ecf20Sopenharmony_ci return; 17578c2ecf20Sopenharmony_ci } 17588c2ecf20Sopenharmony_ci 17598c2ecf20Sopenharmony_ci if (ioceth->fsm == (bfa_fsm_t)bna_ioceth_sm_stopped) 17608c2ecf20Sopenharmony_ci bfa_fsm_send_event(ioceth, IOCETH_E_ENABLE); 17618c2ecf20Sopenharmony_ci} 17628c2ecf20Sopenharmony_ci 17638c2ecf20Sopenharmony_civoid 17648c2ecf20Sopenharmony_cibna_ioceth_disable(struct bna_ioceth *ioceth, enum bna_cleanup_type type) 17658c2ecf20Sopenharmony_ci{ 17668c2ecf20Sopenharmony_ci if (type == BNA_SOFT_CLEANUP) { 17678c2ecf20Sopenharmony_ci bnad_cb_ioceth_disabled(ioceth->bna->bnad); 17688c2ecf20Sopenharmony_ci return; 17698c2ecf20Sopenharmony_ci } 17708c2ecf20Sopenharmony_ci 17718c2ecf20Sopenharmony_ci ioceth->stop_cbfn = bnad_cb_ioceth_disabled; 17728c2ecf20Sopenharmony_ci ioceth->stop_cbarg = ioceth->bna->bnad; 17738c2ecf20Sopenharmony_ci 17748c2ecf20Sopenharmony_ci bfa_fsm_send_event(ioceth, IOCETH_E_DISABLE); 17758c2ecf20Sopenharmony_ci} 17768c2ecf20Sopenharmony_ci 17778c2ecf20Sopenharmony_cistatic void 17788c2ecf20Sopenharmony_cibna_ucam_mod_init(struct bna_ucam_mod *ucam_mod, struct bna *bna, 17798c2ecf20Sopenharmony_ci struct bna_res_info *res_info) 17808c2ecf20Sopenharmony_ci{ 17818c2ecf20Sopenharmony_ci int i; 17828c2ecf20Sopenharmony_ci 17838c2ecf20Sopenharmony_ci ucam_mod->ucmac = (struct bna_mac *) 17848c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mdl[0].kva; 17858c2ecf20Sopenharmony_ci 17868c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&ucam_mod->free_q); 17878c2ecf20Sopenharmony_ci for (i = 0; i < bna->ioceth.attr.num_ucmac; i++) 17888c2ecf20Sopenharmony_ci list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->free_q); 17898c2ecf20Sopenharmony_ci 17908c2ecf20Sopenharmony_ci /* A separate queue to allow synchronous setting of a list of MACs */ 17918c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&ucam_mod->del_q); 17928c2ecf20Sopenharmony_ci for (; i < (bna->ioceth.attr.num_ucmac * 2); i++) 17938c2ecf20Sopenharmony_ci list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->del_q); 17948c2ecf20Sopenharmony_ci 17958c2ecf20Sopenharmony_ci ucam_mod->bna = bna; 17968c2ecf20Sopenharmony_ci} 17978c2ecf20Sopenharmony_ci 17988c2ecf20Sopenharmony_cistatic void 17998c2ecf20Sopenharmony_cibna_ucam_mod_uninit(struct bna_ucam_mod *ucam_mod) 18008c2ecf20Sopenharmony_ci{ 18018c2ecf20Sopenharmony_ci ucam_mod->bna = NULL; 18028c2ecf20Sopenharmony_ci} 18038c2ecf20Sopenharmony_ci 18048c2ecf20Sopenharmony_cistatic void 18058c2ecf20Sopenharmony_cibna_mcam_mod_init(struct bna_mcam_mod *mcam_mod, struct bna *bna, 18068c2ecf20Sopenharmony_ci struct bna_res_info *res_info) 18078c2ecf20Sopenharmony_ci{ 18088c2ecf20Sopenharmony_ci int i; 18098c2ecf20Sopenharmony_ci 18108c2ecf20Sopenharmony_ci mcam_mod->mcmac = (struct bna_mac *) 18118c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mdl[0].kva; 18128c2ecf20Sopenharmony_ci 18138c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&mcam_mod->free_q); 18148c2ecf20Sopenharmony_ci for (i = 0; i < bna->ioceth.attr.num_mcmac; i++) 18158c2ecf20Sopenharmony_ci list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->free_q); 18168c2ecf20Sopenharmony_ci 18178c2ecf20Sopenharmony_ci mcam_mod->mchandle = (struct bna_mcam_handle *) 18188c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.mdl[0].kva; 18198c2ecf20Sopenharmony_ci 18208c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&mcam_mod->free_handle_q); 18218c2ecf20Sopenharmony_ci for (i = 0; i < bna->ioceth.attr.num_mcmac; i++) 18228c2ecf20Sopenharmony_ci list_add_tail(&mcam_mod->mchandle[i].qe, 18238c2ecf20Sopenharmony_ci &mcam_mod->free_handle_q); 18248c2ecf20Sopenharmony_ci 18258c2ecf20Sopenharmony_ci /* A separate queue to allow synchronous setting of a list of MACs */ 18268c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&mcam_mod->del_q); 18278c2ecf20Sopenharmony_ci for (; i < (bna->ioceth.attr.num_mcmac * 2); i++) 18288c2ecf20Sopenharmony_ci list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->del_q); 18298c2ecf20Sopenharmony_ci 18308c2ecf20Sopenharmony_ci mcam_mod->bna = bna; 18318c2ecf20Sopenharmony_ci} 18328c2ecf20Sopenharmony_ci 18338c2ecf20Sopenharmony_cistatic void 18348c2ecf20Sopenharmony_cibna_mcam_mod_uninit(struct bna_mcam_mod *mcam_mod) 18358c2ecf20Sopenharmony_ci{ 18368c2ecf20Sopenharmony_ci mcam_mod->bna = NULL; 18378c2ecf20Sopenharmony_ci} 18388c2ecf20Sopenharmony_ci 18398c2ecf20Sopenharmony_cistatic void 18408c2ecf20Sopenharmony_cibna_bfi_stats_get(struct bna *bna) 18418c2ecf20Sopenharmony_ci{ 18428c2ecf20Sopenharmony_ci struct bfi_enet_stats_req *stats_req = &bna->stats_mod.stats_get; 18438c2ecf20Sopenharmony_ci 18448c2ecf20Sopenharmony_ci bna->stats_mod.stats_get_busy = true; 18458c2ecf20Sopenharmony_ci 18468c2ecf20Sopenharmony_ci bfi_msgq_mhdr_set(stats_req->mh, BFI_MC_ENET, 18478c2ecf20Sopenharmony_ci BFI_ENET_H2I_STATS_GET_REQ, 0, 0); 18488c2ecf20Sopenharmony_ci stats_req->mh.num_entries = htons( 18498c2ecf20Sopenharmony_ci bfi_msgq_num_cmd_entries(sizeof(struct bfi_enet_stats_req))); 18508c2ecf20Sopenharmony_ci stats_req->stats_mask = htons(BFI_ENET_STATS_ALL); 18518c2ecf20Sopenharmony_ci stats_req->tx_enet_mask = htonl(bna->tx_mod.rid_mask); 18528c2ecf20Sopenharmony_ci stats_req->rx_enet_mask = htonl(bna->rx_mod.rid_mask); 18538c2ecf20Sopenharmony_ci stats_req->host_buffer.a32.addr_hi = bna->stats.hw_stats_dma.msb; 18548c2ecf20Sopenharmony_ci stats_req->host_buffer.a32.addr_lo = bna->stats.hw_stats_dma.lsb; 18558c2ecf20Sopenharmony_ci 18568c2ecf20Sopenharmony_ci bfa_msgq_cmd_set(&bna->stats_mod.stats_get_cmd, NULL, NULL, 18578c2ecf20Sopenharmony_ci sizeof(struct bfi_enet_stats_req), &stats_req->mh); 18588c2ecf20Sopenharmony_ci bfa_msgq_cmd_post(&bna->msgq, &bna->stats_mod.stats_get_cmd); 18598c2ecf20Sopenharmony_ci} 18608c2ecf20Sopenharmony_ci 18618c2ecf20Sopenharmony_civoid 18628c2ecf20Sopenharmony_cibna_res_req(struct bna_res_info *res_info) 18638c2ecf20Sopenharmony_ci{ 18648c2ecf20Sopenharmony_ci /* DMA memory for COMMON_MODULE */ 18658c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_COM].res_type = BNA_RES_T_MEM; 18668c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA; 18678c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1; 18688c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN( 18698c2ecf20Sopenharmony_ci (bfa_nw_cee_meminfo() + 18708c2ecf20Sopenharmony_ci bfa_nw_flash_meminfo() + 18718c2ecf20Sopenharmony_ci bfa_msgq_meminfo()), PAGE_SIZE); 18728c2ecf20Sopenharmony_ci 18738c2ecf20Sopenharmony_ci /* DMA memory for retrieving IOC attributes */ 18748c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM; 18758c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA; 18768c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1; 18778c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len = 18788c2ecf20Sopenharmony_ci ALIGN(bfa_nw_ioc_meminfo(), PAGE_SIZE); 18798c2ecf20Sopenharmony_ci 18808c2ecf20Sopenharmony_ci /* Virtual memory for retreiving fw_trc */ 18818c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM; 18828c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mem_type = BNA_MEM_T_KVA; 18838c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.num = 1; 18848c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.len = BNA_DBG_FWTRC_LEN; 18858c2ecf20Sopenharmony_ci 18868c2ecf20Sopenharmony_ci /* DMA memory for retreiving stats */ 18878c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_STATS].res_type = BNA_RES_T_MEM; 18888c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mem_type = BNA_MEM_T_DMA; 18898c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.num = 1; 18908c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.len = 18918c2ecf20Sopenharmony_ci ALIGN(sizeof(struct bfi_enet_stats), 18928c2ecf20Sopenharmony_ci PAGE_SIZE); 18938c2ecf20Sopenharmony_ci} 18948c2ecf20Sopenharmony_ci 18958c2ecf20Sopenharmony_civoid 18968c2ecf20Sopenharmony_cibna_mod_res_req(struct bna *bna, struct bna_res_info *res_info) 18978c2ecf20Sopenharmony_ci{ 18988c2ecf20Sopenharmony_ci struct bna_attr *attr = &bna->ioceth.attr; 18998c2ecf20Sopenharmony_ci 19008c2ecf20Sopenharmony_ci /* Virtual memory for Tx objects - stored by Tx module */ 19018c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_type = BNA_RES_T_MEM; 19028c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.mem_type = 19038c2ecf20Sopenharmony_ci BNA_MEM_T_KVA; 19048c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.num = 1; 19058c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_TX_ARRAY].res_u.mem_info.len = 19068c2ecf20Sopenharmony_ci attr->num_txq * sizeof(struct bna_tx); 19078c2ecf20Sopenharmony_ci 19088c2ecf20Sopenharmony_ci /* Virtual memory for TxQ - stored by Tx module */ 19098c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_type = BNA_RES_T_MEM; 19108c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mem_type = 19118c2ecf20Sopenharmony_ci BNA_MEM_T_KVA; 19128c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.num = 1; 19138c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.len = 19148c2ecf20Sopenharmony_ci attr->num_txq * sizeof(struct bna_txq); 19158c2ecf20Sopenharmony_ci 19168c2ecf20Sopenharmony_ci /* Virtual memory for Rx objects - stored by Rx module */ 19178c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_type = BNA_RES_T_MEM; 19188c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.mem_type = 19198c2ecf20Sopenharmony_ci BNA_MEM_T_KVA; 19208c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.num = 1; 19218c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RX_ARRAY].res_u.mem_info.len = 19228c2ecf20Sopenharmony_ci attr->num_rxp * sizeof(struct bna_rx); 19238c2ecf20Sopenharmony_ci 19248c2ecf20Sopenharmony_ci /* Virtual memory for RxPath - stored by Rx module */ 19258c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_type = BNA_RES_T_MEM; 19268c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mem_type = 19278c2ecf20Sopenharmony_ci BNA_MEM_T_KVA; 19288c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.num = 1; 19298c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RXP_ARRAY].res_u.mem_info.len = 19308c2ecf20Sopenharmony_ci attr->num_rxp * sizeof(struct bna_rxp); 19318c2ecf20Sopenharmony_ci 19328c2ecf20Sopenharmony_ci /* Virtual memory for RxQ - stored by Rx module */ 19338c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_type = BNA_RES_T_MEM; 19348c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mem_type = 19358c2ecf20Sopenharmony_ci BNA_MEM_T_KVA; 19368c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.num = 1; 19378c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.len = 19388c2ecf20Sopenharmony_ci (attr->num_rxp * 2) * sizeof(struct bna_rxq); 19398c2ecf20Sopenharmony_ci 19408c2ecf20Sopenharmony_ci /* Virtual memory for Unicast MAC address - stored by ucam module */ 19418c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_type = BNA_RES_T_MEM; 19428c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mem_type = 19438c2ecf20Sopenharmony_ci BNA_MEM_T_KVA; 19448c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.num = 1; 19458c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.len = 19468c2ecf20Sopenharmony_ci (attr->num_ucmac * 2) * sizeof(struct bna_mac); 19478c2ecf20Sopenharmony_ci 19488c2ecf20Sopenharmony_ci /* Virtual memory for Multicast MAC address - stored by mcam module */ 19498c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_type = BNA_RES_T_MEM; 19508c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mem_type = 19518c2ecf20Sopenharmony_ci BNA_MEM_T_KVA; 19528c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.num = 1; 19538c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.len = 19548c2ecf20Sopenharmony_ci (attr->num_mcmac * 2) * sizeof(struct bna_mac); 19558c2ecf20Sopenharmony_ci 19568c2ecf20Sopenharmony_ci /* Virtual memory for Multicast handle - stored by mcam module */ 19578c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_type = BNA_RES_T_MEM; 19588c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.mem_type = 19598c2ecf20Sopenharmony_ci BNA_MEM_T_KVA; 19608c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.num = 1; 19618c2ecf20Sopenharmony_ci res_info[BNA_MOD_RES_MEM_T_MCHANDLE_ARRAY].res_u.mem_info.len = 19628c2ecf20Sopenharmony_ci attr->num_mcmac * sizeof(struct bna_mcam_handle); 19638c2ecf20Sopenharmony_ci} 19648c2ecf20Sopenharmony_ci 19658c2ecf20Sopenharmony_civoid 19668c2ecf20Sopenharmony_cibna_init(struct bna *bna, struct bnad *bnad, 19678c2ecf20Sopenharmony_ci struct bfa_pcidev *pcidev, struct bna_res_info *res_info) 19688c2ecf20Sopenharmony_ci{ 19698c2ecf20Sopenharmony_ci bna->bnad = bnad; 19708c2ecf20Sopenharmony_ci bna->pcidev = *pcidev; 19718c2ecf20Sopenharmony_ci 19728c2ecf20Sopenharmony_ci bna->stats.hw_stats_kva = (struct bfi_enet_stats *) 19738c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].kva; 19748c2ecf20Sopenharmony_ci bna->stats.hw_stats_dma.msb = 19758c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.msb; 19768c2ecf20Sopenharmony_ci bna->stats.hw_stats_dma.lsb = 19778c2ecf20Sopenharmony_ci res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.lsb; 19788c2ecf20Sopenharmony_ci 19798c2ecf20Sopenharmony_ci bna_reg_addr_init(bna, &bna->pcidev); 19808c2ecf20Sopenharmony_ci 19818c2ecf20Sopenharmony_ci /* Also initializes diag, cee, sfp, phy_port, msgq */ 19828c2ecf20Sopenharmony_ci bna_ioceth_init(&bna->ioceth, bna, res_info); 19838c2ecf20Sopenharmony_ci 19848c2ecf20Sopenharmony_ci bna_enet_init(&bna->enet, bna); 19858c2ecf20Sopenharmony_ci bna_ethport_init(&bna->ethport, bna); 19868c2ecf20Sopenharmony_ci} 19878c2ecf20Sopenharmony_ci 19888c2ecf20Sopenharmony_civoid 19898c2ecf20Sopenharmony_cibna_mod_init(struct bna *bna, struct bna_res_info *res_info) 19908c2ecf20Sopenharmony_ci{ 19918c2ecf20Sopenharmony_ci bna_tx_mod_init(&bna->tx_mod, bna, res_info); 19928c2ecf20Sopenharmony_ci 19938c2ecf20Sopenharmony_ci bna_rx_mod_init(&bna->rx_mod, bna, res_info); 19948c2ecf20Sopenharmony_ci 19958c2ecf20Sopenharmony_ci bna_ucam_mod_init(&bna->ucam_mod, bna, res_info); 19968c2ecf20Sopenharmony_ci 19978c2ecf20Sopenharmony_ci bna_mcam_mod_init(&bna->mcam_mod, bna, res_info); 19988c2ecf20Sopenharmony_ci 19998c2ecf20Sopenharmony_ci bna->default_mode_rid = BFI_INVALID_RID; 20008c2ecf20Sopenharmony_ci bna->promisc_rid = BFI_INVALID_RID; 20018c2ecf20Sopenharmony_ci 20028c2ecf20Sopenharmony_ci bna->mod_flags |= BNA_MOD_F_INIT_DONE; 20038c2ecf20Sopenharmony_ci} 20048c2ecf20Sopenharmony_ci 20058c2ecf20Sopenharmony_civoid 20068c2ecf20Sopenharmony_cibna_uninit(struct bna *bna) 20078c2ecf20Sopenharmony_ci{ 20088c2ecf20Sopenharmony_ci if (bna->mod_flags & BNA_MOD_F_INIT_DONE) { 20098c2ecf20Sopenharmony_ci bna_mcam_mod_uninit(&bna->mcam_mod); 20108c2ecf20Sopenharmony_ci bna_ucam_mod_uninit(&bna->ucam_mod); 20118c2ecf20Sopenharmony_ci bna_rx_mod_uninit(&bna->rx_mod); 20128c2ecf20Sopenharmony_ci bna_tx_mod_uninit(&bna->tx_mod); 20138c2ecf20Sopenharmony_ci bna->mod_flags &= ~BNA_MOD_F_INIT_DONE; 20148c2ecf20Sopenharmony_ci } 20158c2ecf20Sopenharmony_ci 20168c2ecf20Sopenharmony_ci bna_stats_mod_uninit(&bna->stats_mod); 20178c2ecf20Sopenharmony_ci bna_ethport_uninit(&bna->ethport); 20188c2ecf20Sopenharmony_ci bna_enet_uninit(&bna->enet); 20198c2ecf20Sopenharmony_ci 20208c2ecf20Sopenharmony_ci bna_ioceth_uninit(&bna->ioceth); 20218c2ecf20Sopenharmony_ci 20228c2ecf20Sopenharmony_ci bna->bnad = NULL; 20238c2ecf20Sopenharmony_ci} 20248c2ecf20Sopenharmony_ci 20258c2ecf20Sopenharmony_ciint 20268c2ecf20Sopenharmony_cibna_num_txq_set(struct bna *bna, int num_txq) 20278c2ecf20Sopenharmony_ci{ 20288c2ecf20Sopenharmony_ci if (bna->ioceth.attr.fw_query_complete && 20298c2ecf20Sopenharmony_ci (num_txq <= bna->ioceth.attr.num_txq)) { 20308c2ecf20Sopenharmony_ci bna->ioceth.attr.num_txq = num_txq; 20318c2ecf20Sopenharmony_ci return BNA_CB_SUCCESS; 20328c2ecf20Sopenharmony_ci } 20338c2ecf20Sopenharmony_ci 20348c2ecf20Sopenharmony_ci return BNA_CB_FAIL; 20358c2ecf20Sopenharmony_ci} 20368c2ecf20Sopenharmony_ci 20378c2ecf20Sopenharmony_ciint 20388c2ecf20Sopenharmony_cibna_num_rxp_set(struct bna *bna, int num_rxp) 20398c2ecf20Sopenharmony_ci{ 20408c2ecf20Sopenharmony_ci if (bna->ioceth.attr.fw_query_complete && 20418c2ecf20Sopenharmony_ci (num_rxp <= bna->ioceth.attr.num_rxp)) { 20428c2ecf20Sopenharmony_ci bna->ioceth.attr.num_rxp = num_rxp; 20438c2ecf20Sopenharmony_ci return BNA_CB_SUCCESS; 20448c2ecf20Sopenharmony_ci } 20458c2ecf20Sopenharmony_ci 20468c2ecf20Sopenharmony_ci return BNA_CB_FAIL; 20478c2ecf20Sopenharmony_ci} 20488c2ecf20Sopenharmony_ci 20498c2ecf20Sopenharmony_cistruct bna_mac * 20508c2ecf20Sopenharmony_cibna_cam_mod_mac_get(struct list_head *head) 20518c2ecf20Sopenharmony_ci{ 20528c2ecf20Sopenharmony_ci struct bna_mac *mac; 20538c2ecf20Sopenharmony_ci 20548c2ecf20Sopenharmony_ci mac = list_first_entry_or_null(head, struct bna_mac, qe); 20558c2ecf20Sopenharmony_ci if (mac) 20568c2ecf20Sopenharmony_ci list_del(&mac->qe); 20578c2ecf20Sopenharmony_ci 20588c2ecf20Sopenharmony_ci return mac; 20598c2ecf20Sopenharmony_ci} 20608c2ecf20Sopenharmony_ci 20618c2ecf20Sopenharmony_cistruct bna_mcam_handle * 20628c2ecf20Sopenharmony_cibna_mcam_mod_handle_get(struct bna_mcam_mod *mcam_mod) 20638c2ecf20Sopenharmony_ci{ 20648c2ecf20Sopenharmony_ci struct bna_mcam_handle *handle; 20658c2ecf20Sopenharmony_ci 20668c2ecf20Sopenharmony_ci handle = list_first_entry_or_null(&mcam_mod->free_handle_q, 20678c2ecf20Sopenharmony_ci struct bna_mcam_handle, qe); 20688c2ecf20Sopenharmony_ci if (handle) 20698c2ecf20Sopenharmony_ci list_del(&handle->qe); 20708c2ecf20Sopenharmony_ci 20718c2ecf20Sopenharmony_ci return handle; 20728c2ecf20Sopenharmony_ci} 20738c2ecf20Sopenharmony_ci 20748c2ecf20Sopenharmony_civoid 20758c2ecf20Sopenharmony_cibna_mcam_mod_handle_put(struct bna_mcam_mod *mcam_mod, 20768c2ecf20Sopenharmony_ci struct bna_mcam_handle *handle) 20778c2ecf20Sopenharmony_ci{ 20788c2ecf20Sopenharmony_ci list_add_tail(&handle->qe, &mcam_mod->free_handle_q); 20798c2ecf20Sopenharmony_ci} 20808c2ecf20Sopenharmony_ci 20818c2ecf20Sopenharmony_civoid 20828c2ecf20Sopenharmony_cibna_hw_stats_get(struct bna *bna) 20838c2ecf20Sopenharmony_ci{ 20848c2ecf20Sopenharmony_ci if (!bna->stats_mod.ioc_ready) { 20858c2ecf20Sopenharmony_ci bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats); 20868c2ecf20Sopenharmony_ci return; 20878c2ecf20Sopenharmony_ci } 20888c2ecf20Sopenharmony_ci if (bna->stats_mod.stats_get_busy) { 20898c2ecf20Sopenharmony_ci bnad_cb_stats_get(bna->bnad, BNA_CB_BUSY, &bna->stats); 20908c2ecf20Sopenharmony_ci return; 20918c2ecf20Sopenharmony_ci } 20928c2ecf20Sopenharmony_ci 20938c2ecf20Sopenharmony_ci bna_bfi_stats_get(bna); 20948c2ecf20Sopenharmony_ci} 2095