cxgb4: Use vmalloc, if kmalloc fails
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / chelsio / cxgb4 / cxgb4_ethtool.c
index 02e4e028a647e2ab63871b67709fad8da477891c..43e0bc59f3a9944d8a7e092d901121d2376e8005 100644 (file)
@@ -35,79 +35,79 @@ static void set_msglevel(struct net_device *dev, u32 val)
 }
 
 static const char stats_strings[][ETH_GSTRING_LEN] = {
-       "TxOctetsOK         ",
-       "TxFramesOK         ",
-       "TxBroadcastFrames  ",
-       "TxMulticastFrames  ",
-       "TxUnicastFrames    ",
-       "TxErrorFrames      ",
-
-       "TxFrames64         ",
-       "TxFrames65To127    ",
-       "TxFrames128To255   ",
-       "TxFrames256To511   ",
-       "TxFrames512To1023  ",
-       "TxFrames1024To1518 ",
-       "TxFrames1519ToMax  ",
-
-       "TxFramesDropped    ",
-       "TxPauseFrames      ",
-       "TxPPP0Frames       ",
-       "TxPPP1Frames       ",
-       "TxPPP2Frames       ",
-       "TxPPP3Frames       ",
-       "TxPPP4Frames       ",
-       "TxPPP5Frames       ",
-       "TxPPP6Frames       ",
-       "TxPPP7Frames       ",
-
-       "RxOctetsOK         ",
-       "RxFramesOK         ",
-       "RxBroadcastFrames  ",
-       "RxMulticastFrames  ",
-       "RxUnicastFrames    ",
-
-       "RxFramesTooLong    ",
-       "RxJabberErrors     ",
-       "RxFCSErrors        ",
-       "RxLengthErrors     ",
-       "RxSymbolErrors     ",
-       "RxRuntFrames       ",
-
-       "RxFrames64         ",
-       "RxFrames65To127    ",
-       "RxFrames128To255   ",
-       "RxFrames256To511   ",
-       "RxFrames512To1023  ",
-       "RxFrames1024To1518 ",
-       "RxFrames1519ToMax  ",
-
-       "RxPauseFrames      ",
-       "RxPPP0Frames       ",
-       "RxPPP1Frames       ",
-       "RxPPP2Frames       ",
-       "RxPPP3Frames       ",
-       "RxPPP4Frames       ",
-       "RxPPP5Frames       ",
-       "RxPPP6Frames       ",
-       "RxPPP7Frames       ",
-
-       "RxBG0FramesDropped ",
-       "RxBG1FramesDropped ",
-       "RxBG2FramesDropped ",
-       "RxBG3FramesDropped ",
-       "RxBG0FramesTrunc   ",
-       "RxBG1FramesTrunc   ",
-       "RxBG2FramesTrunc   ",
-       "RxBG3FramesTrunc   ",
-
-       "TSO                ",
-       "TxCsumOffload      ",
-       "RxCsumGood         ",
-       "VLANextractions    ",
-       "VLANinsertions     ",
-       "GROpackets         ",
-       "GROmerged          ",
+       "tx_octets_ok           ",
+       "tx_frames_ok           ",
+       "tx_broadcast_frames    ",
+       "tx_multicast_frames    ",
+       "tx_unicast_frames      ",
+       "tx_error_frames        ",
+
+       "tx_frames_64           ",
+       "tx_frames_65_to_127    ",
+       "tx_frames_128_to_255   ",
+       "tx_frames_256_to_511   ",
+       "tx_frames_512_to_1023  ",
+       "tx_frames_1024_to_1518 ",
+       "tx_frames_1519_to_max  ",
+
+       "tx_frames_dropped      ",
+       "tx_pause_frames        ",
+       "tx_ppp0_frames         ",
+       "tx_ppp1_frames         ",
+       "tx_ppp2_frames         ",
+       "tx_ppp3_frames         ",
+       "tx_ppp4_frames         ",
+       "tx_ppp5_frames         ",
+       "tx_ppp6_frames         ",
+       "tx_ppp7_frames         ",
+
+       "rx_octets_ok           ",
+       "rx_frames_ok           ",
+       "rx_broadcast_frames    ",
+       "rx_multicast_frames    ",
+       "rx_unicast_frames      ",
+
+       "rx_frames_too_long     ",
+       "rx_jabber_errors       ",
+       "rx_fcs_errors          ",
+       "rx_length_errors       ",
+       "rx_symbol_errors       ",
+       "rx_runt_frames         ",
+
+       "rx_frames_64           ",
+       "rx_frames_65_to_127    ",
+       "rx_frames_128_to_255   ",
+       "rx_frames_256_to_511   ",
+       "rx_frames_512_to_1023  ",
+       "rx_frames_1024_to_1518 ",
+       "rx_frames_1519_to_max  ",
+
+       "rx_pause_frames        ",
+       "rx_ppp0_frames         ",
+       "rx_ppp1_frames         ",
+       "rx_ppp2_frames         ",
+       "rx_ppp3_frames         ",
+       "rx_ppp4_frames         ",
+       "rx_ppp5_frames         ",
+       "rx_ppp6_frames         ",
+       "rx_ppp7_frames         ",
+
+       "rx_bg0_frames_dropped  ",
+       "rx_bg1_frames_dropped  ",
+       "rx_bg2_frames_dropped  ",
+       "rx_bg3_frames_dropped  ",
+       "rx_bg0_frames_trunc    ",
+       "rx_bg1_frames_trunc    ",
+       "rx_bg2_frames_trunc    ",
+       "rx_bg3_frames_trunc    ",
+
+       "tso                    ",
+       "tx_csum_offload        ",
+       "rx_csum_good           ",
+       "vlan_extractions       ",
+       "vlan_insertions        ",
+       "gro_packets            ",
+       "gro_merged             ",
 };
 
 static char adapter_stats_strings[][ETH_GSTRING_LEN] = {
@@ -612,6 +612,8 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        struct port_info *p = netdev_priv(dev);
        struct link_config *lc = &p->link_cfg;
        u32 speed = ethtool_cmd_speed(cmd);
+       struct link_config old_lc;
+       int ret;
 
        if (cmd->duplex != DUPLEX_FULL)     /* only full-duplex supported */
                return -EINVAL;
@@ -626,13 +628,11 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                return -EINVAL;
        }
 
+       old_lc = *lc;
        if (cmd->autoneg == AUTONEG_DISABLE) {
                cap = speed_to_caps(speed);
 
-               if (!(lc->supported & cap) ||
-                   (speed == 1000) ||
-                   (speed == 10000) ||
-                   (speed == 40000))
+               if (!(lc->supported & cap))
                        return -EINVAL;
                lc->requested_speed = cap;
                lc->advertising = 0;
@@ -645,10 +645,14 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        }
        lc->autoneg = cmd->autoneg;
 
-       if (netif_running(dev))
-               return t4_link_l1cfg(p->adapter, p->adapter->pf, p->tx_chan,
-                                    lc);
-       return 0;
+       /* If the firmware rejects the Link Configuration request, back out
+        * the changes and report the error.
+        */
+       ret = t4_link_l1cfg(p->adapter, p->adapter->mbox, p->tx_chan, lc);
+       if (ret)
+               *lc = old_lc;
+
+       return ret;
 }
 
 static void get_pauseparam(struct net_device *dev,
@@ -847,7 +851,7 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
 {
        int i, err = 0;
        struct adapter *adapter = netdev2adap(dev);
-       u8 *buf = kmalloc(EEPROMSIZE, GFP_KERNEL);
+       u8 *buf = t4_alloc_mem(EEPROMSIZE);
 
        if (!buf)
                return -ENOMEM;
@@ -858,7 +862,7 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
 
        if (!err)
                memcpy(data, buf + e->offset, e->len);
-       kfree(buf);
+       t4_free_mem(buf);
        return err;
 }
 
@@ -887,7 +891,7 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) {
                /* RMW possibly needed for first or last words.
                 */
-               buf = kmalloc(aligned_len, GFP_KERNEL);
+               buf = t4_alloc_mem(aligned_len);
                if (!buf)
                        return -ENOMEM;
                err = eeprom_rd_phys(adapter, aligned_offset, (u32 *)buf);
@@ -915,7 +919,7 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                err = t4_seeprom_wp(adapter, true);
 out:
        if (buf != data)
-               kfree(buf);
+               t4_free_mem(buf);
        return err;
 }
 
@@ -1011,11 +1015,15 @@ static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key,
        if (!p)
                return 0;
 
-       for (i = 0; i < pi->rss_size; i++)
-               pi->rss[i] = p[i];
-       if (pi->adapter->flags & FULL_INIT_DONE)
+       /* Interface must be brought up atleast once */
+       if (pi->adapter->flags & FULL_INIT_DONE) {
+               for (i = 0; i < pi->rss_size; i++)
+                       pi->rss[i] = p[i];
+
                return cxgb4_write_rss(pi, pi->rss);
-       return 0;
+       }
+
+       return -EPERM;
 }
 
 static int get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,