New upstream version 17.11.1
[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         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         if (BNXT_PF(bp))
169                 rc = bnxt_hwrm_func_cfg_def_cp(bp);
170         else
171                 rc = bnxt_hwrm_vf_func_cfg_def_cp(bp);
172
173 err_out:
174         return rc;
175 }
176
177 void bnxt_free_def_cp_ring(struct bnxt *bp)
178 {
179         struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
180
181         if (cpr == NULL)
182                 return;
183
184         bnxt_free_ring(cpr->cp_ring_struct);
185         cpr->cp_ring_struct = NULL;
186         rte_free(cpr->cp_ring_struct);
187         rte_free(cpr);
188         bp->def_cp_ring = NULL;
189 }
190
191 /* For the default completion ring only */
192 int bnxt_init_def_ring_struct(struct bnxt *bp, unsigned int socket_id)
193 {
194         struct bnxt_cp_ring_info *cpr;
195         struct bnxt_ring *ring;
196
197         cpr = rte_zmalloc_socket("cpr",
198                                  sizeof(struct bnxt_cp_ring_info),
199                                  RTE_CACHE_LINE_SIZE, socket_id);
200         if (cpr == NULL)
201                 return -ENOMEM;
202         bp->def_cp_ring = cpr;
203
204         ring = rte_zmalloc_socket("bnxt_cp_ring_struct",
205                                   sizeof(struct bnxt_ring),
206                                   RTE_CACHE_LINE_SIZE, socket_id);
207         if (ring == NULL)
208                 return -ENOMEM;
209         cpr->cp_ring_struct = ring;
210         ring->bd = (void *)cpr->cp_desc_ring;
211         ring->bd_dma = cpr->cp_desc_mapping;
212         ring->ring_size = rte_align32pow2(DEFAULT_CP_RING_SIZE);
213         ring->ring_mask = ring->ring_size - 1;
214         ring->vmem_size = 0;
215         ring->vmem = NULL;
216
217         return 0;
218 }