@@ -91,63 +91,137 @@ static unsigned int mana_checksum_info(struct sk_buff *skb)
9191 return 0 ;
9292}
9393
94+ static void mana_add_sge (struct mana_tx_package * tp , struct mana_skb_head * ash ,
95+ int sg_i , dma_addr_t da , int sge_len , u32 gpa_mkey )
96+ {
97+ ash -> dma_handle [sg_i ] = da ;
98+ ash -> size [sg_i ] = sge_len ;
99+
100+ tp -> wqe_req .sgl [sg_i ].address = da ;
101+ tp -> wqe_req .sgl [sg_i ].mem_key = gpa_mkey ;
102+ tp -> wqe_req .sgl [sg_i ].size = sge_len ;
103+ }
104+
94105static int mana_map_skb (struct sk_buff * skb , struct mana_port_context * apc ,
95- struct mana_tx_package * tp )
106+ struct mana_tx_package * tp , int gso_hs )
96107{
97108 struct mana_skb_head * ash = (struct mana_skb_head * )skb -> head ;
109+ int hsg = 1 ; /* num of SGEs of linear part */
98110 struct gdma_dev * gd = apc -> ac -> gdma_dev ;
111+ int skb_hlen = skb_headlen (skb );
112+ int sge0_len , sge1_len = 0 ;
99113 struct gdma_context * gc ;
100114 struct device * dev ;
101115 skb_frag_t * frag ;
102116 dma_addr_t da ;
117+ int sg_i ;
103118 int i ;
104119
105120 gc = gd -> gdma_context ;
106121 dev = gc -> dev ;
107- da = dma_map_single (dev , skb -> data , skb_headlen (skb ), DMA_TO_DEVICE );
108122
123+ if (gso_hs && gso_hs < skb_hlen ) {
124+ sge0_len = gso_hs ;
125+ sge1_len = skb_hlen - gso_hs ;
126+ } else {
127+ sge0_len = skb_hlen ;
128+ }
129+
130+ da = dma_map_single (dev , skb -> data , sge0_len , DMA_TO_DEVICE );
109131 if (dma_mapping_error (dev , da ))
110132 return - ENOMEM ;
111133
112- ash -> dma_handle [0 ] = da ;
113- ash -> size [0 ] = skb_headlen (skb );
134+ mana_add_sge (tp , ash , 0 , da , sge0_len , gd -> gpa_mkey );
114135
115- tp -> wqe_req .sgl [0 ].address = ash -> dma_handle [0 ];
116- tp -> wqe_req .sgl [0 ].mem_key = gd -> gpa_mkey ;
117- tp -> wqe_req .sgl [0 ].size = ash -> size [0 ];
136+ if (sge1_len ) {
137+ sg_i = 1 ;
138+ da = dma_map_single (dev , skb -> data + sge0_len , sge1_len ,
139+ DMA_TO_DEVICE );
140+ if (dma_mapping_error (dev , da ))
141+ goto frag_err ;
142+
143+ mana_add_sge (tp , ash , sg_i , da , sge1_len , gd -> gpa_mkey );
144+ hsg = 2 ;
145+ }
118146
119147 for (i = 0 ; i < skb_shinfo (skb )-> nr_frags ; i ++ ) {
148+ sg_i = hsg + i ;
149+
120150 frag = & skb_shinfo (skb )-> frags [i ];
121151 da = skb_frag_dma_map (dev , frag , 0 , skb_frag_size (frag ),
122152 DMA_TO_DEVICE );
123-
124153 if (dma_mapping_error (dev , da ))
125154 goto frag_err ;
126155
127- ash -> dma_handle [i + 1 ] = da ;
128- ash -> size [i + 1 ] = skb_frag_size (frag );
129-
130- tp -> wqe_req .sgl [i + 1 ].address = ash -> dma_handle [i + 1 ];
131- tp -> wqe_req .sgl [i + 1 ].mem_key = gd -> gpa_mkey ;
132- tp -> wqe_req .sgl [i + 1 ].size = ash -> size [i + 1 ];
156+ mana_add_sge (tp , ash , sg_i , da , skb_frag_size (frag ),
157+ gd -> gpa_mkey );
133158 }
134159
135160 return 0 ;
136161
137162frag_err :
138- for (i = i - 1 ; i >= 0 ; i -- )
139- dma_unmap_page (dev , ash -> dma_handle [i + 1 ], ash -> size [i + 1 ],
163+ for (i = sg_i - 1 ; i >= hsg ; i -- )
164+ dma_unmap_page (dev , ash -> dma_handle [i ], ash -> size [i ],
140165 DMA_TO_DEVICE );
141166
142- dma_unmap_single (dev , ash -> dma_handle [0 ], ash -> size [0 ], DMA_TO_DEVICE );
167+ for (i = hsg - 1 ; i >= 0 ; i -- )
168+ dma_unmap_single (dev , ash -> dma_handle [i ], ash -> size [i ],
169+ DMA_TO_DEVICE );
143170
144171 return - ENOMEM ;
145172}
146173
174+ /* Handle the case when GSO SKB linear length is too large.
175+ * MANA NIC requires GSO packets to put only the packet header to SGE0.
176+ * So, we need 2 SGEs for the skb linear part which contains more than the
177+ * header.
178+ * Return a positive value for the number of SGEs, or a negative value
179+ * for an error.
180+ */
181+ static int mana_fix_skb_head (struct net_device * ndev , struct sk_buff * skb ,
182+ int gso_hs )
183+ {
184+ int num_sge = 1 + skb_shinfo (skb )-> nr_frags ;
185+ int skb_hlen = skb_headlen (skb );
186+
187+ if (gso_hs < skb_hlen ) {
188+ num_sge ++ ;
189+ } else if (gso_hs > skb_hlen ) {
190+ if (net_ratelimit ())
191+ netdev_err (ndev ,
192+ "TX nonlinear head: hs:%d, skb_hlen:%d\n" ,
193+ gso_hs , skb_hlen );
194+
195+ return - EINVAL ;
196+ }
197+
198+ return num_sge ;
199+ }
200+
201+ /* Get the GSO packet's header size */
202+ static int mana_get_gso_hs (struct sk_buff * skb )
203+ {
204+ int gso_hs ;
205+
206+ if (skb -> encapsulation ) {
207+ gso_hs = skb_inner_tcp_all_headers (skb );
208+ } else {
209+ if (skb_shinfo (skb )-> gso_type & SKB_GSO_UDP_L4 ) {
210+ gso_hs = skb_transport_offset (skb ) +
211+ sizeof (struct udphdr );
212+ } else {
213+ gso_hs = skb_tcp_all_headers (skb );
214+ }
215+ }
216+
217+ return gso_hs ;
218+ }
219+
147220netdev_tx_t mana_start_xmit (struct sk_buff * skb , struct net_device * ndev )
148221{
149222 enum mana_tx_pkt_format pkt_fmt = MANA_SHORT_PKT_FMT ;
150223 struct mana_port_context * apc = netdev_priv (ndev );
224+ int gso_hs = 0 ; /* zero for non-GSO pkts */
151225 u16 txq_idx = skb_get_queue_mapping (skb );
152226 struct gdma_dev * gd = apc -> ac -> gdma_dev ;
153227 bool ipv4 = false, ipv6 = false;
@@ -159,7 +233,6 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
159233 struct mana_txq * txq ;
160234 struct mana_cq * cq ;
161235 int err , len ;
162- u16 ihs ;
163236
164237 if (unlikely (!apc -> port_is_up ))
165238 goto tx_drop ;
@@ -209,26 +282,33 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
209282 pkg .wqe_req .client_data_unit = 0 ;
210283
211284 pkg .wqe_req .num_sge = 1 + skb_shinfo (skb )-> nr_frags ;
212- WARN_ON_ONCE (pkg .wqe_req .num_sge > MAX_TX_WQE_SGL_ENTRIES );
213-
214- if (pkg .wqe_req .num_sge <= ARRAY_SIZE (pkg .sgl_array )) {
215- pkg .wqe_req .sgl = pkg .sgl_array ;
216- } else {
217- pkg .sgl_ptr = kmalloc_array (pkg .wqe_req .num_sge ,
218- sizeof (struct gdma_sge ),
219- GFP_ATOMIC );
220- if (!pkg .sgl_ptr )
221- goto tx_drop_count ;
222-
223- pkg .wqe_req .sgl = pkg .sgl_ptr ;
224- }
225285
226286 if (skb -> protocol == htons (ETH_P_IP ))
227287 ipv4 = true;
228288 else if (skb -> protocol == htons (ETH_P_IPV6 ))
229289 ipv6 = true;
230290
231291 if (skb_is_gso (skb )) {
292+ int num_sge ;
293+
294+ gso_hs = mana_get_gso_hs (skb );
295+
296+ num_sge = mana_fix_skb_head (ndev , skb , gso_hs );
297+ if (num_sge > 0 )
298+ pkg .wqe_req .num_sge = num_sge ;
299+ else
300+ goto tx_drop_count ;
301+
302+ u64_stats_update_begin (& tx_stats -> syncp );
303+ if (skb -> encapsulation ) {
304+ tx_stats -> tso_inner_packets ++ ;
305+ tx_stats -> tso_inner_bytes += skb -> len - gso_hs ;
306+ } else {
307+ tx_stats -> tso_packets ++ ;
308+ tx_stats -> tso_bytes += skb -> len - gso_hs ;
309+ }
310+ u64_stats_update_end (& tx_stats -> syncp );
311+
232312 pkg .tx_oob .s_oob .is_outer_ipv4 = ipv4 ;
233313 pkg .tx_oob .s_oob .is_outer_ipv6 = ipv6 ;
234314
@@ -252,26 +332,6 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
252332 & ipv6_hdr (skb )-> daddr , 0 ,
253333 IPPROTO_TCP , 0 );
254334 }
255-
256- if (skb -> encapsulation ) {
257- ihs = skb_inner_tcp_all_headers (skb );
258- u64_stats_update_begin (& tx_stats -> syncp );
259- tx_stats -> tso_inner_packets ++ ;
260- tx_stats -> tso_inner_bytes += skb -> len - ihs ;
261- u64_stats_update_end (& tx_stats -> syncp );
262- } else {
263- if (skb_shinfo (skb )-> gso_type & SKB_GSO_UDP_L4 ) {
264- ihs = skb_transport_offset (skb ) + sizeof (struct udphdr );
265- } else {
266- ihs = skb_tcp_all_headers (skb );
267- }
268-
269- u64_stats_update_begin (& tx_stats -> syncp );
270- tx_stats -> tso_packets ++ ;
271- tx_stats -> tso_bytes += skb -> len - ihs ;
272- u64_stats_update_end (& tx_stats -> syncp );
273- }
274-
275335 } else if (skb -> ip_summed == CHECKSUM_PARTIAL ) {
276336 csum_type = mana_checksum_info (skb );
277337
@@ -294,11 +354,25 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev)
294354 } else {
295355 /* Can't do offload of this type of checksum */
296356 if (skb_checksum_help (skb ))
297- goto free_sgl_ptr ;
357+ goto tx_drop_count ;
298358 }
299359 }
300360
301- if (mana_map_skb (skb , apc , & pkg )) {
361+ WARN_ON_ONCE (pkg .wqe_req .num_sge > MAX_TX_WQE_SGL_ENTRIES );
362+
363+ if (pkg .wqe_req .num_sge <= ARRAY_SIZE (pkg .sgl_array )) {
364+ pkg .wqe_req .sgl = pkg .sgl_array ;
365+ } else {
366+ pkg .sgl_ptr = kmalloc_array (pkg .wqe_req .num_sge ,
367+ sizeof (struct gdma_sge ),
368+ GFP_ATOMIC );
369+ if (!pkg .sgl_ptr )
370+ goto tx_drop_count ;
371+
372+ pkg .wqe_req .sgl = pkg .sgl_ptr ;
373+ }
374+
375+ if (mana_map_skb (skb , apc , & pkg , gso_hs )) {
302376 u64_stats_update_begin (& tx_stats -> syncp );
303377 tx_stats -> mana_map_err ++ ;
304378 u64_stats_update_end (& tx_stats -> syncp );
@@ -1256,11 +1330,16 @@ static void mana_unmap_skb(struct sk_buff *skb, struct mana_port_context *apc)
12561330 struct mana_skb_head * ash = (struct mana_skb_head * )skb -> head ;
12571331 struct gdma_context * gc = apc -> ac -> gdma_dev -> gdma_context ;
12581332 struct device * dev = gc -> dev ;
1259- int i ;
1333+ int hsg , i ;
1334+
1335+ /* Number of SGEs of linear part */
1336+ hsg = (skb_is_gso (skb ) && skb_headlen (skb ) > ash -> size [0 ]) ? 2 : 1 ;
12601337
1261- dma_unmap_single (dev , ash -> dma_handle [0 ], ash -> size [0 ], DMA_TO_DEVICE );
1338+ for (i = 0 ; i < hsg ; i ++ )
1339+ dma_unmap_single (dev , ash -> dma_handle [i ], ash -> size [i ],
1340+ DMA_TO_DEVICE );
12621341
1263- for (i = 1 ; i < skb_shinfo (skb )-> nr_frags + 1 ; i ++ )
1342+ for (i = hsg ; i < skb_shinfo (skb )-> nr_frags + hsg ; i ++ )
12641343 dma_unmap_page (dev , ash -> dma_handle [i ], ash -> size [i ],
12651344 DMA_TO_DEVICE );
12661345}
0 commit comments