ethernet: unify return value of .ndo_set_mac_address if address is invalid
[deliverable/linux.git] / drivers / net / ethernet / ti / davinci_emac.c
index 815c7970261bc2ee09e8b8107afe6463aeffe69c..6d74cb7aaae8ab9426d63e50f05a190a6d14c816 100644 (file)
@@ -115,6 +115,7 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 #define EMAC_DEF_TX_CH                 (0) /* Default 0th channel */
 #define EMAC_DEF_RX_CH                 (0) /* Default 0th channel */
 #define EMAC_DEF_RX_NUM_DESC           (128)
+#define EMAC_DEF_TX_NUM_DESC           (128)
 #define EMAC_DEF_MAX_TX_CH             (1) /* Max TX channels configured */
 #define EMAC_DEF_MAX_RX_CH             (1) /* Max RX channels configured */
 #define EMAC_POLL_WEIGHT               (64) /* Default NAPI poll weight */
@@ -336,6 +337,7 @@ struct emac_priv {
        u32 mac_hash2;
        u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS];
        u32 rx_addr_type;
+       atomic_t cur_tx;
        const char *phy_id;
        struct phy_device *phydev;
        spinlock_t lock;
@@ -990,10 +992,9 @@ static irqreturn_t emac_irq(int irq, void *dev_id)
 
 static struct sk_buff *emac_rx_alloc(struct emac_priv *priv)
 {
-       struct sk_buff *skb = dev_alloc_skb(priv->rx_buf_size);
+       struct sk_buff *skb = netdev_alloc_skb(priv->ndev, priv->rx_buf_size);
        if (WARN_ON(!skb))
                return NULL;
-       skb->dev = priv->ndev;
        skb_reserve(skb, NET_IP_ALIGN);
        return skb;
 }
@@ -1044,6 +1045,9 @@ static void emac_tx_handler(void *token, int len, int status)
 {
        struct sk_buff          *skb = token;
        struct net_device       *ndev = skb->dev;
+       struct emac_priv        *priv = netdev_priv(ndev);
+
+       atomic_dec(&priv->cur_tx);
 
        if (unlikely(netif_queue_stopped(ndev)))
                netif_start_queue(ndev);
@@ -1092,6 +1096,9 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
                goto fail_tx;
        }
 
+       if (atomic_inc_return(&priv->cur_tx) >= EMAC_DEF_TX_NUM_DESC)
+               netif_stop_queue(ndev);
+
        return NETDEV_TX_OK;
 
 fail_tx:
@@ -1247,15 +1254,15 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr)
        struct sockaddr *sa = addr;
 
        if (!is_valid_ether_addr(sa->sa_data))
-               return -EINVAL;
+               return -EADDRNOTAVAIL;
 
        /* Store mac addr in priv and rx channel and set it in EMAC hw */
        memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
        memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len);
+       ndev->addr_assign_type &= ~NET_ADDR_RANDOM;
 
        /* MAC address is configured only after the interface is enabled. */
        if (netif_running(ndev)) {
-               memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
                emac_setmac(priv, EMAC_DEF_RX_CH, priv->mac_addr);
        }
 
@@ -1592,8 +1599,9 @@ static int emac_dev_open(struct net_device *ndev)
                if (IS_ERR(priv->phydev)) {
                        dev_err(emac_dev, "could not connect to phy %s\n",
                                priv->phy_id);
+                       ret = PTR_ERR(priv->phydev);
                        priv->phydev = NULL;
-                       return PTR_ERR(priv->phydev);
+                       return ret;
                }
 
                priv->link = 0;
@@ -1781,7 +1789,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
 
        ndev = alloc_etherdev(sizeof(struct emac_priv));
        if (!ndev) {
-               dev_err(&pdev->dev, "error allocating net_device\n");
                rc = -ENOMEM;
                goto free_clk;
        }
@@ -1889,7 +1896,8 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
 
        if (!is_valid_ether_addr(priv->mac_addr)) {
                /* Use random MAC if none passed */
-               random_ether_addr(priv->mac_addr);
+               eth_hw_addr_random(ndev);
+               memcpy(priv->mac_addr, ndev->dev_addr, ndev->addr_len);
                dev_warn(&pdev->dev, "using random MAC addr: %pM\n",
                                                        priv->mac_addr);
        }
This page took 0.026133 seconds and 5 git commands to generate.