ethtool.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Marvell Wireless LAN device driver: ethtool
  3. *
  4. * Copyright (C) 2013-2014, Marvell International Ltd.
  5. *
  6. * This software file (the "File") is distributed by Marvell International
  7. * Ltd. under the terms of the GNU General Public License Version 2, June 1991
  8. * (the "License"). You may use, redistribute and/or modify this File in
  9. * accordance with the terms and conditions of the License, a copy of which
  10. * is available by writing to the Free Software Foundation, Inc.,
  11. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  12. * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  13. *
  14. * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  16. * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
  17. * this warranty disclaimer.
  18. */
  19. #include "main.h"
  20. static void mwifiex_ethtool_get_wol(struct net_device *dev,
  21. struct ethtool_wolinfo *wol)
  22. {
  23. struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
  24. u32 conditions = le32_to_cpu(priv->adapter->hs_cfg.conditions);
  25. wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY;
  26. if (conditions == HS_CFG_COND_DEF)
  27. return;
  28. if (conditions & HS_CFG_COND_UNICAST_DATA)
  29. wol->wolopts |= WAKE_UCAST;
  30. if (conditions & HS_CFG_COND_MULTICAST_DATA)
  31. wol->wolopts |= WAKE_MCAST;
  32. if (conditions & HS_CFG_COND_BROADCAST_DATA)
  33. wol->wolopts |= WAKE_BCAST;
  34. if (conditions & HS_CFG_COND_MAC_EVENT)
  35. wol->wolopts |= WAKE_PHY;
  36. }
  37. static int mwifiex_ethtool_set_wol(struct net_device *dev,
  38. struct ethtool_wolinfo *wol)
  39. {
  40. struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
  41. u32 conditions = 0;
  42. if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
  43. return -EOPNOTSUPP;
  44. if (wol->wolopts & WAKE_UCAST)
  45. conditions |= HS_CFG_COND_UNICAST_DATA;
  46. if (wol->wolopts & WAKE_MCAST)
  47. conditions |= HS_CFG_COND_MULTICAST_DATA;
  48. if (wol->wolopts & WAKE_BCAST)
  49. conditions |= HS_CFG_COND_BROADCAST_DATA;
  50. if (wol->wolopts & WAKE_PHY)
  51. conditions |= HS_CFG_COND_MAC_EVENT;
  52. if (wol->wolopts == 0)
  53. conditions |= HS_CFG_COND_DEF;
  54. priv->adapter->hs_cfg.conditions = cpu_to_le32(conditions);
  55. return 0;
  56. }
  57. static int
  58. mwifiex_get_dump_flag(struct net_device *dev, struct ethtool_dump *dump)
  59. {
  60. struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
  61. struct mwifiex_adapter *adapter = priv->adapter;
  62. struct memory_type_mapping *entry;
  63. if (!adapter->if_ops.fw_dump)
  64. return -ENOTSUPP;
  65. dump->flag = adapter->curr_mem_idx;
  66. dump->version = 1;
  67. if (adapter->curr_mem_idx != MWIFIEX_FW_DUMP_IDX) {
  68. entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx];
  69. dump->len = entry->mem_size;
  70. } else {
  71. dump->len = 0;
  72. }
  73. return 0;
  74. }
  75. static int
  76. mwifiex_get_dump_data(struct net_device *dev, struct ethtool_dump *dump,
  77. void *buffer)
  78. {
  79. u8 *p = buffer;
  80. struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
  81. struct mwifiex_adapter *adapter = priv->adapter;
  82. struct memory_type_mapping *entry;
  83. if (!adapter->if_ops.fw_dump)
  84. return -ENOTSUPP;
  85. if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
  86. dev_err(adapter->dev, "firmware dump in progress!!\n");
  87. return -EBUSY;
  88. }
  89. entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx];
  90. if (!entry->mem_ptr)
  91. return -EFAULT;
  92. memcpy(p, entry->mem_ptr, entry->mem_size);
  93. entry->mem_size = 0;
  94. vfree(entry->mem_ptr);
  95. entry->mem_ptr = NULL;
  96. return 0;
  97. }
  98. static int mwifiex_set_dump(struct net_device *dev, struct ethtool_dump *val)
  99. {
  100. struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
  101. struct mwifiex_adapter *adapter = priv->adapter;
  102. if (!adapter->if_ops.fw_dump)
  103. return -ENOTSUPP;
  104. if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
  105. dev_err(adapter->dev, "firmware dump in progress!!\n");
  106. return -EBUSY;
  107. }
  108. if (val->flag == MWIFIEX_FW_DUMP_IDX) {
  109. adapter->curr_mem_idx = val->flag;
  110. adapter->if_ops.fw_dump(adapter);
  111. return 0;
  112. }
  113. if (val->flag < 0 || val->flag >= adapter->num_mem_types)
  114. return -EINVAL;
  115. adapter->curr_mem_idx = val->flag;
  116. return 0;
  117. }
  118. const struct ethtool_ops mwifiex_ethtool_ops = {
  119. .get_wol = mwifiex_ethtool_get_wol,
  120. .set_wol = mwifiex_ethtool_set_wol,
  121. .get_dump_flag = mwifiex_get_dump_flag,
  122. .get_dump_data = mwifiex_get_dump_data,
  123. .set_dump = mwifiex_set_dump,
  124. };