Skip to content

Commit eab3726

Browse files
johndale88kuba-moo
authored andcommitted
enic: Simplify RX handler function
Split up RX handler functions in preparation for moving to a page pool based implementation. No functional changes. Co-developed-by: Nelson Escobar <[email protected]> Signed-off-by: Nelson Escobar <[email protected]> Co-developed-by: Satish Kharat <[email protected]> Signed-off-by: Satish Kharat <[email protected]> Signed-off-by: John Daley <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent fe57762 commit eab3726

File tree

1 file changed

+93
-69
lines changed

1 file changed

+93
-69
lines changed

drivers/net/ethernet/cisco/enic/enic_rq.c

Lines changed: 93 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,94 @@ int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, u8 type,
5050
return 0;
5151
}
5252

53+
static void enic_rq_set_skb_flags(struct vnic_rq *vrq, u8 type, u32 rss_hash,
54+
u8 rss_type, u8 fcoe, u8 fcoe_fc_crc_ok,
55+
u8 vlan_stripped, u8 csum_not_calc,
56+
u8 tcp_udp_csum_ok, u8 ipv6, u8 ipv4_csum_ok,
57+
u16 vlan_tci, struct sk_buff *skb)
58+
{
59+
struct enic *enic = vnic_dev_priv(vrq->vdev);
60+
struct net_device *netdev = enic->netdev;
61+
struct enic_rq_stats *rqstats = &enic->rq[vrq->index].stats;
62+
bool outer_csum_ok = true, encap = false;
63+
64+
if ((netdev->features & NETIF_F_RXHASH) && rss_hash && type == 3) {
65+
switch (rss_type) {
66+
case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv4:
67+
case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6:
68+
case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6_EX:
69+
skb_set_hash(skb, rss_hash, PKT_HASH_TYPE_L4);
70+
rqstats->l4_rss_hash++;
71+
break;
72+
case CQ_ENET_RQ_DESC_RSS_TYPE_IPv4:
73+
case CQ_ENET_RQ_DESC_RSS_TYPE_IPv6:
74+
case CQ_ENET_RQ_DESC_RSS_TYPE_IPv6_EX:
75+
skb_set_hash(skb, rss_hash, PKT_HASH_TYPE_L3);
76+
rqstats->l3_rss_hash++;
77+
break;
78+
}
79+
}
80+
if (enic->vxlan.vxlan_udp_port_number) {
81+
switch (enic->vxlan.patch_level) {
82+
case 0:
83+
if (fcoe) {
84+
encap = true;
85+
outer_csum_ok = fcoe_fc_crc_ok;
86+
}
87+
break;
88+
case 2:
89+
if (type == 7 && (rss_hash & BIT(0))) {
90+
encap = true;
91+
outer_csum_ok = (rss_hash & BIT(1)) &&
92+
(rss_hash & BIT(2));
93+
}
94+
break;
95+
}
96+
}
97+
98+
/* Hardware does not provide whole packet checksum. It only
99+
* provides pseudo checksum. Since hw validates the packet
100+
* checksum but not provide us the checksum value. use
101+
* CHECSUM_UNNECESSARY.
102+
*
103+
* In case of encap pkt tcp_udp_csum_ok/tcp_udp_csum_ok is
104+
* inner csum_ok. outer_csum_ok is set by hw when outer udp
105+
* csum is correct or is zero.
106+
*/
107+
if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc &&
108+
tcp_udp_csum_ok && outer_csum_ok && (ipv4_csum_ok || ipv6)) {
109+
skb->ip_summed = CHECKSUM_UNNECESSARY;
110+
skb->csum_level = encap;
111+
if (encap)
112+
rqstats->csum_unnecessary_encap++;
113+
else
114+
rqstats->csum_unnecessary++;
115+
}
116+
117+
if (vlan_stripped) {
118+
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci);
119+
rqstats->vlan_stripped++;
120+
}
121+
}
122+
123+
static bool enic_rq_pkt_error(struct vnic_rq *vrq, u8 packet_error, u8 fcs_ok,
124+
u16 bytes_written)
125+
{
126+
struct enic *enic = vnic_dev_priv(vrq->vdev);
127+
struct enic_rq_stats *rqstats = &enic->rq[vrq->index].stats;
128+
129+
if (packet_error) {
130+
if (!fcs_ok) {
131+
if (bytes_written > 0)
132+
rqstats->bad_fcs++;
133+
else if (bytes_written == 0)
134+
rqstats->pkt_truncated++;
135+
}
136+
return true;
137+
}
138+
return false;
139+
}
140+
53141
int enic_rq_alloc_buf(struct vnic_rq *rq)
54142
{
55143
struct enic *enic = vnic_dev_priv(rq->vdev);
@@ -113,7 +201,6 @@ void enic_rq_indicate_buf(struct vnic_rq *rq, struct cq_desc *cq_desc,
113201
u8 packet_error;
114202
u16 q_number, completed_index, bytes_written, vlan_tci, checksum;
115203
u32 rss_hash;
116-
bool outer_csum_ok = true, encap = false;
117204

118205
rqstats->packets++;
119206
if (skipped) {
@@ -132,14 +219,7 @@ void enic_rq_indicate_buf(struct vnic_rq *rq, struct cq_desc *cq_desc,
132219
&tcp, &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment,
133220
&fcs_ok);
134221

135-
if (packet_error) {
136-
if (!fcs_ok) {
137-
if (bytes_written > 0)
138-
rqstats->bad_fcs++;
139-
else if (bytes_written == 0)
140-
rqstats->pkt_truncated++;
141-
}
142-
222+
if (enic_rq_pkt_error(rq, packet_error, fcs_ok, bytes_written)) {
143223
dma_unmap_single(&enic->pdev->dev, buf->dma_addr, buf->len,
144224
DMA_FROM_DEVICE);
145225
dev_kfree_skb_any(skb);
@@ -162,66 +242,10 @@ void enic_rq_indicate_buf(struct vnic_rq *rq, struct cq_desc *cq_desc,
162242
skb_put(skb, bytes_written);
163243
skb->protocol = eth_type_trans(skb, netdev);
164244
skb_record_rx_queue(skb, q_number);
165-
if ((netdev->features & NETIF_F_RXHASH) && rss_hash &&
166-
type == 3) {
167-
switch (rss_type) {
168-
case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv4:
169-
case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6:
170-
case CQ_ENET_RQ_DESC_RSS_TYPE_TCP_IPv6_EX:
171-
skb_set_hash(skb, rss_hash, PKT_HASH_TYPE_L4);
172-
rqstats->l4_rss_hash++;
173-
break;
174-
case CQ_ENET_RQ_DESC_RSS_TYPE_IPv4:
175-
case CQ_ENET_RQ_DESC_RSS_TYPE_IPv6:
176-
case CQ_ENET_RQ_DESC_RSS_TYPE_IPv6_EX:
177-
skb_set_hash(skb, rss_hash, PKT_HASH_TYPE_L3);
178-
rqstats->l3_rss_hash++;
179-
break;
180-
}
181-
}
182-
if (enic->vxlan.vxlan_udp_port_number) {
183-
switch (enic->vxlan.patch_level) {
184-
case 0:
185-
if (fcoe) {
186-
encap = true;
187-
outer_csum_ok = fcoe_fc_crc_ok;
188-
}
189-
break;
190-
case 2:
191-
if (type == 7 &&
192-
(rss_hash & BIT(0))) {
193-
encap = true;
194-
outer_csum_ok = (rss_hash & BIT(1)) &&
195-
(rss_hash & BIT(2));
196-
}
197-
break;
198-
}
199-
}
200-
201-
/* Hardware does not provide whole packet checksum. It only
202-
* provides pseudo checksum. Since hw validates the packet
203-
* checksum but not provide us the checksum value. use
204-
* CHECSUM_UNNECESSARY.
205-
*
206-
* In case of encap pkt tcp_udp_csum_ok/tcp_udp_csum_ok is
207-
* inner csum_ok. outer_csum_ok is set by hw when outer udp
208-
* csum is correct or is zero.
209-
*/
210-
if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc &&
211-
tcp_udp_csum_ok && outer_csum_ok &&
212-
(ipv4_csum_ok || ipv6)) {
213-
skb->ip_summed = CHECKSUM_UNNECESSARY;
214-
skb->csum_level = encap;
215-
if (encap)
216-
rqstats->csum_unnecessary_encap++;
217-
else
218-
rqstats->csum_unnecessary++;
219-
}
220-
221-
if (vlan_stripped) {
222-
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci);
223-
rqstats->vlan_stripped++;
224-
}
245+
enic_rq_set_skb_flags(rq, type, rss_hash, rss_type, fcoe,
246+
fcoe_fc_crc_ok, vlan_stripped,
247+
csum_not_calc, tcp_udp_csum_ok, ipv6,
248+
ipv4_csum_ok, vlan_tci, skb);
225249
skb_mark_napi_id(skb, &enic->napi[rq->index]);
226250
if (!(netdev->features & NETIF_F_GRO))
227251
netif_receive_skb(skb);

0 commit comments

Comments
 (0)