Skip to content

Commit a9dc3d5

Browse files
ecree-solarflaredavem330
authored andcommitted
sfc_ef100: RX filter table management and related gubbins
Signed-off-by: Edward Cree <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d19a537 commit a9dc3d5

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

drivers/net/ethernet/sfc/ef100_netdev.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ static int ef100_net_stop(struct net_device *net_dev)
8989
efx_disable_interrupts(efx);
9090
efx_clear_interrupt_affinity(efx);
9191
efx_nic_fini_interrupt(efx);
92+
efx_remove_filters(efx);
9293
efx_fini_napi(efx);
9394
efx_remove_channels(efx);
9495
efx_mcdi_free_vis(efx);
@@ -138,6 +139,10 @@ static int ef100_net_open(struct net_device *net_dev)
138139

139140
efx_init_napi(efx);
140141

142+
rc = efx_probe_filters(efx);
143+
if (rc)
144+
goto fail;
145+
141146
rc = efx_nic_init_interrupt(efx);
142147
if (rc)
143148
goto fail;
@@ -207,8 +212,13 @@ static const struct net_device_ops ef100_netdev_ops = {
207212
.ndo_open = ef100_net_open,
208213
.ndo_stop = ef100_net_stop,
209214
.ndo_start_xmit = ef100_hard_start_xmit,
215+
.ndo_validate_addr = eth_validate_addr,
216+
.ndo_set_rx_mode = efx_set_rx_mode, /* Lookout */
210217
.ndo_get_phys_port_id = efx_get_phys_port_id,
211218
.ndo_get_phys_port_name = efx_get_phys_port_name,
219+
#ifdef CONFIG_RFS_ACCEL
220+
.ndo_rx_flow_steer = efx_filter_rfs,
221+
#endif
212222
};
213223

214224
/* Netdev registration

drivers/net/ethernet/sfc/ef100_nic.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,37 @@ static int ef100_phy_probe(struct efx_nic *efx)
347347
return 0;
348348
}
349349

350+
static int ef100_filter_table_probe(struct efx_nic *efx)
351+
{
352+
return efx_mcdi_filter_table_probe(efx, true);
353+
}
354+
355+
static int ef100_filter_table_up(struct efx_nic *efx)
356+
{
357+
int rc;
358+
359+
rc = efx_mcdi_filter_add_vlan(efx, EFX_FILTER_VID_UNSPEC);
360+
if (rc) {
361+
efx_mcdi_filter_table_down(efx);
362+
return rc;
363+
}
364+
365+
rc = efx_mcdi_filter_add_vlan(efx, 0);
366+
if (rc) {
367+
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
368+
efx_mcdi_filter_table_down(efx);
369+
}
370+
371+
return rc;
372+
}
373+
374+
static void ef100_filter_table_down(struct efx_nic *efx)
375+
{
376+
efx_mcdi_filter_del_vlan(efx, 0);
377+
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
378+
efx_mcdi_filter_table_down(efx);
379+
}
380+
350381
/* Other
351382
*/
352383
static int ef100_reconfigure_mac(struct efx_nic *efx, bool mtu_only)
@@ -393,12 +424,24 @@ static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
393424
__clear_bit(reset_type, &efx->reset_pending);
394425
rc = dev_open(efx->net_dev, NULL);
395426
} else if (reset_type == RESET_TYPE_ALL) {
427+
/* A RESET_TYPE_ALL will cause filters to be removed, so we remove filters
428+
* and reprobe after reset to avoid removing filters twice
429+
*/
430+
down_read(&efx->filter_sem);
431+
ef100_filter_table_down(efx);
432+
up_read(&efx->filter_sem);
396433
rc = efx_mcdi_reset(efx, reset_type);
397434
if (rc)
398435
return rc;
399436

400437
netif_device_attach(efx->net_dev);
401438

439+
down_read(&efx->filter_sem);
440+
rc = ef100_filter_table_up(efx);
441+
up_read(&efx->filter_sem);
442+
if (rc)
443+
return rc;
444+
402445
rc = dev_open(efx->net_dev, NULL);
403446
} else {
404447
rc = 1; /* Leave the device closed */
@@ -480,6 +523,20 @@ const struct efx_nic_type ef100_pf_nic_type = {
480523
.rx_remove = efx_mcdi_rx_remove,
481524
.rx_write = ef100_rx_write,
482525
.rx_packet = __ef100_rx_packet,
526+
.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
527+
.filter_table_probe = ef100_filter_table_up,
528+
.filter_table_restore = efx_mcdi_filter_table_restore,
529+
.filter_table_remove = ef100_filter_table_down,
530+
.filter_insert = efx_mcdi_filter_insert,
531+
.filter_remove_safe = efx_mcdi_filter_remove_safe,
532+
.filter_get_safe = efx_mcdi_filter_get_safe,
533+
.filter_clear_rx = efx_mcdi_filter_clear_rx,
534+
.filter_count_rx_used = efx_mcdi_filter_count_rx_used,
535+
.filter_get_rx_id_limit = efx_mcdi_filter_get_rx_id_limit,
536+
.filter_get_rx_ids = efx_mcdi_filter_get_rx_ids,
537+
#ifdef CONFIG_RFS_ACCEL
538+
.filter_rfs_expire_one = efx_mcdi_filter_rfs_expire_one,
539+
#endif
483540

484541
.get_phys_port_id = efx_ef100_get_phys_port_id,
485542

@@ -840,6 +897,12 @@ static int ef100_probe_main(struct efx_nic *efx)
840897
if (rc)
841898
goto fail;
842899

900+
down_write(&efx->filter_sem);
901+
rc = ef100_filter_table_probe(efx);
902+
up_write(&efx->filter_sem);
903+
if (rc)
904+
goto fail;
905+
843906
rc = ef100_register_netdev(efx);
844907
if (rc)
845908
goto fail;
@@ -877,6 +940,10 @@ void ef100_remove(struct efx_nic *efx)
877940
struct ef100_nic_data *nic_data = efx->nic_data;
878941

879942
ef100_unregister_netdev(efx);
943+
944+
down_write(&efx->filter_sem);
945+
efx_mcdi_filter_table_remove(efx);
946+
up_write(&efx->filter_sem);
880947
efx_fini_channels(efx);
881948
kfree(efx->phy_data);
882949
efx->phy_data = NULL;

0 commit comments

Comments
 (0)