mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 14:42:08 +02:00
sfc: receive packets from EF100 VFs into representors
If the source m-port of a packet in __ef100_rx_packet() is a VF, hand off the packet to the corresponding representor with efx_ef100_rep_rx_packet(). Signed-off-by: Edward Cree <ecree.xilinx@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
08d0b16ecb
commit
f50e8fcda6
|
|
@ -224,6 +224,7 @@ static void efx_ef100_rep_destroy_netdev(struct efx_rep *efv)
|
|||
list_del(&efv->list);
|
||||
spin_unlock_bh(&efx->vf_reps_lock);
|
||||
rtnl_unlock();
|
||||
synchronize_rcu();
|
||||
free_netdev(efv->net_dev);
|
||||
}
|
||||
|
||||
|
|
@ -375,3 +376,21 @@ void efx_ef100_rep_rx_packet(struct efx_rep *efv, struct efx_rx_buffer *rx_buf)
|
|||
if (primed)
|
||||
napi_schedule(&efv->napi);
|
||||
}
|
||||
|
||||
struct efx_rep *efx_ef100_find_rep_by_mport(struct efx_nic *efx, u16 mport)
|
||||
{
|
||||
struct efx_rep *efv, *out = NULL;
|
||||
|
||||
/* spinlock guards against list mutation while we're walking it;
|
||||
* but caller must also hold rcu_read_lock() to ensure the netdev
|
||||
* isn't freed after we drop the spinlock.
|
||||
*/
|
||||
spin_lock_bh(&efx->vf_reps_lock);
|
||||
list_for_each_entry(efv, &efx->vf_reps, list)
|
||||
if (efv->mport == mport) {
|
||||
out = efv;
|
||||
break;
|
||||
}
|
||||
spin_unlock_bh(&efx->vf_reps_lock);
|
||||
return out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,4 +58,9 @@ void efx_ef100_vfrep_destroy(struct efx_nic *efx, struct efx_rep *efv);
|
|||
void efx_ef100_fini_vfreps(struct efx_nic *efx);
|
||||
|
||||
void efx_ef100_rep_rx_packet(struct efx_rep *efv, struct efx_rx_buffer *rx_buf);
|
||||
/* Returns the representor corresponding to a VF m-port, or NULL
|
||||
* @mport is an m-port label, *not* an m-port ID!
|
||||
* Caller must hold rcu_read_lock().
|
||||
*/
|
||||
struct efx_rep *efx_ef100_find_rep_by_mport(struct efx_nic *efx, u16 mport);
|
||||
#endif /* EF100_REP_H */
|
||||
|
|
|
|||
|
|
@ -85,6 +85,24 @@ void __ef100_rx_packet(struct efx_channel *channel)
|
|||
nic_data = efx->nic_data;
|
||||
|
||||
if (nic_data->have_mport && ing_port != nic_data->base_mport) {
|
||||
#ifdef CONFIG_SFC_SRIOV
|
||||
struct efx_rep *efv;
|
||||
|
||||
rcu_read_lock();
|
||||
efv = efx_ef100_find_rep_by_mport(efx, ing_port);
|
||||
if (efv) {
|
||||
if (efv->net_dev->flags & IFF_UP)
|
||||
efx_ef100_rep_rx_packet(efv, rx_buf);
|
||||
rcu_read_unlock();
|
||||
/* Representor Rx doesn't care about PF Rx buffer
|
||||
* ownership, it just makes a copy. So, we are done
|
||||
* with the Rx buffer from PF point of view and should
|
||||
* free it.
|
||||
*/
|
||||
goto free_rx_buffer;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
#endif
|
||||
if (net_ratelimit())
|
||||
netif_warn(efx, drv, efx->net_dev,
|
||||
"Unrecognised ing_port %04x (base %04x), dropping\n",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user