26b2755e122d926975e41e146e1246524f27e869
[dpdk.git] / drivers / net / bnxt / bnxt_cpr.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) Broadcom Limited.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Broadcom Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <rte_malloc.h>
35
36 #include "bnxt.h"
37 #include "bnxt_cpr.h"
38 #include "bnxt_hwrm.h"
39 #include "bnxt_ring.h"
40 #include "hsi_struct_def_dpdk.h"
41
42 /*
43  * Async event handling
44  */
45 void bnxt_handle_async_event(struct bnxt *bp,
46                              struct cmpl_base *cmp)
47 {
48         struct hwrm_async_event_cmpl *async_cmp =
49                                 (struct hwrm_async_event_cmpl *)cmp;
50         uint16_t event_id = rte_le_to_cpu_16(async_cmp->event_id);
51
52         /* TODO: HWRM async events are not defined yet */
53         /* Needs to handle: link events, error events, etc. */
54         switch (event_id) {
55         case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
56         case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
57         case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
58                 bnxt_link_update_op(bp->eth_dev, 0);
59                 break;
60         default:
61                 RTE_LOG(DEBUG, PMD, "handle_async_event id = 0x%x\n", event_id);
62                 break;
63         }
64 }
65
66 void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl)
67 {
68         struct hwrm_exec_fwd_resp_input *fwreq;
69         struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
70         struct input *fwd_cmd;
71         uint16_t fw_vf_id;
72         uint16_t vf_id;
73         uint16_t req_len;
74         int rc;
75
76         if (bp->pf.active_vfs <= 0) {
77                 RTE_LOG(ERR, PMD, "Forwarded VF with no active VFs\n");
78                 return;
79         }
80
81         /* Qualify the fwd request */
82         fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
83         vf_id = fw_vf_id - bp->pf.first_vf_id;
84
85         req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
86                    HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
87                 HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
88         if (req_len > sizeof(fwreq->encap_request))
89                 req_len = sizeof(fwreq->encap_request);
90
91         /* Locate VF's forwarded command */
92         fwd_cmd = (struct input *)bp->pf.vf_info[vf_id].req_buf;
93
94         if (fw_vf_id < bp->pf.first_vf_id ||
95             fw_vf_id >= (bp->pf.first_vf_id) + bp->pf.active_vfs) {
96                 RTE_LOG(ERR, PMD,
97                 "FWD req's source_id 0x%x out of range 0x%x - 0x%x (%d %d)\n",
98                         fw_vf_id, bp->pf.first_vf_id,
99                         (bp->pf.first_vf_id) + bp->pf.active_vfs - 1,
100                         bp->pf.first_vf_id, bp->pf.active_vfs);
101                 goto reject;
102         }
103
104         if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd) == true) {
105                 /*
106                  * In older firmware versions, the MAC had to be all zeros for
107                  * the VF to set it's MAC via hwrm_func_vf_cfg. Set to all
108                  * zeros if it's being configured and has been ok'd by caller.
109                  */
110                 if (fwd_cmd->req_type == HWRM_FUNC_VF_CFG) {
111                         struct hwrm_func_vf_cfg_input *vfc = (void *)fwd_cmd;
112
113                         if (vfc->enables &
114                             HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR) {
115                                 bnxt_hwrm_func_vf_mac(bp, vf_id,
116                                 (const uint8_t *)"\x00\x00\x00\x00\x00");
117                         }
118                 }
119                 if (fwd_cmd->req_type == HWRM_CFA_L2_SET_RX_MASK) {
120                         struct hwrm_cfa_l2_set_rx_mask_input *srm =
121                                                         (void *)fwd_cmd;
122
123                         srm->vlan_tag_tbl_addr = rte_cpu_to_le_64(0);
124                         srm->num_vlan_tags = rte_cpu_to_le_32(0);
125                         srm->mask &= ~rte_cpu_to_le_32(
126                                 HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY |
127                             HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN |
128                             HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN);
129                 }
130                 /* Forward */
131                 rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
132                 if (rc) {
133                         RTE_LOG(ERR, PMD,
134                                 "Failed to send FWD req VF 0x%x, type 0x%x.\n",
135                                 fw_vf_id - bp->pf.first_vf_id,
136                                 rte_le_to_cpu_16(fwd_cmd->req_type));
137                 }
138                 return;
139         }
140
141 reject:
142         rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
143         if (rc) {
144                 RTE_LOG(ERR, PMD,
145                         "Failed to send REJECT req VF 0x%x, type 0x%x.\n",
146                         fw_vf_id - bp->pf.first_vf_id,
147                         rte_le_to_cpu_16(fwd_cmd->req_type));
148         }
149
150         return;
151 }
152
153 /* For the default completion ring only */
154 int bnxt_alloc_def_cp_ring(struct bnxt *bp)
155 {
156         struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
157         struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
158         int rc;
159
160         rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
161                                   HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
162                                   0, HWRM_NA_SIGNATURE,
163                                   HWRM_NA_SIGNATURE);
164         if (rc)
165                 goto err_out;
166         cpr->cp_doorbell = bp->pdev->mem_resource[2].addr;
167         B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
168         bp->grp_info[0].cp_fw_ring_id = cp_ring->fw_ring_id;
169         if (BNXT_PF(bp))
170                 rc = bnxt_hwrm_func_cfg_def_cp(bp);
171         else
172                 rc = bnxt_hwrm_vf_func_cfg_def_cp(bp);
173
174 err_out:
175         return rc;
176 }
177
178 void bnxt_free_def_cp_ring(struct bnxt *bp)
179 {
180         struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
181
182         if (cpr == NULL)
183                 return;
184
185         bnxt_free_ring(cpr->cp_ring_struct);
186         cpr->cp_ring_struct = NULL;
187         rte_free(cpr->cp_ring_struct);
188         rte_free(cpr);
189         bp->def_cp_ring = NULL;
190 }
191
192 /* For the default completion ring only */
193 int bnxt_init_def_ring_struct(struct bnxt *bp, unsigned int socket_id)
194 {
195         struct bnxt_cp_ring_info *cpr;
196         struct bnxt_ring *ring;
197
198         cpr = rte_zmalloc_socket("cpr",
199                                  sizeof(struct bnxt_cp_ring_info),
200                                  RTE_CACHE_LINE_SIZE, socket_id);
201         if (cpr == NULL)
202                 return -ENOMEM;
203         bp->def_cp_ring = cpr;
204
205         ring = rte_zmalloc_socket("bnxt_cp_ring_struct",
206                                   sizeof(struct bnxt_ring),
207                                   RTE_CACHE_LINE_SIZE, socket_id);
208         if (ring == NULL)
209                 return -ENOMEM;
210         cpr->cp_ring_struct = ring;
211         ring->bd = (void *)cpr->cp_desc_ring;
212         ring->bd_dma = cpr->cp_desc_mapping;
213         ring->ring_size = rte_align32pow2(DEFAULT_CP_RING_SIZE);
214         ring->ring_mask = ring->ring_size - 1;
215         ring->vmem_size = 0;
216         ring->vmem = NULL;
217
218         return 0;
219 }