1*eef4f27bSRobert Mustacchi /*
2*eef4f27bSRobert Mustacchi * Copyright 2014-2017 Cavium, Inc.
3*eef4f27bSRobert Mustacchi * The contents of this file are subject to the terms of the Common Development
4*eef4f27bSRobert Mustacchi * and Distribution License, v.1, (the "License").
5*eef4f27bSRobert Mustacchi *
6*eef4f27bSRobert Mustacchi * You may not use this file except in compliance with the License.
7*eef4f27bSRobert Mustacchi *
8*eef4f27bSRobert Mustacchi * You can obtain a copy of the License at available
9*eef4f27bSRobert Mustacchi * at http://opensource.org/licenses/CDDL-1.0
10*eef4f27bSRobert Mustacchi *
11*eef4f27bSRobert Mustacchi * See the License for the specific language governing permissions and
12*eef4f27bSRobert Mustacchi * limitations under the License.
13*eef4f27bSRobert Mustacchi */
14*eef4f27bSRobert Mustacchi
15*eef4f27bSRobert Mustacchi /*
16*eef4f27bSRobert Mustacchi * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
17*eef4f27bSRobert Mustacchi * Copyright (c) 2019, Joyent, Inc.
18*eef4f27bSRobert Mustacchi */
19*eef4f27bSRobert Mustacchi
20*eef4f27bSRobert Mustacchi #include "bnx.h"
21*eef4f27bSRobert Mustacchi #include "bnx_mm.h"
22*eef4f27bSRobert Mustacchi #include "bnxsnd.h"
23*eef4f27bSRobert Mustacchi #include "bnxrcv.h"
24*eef4f27bSRobert Mustacchi #include "bnxint.h"
25*eef4f27bSRobert Mustacchi #include "bnxtmr.h"
26*eef4f27bSRobert Mustacchi #include "bnxcfg.h"
27*eef4f27bSRobert Mustacchi
28*eef4f27bSRobert Mustacchi void
bnx_update_phy(um_device_t * const umdevice)29*eef4f27bSRobert Mustacchi bnx_update_phy(um_device_t * const umdevice)
30*eef4f27bSRobert Mustacchi {
31*eef4f27bSRobert Mustacchi lm_status_t lmstatus;
32*eef4f27bSRobert Mustacchi lm_device_t *lmdevice;
33*eef4f27bSRobert Mustacchi
34*eef4f27bSRobert Mustacchi lmdevice = &(umdevice->lm_dev);
35*eef4f27bSRobert Mustacchi
36*eef4f27bSRobert Mustacchi /* Map 'ndd' parameters to LM struct. */
37*eef4f27bSRobert Mustacchi bnx_cfg_map_phy(umdevice);
38*eef4f27bSRobert Mustacchi
39*eef4f27bSRobert Mustacchi mutex_enter(&umdevice->os_param.phy_mutex);
40*eef4f27bSRobert Mustacchi
41*eef4f27bSRobert Mustacchi /* Reset, re-program and bring-up phy. */
42*eef4f27bSRobert Mustacchi lmstatus = lm_init_phy(lmdevice, lmdevice->params.req_medium,
43*eef4f27bSRobert Mustacchi lmdevice->params.flow_ctrl_cap, lmdevice->params.selective_autoneg,
44*eef4f27bSRobert Mustacchi lmdevice->params.wire_speed, 0);
45*eef4f27bSRobert Mustacchi if (lmstatus != LM_STATUS_SUCCESS) {
46*eef4f27bSRobert Mustacchi cmn_err(CE_WARN, "%s: Failed to configure the PHY.",
47*eef4f27bSRobert Mustacchi umdevice->dev_name);
48*eef4f27bSRobert Mustacchi }
49*eef4f27bSRobert Mustacchi
50*eef4f27bSRobert Mustacchi lm_service_phy_int(lmdevice, TRUE);
51*eef4f27bSRobert Mustacchi
52*eef4f27bSRobert Mustacchi mutex_exit(&umdevice->os_param.phy_mutex);
53*eef4f27bSRobert Mustacchi }
54*eef4f27bSRobert Mustacchi
55*eef4f27bSRobert Mustacchi ddi_dma_handle_t *
bnx_find_dma_hdl(um_device_t * const umdevice,const void * const virtaddr)56*eef4f27bSRobert Mustacchi bnx_find_dma_hdl(um_device_t *const umdevice, const void *const virtaddr)
57*eef4f27bSRobert Mustacchi {
58*eef4f27bSRobert Mustacchi int i;
59*eef4f27bSRobert Mustacchi ddi_dma_handle_t *dmahdl;
60*eef4f27bSRobert Mustacchi
61*eef4f27bSRobert Mustacchi dmahdl = NULL;
62*eef4f27bSRobert Mustacchi for (i = 0; i < umdevice->os_param.dma_handles_used; i++) {
63*eef4f27bSRobert Mustacchi if (umdevice->os_param.dma_virt[i] == virtaddr) {
64*eef4f27bSRobert Mustacchi dmahdl = &(umdevice->os_param.dma_handle[i]);
65*eef4f27bSRobert Mustacchi }
66*eef4f27bSRobert Mustacchi }
67*eef4f27bSRobert Mustacchi
68*eef4f27bSRobert Mustacchi return (dmahdl);
69*eef4f27bSRobert Mustacchi }
70*eef4f27bSRobert Mustacchi
71*eef4f27bSRobert Mustacchi static void
bnx_free_lmmem(um_device_t * const umdevice)72*eef4f27bSRobert Mustacchi bnx_free_lmmem(um_device_t * const umdevice)
73*eef4f27bSRobert Mustacchi {
74*eef4f27bSRobert Mustacchi int i;
75*eef4f27bSRobert Mustacchi bnx_memreq_t *memreq;
76*eef4f27bSRobert Mustacchi ddi_dma_handle_t *dma_handle;
77*eef4f27bSRobert Mustacchi ddi_acc_handle_t *acc_handle;
78*eef4f27bSRobert Mustacchi
79*eef4f27bSRobert Mustacchi if (umdevice->os_param.dma_handles_used != 0) {
80*eef4f27bSRobert Mustacchi i = umdevice->os_param.dma_handles_used - 1;
81*eef4f27bSRobert Mustacchi
82*eef4f27bSRobert Mustacchi dma_handle = &(umdevice->os_param.dma_handle[i]);
83*eef4f27bSRobert Mustacchi acc_handle = &(umdevice->os_param.dma_acc_handle[i]);
84*eef4f27bSRobert Mustacchi
85*eef4f27bSRobert Mustacchi /* Free all shared memory. */
86*eef4f27bSRobert Mustacchi for (; i >= 0; i--) {
87*eef4f27bSRobert Mustacchi (void) ddi_dma_unbind_handle(*dma_handle);
88*eef4f27bSRobert Mustacchi
89*eef4f27bSRobert Mustacchi ddi_dma_mem_free(acc_handle);
90*eef4f27bSRobert Mustacchi
91*eef4f27bSRobert Mustacchi ddi_dma_free_handle(dma_handle);
92*eef4f27bSRobert Mustacchi
93*eef4f27bSRobert Mustacchi dma_handle--;
94*eef4f27bSRobert Mustacchi acc_handle--;
95*eef4f27bSRobert Mustacchi }
96*eef4f27bSRobert Mustacchi
97*eef4f27bSRobert Mustacchi umdevice->os_param.dma_handles_used = 0;
98*eef4f27bSRobert Mustacchi }
99*eef4f27bSRobert Mustacchi
100*eef4f27bSRobert Mustacchi if (umdevice->memcnt != 0) {
101*eef4f27bSRobert Mustacchi /* Free all local memory. */
102*eef4f27bSRobert Mustacchi for (i = umdevice->memcnt - 1; i >= 0; i--) {
103*eef4f27bSRobert Mustacchi memreq = &umdevice->memreq[i];
104*eef4f27bSRobert Mustacchi
105*eef4f27bSRobert Mustacchi kmem_free(memreq->addr, memreq->size);
106*eef4f27bSRobert Mustacchi
107*eef4f27bSRobert Mustacchi memreq->addr = NULL;
108*eef4f27bSRobert Mustacchi memreq->size = 0;
109*eef4f27bSRobert Mustacchi }
110*eef4f27bSRobert Mustacchi
111*eef4f27bSRobert Mustacchi umdevice->memcnt = 0;
112*eef4f27bSRobert Mustacchi }
113*eef4f27bSRobert Mustacchi }
114*eef4f27bSRobert Mustacchi
115*eef4f27bSRobert Mustacchi int
bnx_hdwr_init(um_device_t * const umdevice)116*eef4f27bSRobert Mustacchi bnx_hdwr_init(um_device_t *const umdevice)
117*eef4f27bSRobert Mustacchi {
118*eef4f27bSRobert Mustacchi lm_status_t lmstatus;
119*eef4f27bSRobert Mustacchi lm_device_t *lmdevice;
120*eef4f27bSRobert Mustacchi
121*eef4f27bSRobert Mustacchi lmdevice = &(umdevice->lm_dev);
122*eef4f27bSRobert Mustacchi
123*eef4f27bSRobert Mustacchi lmstatus = lm_get_dev_info(lmdevice);
124*eef4f27bSRobert Mustacchi if (lmstatus != LM_STATUS_SUCCESS) {
125*eef4f27bSRobert Mustacchi cmn_err(CE_WARN, "%s: Failed to get device information.\n",
126*eef4f27bSRobert Mustacchi umdevice->dev_name);
127*eef4f27bSRobert Mustacchi return (-1);
128*eef4f27bSRobert Mustacchi }
129*eef4f27bSRobert Mustacchi
130*eef4f27bSRobert Mustacchi /*
131*eef4f27bSRobert Mustacchi * Initialize the adapter resource. Mainly allocating memory needed
132*eef4f27bSRobert Mustacchi * by the driver, such as packet descriptors, shared memory, etc.
133*eef4f27bSRobert Mustacchi */
134*eef4f27bSRobert Mustacchi lmstatus = lm_init_resc(lmdevice);
135*eef4f27bSRobert Mustacchi if (lmstatus != LM_STATUS_SUCCESS) {
136*eef4f27bSRobert Mustacchi cmn_err(CE_WARN, "%s: Failed to allocate device resources.\n",
137*eef4f27bSRobert Mustacchi umdevice->dev_name);
138*eef4f27bSRobert Mustacchi goto error1;
139*eef4f27bSRobert Mustacchi }
140*eef4f27bSRobert Mustacchi
141*eef4f27bSRobert Mustacchi if (bnx_txpkts_init(umdevice)) {
142*eef4f27bSRobert Mustacchi goto error1;
143*eef4f27bSRobert Mustacchi }
144*eef4f27bSRobert Mustacchi
145*eef4f27bSRobert Mustacchi if (bnx_rxpkts_init(umdevice)) {
146*eef4f27bSRobert Mustacchi goto error2;
147*eef4f27bSRobert Mustacchi }
148*eef4f27bSRobert Mustacchi
149*eef4f27bSRobert Mustacchi /* Find the DMA handle associated with the status block memory. */
150*eef4f27bSRobert Mustacchi umdevice->os_param.status_block_dma_hdl = bnx_find_dma_hdl(umdevice,
151*eef4f27bSRobert Mustacchi (void *)(umdevice->lm_dev.vars.status_virt));
152*eef4f27bSRobert Mustacchi
153*eef4f27bSRobert Mustacchi /* Reset the local interrupt event index. */
154*eef4f27bSRobert Mustacchi umdevice->dev_var.processed_status_idx = 0;
155*eef4f27bSRobert Mustacchi
156*eef4f27bSRobert Mustacchi /* Initialize the receive mask to a sane default. */
157*eef4f27bSRobert Mustacchi umdevice->dev_var.rx_filter_mask = LM_RX_MASK_ACCEPT_UNICAST |
158*eef4f27bSRobert Mustacchi LM_RX_MASK_ACCEPT_BROADCAST;
159*eef4f27bSRobert Mustacchi
160*eef4f27bSRobert Mustacchi return (0);
161*eef4f27bSRobert Mustacchi
162*eef4f27bSRobert Mustacchi error2:
163*eef4f27bSRobert Mustacchi bnx_txpkts_fini(umdevice);
164*eef4f27bSRobert Mustacchi
165*eef4f27bSRobert Mustacchi error1:
166*eef4f27bSRobert Mustacchi bnx_free_lmmem(umdevice);
167*eef4f27bSRobert Mustacchi
168*eef4f27bSRobert Mustacchi return (-1);
169*eef4f27bSRobert Mustacchi }
170*eef4f27bSRobert Mustacchi
171*eef4f27bSRobert Mustacchi int
bnx_hdwr_acquire(um_device_t * const umdevice)172*eef4f27bSRobert Mustacchi bnx_hdwr_acquire(um_device_t *const umdevice)
173*eef4f27bSRobert Mustacchi {
174*eef4f27bSRobert Mustacchi lm_status_t lmstatus;
175*eef4f27bSRobert Mustacchi lm_device_t *lmdevice;
176*eef4f27bSRobert Mustacchi
177*eef4f27bSRobert Mustacchi lmdevice = &(umdevice->lm_dev);
178*eef4f27bSRobert Mustacchi
179*eef4f27bSRobert Mustacchi /* Reset the configuration to the hardware default. */
180*eef4f27bSRobert Mustacchi bnx_cfg_reset(umdevice);
181*eef4f27bSRobert Mustacchi
182*eef4f27bSRobert Mustacchi /*
183*eef4f27bSRobert Mustacchi * A call to lm_reset() implicitly means we are relieving the firmware
184*eef4f27bSRobert Mustacchi * of it's responsibility to maintain the device. The driver assumes
185*eef4f27bSRobert Mustacchi * control. The LM vars.medium field normally gets set with a call to
186*eef4f27bSRobert Mustacchi * lm_init_phy(), but this function cannot be called before we assume
187*eef4f27bSRobert Mustacchi * control of the device. If we did, we run the risk of contending
188*eef4f27bSRobert Mustacchi * with the firmware for PHY accesses. Do the next best thing.
189*eef4f27bSRobert Mustacchi */
190*eef4f27bSRobert Mustacchi lmdevice->vars.medium = lm_get_medium(lmdevice);
191*eef4f27bSRobert Mustacchi
192*eef4f27bSRobert Mustacchi /* Map 'ndd' parameters to LM struct. */
193*eef4f27bSRobert Mustacchi bnx_cfg_map_phy(umdevice);
194*eef4f27bSRobert Mustacchi
195*eef4f27bSRobert Mustacchi /* Bring the chip under driver control. */
196*eef4f27bSRobert Mustacchi lmstatus = lm_reset(lmdevice, LM_REASON_DRIVER_RESET);
197*eef4f27bSRobert Mustacchi if (lmstatus != LM_STATUS_SUCCESS) {
198*eef4f27bSRobert Mustacchi cmn_err(CE_WARN, "%s: Failed to reset chip.\n",
199*eef4f27bSRobert Mustacchi umdevice->dev_name);
200*eef4f27bSRobert Mustacchi return (-1);
201*eef4f27bSRobert Mustacchi }
202*eef4f27bSRobert Mustacchi
203*eef4f27bSRobert Mustacchi /* Configure the PHY to the requested settings. */
204*eef4f27bSRobert Mustacchi lmstatus = lm_init_phy(lmdevice, lmdevice->params.req_medium,
205*eef4f27bSRobert Mustacchi lmdevice->params.flow_ctrl_cap, lmdevice->params.selective_autoneg,
206*eef4f27bSRobert Mustacchi lmdevice->params.wire_speed, 0);
207*eef4f27bSRobert Mustacchi if (lmstatus != LM_STATUS_SUCCESS) {
208*eef4f27bSRobert Mustacchi cmn_err(CE_WARN, "%s: Failed to initialize the PHY.",
209*eef4f27bSRobert Mustacchi umdevice->dev_name);
210*eef4f27bSRobert Mustacchi }
211*eef4f27bSRobert Mustacchi
212*eef4f27bSRobert Mustacchi lm_service_phy_int(lmdevice, FALSE); /* force a phy status update */
213*eef4f27bSRobert Mustacchi
214*eef4f27bSRobert Mustacchi umdevice->dev_var.indLink = lmdevice->vars.link_status;
215*eef4f27bSRobert Mustacchi umdevice->dev_var.indMedium = lmdevice->vars.medium;
216*eef4f27bSRobert Mustacchi
217*eef4f27bSRobert Mustacchi /*
218*eef4f27bSRobert Mustacchi * Need to clear TX PATCH scratch register at offset 0x420
219*eef4f27bSRobert Mustacchi * to instruct chip to do full TCP checksum calculations.
220*eef4f27bSRobert Mustacchi */
221*eef4f27bSRobert Mustacchi REG_WR_IND(lmdevice, (OFFSETOF(reg_space_t, tpat.tpat_scratch[0]) +
222*eef4f27bSRobert Mustacchi 0x420), 0);
223*eef4f27bSRobert Mustacchi
224*eef4f27bSRobert Mustacchi FLUSHPOSTEDWRITES(lmdevice);
225*eef4f27bSRobert Mustacchi
226*eef4f27bSRobert Mustacchi umdevice->recv_discards = 0;
227*eef4f27bSRobert Mustacchi
228*eef4f27bSRobert Mustacchi /* Make sure the rx statistics counters are reset. */
229*eef4f27bSRobert Mustacchi bzero(&(lmdevice->rx_info.stats), sizeof (lm_rx_stats_t));
230*eef4f27bSRobert Mustacchi
231*eef4f27bSRobert Mustacchi /* Post rx buffers to the chip. */
232*eef4f27bSRobert Mustacchi (void) lm_post_buffers(lmdevice, 0, NULL);
233*eef4f27bSRobert Mustacchi
234*eef4f27bSRobert Mustacchi /* Allow the hardware to accept rx traffic. */
235*eef4f27bSRobert Mustacchi (void) lm_set_rx_mask(lmdevice, RX_FILTER_USER_IDX0,
236*eef4f27bSRobert Mustacchi umdevice->dev_var.rx_filter_mask);
237*eef4f27bSRobert Mustacchi
238*eef4f27bSRobert Mustacchi FLUSHPOSTEDWRITES(lmdevice);
239*eef4f27bSRobert Mustacchi
240*eef4f27bSRobert Mustacchi /* Enable interrupts. */
241*eef4f27bSRobert Mustacchi bnx_intr_enable(umdevice);
242*eef4f27bSRobert Mustacchi
243*eef4f27bSRobert Mustacchi /* Start the periodic timer. */
244*eef4f27bSRobert Mustacchi bnx_timer_start(umdevice);
245*eef4f27bSRobert Mustacchi
246*eef4f27bSRobert Mustacchi return (0);
247*eef4f27bSRobert Mustacchi }
248*eef4f27bSRobert Mustacchi
249*eef4f27bSRobert Mustacchi void
bnx_hdwr_release(um_device_t * const umdevice)250*eef4f27bSRobert Mustacchi bnx_hdwr_release(um_device_t *const umdevice)
251*eef4f27bSRobert Mustacchi {
252*eef4f27bSRobert Mustacchi int reason;
253*eef4f27bSRobert Mustacchi lm_device_t *lmdevice;
254*eef4f27bSRobert Mustacchi
255*eef4f27bSRobert Mustacchi lmdevice = &(umdevice->lm_dev);
256*eef4f27bSRobert Mustacchi
257*eef4f27bSRobert Mustacchi /* Stop the periodic timer. */
258*eef4f27bSRobert Mustacchi bnx_timer_stop(umdevice);
259*eef4f27bSRobert Mustacchi
260*eef4f27bSRobert Mustacchi /* Disable interrupts. */
261*eef4f27bSRobert Mustacchi bnx_intr_disable(umdevice);
262*eef4f27bSRobert Mustacchi
263*eef4f27bSRobert Mustacchi /*
264*eef4f27bSRobert Mustacchi * In Solaris when RX traffic is accepted, the system might generate
265*eef4f27bSRobert Mustacchi * and attempt to send some TX packets (from within gld_recv() !).
266*eef4f27bSRobert Mustacchi * Claiming any TX locks before this point would create a deadlock.
267*eef4f27bSRobert Mustacchi * The ISR would be waiting for a lock acquired here that would never
268*eef4f27bSRobert Mustacchi * be freed, since we in-turn would be waiting for the ISR to finish
269*eef4f27bSRobert Mustacchi * here. Consequently, we acquire the TX lock as soon as we know that
270*eef4f27bSRobert Mustacchi * no TX traffic is a result of RX traffic.
271*eef4f27bSRobert Mustacchi */
272*eef4f27bSRobert Mustacchi rw_enter(&umdevice->os_param.gld_snd_mutex, RW_WRITER);
273*eef4f27bSRobert Mustacchi
274*eef4f27bSRobert Mustacchi /* Set RX mask to stop receiving any further packets */
275*eef4f27bSRobert Mustacchi (void) lm_set_rx_mask(lmdevice, RX_FILTER_USER_IDX0,
276*eef4f27bSRobert Mustacchi LM_RX_MASK_ACCEPT_NONE);
277*eef4f27bSRobert Mustacchi
278*eef4f27bSRobert Mustacchi FLUSHPOSTEDWRITES(lmdevice);
279*eef4f27bSRobert Mustacchi
280*eef4f27bSRobert Mustacchi if (umdevice->dev_var.fw_ver < FW_VER_WITH_UNLOAD_POWER_DOWN) {
281*eef4f27bSRobert Mustacchi reason = LM_REASON_DRIVER_SHUTDOWN;
282*eef4f27bSRobert Mustacchi } else {
283*eef4f27bSRobert Mustacchi reason = LM_REASON_DRIVER_UNLOAD_POWER_DOWN;
284*eef4f27bSRobert Mustacchi }
285*eef4f27bSRobert Mustacchi
286*eef4f27bSRobert Mustacchi lm_chip_reset(lmdevice, reason);
287*eef4f27bSRobert Mustacchi
288*eef4f27bSRobert Mustacchi FLUSHPOSTEDWRITES(lmdevice);
289*eef4f27bSRobert Mustacchi
290*eef4f27bSRobert Mustacchi /* Reclaim all tx buffers submitted to the hardware. */
291*eef4f27bSRobert Mustacchi bnx_txpkts_flush(umdevice);
292*eef4f27bSRobert Mustacchi
293*eef4f27bSRobert Mustacchi /* Reclaim all rx buffers submitted to the hardware. */
294*eef4f27bSRobert Mustacchi bnx_rxpkts_recycle(umdevice);
295*eef4f27bSRobert Mustacchi
296*eef4f27bSRobert Mustacchi rw_exit(&umdevice->os_param.gld_snd_mutex);
297*eef4f27bSRobert Mustacchi }
298*eef4f27bSRobert Mustacchi
299*eef4f27bSRobert Mustacchi void
bnx_hdwr_fini(um_device_t * const umdevice)300*eef4f27bSRobert Mustacchi bnx_hdwr_fini(um_device_t *const umdevice)
301*eef4f27bSRobert Mustacchi {
302*eef4f27bSRobert Mustacchi bnx_rxpkts_fini(umdevice);
303*eef4f27bSRobert Mustacchi
304*eef4f27bSRobert Mustacchi bnx_txpkts_fini(umdevice);
305*eef4f27bSRobert Mustacchi
306*eef4f27bSRobert Mustacchi bnx_free_lmmem(umdevice);
307*eef4f27bSRobert Mustacchi }
308*eef4f27bSRobert Mustacchi
309*eef4f27bSRobert Mustacchi static u32_t
compute_crc32(const u8_t * const buf,u32_t buf_size)310*eef4f27bSRobert Mustacchi compute_crc32(const u8_t *const buf, u32_t buf_size)
311*eef4f27bSRobert Mustacchi {
312*eef4f27bSRobert Mustacchi u32_t reg;
313*eef4f27bSRobert Mustacchi u32_t tmp;
314*eef4f27bSRobert Mustacchi u32_t j;
315*eef4f27bSRobert Mustacchi u32_t k;
316*eef4f27bSRobert Mustacchi
317*eef4f27bSRobert Mustacchi reg = 0xffffffff;
318*eef4f27bSRobert Mustacchi
319*eef4f27bSRobert Mustacchi for (j = 0; j < buf_size; j++) {
320*eef4f27bSRobert Mustacchi reg ^= buf[j];
321*eef4f27bSRobert Mustacchi
322*eef4f27bSRobert Mustacchi for (k = 0; k < 8; k++) {
323*eef4f27bSRobert Mustacchi tmp = reg & 0x01;
324*eef4f27bSRobert Mustacchi
325*eef4f27bSRobert Mustacchi reg >>= 1;
326*eef4f27bSRobert Mustacchi
327*eef4f27bSRobert Mustacchi if (tmp) {
328*eef4f27bSRobert Mustacchi reg ^= 0xedb88320;
329*eef4f27bSRobert Mustacchi }
330*eef4f27bSRobert Mustacchi }
331*eef4f27bSRobert Mustacchi }
332*eef4f27bSRobert Mustacchi
333*eef4f27bSRobert Mustacchi return (~reg);
334*eef4f27bSRobert Mustacchi }
335*eef4f27bSRobert Mustacchi
336*eef4f27bSRobert Mustacchi int
bnx_find_mchash_collision(lm_mc_table_t * mc_table,const uint8_t * const mc_addr)337*eef4f27bSRobert Mustacchi bnx_find_mchash_collision(lm_mc_table_t *mc_table, const uint8_t *const mc_addr)
338*eef4f27bSRobert Mustacchi {
339*eef4f27bSRobert Mustacchi u32_t cur_bit_pos;
340*eef4f27bSRobert Mustacchi u32_t tgt_bit_pos;
341*eef4f27bSRobert Mustacchi u32_t idx;
342*eef4f27bSRobert Mustacchi u32_t crc32;
343*eef4f27bSRobert Mustacchi
344*eef4f27bSRobert Mustacchi crc32 = compute_crc32(mc_addr, ETHERNET_ADDRESS_SIZE);
345*eef4f27bSRobert Mustacchi
346*eef4f27bSRobert Mustacchi tgt_bit_pos = ~crc32 & 0xff;
347*eef4f27bSRobert Mustacchi
348*eef4f27bSRobert Mustacchi for (idx = 0; idx < mc_table->entry_cnt; idx++) {
349*eef4f27bSRobert Mustacchi crc32 = compute_crc32(mc_table->addr_arr[idx].mc_addr,
350*eef4f27bSRobert Mustacchi ETHERNET_ADDRESS_SIZE);
351*eef4f27bSRobert Mustacchi
352*eef4f27bSRobert Mustacchi /*
353*eef4f27bSRobert Mustacchi * The most significant 7 bits of the CRC32 (no inversion),
354*eef4f27bSRobert Mustacchi * are used to index into one of the possible 128 bit positions.
355*eef4f27bSRobert Mustacchi */
356*eef4f27bSRobert Mustacchi cur_bit_pos = ~crc32 & 0xff;
357*eef4f27bSRobert Mustacchi
358*eef4f27bSRobert Mustacchi if (tgt_bit_pos == cur_bit_pos) {
359*eef4f27bSRobert Mustacchi return (idx);
360*eef4f27bSRobert Mustacchi }
361*eef4f27bSRobert Mustacchi }
362*eef4f27bSRobert Mustacchi
363*eef4f27bSRobert Mustacchi return (-1);
364*eef4f27bSRobert Mustacchi }
365*eef4f27bSRobert Mustacchi
366*eef4f27bSRobert Mustacchi
367*eef4f27bSRobert Mustacchi
368*eef4f27bSRobert Mustacchi /*
369*eef4f27bSRobert Mustacchi * Name: um_send_driver_pulse
370*eef4f27bSRobert Mustacchi *
371*eef4f27bSRobert Mustacchi * Input: ptr to driver structure
372*eef4f27bSRobert Mustacchi *
373*eef4f27bSRobert Mustacchi * Return: none
374*eef4f27bSRobert Mustacchi *
375*eef4f27bSRobert Mustacchi * Description: um_send_driver_pulse routine sends heartbeat pulse to firmware.
376*eef4f27bSRobert Mustacchi */
377*eef4f27bSRobert Mustacchi void
um_send_driver_pulse(um_device_t * const umdevice)378*eef4f27bSRobert Mustacchi um_send_driver_pulse(um_device_t *const umdevice)
379*eef4f27bSRobert Mustacchi {
380*eef4f27bSRobert Mustacchi u32_t msg_code;
381*eef4f27bSRobert Mustacchi u32_t offset;
382*eef4f27bSRobert Mustacchi lm_device_t *lmdevice;
383*eef4f27bSRobert Mustacchi
384*eef4f27bSRobert Mustacchi lmdevice = &(umdevice->lm_dev);
385*eef4f27bSRobert Mustacchi
386*eef4f27bSRobert Mustacchi offset = lmdevice->hw_info.shmem_base;
387*eef4f27bSRobert Mustacchi offset += OFFSETOF(shmem_region_t, drv_fw_mb.drv_pulse_mb);
388*eef4f27bSRobert Mustacchi
389*eef4f27bSRobert Mustacchi mutex_enter(&umdevice->os_param.ind_mutex);
390*eef4f27bSRobert Mustacchi
391*eef4f27bSRobert Mustacchi lmdevice->vars.drv_pulse_wr_seq++;
392*eef4f27bSRobert Mustacchi
393*eef4f27bSRobert Mustacchi msg_code = lmdevice->vars.drv_pulse_wr_seq & DRV_PULSE_SEQ_MASK;
394*eef4f27bSRobert Mustacchi
395*eef4f27bSRobert Mustacchi mutex_exit(&umdevice->os_param.ind_mutex);
396*eef4f27bSRobert Mustacchi
397*eef4f27bSRobert Mustacchi if (lmdevice->params.test_mode & TEST_MODE_DRIVER_PULSE_ALWAYS_ALIVE) {
398*eef4f27bSRobert Mustacchi msg_code |= DRV_PULSE_ALWAYS_ALIVE;
399*eef4f27bSRobert Mustacchi }
400*eef4f27bSRobert Mustacchi
401*eef4f27bSRobert Mustacchi REG_WR_IND(lmdevice, offset, msg_code);
402*eef4f27bSRobert Mustacchi }
403