On Thu, 13 Jan 2022, Ricardo Martinez wrote: > From: Haijun Liu <haijun.liu@xxxxxxxxxxxx> > > Creates the Cross Core Modem Network Interface (CCMNI) which implements > the wwan_ops for registration with the WWAN framework, CCMNI also > implements the net_device_ops functions used by the network device. > Network device operations include open, close, start transmission, TX > timeout, change MTU, and select queue. > > Signed-off-by: Haijun Liu <haijun.liu@xxxxxxxxxxxx> > Co-developed-by: Chandrashekar Devegowda <chandrashekar.devegowda@xxxxxxxxx> > Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@xxxxxxxxx> > Co-developed-by: Ricardo Martinez <ricardo.martinez@xxxxxxxxxxxxxxx> > Signed-off-by: Ricardo Martinez <ricardo.martinez@xxxxxxxxxxxxxxx> > --- > +static int t7xx_ccmni_open(struct net_device *dev) > +{ > + struct t7xx_ccmni *ccmni = wwan_netdev_drvpriv(dev); > + > + netif_carrier_on(dev); > + netif_tx_start_all_queues(dev); > + atomic_inc(&ccmni->usage); > + return 0; > +} > + > +static int t7xx_ccmni_close(struct net_device *dev) > +{ > + struct t7xx_ccmni *ccmni = wwan_netdev_drvpriv(dev); > + > + if (atomic_dec_return(&ccmni->usage) < 0) > + return -EINVAL; I'm certainly way out of my expertize here in knowing how/when these open and close can be called. That kept in mind, I wonder if there's need to do rollback for the atomic dec. > +static void t7xx_ccmni_wwan_setup(struct net_device *dev) > +{ > + dev->header_ops = NULL; > + dev->hard_header_len += sizeof(struct ccci_header); > + > + dev->mtu = ETH_DATA_LEN; > + dev->max_mtu = CCMNI_MTU_MAX; > + dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; > + dev->watchdog_timeo = CCMNI_NETDEV_WDT_TO; > + /* CCMNI is a pure IP device */ > + dev->flags = IFF_POINTOPOINT | IFF_NOARP; > + > + /* Not supporting VLAN */ > + dev->features = NETIF_F_VLAN_CHALLENGED; > + > + dev->features |= NETIF_F_SG; > + dev->hw_features |= NETIF_F_SG; > + > + /* Uplink checksum offload */ > + dev->features |= NETIF_F_HW_CSUM; > + dev->hw_features |= NETIF_F_HW_CSUM; > + > + /* Downlink checksum offload */ > + dev->features |= NETIF_F_RXCSUM; > + dev->hw_features |= NETIF_F_RXCSUM; > + > + /* Use kernel default free_netdev() function */ > + dev->needs_free_netdev = true; > + > + /* No need to free again because of free_netdev() */ > + dev->priv_destructor = NULL; Isn't the struct zeroed for you? Maybe some of those comments are not that useful? > + ctlb->capability = NIC_CAP_TXBUSY_STOP | NIC_CAP_SGIO | > + NIC_CAP_DATA_ACK_DVD | NIC_CAP_CCMNI_MQ; Is capability going to remain constant? And some of these are not used at all. Related to this, e.g., the NETIF_F_SG setting above doesn't seem to care about what is in capability (assuming SGIO means what I think it does), should it? > + /* WWAN core will create a netdev for the default IP MUX channel */ > + ret = wwan_register_ops(dev, &ccmni_wwan_ops, ctlb, IP_MUX_SESSION_DEFAULT); > + if (ret) > + goto err_unregister_ops; > + > + init_md_status_notifier(t7xx_dev); > + > + return 0; > + > +err_unregister_ops: > + wwan_unregister_ops(dev); If wwan_register_ops fails, why is wwan_unregister_ops needed? > +/* Must be less than DPMAIF_HW_MTU_SIZE (3*1024 + 8) */ This could be enforced with BUILD_BUG_ON if you want. -- i.