|
@@ -283,9 +283,6 @@ struct mvneta_port {
|
|
|
u32 cause_rx_tx;
|
|
|
struct napi_struct napi;
|
|
|
|
|
|
- /* Napi weight */
|
|
|
- int weight;
|
|
|
-
|
|
|
/* Core clock */
|
|
|
struct clk *clk;
|
|
|
u8 mcast_count[256];
|
|
@@ -451,7 +448,10 @@ struct mvneta_rx_queue {
|
|
|
int next_desc_to_proc;
|
|
|
};
|
|
|
|
|
|
-static int rxq_number = 8;
|
|
|
+/* The hardware supports eight (8) rx queues, but we are only allowing
|
|
|
+ * the first one to be used. Therefore, let's just allocate one queue.
|
|
|
+ */
|
|
|
+static int rxq_number = 1;
|
|
|
static int txq_number = 8;
|
|
|
|
|
|
static int rxq_def;
|
|
@@ -1654,9 +1654,9 @@ static int mvneta_tx_frag_process(struct mvneta_port *pp, struct sk_buff *skb,
|
|
|
struct mvneta_tx_queue *txq)
|
|
|
{
|
|
|
struct mvneta_tx_desc *tx_desc;
|
|
|
- int i;
|
|
|
+ int i, nr_frags = skb_shinfo(skb)->nr_frags;
|
|
|
|
|
|
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
|
|
+ for (i = 0; i < nr_frags; i++) {
|
|
|
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
|
|
|
void *addr = page_address(frag->page.p) + frag->page_offset;
|
|
|
|
|
@@ -1673,20 +1673,16 @@ static int mvneta_tx_frag_process(struct mvneta_port *pp, struct sk_buff *skb,
|
|
|
goto error;
|
|
|
}
|
|
|
|
|
|
- if (i == (skb_shinfo(skb)->nr_frags - 1)) {
|
|
|
+ if (i == nr_frags - 1) {
|
|
|
/* Last descriptor */
|
|
|
tx_desc->command = MVNETA_TXD_L_DESC | MVNETA_TXD_Z_PAD;
|
|
|
-
|
|
|
txq->tx_skb[txq->txq_put_index] = skb;
|
|
|
-
|
|
|
- mvneta_txq_inc_put(txq);
|
|
|
} else {
|
|
|
/* Descriptor in the middle: Not First, Not Last */
|
|
|
tx_desc->command = 0;
|
|
|
-
|
|
|
txq->tx_skb[txq->txq_put_index] = NULL;
|
|
|
- mvneta_txq_inc_put(txq);
|
|
|
}
|
|
|
+ mvneta_txq_inc_put(txq);
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -2137,7 +2133,7 @@ static void mvneta_tx_reset(struct mvneta_port *pp)
|
|
|
{
|
|
|
int queue;
|
|
|
|
|
|
- /* free the skb's in the hal tx ring */
|
|
|
+ /* free the skb's in the tx ring */
|
|
|
for (queue = 0; queue < txq_number; queue++)
|
|
|
mvneta_txq_done_force(pp, &pp->txqs[queue]);
|
|
|
|
|
@@ -2429,24 +2425,28 @@ static int mvneta_change_mtu(struct net_device *dev, int mtu)
|
|
|
return 0;
|
|
|
|
|
|
/* The interface is running, so we have to force a
|
|
|
- * reallocation of the RXQs
|
|
|
+ * reallocation of the queues
|
|
|
*/
|
|
|
mvneta_stop_dev(pp);
|
|
|
|
|
|
mvneta_cleanup_txqs(pp);
|
|
|
mvneta_cleanup_rxqs(pp);
|
|
|
|
|
|
- pp->pkt_size = MVNETA_RX_PKT_SIZE(pp->dev->mtu);
|
|
|
+ pp->pkt_size = MVNETA_RX_PKT_SIZE(dev->mtu);
|
|
|
pp->frag_size = SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(pp->pkt_size)) +
|
|
|
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
|
|
|
|
|
ret = mvneta_setup_rxqs(pp);
|
|
|
if (ret) {
|
|
|
- netdev_err(pp->dev, "unable to setup rxqs after MTU change\n");
|
|
|
+ netdev_err(dev, "unable to setup rxqs after MTU change\n");
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
- mvneta_setup_txqs(pp);
|
|
|
+ ret = mvneta_setup_txqs(pp);
|
|
|
+ if (ret) {
|
|
|
+ netdev_err(dev, "unable to setup txqs after MTU change\n");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
|
|
|
mvneta_start_dev(pp);
|
|
|
mvneta_port_up(pp);
|
|
@@ -2473,22 +2473,19 @@ static void mvneta_get_mac_addr(struct mvneta_port *pp, unsigned char *addr)
|
|
|
static int mvneta_set_mac_addr(struct net_device *dev, void *addr)
|
|
|
{
|
|
|
struct mvneta_port *pp = netdev_priv(dev);
|
|
|
- u8 *mac = addr + 2;
|
|
|
- int i;
|
|
|
-
|
|
|
- if (netif_running(dev))
|
|
|
- return -EBUSY;
|
|
|
+ struct sockaddr *sockaddr = addr;
|
|
|
+ int ret;
|
|
|
|
|
|
+ ret = eth_prepare_mac_addr_change(dev, addr);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
/* Remove previous address table entry */
|
|
|
mvneta_mac_addr_set(pp, dev->dev_addr, -1);
|
|
|
|
|
|
/* Set new addr in hw */
|
|
|
- mvneta_mac_addr_set(pp, mac, rxq_def);
|
|
|
-
|
|
|
- /* Set addr in the device */
|
|
|
- for (i = 0; i < ETH_ALEN; i++)
|
|
|
- dev->dev_addr[i] = mac[i];
|
|
|
+ mvneta_mac_addr_set(pp, sockaddr->sa_data, rxq_def);
|
|
|
|
|
|
+ eth_commit_mac_addr_change(dev, addr);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2583,8 +2580,6 @@ static int mvneta_open(struct net_device *dev)
|
|
|
struct mvneta_port *pp = netdev_priv(dev);
|
|
|
int ret;
|
|
|
|
|
|
- mvneta_mac_addr_set(pp, dev->dev_addr, rxq_def);
|
|
|
-
|
|
|
pp->pkt_size = MVNETA_RX_PKT_SIZE(pp->dev->mtu);
|
|
|
pp->frag_size = SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(pp->pkt_size)) +
|
|
|
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
|
@@ -2788,7 +2783,7 @@ const struct ethtool_ops mvneta_eth_tool_ops = {
|
|
|
};
|
|
|
|
|
|
/* Initialize hw */
|
|
|
-static int mvneta_init(struct mvneta_port *pp, int phy_addr)
|
|
|
+static int mvneta_init(struct device *dev, struct mvneta_port *pp)
|
|
|
{
|
|
|
int queue;
|
|
|
|
|
@@ -2798,8 +2793,8 @@ static int mvneta_init(struct mvneta_port *pp, int phy_addr)
|
|
|
/* Set port default values */
|
|
|
mvneta_defaults_set(pp);
|
|
|
|
|
|
- pp->txqs = kzalloc(txq_number * sizeof(struct mvneta_tx_queue),
|
|
|
- GFP_KERNEL);
|
|
|
+ pp->txqs = devm_kcalloc(dev, txq_number, sizeof(struct mvneta_tx_queue),
|
|
|
+ GFP_KERNEL);
|
|
|
if (!pp->txqs)
|
|
|
return -ENOMEM;
|
|
|
|
|
@@ -2811,12 +2806,10 @@ static int mvneta_init(struct mvneta_port *pp, int phy_addr)
|
|
|
txq->done_pkts_coal = MVNETA_TXDONE_COAL_PKTS;
|
|
|
}
|
|
|
|
|
|
- pp->rxqs = kzalloc(rxq_number * sizeof(struct mvneta_rx_queue),
|
|
|
- GFP_KERNEL);
|
|
|
- if (!pp->rxqs) {
|
|
|
- kfree(pp->txqs);
|
|
|
+ pp->rxqs = devm_kcalloc(dev, rxq_number, sizeof(struct mvneta_rx_queue),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (!pp->rxqs)
|
|
|
return -ENOMEM;
|
|
|
- }
|
|
|
|
|
|
/* Create Rx descriptor rings */
|
|
|
for (queue = 0; queue < rxq_number; queue++) {
|
|
@@ -2830,12 +2823,6 @@ static int mvneta_init(struct mvneta_port *pp, int phy_addr)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void mvneta_deinit(struct mvneta_port *pp)
|
|
|
-{
|
|
|
- kfree(pp->txqs);
|
|
|
- kfree(pp->rxqs);
|
|
|
-}
|
|
|
-
|
|
|
/* platform glue : initialize decoding windows */
|
|
|
static void mvneta_conf_mbus_windows(struct mvneta_port *pp,
|
|
|
const struct mbus_dram_target_info *dram)
|
|
@@ -2918,7 +2905,6 @@ static int mvneta_probe(struct platform_device *pdev)
|
|
|
struct resource *res;
|
|
|
struct device_node *dn = pdev->dev.of_node;
|
|
|
struct device_node *phy_node;
|
|
|
- u32 phy_addr;
|
|
|
struct mvneta_port *pp;
|
|
|
struct net_device *dev;
|
|
|
const char *dt_mac_addr;
|
|
@@ -2979,8 +2965,6 @@ static int mvneta_probe(struct platform_device *pdev)
|
|
|
dev->ethtool_ops = &mvneta_eth_tool_ops;
|
|
|
|
|
|
pp = netdev_priv(dev);
|
|
|
-
|
|
|
- pp->weight = MVNETA_RX_POLL_WEIGHT;
|
|
|
pp->phy_node = phy_node;
|
|
|
pp->phy_interface = phy_mode;
|
|
|
|
|
@@ -3027,23 +3011,21 @@ static int mvneta_probe(struct platform_device *pdev)
|
|
|
pp->dev = dev;
|
|
|
SET_NETDEV_DEV(dev, &pdev->dev);
|
|
|
|
|
|
- err = mvneta_init(pp, phy_addr);
|
|
|
- if (err < 0) {
|
|
|
- dev_err(&pdev->dev, "can't init eth hal\n");
|
|
|
+ err = mvneta_init(&pdev->dev, pp);
|
|
|
+ if (err < 0)
|
|
|
goto err_free_stats;
|
|
|
- }
|
|
|
|
|
|
err = mvneta_port_power_up(pp, phy_mode);
|
|
|
if (err < 0) {
|
|
|
dev_err(&pdev->dev, "can't power up port\n");
|
|
|
- goto err_deinit;
|
|
|
+ goto err_free_stats;
|
|
|
}
|
|
|
|
|
|
dram_target_info = mv_mbus_dram_info();
|
|
|
if (dram_target_info)
|
|
|
mvneta_conf_mbus_windows(pp, dram_target_info);
|
|
|
|
|
|
- netif_napi_add(dev, &pp->napi, mvneta_poll, pp->weight);
|
|
|
+ netif_napi_add(dev, &pp->napi, mvneta_poll, MVNETA_RX_POLL_WEIGHT);
|
|
|
|
|
|
dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
|
|
|
dev->hw_features |= dev->features;
|
|
@@ -3053,7 +3035,7 @@ static int mvneta_probe(struct platform_device *pdev)
|
|
|
err = register_netdev(dev);
|
|
|
if (err < 0) {
|
|
|
dev_err(&pdev->dev, "failed to register\n");
|
|
|
- goto err_deinit;
|
|
|
+ goto err_free_stats;
|
|
|
}
|
|
|
|
|
|
netdev_info(dev, "Using %s mac address %pM\n", mac_from,
|
|
@@ -3063,8 +3045,6 @@ static int mvneta_probe(struct platform_device *pdev)
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
-err_deinit:
|
|
|
- mvneta_deinit(pp);
|
|
|
err_free_stats:
|
|
|
free_percpu(pp->stats);
|
|
|
err_clk:
|
|
@@ -3083,7 +3063,6 @@ static int mvneta_remove(struct platform_device *pdev)
|
|
|
struct mvneta_port *pp = netdev_priv(dev);
|
|
|
|
|
|
unregister_netdev(dev);
|
|
|
- mvneta_deinit(pp);
|
|
|
clk_disable_unprepare(pp->clk);
|
|
|
free_percpu(pp->stats);
|
|
|
irq_dispose_mapping(dev->irq);
|