@@ -231,55 +231,133 @@ static inline struct net_if *get_iface(struct eth_context *ctx,
231231#endif
232232}
233233
234- static int read_data (struct eth_context * ctx , int fd )
234+ #if defined(CONFIG_NET_VLAN )
235+ static struct net_pkt * prepare_vlan_pkt (struct eth_context * ctx ,
236+ int count , u16_t * vlan_tag , int * status )
235237{
236- u16_t vlan_tag = NET_VLAN_TAG_UNSPEC ;
237- struct net_if * iface ;
238+ struct net_eth_vlan_hdr * hdr = (struct net_eth_vlan_hdr * )ctx -> recv ;
238239 struct net_pkt * pkt ;
239- int count ;
240+ u8_t pos ;
240241
241- count = eth_read_data (fd , ctx -> recv , sizeof (ctx -> recv ));
242- if (count <= 0 ) {
243- return 0 ;
242+ if (IS_ENABLED (CONFIG_ETH_NATIVE_POSIX_VLAN_TAG_STRIP )) {
243+ count -= NET_ETH_VLAN_HDR_SIZE ;
244244 }
245245
246246 pkt = net_pkt_rx_alloc_with_buffer (ctx -> iface , count ,
247247 AF_UNSPEC , 0 , NET_BUF_TIMEOUT );
248248 if (!pkt ) {
249- return - ENOMEM ;
249+ * status = - ENOMEM ;
250+ return NULL ;
251+ }
252+
253+ net_pkt_set_vlan_tci (pkt , ntohs (hdr -> vlan .tci ));
254+ * vlan_tag = net_pkt_vlan_tag (pkt );
255+
256+ pos = 0 ;
257+
258+ if (IS_ENABLED (CONFIG_ETH_NATIVE_POSIX_VLAN_TAG_STRIP )) {
259+ if (net_pkt_write (pkt , ctx -> recv ,
260+ 2 * sizeof (struct net_eth_addr ))) {
261+ goto error ;
262+ }
263+
264+ pos = (2 * sizeof (struct net_eth_addr )) + NET_ETH_VLAN_HDR_SIZE ;
265+ count -= (2 * sizeof (struct net_eth_addr ));
266+ }
267+
268+ if (net_pkt_write (pkt , ctx -> recv + pos , count )) {
269+ goto error ;
270+ }
271+
272+ #if CONFIG_NET_TC_RX_COUNT > 1
273+ {
274+ enum net_priority prio ;
275+
276+ prio = net_vlan2priority (net_pkt_vlan_priority (pkt ));
277+ net_pkt_set_priority (pkt , prio );
278+ }
279+ #endif
280+
281+ * status = 0 ;
282+
283+ LOG_DBG ("Recv pkt %p len %d" , pkt , count );
284+
285+ return pkt ;
286+
287+ error :
288+ net_pkt_unref (pkt );
289+ * status = - ENOBUFS ;
290+ return NULL ;
291+ }
292+ #endif
293+
294+ static struct net_pkt * prepare_non_vlan_pkt (struct eth_context * ctx ,
295+ int count , int * status )
296+ {
297+ struct net_pkt * pkt ;
298+
299+ pkt = net_pkt_rx_alloc_with_buffer (ctx -> iface , count ,
300+ AF_UNSPEC , 0 , NET_BUF_TIMEOUT );
301+ if (!pkt ) {
302+ * status = - ENOMEM ;
303+ return NULL ;
250304 }
251305
252306 if (net_pkt_write (pkt , ctx -> recv , count )) {
253- return - ENOBUFS ;
307+ net_pkt_unref (pkt );
308+ * status = - ENOBUFS ;
309+ return NULL ;
310+ }
311+
312+ * status = 0 ;
313+
314+ LOG_DBG ("Recv pkt %p len %d" , pkt , count );
315+
316+ return pkt ;
317+ }
318+
319+ static int read_data (struct eth_context * ctx , int fd )
320+ {
321+ u16_t vlan_tag = NET_VLAN_TAG_UNSPEC ;
322+ struct net_if * iface ;
323+ struct net_pkt * pkt = NULL ;
324+ int status ;
325+ int count ;
326+
327+ count = eth_read_data (fd , ctx -> recv , sizeof (ctx -> recv ));
328+ if (count <= 0 ) {
329+ return 0 ;
254330 }
255331
256332#if defined(CONFIG_NET_VLAN )
257333 {
258- struct net_eth_hdr * hdr = NET_ETH_HDR ( pkt );
334+ struct net_eth_hdr * hdr = ( struct net_eth_hdr * )( ctx -> recv );
259335
260336 if (ntohs (hdr -> type ) == NET_ETH_PTYPE_VLAN ) {
261- struct net_eth_vlan_hdr * hdr_vlan =
262- (struct net_eth_vlan_hdr * )NET_ETH_HDR (pkt );
337+ pkt = prepare_vlan_pkt (ctx , count , & vlan_tag , & status );
338+ if (!pkt ) {
339+ return status ;
340+ }
341+ } else {
342+ pkt = prepare_non_vlan_pkt (ctx , count , & status );
343+ if (!pkt ) {
344+ return status ;
345+ }
263346
264- net_pkt_set_vlan_tci (pkt , ntohs (hdr_vlan -> vlan .tci ));
265- vlan_tag = net_pkt_vlan_tag (pkt );
347+ net_pkt_set_vlan_tci (pkt , 0 );
266348 }
267-
268- #if CONFIG_NET_TC_RX_COUNT > 1
269- {
270- enum net_priority prio ;
271-
272- prio = net_vlan2priority (net_pkt_vlan_priority (pkt ));
273- net_pkt_set_priority (pkt , prio );
349+ }
350+ #else
351+ {
352+ pkt = prepare_non_vlan_pkt (ctx , count , & status );
353+ if (!pkt ) {
354+ return status ;
274355 }
275- #endif
276356 }
277357#endif
278358
279359 iface = get_iface (ctx , vlan_tag );
280360
281- LOG_DBG ("Recv pkt %p len %d" , pkt , count );
282-
283361 update_gptp (iface , pkt , false);
284362
285363 if (net_recv_data (iface , pkt ) < 0 ) {
@@ -384,6 +462,9 @@ enum ethernet_hw_caps eth_posix_native_get_capabilities(struct device *dev)
384462 ARG_UNUSED (dev );
385463
386464 return ETHERNET_HW_VLAN
465+ #if defined(CONFIG_ETH_NATIVE_POSIX_VLAN_TAG_STRIP )
466+ | ETHERNET_HW_VLAN_TAG_STRIP
467+ #endif
387468#if defined(CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK )
388469 | ETHERNET_PTP
389470#endif
0 commit comments