| 1367 | ****************************************************************************/ |
| 1368 | |
| 1369 | int netdev_lower_register(FAR struct netdev_lowerhalf_s *dev, |
| 1370 | enum net_lltype_e lltype) |
| 1371 | { |
| 1372 | FAR struct netdev_upperhalf_s *upper; |
| 1373 | size_t extra_size; |
| 1374 | int cpu = 0; |
| 1375 | int ret; |
| 1376 | |
| 1377 | if (dev == NULL || dev->ops == NULL || |
| 1378 | dev->ops->transmit == NULL || dev->ops->receive == NULL) |
| 1379 | { |
| 1380 | nerr("ERROR: Invalid lower half device\n"); |
| 1381 | return -EINVAL; |
| 1382 | } |
| 1383 | |
| 1384 | if (dev->quota_ptr == NULL) |
| 1385 | { |
| 1386 | dev->quota_ptr = dev->quota; |
| 1387 | } |
| 1388 | |
| 1389 | if (quota_is_valid(dev) == false) |
| 1390 | { |
| 1391 | return -EINVAL; |
| 1392 | } |
| 1393 | |
| 1394 | switch (dev->rxtype) |
| 1395 | { |
| 1396 | case NETDEV_RX_WORK: |
| 1397 | extra_size = sizeof(struct work_s); |
| 1398 | break; |
| 1399 | case NETDEV_RX_DIRECT: |
| 1400 | extra_size = 0; /* No extra size needed for direct mode */ |
| 1401 | break; |
| 1402 | case NETDEV_RX_THREAD: |
| 1403 | extra_size = sizeof(struct netdev_thread_s); |
| 1404 | cpu = 1; |
| 1405 | break; |
| 1406 | case NETDEV_RX_THREAD_RSS: |
| 1407 | extra_size = sizeof(struct netdev_thread_s) * CONFIG_SMP_NCPUS; |
| 1408 | cpu = CONFIG_SMP_NCPUS; |
| 1409 | break; |
| 1410 | default: |
| 1411 | nerr("ERROR: Unrecognized device rxtype: %d\n", dev->rxtype); |
| 1412 | return -EINVAL; |
| 1413 | } |
| 1414 | |
| 1415 | if ((upper = netdev_upper_alloc(dev, extra_size)) == NULL) |
| 1416 | { |
| 1417 | return -ENOMEM; |
| 1418 | } |
| 1419 | |
| 1420 | upper->txing = false; |
| 1421 | |
| 1422 | dev->netdev.d_ifup = netdev_upper_ifup; |
| 1423 | dev->netdev.d_ifdown = netdev_upper_ifdown; |
| 1424 | dev->netdev.d_txavail = netdev_upper_txavail; |
| 1425 | #ifdef CONFIG_NET_MCASTGROUP |
| 1426 | dev->netdev.d_addmac = netdev_upper_addmac; |
no test coverage detected