Skip to content

Commit 965b549

Browse files
ecree-solarflaredavem330
authored andcommitted
sfc_ef100: implement ndo_open/close and EVQ probing
Channels are probed, but actual event handling is still stubbed out. Stub implementation of check_caps is needed because ptp.c will call into it from efx_ptp_use_mac_tx_timestamps() to decide if it wants TXQs. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2200e6d commit 965b549

File tree

7 files changed

+225
-0
lines changed

7 files changed

+225
-0
lines changed

drivers/net/ethernet/sfc/ef100_netdev.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,147 @@ static void ef100_update_name(struct efx_nic *efx)
2929
strcpy(efx->name, efx->net_dev->name);
3030
}
3131

32+
static int ef100_alloc_vis(struct efx_nic *efx, unsigned int *allocated_vis)
33+
{
34+
/* EF100 uses a single TXQ per channel, as all checksum offloading
35+
* is configured in the TX descriptor, and there is no TX Pacer for
36+
* HIGHPRI queues.
37+
*/
38+
unsigned int tx_vis = efx->n_tx_channels + efx->n_extra_tx_channels;
39+
unsigned int rx_vis = efx->n_rx_channels;
40+
unsigned int min_vis, max_vis;
41+
42+
EFX_WARN_ON_PARANOID(efx->tx_queues_per_channel != 1);
43+
44+
tx_vis += efx->n_xdp_channels * efx->xdp_tx_per_channel;
45+
46+
max_vis = max(rx_vis, tx_vis);
47+
/* Currently don't handle resource starvation and only accept
48+
* our maximum needs and no less.
49+
*/
50+
min_vis = max_vis;
51+
52+
return efx_mcdi_alloc_vis(efx, min_vis, max_vis,
53+
NULL, allocated_vis);
54+
}
55+
56+
static int ef100_remap_bar(struct efx_nic *efx, int max_vis)
57+
{
58+
unsigned int uc_mem_map_size;
59+
void __iomem *membase;
60+
61+
efx->max_vis = max_vis;
62+
uc_mem_map_size = PAGE_ALIGN(max_vis * efx->vi_stride);
63+
64+
/* Extend the original UC mapping of the memory BAR */
65+
membase = ioremap(efx->membase_phys, uc_mem_map_size);
66+
if (!membase) {
67+
netif_err(efx, probe, efx->net_dev,
68+
"could not extend memory BAR to %x\n",
69+
uc_mem_map_size);
70+
return -ENOMEM;
71+
}
72+
iounmap(efx->membase);
73+
efx->membase = membase;
74+
return 0;
75+
}
76+
77+
/* Context: process, rtnl_lock() held.
78+
* Note that the kernel will ignore our return code; this method
79+
* should really be a void.
80+
*/
81+
static int ef100_net_stop(struct net_device *net_dev)
82+
{
83+
struct efx_nic *efx = netdev_priv(net_dev);
84+
85+
netif_dbg(efx, ifdown, efx->net_dev, "closing on CPU %d\n",
86+
raw_smp_processor_id());
87+
88+
netif_stop_queue(net_dev);
89+
efx_stop_all(efx);
90+
efx_disable_interrupts(efx);
91+
efx_clear_interrupt_affinity(efx);
92+
efx_nic_fini_interrupt(efx);
93+
efx_fini_napi(efx);
94+
efx_remove_channels(efx);
95+
efx_mcdi_free_vis(efx);
96+
efx_remove_interrupts(efx);
97+
98+
return 0;
99+
}
100+
101+
/* Context: process, rtnl_lock() held. */
102+
static int ef100_net_open(struct net_device *net_dev)
103+
{
104+
struct efx_nic *efx = netdev_priv(net_dev);
105+
unsigned int allocated_vis;
106+
int rc;
107+
108+
ef100_update_name(efx);
109+
netif_dbg(efx, ifup, net_dev, "opening device on CPU %d\n",
110+
raw_smp_processor_id());
111+
112+
rc = efx_check_disabled(efx);
113+
if (rc)
114+
goto fail;
115+
116+
rc = efx_probe_interrupts(efx);
117+
if (rc)
118+
goto fail;
119+
120+
rc = efx_set_channels(efx);
121+
if (rc)
122+
goto fail;
123+
124+
rc = efx_mcdi_free_vis(efx);
125+
if (rc)
126+
goto fail;
127+
128+
rc = ef100_alloc_vis(efx, &allocated_vis);
129+
if (rc)
130+
goto fail;
131+
132+
rc = efx_probe_channels(efx);
133+
if (rc)
134+
return rc;
135+
136+
rc = ef100_remap_bar(efx, allocated_vis);
137+
if (rc)
138+
goto fail;
139+
140+
efx_init_napi(efx);
141+
142+
rc = efx_nic_init_interrupt(efx);
143+
if (rc)
144+
goto fail;
145+
efx_set_interrupt_affinity(efx);
146+
147+
rc = efx_enable_interrupts(efx);
148+
if (rc)
149+
goto fail;
150+
151+
/* in case the MC rebooted while we were stopped, consume the change
152+
* to the warm reboot count
153+
*/
154+
(void) efx_mcdi_poll_reboot(efx);
155+
156+
efx_start_all(efx);
157+
158+
/* Link state detection is normally event-driven; we have
159+
* to poll now because we could have missed a change
160+
*/
161+
mutex_lock(&efx->mac_lock);
162+
if (efx_mcdi_phy_poll(efx))
163+
efx_link_status_changed(efx);
164+
mutex_unlock(&efx->mac_lock);
165+
166+
return 0;
167+
168+
fail:
169+
ef100_net_stop(net_dev);
170+
return rc;
171+
}
172+
32173
/* Initiate a packet transmission. We use one channel per CPU
33174
* (sharing when we have more CPUs than channels).
34175
*
@@ -64,6 +205,8 @@ static netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb,
64205
}
65206

66207
static const struct net_device_ops ef100_netdev_ops = {
208+
.ndo_open = ef100_net_open,
209+
.ndo_stop = ef100_net_stop,
67210
.ndo_start_xmit = ef100_hard_start_xmit,
68211
};
69212

drivers/net/ethernet/sfc/ef100_nic.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,34 @@ static int ef100_ev_probe(struct efx_channel *channel)
135135
GFP_KERNEL);
136136
}
137137

138+
static int ef100_ev_init(struct efx_channel *channel)
139+
{
140+
struct ef100_nic_data *nic_data = channel->efx->nic_data;
141+
142+
/* initial phase is 0 */
143+
clear_bit(channel->channel, nic_data->evq_phases);
144+
145+
return efx_mcdi_ev_init(channel, false, false);
146+
}
147+
148+
static void ef100_ev_read_ack(struct efx_channel *channel)
149+
{
150+
efx_dword_t evq_prime;
151+
152+
EFX_POPULATE_DWORD_2(evq_prime,
153+
ERF_GZ_EVQ_ID, channel->channel,
154+
ERF_GZ_IDX, channel->eventq_read_ptr &
155+
channel->eventq_mask);
156+
157+
efx_writed(channel->efx, &evq_prime,
158+
efx_reg(channel->efx, ER_GZ_EVQ_INT_PRIME));
159+
}
160+
161+
static int ef100_ev_process(struct efx_channel *channel, int quota)
162+
{
163+
return 0;
164+
}
165+
138166
static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id)
139167
{
140168
struct efx_msi_context *context = dev_id;
@@ -210,6 +238,13 @@ static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
210238
return rc;
211239
}
212240

241+
static unsigned int ef100_check_caps(const struct efx_nic *efx,
242+
u8 flag, u32 offset)
243+
{
244+
/* stub */
245+
return 0;
246+
}
247+
213248
/* NIC level access functions
214249
*/
215250
const struct efx_nic_type ef100_pf_nic_type = {
@@ -230,8 +265,24 @@ const struct efx_nic_type ef100_pf_nic_type = {
230265
.map_reset_flags = ef100_map_reset_flags,
231266
.reset = ef100_reset,
232267

268+
.check_caps = ef100_check_caps,
269+
233270
.ev_probe = ef100_ev_probe,
271+
.ev_init = ef100_ev_init,
272+
.ev_fini = efx_mcdi_ev_fini,
273+
.ev_remove = efx_mcdi_ev_remove,
234274
.irq_handle_msi = ef100_msi_interrupt,
275+
.ev_process = ef100_ev_process,
276+
.ev_read_ack = ef100_ev_read_ack,
277+
.tx_probe = ef100_tx_probe,
278+
.tx_init = ef100_tx_init,
279+
.tx_write = ef100_tx_write,
280+
.tx_enqueue = ef100_enqueue_skb,
281+
.rx_probe = efx_mcdi_rx_probe,
282+
.rx_init = efx_mcdi_rx_init,
283+
.rx_remove = efx_mcdi_rx_remove,
284+
.rx_write = ef100_rx_write,
285+
.rx_packet = __ef100_rx_packet,
235286

236287
/* Per-type bar/size configuration not used on ef100. Location of
237288
* registers is defined by extended capabilities.

drivers/net/ethernet/sfc/ef100_nic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct ef100_nic_data {
2121
struct efx_nic *efx;
2222
struct efx_buffer mcdi_buf;
2323
u16 warm_boot_count;
24+
DECLARE_BITMAP(evq_phases, EFX_MAX_CHANNELS);
2425
};
2526

2627
#define efx_ef100_has_cap(caps, flag) \

drivers/net/ethernet/sfc/ef100_rx.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
#include "rx_common.h"
1414
#include "efx.h"
1515

16+
/* RX stubs */
17+
18+
void ef100_rx_write(struct efx_rx_queue *rx_queue)
19+
{
20+
}
21+
1622
void __ef100_rx_packet(struct efx_channel *channel)
1723
{
1824
/* Stub. No RX path yet. Discard the buffer. */

drivers/net/ethernet/sfc/ef100_rx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "net_driver.h"
1616

17+
void ef100_rx_write(struct efx_rx_queue *rx_queue);
1718
void __ef100_rx_packet(struct efx_channel *channel);
1819

1920
#endif

drivers/net/ethernet/sfc/ef100_tx.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@
1414
#include "nic_common.h"
1515
#include "ef100_tx.h"
1616

17+
/* TX queue stubs */
18+
int ef100_tx_probe(struct efx_tx_queue *tx_queue)
19+
{
20+
return 0;
21+
}
22+
23+
void ef100_tx_init(struct efx_tx_queue *tx_queue)
24+
{
25+
/* must be the inverse of lookup in efx_get_tx_channel */
26+
tx_queue->core_txq =
27+
netdev_get_tx_queue(tx_queue->efx->net_dev,
28+
tx_queue->channel->channel -
29+
tx_queue->efx->tx_channel_offset);
30+
}
31+
32+
void ef100_tx_write(struct efx_tx_queue *tx_queue)
33+
{
34+
}
35+
1736
/* Add a socket buffer to a TX queue
1837
*
1938
* You must hold netif_tx_lock() to call this function.

drivers/net/ethernet/sfc/ef100_tx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,9 @@
1414

1515
#include "net_driver.h"
1616

17+
int ef100_tx_probe(struct efx_tx_queue *tx_queue);
18+
void ef100_tx_init(struct efx_tx_queue *tx_queue);
19+
void ef100_tx_write(struct efx_tx_queue *tx_queue);
20+
1721
netdev_tx_t ef100_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
1822
#endif

0 commit comments

Comments
 (0)