diff options
Diffstat (limited to 'drivers/net/ethernet/ti/netcp_core.c')
-rw-r--r-- | drivers/net/ethernet/ti/netcp_core.c | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c index 32516661f180..c243335ed649 100644 --- a/drivers/net/ethernet/ti/netcp_core.c +++ b/drivers/net/ethernet/ti/netcp_core.c @@ -100,6 +100,11 @@ struct netcp_intf_modpriv { void *module_priv; }; +struct netcp_tx_cb { + void *ts_context; + void (*txtstamp)(void *context, struct sk_buff *skb); +}; + static LIST_HEAD(netcp_devices); static LIST_HEAD(netcp_modules); static DEFINE_MUTEX(netcp_modules_lock); @@ -544,6 +549,7 @@ int netcp_register_rxhook(struct netcp_intf *netcp_priv, int order, return 0; } +EXPORT_SYMBOL_GPL(netcp_register_rxhook); int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, netcp_hook_rtn *hook_rtn, void *hook_data) @@ -566,6 +572,7 @@ int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order, return -ENOENT; } +EXPORT_SYMBOL_GPL(netcp_unregister_rxhook); static void netcp_frag_free(bool is_frag, void *ptr) { @@ -730,6 +737,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp) /* Call each of the RX hooks */ p_info.skb = skb; + skb->dev = netcp->ndev; p_info.rxtstamp_complete = false; list_for_each_entry(rx_hook, &netcp->rxhook_list_head, list) { int ret; @@ -987,6 +995,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, unsigned int budget) { struct knav_dma_desc *desc; + struct netcp_tx_cb *tx_cb; struct sk_buff *skb; unsigned int dma_sz; dma_addr_t dma; @@ -1014,6 +1023,10 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp, continue; } + tx_cb = (struct netcp_tx_cb *)skb->cb; + if (tx_cb->txtstamp) + tx_cb->txtstamp(tx_cb->ts_context, skb); + if (netif_subqueue_stopped(netcp->ndev, skb) && netif_running(netcp->ndev) && (knav_pool_count(netcp->tx_pool) > @@ -1154,6 +1167,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, struct netcp_tx_pipe *tx_pipe = NULL; struct netcp_hook_list *tx_hook; struct netcp_packet p_info; + struct netcp_tx_cb *tx_cb; unsigned int dma_sz; dma_addr_t dma; u32 tmp = 0; @@ -1164,7 +1178,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, p_info.tx_pipe = NULL; p_info.psdata_len = 0; p_info.ts_context = NULL; - p_info.txtstamp_complete = NULL; + p_info.txtstamp = NULL; p_info.epib = desc->epib; p_info.psdata = (u32 __force *)desc->psdata; memset(p_info.epib, 0, KNAV_DMA_NUM_EPIB_WORDS * sizeof(__le32)); @@ -1189,6 +1203,10 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp, goto out; } + tx_cb = (struct netcp_tx_cb *)skb->cb; + tx_cb->ts_context = p_info.ts_context; + tx_cb->txtstamp = p_info.txtstamp; + /* update descriptor */ if (p_info.psdata_len) { /* psdata points to both native-endian and device-endian data */ @@ -1568,7 +1586,7 @@ static int netcp_setup_navigator_resources(struct net_device *ndev) /* open Tx completion queue */ snprintf(name, sizeof(name), "tx-compl-%s", ndev->name); netcp->tx_compl_q = knav_queue_open(name, netcp->tx_compl_qid, 0); - if (IS_ERR_OR_NULL(netcp->tx_compl_q)) { + if (IS_ERR(netcp->tx_compl_q)) { ret = PTR_ERR(netcp->tx_compl_q); goto fail; } @@ -1588,7 +1606,7 @@ static int netcp_setup_navigator_resources(struct net_device *ndev) /* open Rx completion queue */ snprintf(name, sizeof(name), "rx-compl-%s", ndev->name); netcp->rx_queue = knav_queue_open(name, netcp->rx_queue_id, 0); - if (IS_ERR_OR_NULL(netcp->rx_queue)) { + if (IS_ERR(netcp->rx_queue)) { ret = PTR_ERR(netcp->rx_queue); goto fail; } @@ -1610,7 +1628,7 @@ static int netcp_setup_navigator_resources(struct net_device *ndev) ++i) { snprintf(name, sizeof(name), "rx-fdq-%s-%d", ndev->name, i); netcp->rx_fdq[i] = knav_queue_open(name, KNAV_QUEUE_GP, 0); - if (IS_ERR_OR_NULL(netcp->rx_fdq[i])) { + if (IS_ERR(netcp->rx_fdq[i])) { ret = PTR_ERR(netcp->rx_fdq[i]); goto fail; } @@ -1766,21 +1784,6 @@ out: return (ret == 0) ? 0 : err; } -static int netcp_ndo_change_mtu(struct net_device *ndev, int new_mtu) -{ - struct netcp_intf *netcp = netdev_priv(ndev); - - /* MTU < 68 is an error for IPv4 traffic */ - if ((new_mtu < 68) || - (new_mtu > (NETCP_MAX_FRAME_SIZE - ETH_HLEN - ETH_FCS_LEN))) { - dev_err(netcp->ndev_dev, "Invalid mtu size = %d\n", new_mtu); - return -EINVAL; - } - - ndev->mtu = new_mtu; - return 0; -} - static void netcp_ndo_tx_timeout(struct net_device *ndev) { struct netcp_intf *netcp = netdev_priv(ndev); @@ -1886,7 +1889,6 @@ static const struct net_device_ops netcp_netdev_ops = { .ndo_start_xmit = netcp_ndo_start_xmit, .ndo_set_rx_mode = netcp_set_rx_mode, .ndo_do_ioctl = netcp_ndo_ioctl, - .ndo_change_mtu = netcp_ndo_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_vlan_rx_add_vid = netcp_rx_add_vid, @@ -1923,6 +1925,10 @@ static int netcp_create_interface(struct netcp_device *netcp_device, ndev->hw_features = ndev->features; ndev->vlan_features |= NETIF_F_SG; + /* MTU range: 68 - 9486 */ + ndev->min_mtu = ETH_MIN_MTU; + ndev->max_mtu = NETCP_MAX_FRAME_SIZE - (ETH_HLEN + ETH_FCS_LEN); + netcp = netdev_priv(ndev); spin_lock_init(&netcp->lock); INIT_LIST_HEAD(&netcp->module_head); @@ -2070,7 +2076,6 @@ static void netcp_delete_interface(struct netcp_device *netcp_device, if (module->release) module->release(intf_modpriv->module_priv); list_del(&intf_modpriv->intf_list); - kfree(intf_modpriv); } WARN(!list_empty(&netcp->module_head), "%s interface module list is not empty!\n", ndev->name); @@ -2133,6 +2138,8 @@ static int netcp_probe(struct platform_device *pdev) } } + of_node_put(interfaces); + /* Add the device instance to the list */ list_add_tail(&netcp_device->device_list, &netcp_devices); @@ -2145,6 +2152,8 @@ probe_quit_interface: netcp_delete_interface(netcp_device, netcp_intf->ndev); } + of_node_put(interfaces); + probe_quit: pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -2165,7 +2174,6 @@ static int netcp_remove(struct platform_device *pdev) dev_dbg(&pdev->dev, "Removing module \"%s\"\n", module->name); module->remove(netcp_device, inst_modpriv->module_priv); list_del(&inst_modpriv->inst_list); - kfree(inst_modpriv); } /* now that all modules are removed, clean up the interfaces */ |