Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/aq/aq_irq.c
96295 views
1
/*
2
* aQuantia Corporation Network Driver
3
* Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
*
9
* (1) Redistributions of source code must retain the above
10
* copyright notice, this list of conditions and the following
11
* disclaimer.
12
*
13
* (2) Redistributions in binary form must reproduce the above
14
* copyright notice, this list of conditions and the following
15
* disclaimer in the documentation and/or other materials provided
16
* with the distribution.
17
*
18
* (3)The name of the author may not be used to endorse or promote
19
* products derived from this software without specific prior
20
* written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
23
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
26
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
28
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
*/
34
35
36
#include <sys/cdefs.h>
37
__FBSDID("$FreeBSD$");
38
39
#include <sys/param.h>
40
#include <sys/bitstring.h>
41
#include <sys/kernel.h>
42
#include <sys/socket.h>
43
#include <net/ethernet.h>
44
#include <net/if.h>
45
#include <net/if_dl.h>
46
#include <net/if_media.h>
47
#include <net/if_var.h>
48
#include <net/iflib.h>
49
50
#include "aq_common.h"
51
#include "aq_device.h"
52
#include "aq_ring.h"
53
#include "aq_dbg.h"
54
#include "aq_hw.h"
55
#include "aq_hw_llh.h"
56
57
int
58
aq_update_hw_stats(aq_dev_t *aq_dev)
59
{
60
struct aq_hw *hw = &aq_dev->hw;
61
struct aq_hw_fw_mbox mbox;
62
63
aq_hw_mpi_read_stats(hw, &mbox);
64
65
#define AQ_SDELTA(_N_) (aq_dev->curr_stats._N_ += \
66
mbox.stats._N_ - aq_dev->last_stats._N_)
67
if (aq_dev->linkup) {
68
AQ_SDELTA(uprc);
69
AQ_SDELTA(mprc);
70
AQ_SDELTA(bprc);
71
AQ_SDELTA(cprc);
72
AQ_SDELTA(erpt);
73
74
AQ_SDELTA(uptc);
75
AQ_SDELTA(mptc);
76
AQ_SDELTA(bptc);
77
AQ_SDELTA(erpr);
78
79
AQ_SDELTA(ubrc);
80
AQ_SDELTA(ubtc);
81
AQ_SDELTA(mbrc);
82
AQ_SDELTA(mbtc);
83
AQ_SDELTA(bbrc);
84
AQ_SDELTA(bbtc);
85
86
AQ_SDELTA(ptc);
87
AQ_SDELTA(prc);
88
89
AQ_SDELTA(dpc);
90
91
aq_dev->curr_stats.brc = aq_dev->curr_stats.ubrc +
92
aq_dev->curr_stats.mbrc + aq_dev->curr_stats.bbrc;
93
aq_dev->curr_stats.btc = aq_dev->curr_stats.ubtc +
94
aq_dev->curr_stats.mbtc + aq_dev->curr_stats.bbtc;
95
96
}
97
#undef AQ_SDELTA
98
99
memcpy(&aq_dev->last_stats, &mbox.stats, sizeof(mbox.stats));
100
101
return (0);
102
}
103
104
105
void
106
aq_if_update_admin_status(if_ctx_t ctx)
107
{
108
aq_dev_t *aq_dev = iflib_get_softc(ctx);
109
struct aq_hw *hw = &aq_dev->hw;
110
uint32_t link_speed;
111
112
// AQ_DBG_ENTER();
113
114
struct aq_hw_fc_info fc_neg;
115
aq_hw_get_link_state(hw, &link_speed, &fc_neg);
116
// AQ_DBG_PRINT(" link_speed=%d aq_dev->linkup=%d", link_speed, aq_dev->linkup);
117
if (link_speed && !aq_dev->linkup) { /* link was DOWN */
118
device_printf(aq_dev->dev, "atlantic: link UP: speed=%d\n", link_speed);
119
120
aq_dev->linkup = 1;
121
122
#if __FreeBSD__ >= 12
123
/* Disable TSO if link speed < 1G */
124
if (link_speed < 1000 && (iflib_get_softc_ctx(ctx)->isc_capabilities & (IFCAP_TSO4 | IFCAP_TSO6))) {
125
iflib_get_softc_ctx(ctx)->isc_capabilities &= ~(IFCAP_TSO4 | IFCAP_TSO6);
126
device_printf(aq_dev->dev, "atlantic: TSO disabled for link speed < 1G");
127
}else{
128
iflib_get_softc_ctx(ctx)->isc_capabilities |= (IFCAP_TSO4 | IFCAP_TSO6);
129
}
130
#endif
131
/* turn on/off RX Pause in RPB */
132
rpb_rx_xoff_en_per_tc_set(hw, fc_neg.fc_rx, 0);
133
134
135
iflib_link_state_change(ctx, LINK_STATE_UP, IF_Mbps(link_speed));
136
aq_mediastatus_update(aq_dev, link_speed, &fc_neg);
137
138
/* update ITR settings according new link speed */
139
aq_hw_interrupt_moderation_set(hw);
140
} else if (link_speed == 0U && aq_dev->linkup) { /* link was UP */
141
device_printf(aq_dev->dev, "atlantic: link DOWN\n");
142
143
aq_dev->linkup = 0;
144
145
/* turn off RX Pause in RPB */
146
rpb_rx_xoff_en_per_tc_set(hw, 0, 0);
147
148
iflib_link_state_change(ctx, LINK_STATE_DOWN, 0);
149
aq_mediastatus_update(aq_dev, link_speed, &fc_neg);
150
}
151
152
aq_update_hw_stats(aq_dev);
153
// AQ_DBG_EXIT(0);
154
}
155
156
/**************************************************************************/
157
/* interrupt service routine (Top half) */
158
/**************************************************************************/
159
int
160
aq_isr_rx(void *arg)
161
{
162
struct aq_ring *ring = arg;
163
struct aq_dev *aq_dev = ring->dev;
164
struct aq_hw *hw = &aq_dev->hw;
165
166
/* clear interrupt status */
167
itr_irq_status_clearlsw_set(hw, BIT(ring->msix));
168
ring->stats.irq++;
169
return (FILTER_SCHEDULE_THREAD);
170
}
171
172
/**************************************************************************/
173
/* interrupt service routine (Top half) */
174
/**************************************************************************/
175
int
176
aq_linkstat_isr(void *arg)
177
{
178
aq_dev_t *aq_dev = arg;
179
struct aq_hw *hw = &aq_dev->hw;
180
181
/* clear interrupt status */
182
itr_irq_status_clearlsw_set(hw, aq_dev->msix);
183
184
iflib_admin_intr_deferred(aq_dev->ctx);
185
186
return (FILTER_HANDLED);
187
}
188
189