New upstream version 18.02
[deb_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, 1);
59                 break;
60         case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD:
61                 PMD_DRV_LOG(INFO, "Async event: PF driver unloaded\n");
62                 break;
63         case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE:
64                 PMD_DRV_LOG(INFO, "Async event: VF config changed\n");
65                 break;
66         case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED:
67                 PMD_DRV_LOG(INFO, "Port conn async event\n");
68                 break;
69         default:
70                 PMD_DRV_LOG(INFO, "handle_async_event id = 0x%x\n", event_id);
71                 break;
72         }
73 }
74
75 void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl)
76 {
77         struct hwrm_exec_fwd_resp_input *fwreq;
78         struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
79         struct input *fwd_cmd;
80         uint16_t fw_vf_id;
81         uint16_t vf_id;
82         uint16_t req_len;
83         int rc;
84
85         if (bp->pf.active_vfs <= 0) {
86                 PMD_DRV_LOG(ERR, "Forwarded VF with no active VFs\n");
87                 return;
88         }
89
90         /* Qualify the fwd request */
91         fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
92         vf_id = fw_vf_id - bp->pf.first_vf_id;
93
94         req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
95                    HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
96                 HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
97         if (req_len > sizeof(fwreq->encap_request))
98                 req_len = sizeof(fwreq->encap_request);
99
100         /* Locate VF's forwarded command */
101         fwd_cmd = (struct input *)bp->pf.vf_info[vf_id].req_buf;
102
103         if (fw_vf_id < bp->pf.first_vf_id ||
104             fw_vf_id >= (bp->pf.first_vf_id) + bp->pf.active_vfs) {
105                 PMD_DRV_LOG(ERR,
106                 "FWD req's source_id 0x%x out of range 0x%x - 0x%x (%d %d)\n",
107                         fw_vf_id, bp->pf.first_vf_id,
108                         (bp->pf.first_vf_id) + bp->pf.active_vfs - 1,
109                         bp->pf.first_vf_id, bp->pf.active_vfs);
110                 goto reject;
111         }
112
113         if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd) == true) {
114                 /*
115                  * In older firmware versions, the MAC had to be all zeros for
116                  * the VF to set it's MAC via hwrm_func_vf_cfg. Set to all
117                  * zeros if it's being configured and has been ok'd by caller.
118                  */
119                 if (fwd_cmd->req_type == HWRM_FUNC_VF_CFG) {
120                         struct hwrm_func_vf_cfg_input *vfc = (void *)fwd_cmd;
121
122                         if (vfc->enables &
123                             HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR) {
124                                 bnxt_hwrm_func_vf_mac(bp, vf_id,
125                                 (const uint8_t *)"\x00\x00\x00\x00\x00");
126                         }
127                 }
128                 if (fwd_cmd->req_type == HWRM_CFA_L2_SET_RX_MASK) {
129                         struct hwrm_cfa_l2_set_rx_mask_input *srm =
130                                                         (void *)fwd_cmd;
131
132                         srm->vlan_tag_tbl_addr = rte_cpu_to_le_64(0);
133                         srm->num_vlan_tags = rte_cpu_to_le_32(0);
134                         srm->mask &= ~rte_cpu_to_le_32(
135                                 HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY |
136                             HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN |
137                             HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN);
138                 }
139                 /* Forward */
140                 rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
141                 if (rc) {
142                         PMD_DRV_LOG(ERR,
143                                 "Failed to send FWD req VF 0x%x, type 0x%x.\n",
144                                 fw_vf_id - bp->pf.first_vf_id,
145                                 rte_le_to_cpu_16(fwd_cmd->req_type));
146                 }
147                 return;
148         }
149
150 reject:
151         rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
152         if (rc) {
153                 PMD_DRV_LOG(ERR,
154                         "Failed to send REJECT req VF 0x%x, type 0x%x.\n",
155                         fw_vf_id - bp->pf.first_vf_id,
156                         rte_le_to_cpu_16(fwd_cmd->req_type));
157         }
158
159         return;
160 }
161
162 /* For the default completion ring only */
163 int bnxt_alloc_def_cp_ring(struct bnxt *bp)
164 {
165         struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
166         struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
167         int rc;
168
169         rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
170                                   HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
171                                   0, HWRM_NA_SIGNATURE,
172                                   HWRM_NA_SIGNATURE);
173         if (rc)
174                 goto err_out;
175         cpr->cp_doorbell = bp->pdev->mem_resource[2].addr;
176         B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
177         if (BNXT_PF(bp))
178                 rc = bnxt_hwrm_func_cfg_def_cp(bp);
179         else
180                 rc = bnxt_hwrm_vf_func_cfg_def_cp(bp);
181
182 err_out:
183         return rc;
184 }
185
186 void bnxt_free_def_cp_ring(struct bnxt *bp)
187 {
188         struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
189
190         if (cpr == NULL)
191                 return;
192
193         bnxt_free_ring(cpr->cp_ring_struct);
194         cpr->cp_ring_struct = NULL;
195         rte_free(cpr->cp_ring_struct);
196         rte_free(cpr);
197         bp->def_cp_ring = NULL;
198 }
199
200 /* For the default completion ring only */
201 int bnxt_init_def_ring_struct(struct bnxt *bp, unsigned int socket_id)
202 {
203         struct bnxt_cp_ring_info *cpr;
204         struct bnxt_ring *ring;
205
206         cpr = rte_zmalloc_socket("cpr",
207                                  sizeof(struct bnxt_cp_ring_info),
208                                  RTE_CACHE_LINE_SIZE, socket_id);
209         if (cpr == NULL)
210                 return -ENOMEM;
211         bp->def_cp_ring = cpr;
212
213         ring = rte_zmalloc_socket("bnxt_cp_ring_struct",
214                                   sizeof(struct bnxt_ring),
215                                   RTE_CACHE_LINE_SIZE, socket_id);
216         if (ring == NULL)
217                 return -ENOMEM;
218         cpr->cp_ring_struct = ring;
219         ring->bd = (void *)cpr->cp_desc_ring;
220         ring->bd_dma = cpr->cp_desc_mapping;
221         ring->ring_size = rte_align32pow2(DEFAULT_CP_RING_SIZE);
222         ring->ring_mask = ring->ring_size - 1;
223         ring->vmem_size = 0;
224         ring->vmem = NULL;
225
226         return 0;
227 }