summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/ti/netcp_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/ti/netcp_core.c')
-rw-r--r--drivers/net/ethernet/ti/netcp_core.c52
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 */