Thursday, May 10, 2018

let's make a variation , to sybill attacks...and let's calculate the source code that comes from the sensor nodes, so we get to know the path of jamming with a DDos attack, like RTS blocking activity. And not forgetting when they detect an attack, they disconnect the radios, so the objective is disrupt operations.

Task:
Find the shortest path between two nodes (points). 
Solution:

The most famous solution for this problem was first proposed by Dijkstra. Generally, his solution is the most efficient and used in most cases.

Algorithm:
  1. Set the distance to source node to 0, and the distances to all other nodes to infinity.
  2. Among all unprocessed nodes find the one that has the minimum distance to it yet found. Let this node be i. Ifi is the destination (end) node then exit because the shortest path from source to destination has been found. Otherwise mark it as processed and go to point 3.
    Note: If distances to all unprocessed nodes are equal to Infinity then no path from source to destination node exists.
  3. Look at each unprocessed neighbor of node i. If the shortest distance to j is greater than the shortest distance to i + the cost of the edge between these 2 nodes, then update the shortest distance/path to j with this one and mark that it has been reached from i.
    Go back to point 2.
Pseudocode:

# N - number of nodes
# weight(i,j) - weight of the edge from node i to j ; equal to infinity if such an edge doesn't exist
# dist(i) - the shortest path from source node to i
# parent(i) - node that precedes i in a shortest path, used to reconstruct the shortest path


# initialize all values
For i = 1 to N
    dist(i) = infinity
    processed(i) = false
    parent(i) = null
End For
dist(source) = 0

While (not all nodes have been processed)
    If (distances to all unprocessed nodes are equal to infinity) Then
        no path from source to destination node exists
        Exit
    End If

    Let i be an unprocessed node for which dist(i) is the smallest among all unprocessed nodes.

    If i = destination Then Exit While    # shortest path from source to destination has been found
    Set processed(i) = true
  
    For Each unprocessed node j    # i.e. for which processed(j) = false
        If dist(i) + weight(i,j) < dist(j) Then
            # a shorter path from source node to j has been found ; update it
            dist(j) = dist(i) + weight(i,j)
            parent(j) = i
        End If
    End For
End While

# the length of the shortest path is thus dist(destination)

# path reconstruction is given below
Set i = destination
While i != source
    Append i to the beginning of the currently constructed path
    i = parent(i)
End While
Append source to the beginning of the path

Complexity:

In average each of N nodes is processed, and for each all of its neighbors are updated in O(N). Thus the complexity is O(N2).

Restrictions:

This algorithm doesn't work for graphs that have negative edges. For these you should use Bellman-Ford algorithm, that runs in O(NM), where M is the number of edges.

Optimizations:
  1. For sparse graphs a complexity of O(NlogN) may be obtained. For this purpose a heap is used to store the shortest distances to nodes, and neighbors of each node are stored in lists. In this way the unprocessed node with the minimum distance is found in logN and the update of each node is also done in logN.
    Providing that the graph is sparse, each node has few neighbors and thus the average complexity is O(NlogN).
  2. If edges have no costs then a Breadth First Search (BFS) algorithm can be applied to find the shortest path. It would run substantially faster, especially for graphs that have structures similar to mazes, tables, where each point has few neighbors.
Extensions:

If the above code is run until all nodes are processed (or until no unprocessed node is reachable) then we will get the shortest paths from source point to all other points (those that are reachable from it).


Sample Execution:

Given:

A sample graph made in Graph Magics. node 1 is start (source) node and 2 is end (destination) node. We need to find the shortest path between these two nodes.

Below execution steps of this algorithm are shown (all images are created in Graph Magics).

Legend:
- unprocessed nodes are colored in light gray
current node (the one that is being processed) is colored in blue
processed nodes are colored in red
- the number on a node represents the shortest path length to it yet found


Starting state:

NodeProcessedDistance from SourceParent
1false0null
2falseInfinitynull
3falseInfinitynull
4falseInfinitynull
5falseInfinitynull
6falseInfinitynull
7falseInfinitynull

Download this graph (viewable with Graph Magics)


Among all unprocessed nodes, has the minimum distance from the source.

After updating the neighbors of node 1:

NodeProcessedDistance from SourceParent
1true0null
2falseInfinitynull
3false51
4falseInfinitynull
5falseInfinitynull
6false151
7falseInfinitynull

Among all unprocessed nodes, 3 has the minimum distance from the source.

After updating the neighbors of node 3:

NodeProcessedDistance from SourceParent
1true0null
2falseInfinitynull
3true51
4falseInfinitynull
5false303
6false151
7falseInfinitynull

Among all unprocessed nodes, has the minimum distance from the source.

After updating the neighbors of 6:

NodeProcessedDistance from SourceParent
1true0null
2false456
3true51
4false206
5false303
6true151
7false256

Among all unprocessed nodes, 4 has the minimum distance from the source.

After updating the neighbors of 4:

NodeProcessedDistance from SourceParent
1true0null
2false404
3true51
4true206
5false303
6true151
7false256

Among all unprocessed nodes, 7 has the minimum distance from the source.

After updating the neighbors of 7:

NodeProcessedDistance from SourceParent
1true0null
2false404
3true51
4true206
5false303
6true151
7true256

Among all unprocessed nodes, 5 has the minimum distance from the source.

After updating the neighbors of 5:

NodeProcessedDistance from SourceParent
1true0null
2false404
3true51
4true206
5true303
6true151
7true256

2 is the node that has the shortest path to it yet found among all unprocessed nodes (in this example it is the only one left).
So we stop here the execution because we have found the shortest path from source to destination node (i.e. from 1 to 2).


Shortest path found:
1 >> 6 >> 4 >> 2

Cost of the path - 40



Applications:

This is probably the most used graph algorithm. It may be applied in situations where the shortest path between 2 points is needed. Examples of such applications would be:

  • Computer games - finding the best/shortest route from one point to another.
  • Maps - finding the shortest/cheapest path for a car from one city to another, by using given roads.
  • May be used to find the fastest way for a car to get from one point to another inside a certain city. E.g. satellite navigation system that shows to drivers which way they should better go.


A maze

The shortest path between the corners of the maze

disruptive technology Reactive Data/ACK jammer

and now comes the 7Up

  1. diff -Naur backports-4.4.2-1/defconfigs/ath9k-debug backports-4.4.2-1-modwifi/defconfigs/ath9k-debug
  2. --- backports-4.4.2-1/defconfigs/ath9k-debug    2016-02-18 22:41:34.000000000 +0100
  3. +++ backports-4.4.2-1-modwifi/defconfigs/ath9k-debug    2016-04-03 13:28:53.000000000 +0200
  4. @@ -17,3 +17,4 @@
  5.  CPTCFG_ATH9K_HTC=m
  6.  CPTCFG_ATH_DEBUG=y
  7.  CPTCFG_ATH9K_DEBUGFS=y
  8. +CPTCFG_ATH9K_HTC_DEBUGFS=y
  9. diff -Naur backports-4.4.2-1/drivers/net/wireless/ath/ath9k/htc_drv_debug.c backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
  10. --- backports-4.4.2-1/drivers/net/wireless/ath/ath9k/htc_drv_debug.c    2016-02-18 22:41:35.000000000 +0100
  11. +++ backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/htc_drv_debug.c    2016-04-03 13:28:54.000000000 +0200
  12. @@ -15,6 +15,61 @@
  13.   */
  14.  
  15.  #include "htc.h"
  16. +#include "hw.h"
  17. +
  18. +typedef u32 (*GetTimeFunc)(struct ath_hw *ah);
  19. +typedef void (*SetTimeFunc)(struct ath_hw *ah, u32 us);
  20. +
  21. +struct time_func {
  22. +   const char *name;
  23. +   GetTimeFunc getter;
  24. +   SetTimeFunc setter;
  25. +   const char *comments;
  26. +};
  27. +
  28. +struct time_func_context {
  29. +   struct time_func *timefunc;
  30. +   struct ath9k_htc_priv *htcpriv;
  31. +};
  32. +
  33. +struct time_func timefunctions[] =
  34. +{
  35. +   {"time_sifs",       ath9k_hw_get_sifs_time,     ath9k_hw_set_sifs_time,
  36. +       "SIFS time in microseconds (us) = Rx/Tx time = required time to wait after Rx."},
  37. +   {"time_slottime",   ath9k_hw_getslottime,       ath9k_hw_setslottime,
  38. +       "Slot time (aSlotTime) in microseconds (us) = slot time as used in backoff algo."},
  39. +   {"time_ack_timeout",    ath9k_hw_get_ack_timeout,   ath9k_hw_set_ack_timeout,
  40. +       "ACK timeout in microseconds (us)"},
  41. +   {"time_cts_timeout",    ath9k_hw_get_cts_timeout,   ath9k_hw_set_cts_timeout,
  42. +       "CTS timeout in microseconds (us)"},
  43. +   {"time_eifs",       ath9k_hw_get_eifs_timeout,  ath9k_hw_set_eifs_timeout,
  44. +       "EIFS time in microseconds (us)"}
  45. +};
  46. +
  47. +struct reg_ops registers[] = {
  48. +   // Backoff parameters
  49. +   {"ifs_cwmin_queue0",        AR_DLCL_IFS(0),     AR_D_LCL_IFS_CWMIN,
  50. +       "Backoff behaviour (queue 0): CW_MIN is the minimum number of time slots to wait."},
  51. +   {"ifs_cwmax_queue0",        AR_DLCL_IFS(0),     AR_D_LCL_IFS_CWMAX,
  52. +       "Backoff behaviour (queue 0): CW_MAX is the maximum number of time slots to wait."},
  53. +   {"ifs_aifs_queue0",     AR_DLCL_IFS(0),     AR_D_LCL_IFS_AIFS,
  54. +       "AIFS (in number of aSlotTime's) for queue 0."},
  55. +   // Disable backoff
  56. +   {"ifs_ignore_backoff",      AR_D_GBL_IFS_MISC,  AR_D_GBL_IFS_MISC_IGNORE_BACKOFF,
  57. +       "Ignore backoff (perhaps you also want to disable waiting for ACKs - see inject_noack)."},
  58. +   // Virtual and physical carrier sense
  59. +   {"ignore_virt_cs",      AR_DIAG_SW,     AR_DIAG_IGNORE_VIRT_CS,
  60. +       "Disables virtual carrier (cts/rts) sense when set."},
  61. +   {"force_channel_idle",      AR_DIAG_SW,     AR_DIAG_FORCE_CH_IDLE_HIGH,
  62. +       "Disables physical carrier sense (air clear) when set."},
  63. +   {"diag_rx_disable",     AR_DIAG_SW,     AR_DIAG_RX_DIS,
  64. +       "Block incoming frames from being sent to the firmware."},
  65. +   // Other
  66. +   {"diag_corrupt_fcs",        AR_DIAG_SW,     AR_DIAG_CORR_FCS,
  67. +       "If set, every transmitted packet is given an incorrect FCS."},
  68. +   {"cpu_freq_pll",        0x00056000,     -1,
  69. +       "Value = frequency * 4 + 5 (Setting of the Phase Locked Loop)."},
  70. +};
  71.  
  72.  static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
  73.                        size_t count, loff_t *ppos)
  74. @@ -398,6 +453,633 @@
  75.     .llseek = default_llseek,
  76.  };
  77.  
  78. +static ssize_t read_file_reg_ops(struct file *file, char __user *user_buf,
  79. +                size_t count, loff_t *ppos)
  80. +{
  81. +   struct reg_ops_instance *instance = file->private_data;
  82. +   struct ath9k_htc_priv *priv = instance->owner;
  83. +   struct reg_ops *regops = instance->regops;
  84. +   char buf[512];
  85. +   unsigned int len;
  86. +   unsigned int regval, mask;
  87. +
  88. +   ath9k_htc_ps_wakeup(priv);
  89. +   regval = REG_READ(priv->ah, regops->address);
  90. +   ath9k_htc_ps_restore(priv);
  91. +
  92. +   // apply mask, and shift according to mask
  93. +   regval &= regops->mask;
  94. +   mask = regops->mask;
  95. +   while ( (mask & 1) == 0) {
  96. +       mask >>= 1;
  97. +       regval >>= 1;
  98. +   }
  99. +
  100. +   len = snprintf(buf, sizeof(buf), "%s: %s\nValue: 0x%08X = %d (forced: %d)\n",
  101. +                   regops->name, regops->description, regval, regval,
  102. +                   !!(instance->valueset));
  103. +
  104. +   return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  105. +}
  106. +
  107. +static ssize_t write_file_reg_ops(struct file *file, const char __user *user_buf,
  108. +                 size_t count, loff_t *ppos)
  109. +{
  110. +   struct reg_ops_instance *instance = file->private_data;
  111. +   struct ath9k_htc_priv *priv = instance->owner;
  112. +   struct reg_ops *regops = instance->regops;
  113. +   unsigned long val;
  114. +   char buf[32];
  115. +   ssize_t len;
  116. +   unsigned int mask, regval;
  117. +
  118. +   len = min(count, sizeof(buf) - 1);
  119. +   if (copy_from_user(buf, user_buf, len))
  120. +       return -EINVAL;
  121. +
  122. +   buf[len] = '\0';
  123. +   if (kstrtoul(buf, 0, &val))
  124. +       return -EINVAL;
  125. +
  126. +   // shift according to mask
  127. +   mask = regops->mask;
  128. +   while ( (mask & 1) == 0) {
  129. +       mask >>= 1;
  130. +       val <<= 1;
  131. +   }
  132. +
  133. +   // apply mask to assure we're not overwriting anything else
  134. +   val &= regops->mask;
  135. +
  136. +   ath9k_htc_ps_wakeup(priv);
  137. +   regval = REG_READ(priv->ah, regops->address);
  138. +   regval = (regval & ~regops->mask) | val;
  139. +   REG_WRITE(priv->ah, regops->address, regval);
  140. +   ath9k_htc_ps_restore(priv);
  141. +
  142. +   instance->valueset = 1;
  143. +   instance->value = val;
  144. +
  145. +   return count;
  146. +}
  147. +
  148. +static const struct file_operations fops_reg_ops = {
  149. +   .read = read_file_reg_ops,
  150. +   .write = write_file_reg_ops,
  151. +   .open = simple_open,
  152. +   .owner = THIS_MODULE,
  153. +   .llseek = default_llseek,
  154. +};
  155. +
  156. +static ssize_t read_file_dmesg(struct file *file, char __user *user_buf,
  157. +                  size_t count, loff_t *ppos)
  158. +{
  159. +   struct ath9k_htc_priv *priv = file->private_data;
  160. +   struct wmi_debugmsg_cmd cmd;
  161. +   struct wmi_debugmsg_resp cmd_rsp;
  162. +   /** ppos is the amount of data already read (maintained by caller) */
  163. +   int offset = *ppos;
  164. +   int ret;
  165. +
  166. +   /** Note: don't need to wake the WiFi MAC chip to get debug messages! */
  167. +   memset(&cmd, 0, sizeof(cmd));
  168. +   cmd.offset = cpu_to_be16(offset);
  169. +
  170. +   memset(&cmd_rsp, 0, sizeof(cmd_rsp));
  171. +   ret = ath9k_wmi_cmd(priv->wmi, WMI_DEBUGMSG_CMDID,
  172. +               (u8*)&cmd, sizeof(cmd),
  173. +               (u8*)&cmd_rsp, sizeof(cmd_rsp),
  174. +               HZ*2);
  175. +   if (ret) {
  176. +       printk("ath9k_htc %s: Something went wrong reading firmware dmesg (ret: %d, len: %d)\n",
  177. +           __FUNCTION__, ret, cmd_rsp.length);
  178. +       return -EIO;
  179. +   }
  180. +
  181. +   // Don't overflow user_buf
  182. +   if (count < cmd_rsp.length)
  183. +       cmd_rsp.length = count;
  184. +
  185. +   // Length of zero signifies EOF
  186. +   if (cmd_rsp.length != 0) {
  187. +       // Returns number of bytes that could not be copied
  188. +       if (copy_to_user(user_buf, cmd_rsp.buffer, cmd_rsp.length) != 0)
  189. +           return -EFAULT;
  190. +   }
  191. +
  192. +   *ppos += cmd_rsp.length;
  193. +   return cmd_rsp.length;
  194. +}
  195. +
  196. +static const struct file_operations fops_dmesg = {
  197. +   .read = read_file_dmesg,
  198. +   .open = simple_open,
  199. +   .owner = THIS_MODULE,
  200. +   .llseek = default_llseek,
  201. +};
  202. +
  203. +static ssize_t read_file_reactivejam(struct file *file, char __user *user_buf,
  204. +                size_t count, loff_t *ppos)
  205. +{
  206. +   char output[] = "Jam beacons and probe responses by writing the bssid and"
  207. +           "duration (in msecs) to this file as 'XX:XX:XX:XX:XX:XX,10000'.\n"
  208. +           "Duration of 0 means an infinite jam (device becomes unresponsive).\n";
  209. +   return simple_read_from_buffer(user_buf, count, ppos, output, sizeof(output));
  210. +}
  211. +
  212. +static ssize_t write_file_reactivejam(struct file *file, const char __user *user_buf,
  213. +                     size_t count, loff_t *ppos)
  214. +{
  215. +   struct ath9k_htc_priv *priv = file->private_data;
  216. +   struct wmi_reactivejam_cmd cmd;
  217. +   char buf[32] = {0}, reply[128] = {0};
  218. +   unsigned int intmac[6];
  219. +   unsigned int duration;
  220. +   int rval, len, i;
  221. +
  222. +   if (*ppos != 0) return 0;
  223. +
  224. +   // copy over input
  225. +   len = min(count, sizeof(buf) - 1);
  226. +   if (unlikely(copy_from_user(buf, user_buf, len))) {
  227. +       printk("ath9k_htc %s: copy_from_user failed\n", __FUNCTION__);
  228. +       return -EFAULT;
  229. +   }
  230. +   buf[sizeof(buf) - 1] = 0;
  231. +
  232. +   // parse input
  233. +   if ( 7 != sscanf(buf, "%x:%x:%x:%x:%x:%x,%u", &intmac[0], &intmac[1], &intmac[2],
  234. +       &intmac[3], &intmac[4], &intmac[5], &duration) ) {
  235. +       printk("ath9k_htc %s: invalid format\n", __FUNCTION__);
  236. +       return -EINVAL;
  237. +   }
  238. +
  239. +   // save input to command
  240. +   for (i = 0; i < 6; ++i)
  241. +       cmd.bssid[i] = intmac[i];
  242. +   cmd.mduration = cpu_to_be32(duration);
  243. +
  244. +   printk("ath9k_htc: Reactively jamming %x:%x:%x:%x:%x:%x ", cmd.bssid[0], cmd.bssid[1],
  245. +       cmd.bssid[2], cmd.bssid[3], cmd.bssid[4], cmd.bssid[5]);
  246. +   if (cmd.mduration == 0)
  247. +       printk("indefinitely (device will be unresponsive)\n");
  248. +   else
  249. +       printk("for %u miliseconds\n", duration);
  250. +
  251. +   // Blocking call! Wait for duration + 4 seconds. Response is an ASCII string. If the duration
  252. +   // is zero, firmware instantly replies, but will then become unresponsive (infinite jam).
  253. +   ath9k_htc_ps_wakeup(priv); 
  254. +   rval = ath9k_wmi_cmd(priv->wmi, WMI_REACTIVEJAM_CMDID,
  255. +           (u8*)&cmd, sizeof(cmd),
  256. +           (u8*)reply, sizeof(reply),
  257. +           HZ * (duration / 1000 + 4));
  258. +   ath9k_htc_ps_restore(priv);
  259. +
  260. +   if (unlikely(rval) && cmd.mduration != 0) {
  261. +       printk("ath9k_htc %s: WMI_REACTIVEJAM_CMD failed with %d\n", __FUNCTION__, rval);
  262. +       return -EBUSY;
  263. +   }
  264. +
  265. +   // Reset radio settings
  266. +   ath9k_hw_init_global_settings(priv->ah);
  267. +
  268. +   return count;
  269. +}
  270. +
  271. +static const struct file_operations fops_reactivejam = {
  272. +   .read = read_file_reactivejam,
  273. +   .write = write_file_reactivejam,
  274. +   .open = simple_open,
  275. +   .owner = THIS_MODULE,
  276. +   .llseek = default_llseek,
  277. +};
  278. +
  279. +static ssize_t read_file_constantjam(struct file *file, char __user *user_buf,
  280. +                  size_t count, loff_t *ppos)
  281. +{
  282. +   struct ath9k_htc_priv *priv = file->private_data;
  283. +   struct wmi_constantjam_resp cmd_rsp;
  284. +   struct wmi_constantjam_cmd cmd;
  285. +   char buf[128];
  286. +   unsigned int len;
  287. +   int rval;
  288. +  
  289. +   if (*ppos != 0) return 0;
  290. +
  291. +   memset(&cmd, 0, sizeof(cmd));
  292. +   cmd.request = CONSTJAM_STATUS;
  293. +
  294. +   // Send command to firmware
  295. +   rval = ath9k_wmi_cmd(priv->wmi, WMI_CONSTANTJAM_CMDID,
  296. +           (u8 *)&cmd, sizeof(cmd),
  297. +           (u8 *)&cmd_rsp, sizeof(cmd_rsp),
  298. +           HZ*2);
  299. +
  300. +   if (unlikely(rval)) {
  301. +       printk(">>>> WMI_CONSTANTJAM_CMD failed: %d\n", rval);
  302. +       return -EIO;
  303. +   }
  304. +
  305. +   len = snprintf(buf, sizeof(buf), "Constant jammer running: %d\n", cmd_rsp.status);
  306. +   return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  307. +}
  308. +
  309. +static ssize_t write_file_constantjam(struct file *file, const char __user *user_buf,
  310. +                size_t count, loff_t *ppos)
  311. +{
  312. +   struct ath9k_htc_priv *priv = file->private_data;
  313. +   struct wmi_constantjam_resp cmd_rsp;
  314. +   struct wmi_constantjam_cmd cmd;
  315. +   unsigned long val;
  316. +   char buf[32];
  317. +   ssize_t len;
  318. +   int rval = 0;
  319. +
  320. +   if (*ppos != 0) return 0;
  321. +
  322. +   // parse input
  323. +   len = min(count, sizeof(buf) - 1);
  324. +   if (copy_from_user(buf, user_buf, len))
  325. +       return -EINVAL;
  326. +
  327. +   buf[len] = '\0';
  328. +   if (kstrtoul(buf, 0, &val))
  329. +       return -EINVAL;
  330. +
  331. +   memset(&cmd, 0, sizeof(cmd));
  332. +   // should we start or stop
  333. +   cmd.request = val == 0 ? CONSTJAM_STOP : CONSTJAM_START;
  334. +   // full continuous jamming (disable carrier sense, no timeouts between packets)
  335. +   cmd.conf_radio = 1;
  336. +   // length of packet used for jamming (pick a small one to avoid memory issues)
  337. +   cmd.len = cpu_to_be16(50);
  338. +
  339. +   // Send command to firmware
  340. +   ath9k_htc_ps_wakeup(priv);
  341. +   rval = ath9k_wmi_cmd(priv->wmi, WMI_CONSTANTJAM_CMDID,
  342. +           (u8 *)&cmd, sizeof(cmd),
  343. +           (u8 *)&cmd_rsp, sizeof(cmd_rsp),
  344. +           HZ*2);
  345. +
  346. +   if (unlikely(rval)) {
  347. +       printk(">>>> WMI_CONSTANTJAM_CMD failed: %d\n", rval);
  348. +       return -EIO;
  349. +   }
  350. +
  351. +   if (cmd.request == CONSTJAM_STOP)
  352. +       ath9k_htc_ps_restore(priv);
  353. +
  354. +   return count;
  355. +}
  356. +
  357. +static const struct file_operations fops_constantjam = {
  358. +   .read = read_file_constantjam,
  359. +   .write = write_file_constantjam,
  360. +   .open = simple_open,
  361. +   .owner = THIS_MODULE,
  362. +   .llseek = default_llseek,
  363. +};
  364. +
  365. +static ssize_t read_file_macaddr(struct file *file, char __user *user_buf,
  366. +                size_t count, loff_t *ppos)
  367. +{
  368. +   struct ath9k_htc_priv *priv = file->private_data;
  369. +   char buf[512];
  370. +   unsigned int len;
  371. +   unsigned int low, upper;
  372. +
  373. +   ath9k_htc_ps_wakeup(priv);
  374. +   low = REG_READ(priv->ah, AR_STA_ID0);
  375. +   upper = REG_READ(priv->ah, AR_STA_ID1) & AR_STA_ID1_SADH_MASK;
  376. +   ath9k_htc_ps_restore(priv);
  377. +
  378. +   len = snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X\n",
  379. +           low & 0xFF, (low >> 8) & 0xFF, (low >> 16) & 0xFF,
  380. +           (low >> 24) & 0xFF, upper & 0xFF, (upper >> 8) & 0xFF);
  381. +   return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  382. +}
  383. +
  384. +static ssize_t write_file_macaddr(struct file *file, const char __user *user_buf,
  385. +                 size_t count, loff_t *ppos)
  386. +{
  387. +   struct ath9k_htc_priv *priv = file->private_data;
  388. +   char buf[32];
  389. +   unsigned int mac[6];
  390. +   unsigned int low, upper;
  391. +   ssize_t len;
  392. +
  393. +   len = min(count, sizeof(buf) - 1);
  394. +   if (copy_from_user(buf, user_buf, len))
  395. +       return -EFAULT;
  396. +   buf[sizeof(buf) - 1] = 0;
  397. +
  398. +   if ( 6 != sscanf(buf, "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) )
  399. +       return -EINVAL;
  400. +
  401. +   low = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24);
  402. +   upper = mac[4] | (mac[5] << 8);
  403. +
  404. +   ath9k_htc_ps_wakeup(priv);
  405. +   REG_WRITE(priv->ah, AR_STA_ID0, low);
  406. +   REG_WRITE(priv->ah, AR_STA_ID1, upper & AR_STA_ID1_SADH_MASK);
  407. +   ath9k_htc_ps_restore(priv);
  408. +
  409. +   return count;
  410. +}
  411. +
  412. +static const struct file_operations fops_macaddr = {
  413. +   .read = read_file_macaddr,
  414. +   .write = write_file_macaddr,
  415. +   .open = simple_open,
  416. +   .owner = THIS_MODULE,
  417. +   .llseek = default_llseek,
  418. +};
  419. +
  420. +static ssize_t read_file_bssidmask(struct file *file, char __user *user_buf,
  421. +                  size_t count, loff_t *ppos)
  422. +{
  423. +   struct ath9k_htc_priv *priv = file->private_data;
  424. +   char buf[512];
  425. +   unsigned int len;
  426. +   unsigned int low, upper;       
  427. +
  428. +   ath9k_htc_ps_wakeup(priv);
  429. +   low = REG_READ(priv->ah, AR_BSSMSKL);
  430. +   upper = REG_READ(priv->ah, AR_BSSMSKU);
  431. +   ath9k_htc_ps_restore(priv);
  432. +
  433. +   len = snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X\n",
  434. +           low & 0xFF, (low >> 8) & 0xFF, (low >> 16) & 0xFF,
  435. +           (low >> 24) & 0xFF, upper & 0xFF, (upper >> 8) & 0xFF);
  436. +   return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  437. +}
  438. +
  439. +static ssize_t write_file_bssidmask(struct file *file, const char __user *user_buf,
  440. +                   size_t count, loff_t *ppos)
  441. +{
  442. +   struct ath9k_htc_priv *priv = file->private_data;
  443. +   char buf[32];
  444. +   unsigned int mask[6];
  445. +   unsigned int low, upper;
  446. +   ssize_t len;
  447. +
  448. +   len = min(count, sizeof(buf) - 1);
  449. +   if (copy_from_user(buf, user_buf, len))
  450. +       return -EFAULT;
  451. +   buf[sizeof(buf) - 1] = 0;
  452. +
  453. +   if ( 6 != sscanf(buf, "%x:%x:%x:%x:%x:%x", &mask[0], &mask[1], &mask[2], &mask[3], &mask[4], &mask[5]) )
  454. +       return -EINVAL;
  455. +
  456. +   low = mask[0] | (mask[1] << 8) | (mask[2] << 16) | (mask[3] << 24);
  457. +   upper = mask[4] | (mask[5] << 8);
  458. +
  459. +   ath9k_htc_ps_wakeup(priv);
  460. +   REG_WRITE(priv->ah, AR_BSSMSKL, low);
  461. +   REG_WRITE(priv->ah, AR_BSSMSKU, upper & AR_BSS_ID1_U16);
  462. +   ath9k_htc_ps_restore(priv);
  463. +
  464. +   return count;
  465. +}
  466. +
  467. +static const struct file_operations fops_bssidmask = {
  468. +   .read = read_file_bssidmask,
  469. +   .write = write_file_bssidmask,
  470. +   .open = simple_open,
  471. +   .owner = THIS_MODULE,
  472. +   .llseek = default_llseek,
  473. +};
  474. +
  475. +static ssize_t read_file_inject_noack(struct file *file, char __user *user_buf,
  476. +                size_t count, loff_t *ppos)
  477. +{
  478. +   struct ath9k_htc_priv *priv = file->private_data;
  479. +   char buf[64];
  480. +   int len;
  481. +
  482. +   len = snprintf(buf, sizeof(buf), "%d\n", priv->inject_noack);
  483. +   return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  484. +}
  485. +
  486. +static ssize_t write_file_inject_noack(struct file *file, const char __user *user_buf,
  487. +                 size_t count, loff_t *ppos)
  488. +{
  489. +   struct ath9k_htc_priv *priv = file->private_data;
  490. +   char buf[32];
  491. +   unsigned long val;
  492. +   int len;
  493. +
  494. +   len = min(count, sizeof(buf) - 1);
  495. +   if (copy_from_user(buf, user_buf, len))
  496. +       return -EFAULT;
  497. +
  498. +   buf[len] = '\0';
  499. +   if (kstrtoul(buf, 0, &val))
  500. +       return -EINVAL;
  501. +
  502. +   priv->inject_noack = val;
  503. +
  504. +   return count;
  505. +}
  506. +
  507. +static const struct file_operations fops_inject_noack = {
  508. +   .read = read_file_inject_noack,
  509. +   .write = write_file_inject_noack,
  510. +   .open = simple_open,
  511. +   .owner = THIS_MODULE,
  512. +   .llseek = default_llseek,
  513. +};
  514. +
  515. +static ssize_t read_file_fastreply_packet(struct file *file, char __user *user_buf,
  516. +                  size_t count, loff_t *ppos)
  517. +{
  518. +   char buf[128] = "Write the reply packet used in fastreply_start to this file.\n";
  519. +   return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
  520. +}
  521. +
  522. +static ssize_t write_file_fastreply_packet(struct file *file,
  523. +   const char __user *user_buf, size_t count, loff_t *ppos)
  524. +{
  525. +   struct ath9k_htc_priv *priv = file->private_data;
  526. +   struct wmi_fastreply_cmd cmd;
  527. +   uint8_t buff[256];
  528. +   unsigned int offset;
  529. +   int reply, rval;
  530. +
  531. +   if (*ppos != 0) return 0;
  532. +
  533. +   //
  534. +   // 1. copy input
  535. +   //
  536. +
  537. +   if (count > 256) {
  538. +       printk("fastreply_packet: packet is too long (%zu)\n", count);
  539. +       return -EMSGSIZE;
  540. +   }
  541. +
  542. +   if (copy_from_user(buff, user_buf, count))
  543. +       return -EFAULT;
  544. +
  545. +   //
  546. +   // 2. send the buffer to the firmware
  547. +   //
  548. +      
  549. +   cmd.type = FASTREPLY_PKT;
  550. +   cmd.pkt.length = count;
  551. +
  552. +   ath9k_htc_ps_wakeup(priv);
  553. +
  554. +   for (offset = 0; offset < count; offset += sizeof(cmd.pkt.data))
  555. +   {
  556. +       cmd.pkt.offset = offset;
  557. +       cmd.pkt.datalen = min(40U, (unsigned int)(count - offset));
  558. +       memcpy(cmd.pkt.data, &buff[offset], cmd.pkt.datalen);
  559. +
  560. +       rval = ath9k_wmi_cmd(priv->wmi, WMI_FASTREPLY_CMDID,
  561. +               (u8*)&cmd, sizeof(cmd),
  562. +               (u8*)&reply, sizeof(reply),
  563. +               2*HZ);
  564. +
  565. +       if (unlikely(rval)) {
  566. +           printk("ath9k_htc %s: WMI_FASTREPLY_CMDID failed with %d\n", __FUNCTION__, rval);
  567. +           ath9k_htc_ps_restore(priv);
  568. +           return -EIO;
  569. +       }
  570. +   }
  571. +
  572. +   ath9k_htc_ps_restore(priv);
  573. +
  574. +   return count;
  575. +}
  576. +
  577. +
  578. +static const struct file_operations fops_fastreply_packet = {
  579. +   .read = read_file_fastreply_packet,
  580. +   .write = write_file_fastreply_packet,
  581. +   .open = simple_open,
  582. +   .owner = THIS_MODULE,
  583. +   .llseek = default_llseek,
  584. +};
  585. +
  586. +static ssize_t read_file_fastreply_start(struct file *file, char __user *user_buf,
  587. +                  size_t count, loff_t *ppos)
  588. +{
  589. +   char buf[128] = "Write the source MAC and duration ( 90:18:7c:6e:6b:20,10000 ) to this file.\n"
  590. +           "Set the reply packet using fastreply_packet.\n";
  591. +   return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
  592. +}
  593. +
  594. +static ssize_t write_file_fastreply_start(struct file *file,
  595. +   const char __user *user_buf, size_t count, loff_t *ppos)
  596. +{
  597. +   struct ath9k_htc_priv *priv = file->private_data;
  598. +   struct wmi_fastreply_cmd cmd;
  599. +   char input[256];
  600. +   int mac[6];
  601. +   unsigned int duration;
  602. +   int len, reply, rval, i;
  603. +
  604. +   if (*ppos != 0) return 0;
  605. +
  606. +   // 1. parse input
  607. +
  608. +   len = min(count, sizeof(input) - 1);
  609. +   if (copy_from_user(input, user_buf, len))
  610. +       return -EFAULT;
  611. +   input[len] = '\0';
  612. +
  613. +   if (sscanf(input, "%x:%x:%x:%x:%x:%x,%u", &mac[0], &mac[1], &mac[2],
  614. +       &mac[3], &mac[4], &mac[5], &duration) != 7) {
  615. +       printk("%s: sscanf parsing failed\n", __FUNCTION__);
  616. +       return -EINVAL;
  617. +   }
  618. +
  619. +   // 2. send the start command
  620. +  
  621. +   cmd.type = FASTREPLY_START;
  622. +   cmd.start.mduration = cpu_to_be32(duration);
  623. +   for (i = 0; i < 6; ++i)
  624. +       cmd.start.source[i] = mac[i];
  625. +
  626. +   ath9k_htc_ps_wakeup(priv);
  627. +  
  628. +   rval = ath9k_wmi_cmd(priv->wmi, WMI_FASTREPLY_CMDID,
  629. +           (u8*)&cmd, sizeof(cmd),
  630. +           (u8*)&reply, sizeof(reply),
  631. +           HZ * (duration / 1000 + 4));
  632. +
  633. +   ath9k_htc_ps_restore(priv);
  634. +
  635. +   if (unlikely(rval)) {
  636. +       printk("ath9k_htc %s: WMI_FASTREPLY_CMDID failed with %d\n", __FUNCTION__, rval);
  637. +       return -EBUSY;
  638. +   }
  639. +
  640. +   return count;
  641. +}
  642. +
  643. +static const struct file_operations fops_fastreply_start = {
  644. +   .read = read_file_fastreply_start,
  645. +   .write = write_file_fastreply_start,
  646. +   .open = simple_open,
  647. +   .owner = THIS_MODULE,
  648. +   .llseek = default_llseek,
  649. +};
  650. +
  651. +
  652. +static ssize_t read_file_timefunc(struct file *file, char __user *user_buf,
  653. +                 size_t count, loff_t *ppos)
  654. +{
  655. +   struct time_func_context *context = file->private_data;
  656. +   struct time_func *timefunc = context->timefunc;
  657. +   struct ath9k_htc_priv *priv = context->htcpriv;
  658. +   char buf[512];
  659. +   unsigned int len, val;
  660. +
  661. +   // FIXME: Is the wakeup/restore call needed?
  662. +   ath9k_htc_ps_wakeup(priv);
  663. +   val = timefunc->getter(priv->ah);
  664. +   ath9k_htc_ps_restore(priv);
  665. +
  666. +   len = snprintf(buf, sizeof(buf), "%s: %s\nValue: 0x%08X = %d\n",
  667. +       timefunc->name, timefunc->comments, val, val);
  668. +   return simple_read_from_buffer(user_buf, count, ppos, buf, len);
  669. +}
  670. +
  671. +static ssize_t write_file_timefunc(struct file *file, const char __user *user_buf,
  672. +                  size_t count, loff_t *ppos)
  673. +{
  674. +   struct time_func_context *context = file->private_data;
  675. +   struct time_func *timefunc = context->timefunc;
  676. +   struct ath9k_htc_priv *priv = context->htcpriv;
  677. +   unsigned long val;
  678. +   char buf[32];
  679. +   ssize_t len;
  680. +
  681. +   len = min(count, sizeof(buf) - 1);
  682. +   if (copy_from_user(buf, user_buf, len))
  683. +       return -EINVAL;
  684. +
  685. +   buf[len] = '\0';
  686. +   if (kstrtoul(buf, 0, &val))
  687. +       return -EINVAL;
  688. +
  689. +   // FIXME: Is the wakeup/restore call needed?
  690. +   ath9k_htc_ps_wakeup(priv);
  691. +   timefunc->setter(priv->ah, (u32)val);
  692. +   ath9k_htc_ps_restore(priv);
  693. +
  694. +   return count;
  695. +}
  696. +
  697. +static const struct file_operations fops_timefunc = {
  698. +   .read = read_file_timefunc,
  699. +   .write = write_file_timefunc,
  700. +   .open = simple_open,
  701. +   .owner = THIS_MODULE,
  702. +   .llseek = default_llseek,
  703. +};
  704. +
  705.  /* Ethtool support for get-stats */
  706.  #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
  707.  static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = {
  708. @@ -488,6 +1170,8 @@
  709.  {
  710.     struct ath_common *common = ath9k_hw_common(ah);
  711.     struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
  712. +   struct reg_ops_instance *previnstance;
  713. +   int i;
  714.  
  715.     priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
  716.                          priv->hw->wiphy->debugfsdir);
  717. @@ -516,9 +1200,79 @@
  718.                 priv, &fops_queue);
  719.     debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
  720.                 priv, &fops_debug);
  721. +   debugfs_create_file("dmesg", S_IRUSR, priv->debug.debugfs_phy,
  722. +               priv, &fops_dmesg);
  723. +   debugfs_create_file("reactivejam", S_IRUSR, priv->debug.debugfs_phy,
  724. +               priv, &fops_reactivejam);
  725. +   debugfs_create_file("constantjam", S_IRUSR, priv->debug.debugfs_phy,
  726. +               priv, &fops_constantjam);
  727. +   debugfs_create_file("fastreply_packet", S_IRUSR | S_IWUSR,
  728. +               priv->debug.debugfs_phy, priv, &fops_fastreply_packet);
  729. +   debugfs_create_file("fastreply_start", S_IRUSR | S_IWUSR,
  730. +               priv->debug.debugfs_phy, priv, &fops_fastreply_start);
  731. +   debugfs_create_file("macaddr", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
  732. +               priv, &fops_macaddr);
  733. +   debugfs_create_file("bssidmask", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
  734. +               priv, &fops_bssidmask);
  735. +   debugfs_create_file("inject_noack", S_IRUSR | S_IWUSR,
  736. +               priv->debug.debugfs_phy, priv, &fops_inject_noack);
  737.  
  738.     ath9k_cmn_debug_base_eeprom(priv->debug.debugfs_phy, priv->ah);
  739.     ath9k_cmn_debug_modal_eeprom(priv->debug.debugfs_phy, priv->ah);
  740.  
  741. +   //
  742. +   // Read/write access to registers
  743. +   //
  744. +
  745. +   priv->debug.debugfs_phy_regs = debugfs_create_dir("registers", priv->debug.debugfs_phy);
  746. +   if (!priv->debug.debugfs_phy_regs)
  747. +       return -ENOMEM;
  748. +
  749. +   previnstance = NULL;
  750. +   for (i = 0; i < sizeof(registers) / sizeof(registers[0]); ++i)
  751. +   {
  752. +       struct reg_ops *regops = &registers[i];
  753. +       struct reg_ops_instance *instance;
  754. +
  755. +       // Allocated linked list is freed in ath9k_hw_deinit
  756. +       instance = kzalloc(sizeof(struct reg_ops_instance), GFP_KERNEL);
  757. +       if (!instance) return -ENOMEM;
  758. +
  759. +       instance->regops = regops;
  760. +       instance->owner = priv;
  761. +
  762. +       instance->valueset = 0;
  763. +       instance->value = 0;
  764. +       instance->next = previnstance;
  765. +
  766. +       // Read/write access using general functions
  767. +       debugfs_create_file(regops->name, S_IRUSR|S_IWUSR,
  768. +           priv->debug.debugfs_phy_regs, instance, &fops_reg_ops);
  769. +
  770. +       previnstance = instance;
  771. +   }
  772. +  
  773. +   priv->ah->modified_registers = previnstance;
  774. +  
  775. +
  776. +   //
  777. +   // Time functions
  778. +   //
  779. +
  780. +   for (i = 0; i < sizeof(timefunctions) / sizeof(timefunctions[0]); ++i)
  781. +   {
  782. +       // Allocate a context
  783. +       struct time_func_context *context;
  784. +       context = devm_kzalloc(priv->dev, sizeof(struct time_func_context), GFP_KERNEL);
  785. +       if (!context) return -ENOMEM;
  786. +
  787. +       context->timefunc = &timefunctions[i];
  788. +       context->htcpriv = priv;
  789. +
  790. +       // Read/write access using general functions
  791. +       debugfs_create_file(context->timefunc->name, S_IRUSR|S_IWUSR,
  792. +           priv->debug.debugfs_phy, context, &fops_timefunc);
  793. +   }
  794. +
  795.     return 0;
  796.  }
  797. diff -Naur backports-4.4.2-1/drivers/net/wireless/ath/ath9k/htc_drv_init.c backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/htc_drv_init.c
  798. --- backports-4.4.2-1/drivers/net/wireless/ath/ath9k/htc_drv_init.c 2016-02-18 22:41:35.000000000 +0100
  799. +++ backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/htc_drv_init.c 2016-04-03 13:28:54.000000000 +0200
  800. @@ -99,6 +99,18 @@
  801.  
  802.  static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
  803.  {
  804. +   if (priv->debug.debugfs_phy_regs)
  805. +       debugfs_remove(priv->debug.debugfs_phy_regs);
  806. +   priv->debug.debugfs_phy_regs = NULL;
  807. +
  808. +   if (priv->debug.debugfs_phy)
  809. +       debugfs_remove(priv->debug.debugfs_phy);
  810. +   priv->debug.debugfs_phy = NULL;
  811. +
  812. +   if (priv->hw->wiphy->debugfsdir)
  813. +       debugfs_remove(priv->hw->wiphy->debugfsdir);
  814. +   priv->hw->wiphy->debugfsdir = NULL;
  815. +
  816.     ath9k_hw_deinit(priv->ah);
  817.     kfree(priv->ah);
  818.     priv->ah = NULL;
  819. diff -Naur backports-4.4.2-1/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
  820. --- backports-4.4.2-1/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c 2016-02-18 22:41:36.000000000 +0100
  821. +++ backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c 2016-04-03 13:28:54.000000000 +0200
  822. @@ -211,6 +211,7 @@
  823.     return error;
  824.  }
  825.  
  826. +/** Used to handle management and injected frames */
  827.  static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv,
  828.                   struct ath9k_htc_vif *avp,
  829.                   struct sk_buff *skb,
  830. @@ -222,6 +223,7 @@
  831.     struct tx_mgmt_hdr mgmt_hdr;
  832.     struct ath9k_htc_tx_ctl *tx_ctl;
  833.     u8 *tx_fhdr;
  834. +   u8 flags = 0;
  835.  
  836.     tx_ctl = HTC_SKB_CB(skb);
  837.     hdr = (struct ieee80211_hdr *) skb->data;
  838. @@ -238,12 +240,19 @@
  839.         mgmt->u.probe_resp.timestamp = avp->tsfadjust;
  840.     }
  841.  
  842. +   /* Should firmware assign sequence number */
  843. +   if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
  844. +       flags |= ATH9K_HTC_TX_ASSIGN_SEQ;
  845. +   /* Don't retransmit injected packets if requested so */
  846. +   if (unlikely(priv->inject_noack && (tx_info->flags & IEEE80211_TX_CTL_INJECTED)))
  847. +       flags |= ATH9K_HTC_TX_NO_ACK;
  848. +
  849.     tx_ctl->type = ATH9K_HTC_MGMT;
  850.  
  851.     mgmt_hdr.node_idx = sta_idx;
  852.     mgmt_hdr.vif_idx = vif_idx;
  853.     mgmt_hdr.tidno = 0;
  854. -   mgmt_hdr.flags = 0;
  855. +   mgmt_hdr.flags = flags;
  856.     mgmt_hdr.cookie = slot;
  857.  
  858.     mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
  859. @@ -302,6 +311,13 @@
  860.         tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
  861.     }
  862.  
  863. +   /* Should firmware assign sequence number */
  864. +   if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
  865. +       flags |= ATH9K_HTC_TX_ASSIGN_SEQ;
  866. +   /* Don't retransmit injected packets if requested so */
  867. +   if (unlikely(priv->inject_noack && (tx_info->flags & IEEE80211_TX_CTL_INJECTED)))
  868. +       flags |= ATH9K_HTC_TX_NO_ACK;
  869. +
  870.     /* Check for RTS protection */
  871.     if (priv->hw->wiphy->rts_threshold != (u32) -1)
  872.         if (skb->len > priv->hw->wiphy->rts_threshold)
  873. @@ -373,12 +389,11 @@
  874.         sta_idx = priv->vif_sta_pos[vif_idx];
  875.     }
  876.  
  877. -   if (ieee80211_is_data(hdr->frame_control))
  878. -       ath9k_htc_tx_data(priv, vif, skb,
  879. -                 sta_idx, vif_idx, slot, is_cab);
  880. +   /** Treat injected frames as management frames to avoid modifications to them */
  881. +   if (ieee80211_is_data(hdr->frame_control) && !(tx_info->flags & IEEE80211_TX_CTL_INJECTED))
  882. +       ath9k_htc_tx_data(priv, vif, skb, sta_idx, vif_idx, slot, is_cab);
  883.     else
  884. -       ath9k_htc_tx_mgmt(priv, avp, skb,
  885. -                 sta_idx, vif_idx, slot);
  886. +       ath9k_htc_tx_mgmt(priv, avp, skb, sta_idx, vif_idx, slot);
  887.  
  888.  
  889.     return htc_send(priv->htc, skb);
  890. diff -Naur backports-4.4.2-1/drivers/net/wireless/ath/ath9k/htc.h backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/htc.h
  891. --- backports-4.4.2-1/drivers/net/wireless/ath/ath9k/htc.h  2016-02-18 22:41:35.000000000 +0100
  892. +++ backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/htc.h  2016-04-03 13:28:54.000000000 +0200
  893. @@ -69,6 +69,8 @@
  894.  
  895.  #define ATH9K_HTC_TX_CTSONLY      0x1
  896.  #define ATH9K_HTC_TX_RTSCTS       0x2
  897. +#define ATH9K_HTC_TX_ASSIGN_SEQ   0x10
  898. +#define ATH9K_HTC_TX_NO_ACK       0x20
  899.  
  900.  struct tx_frame_hdr {
  901.     u8 data_type;
  902. @@ -357,6 +359,7 @@
  903.  
  904.  struct ath9k_debug {
  905.     struct dentry *debugfs_phy;
  906. +   struct dentry *debugfs_phy_regs;
  907.     struct ath_tx_stats tx_stats;
  908.     struct ath_rx_stats rx_stats;
  909.     struct ath_skbrx_stats skbrx_stats;
  910. @@ -510,6 +513,9 @@
  911.     bool ps_enabled;
  912.     bool ps_idle;
  913.  
  914. +   /** If set, injected packets are never retransmitted (not waiting for ACK) */
  915. +   u8 inject_noack;
  916. +
  917.  #ifdef CPTCFG_MAC80211_LEDS
  918.     enum led_brightness brightness;
  919.     bool led_registered;
  920. diff -Naur backports-4.4.2-1/drivers/net/wireless/ath/ath9k/hw.c backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/hw.c
  921. --- backports-4.4.2-1/drivers/net/wireless/ath/ath9k/hw.c   2016-02-18 22:41:36.000000000 +0100
  922. +++ backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/hw.c   2016-04-03 13:28:54.000000000 +0200
  923. @@ -67,6 +67,7 @@
  924.     common->clockrate = clockrate;
  925.  }
  926.  
  927. +/** This is the clockrate of the wireless chip (not the chip running the firmware for ath9k_htc) */
  928.  static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
  929.  {
  930.     struct ath_common *common = ath9k_hw_common(ah);
  931. @@ -74,6 +75,17 @@
  932.     return usecs * common->clockrate;
  933.  }
  934.  
  935. +/** This is the clockrate of the wireless chip (not the chip running the firmware for ath9k_htc) */
  936. +static u32 ath9k_hw_mac_to_usecs(struct ath_hw *ah, u32 clks)
  937. +{
  938. +   struct ath_common *common = ath9k_hw_common(ah);
  939. +
  940. +   if (common->clockrate == 0)
  941. +       return 0xFFFFFFFF;
  942. +
  943. +   return clks / common->clockrate;
  944. +}
  945. +
  946.  bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
  947.  {
  948.     int i;
  949. @@ -246,6 +258,24 @@
  950.         centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
  951.  }
  952.  
  953. +static void ath9k_restore_registers(struct ath_hw *ah)
  954. +{
  955. +   struct reg_ops_instance *saved_reg = ah->modified_registers;
  956. +   int regval;
  957. +
  958. +   while (saved_reg != NULL)
  959. +   {
  960. +       if (saved_reg->valueset)
  961. +       {
  962. +           regval = REG_READ(ah, saved_reg->regops->address);
  963. +           regval = (regval & ~saved_reg->regops->mask) | saved_reg->value;
  964. +           REG_WRITE(ah, saved_reg->regops->address, regval);
  965. +       }
  966. +
  967. +       saved_reg = saved_reg->next;
  968. +   }
  969. +}
  970. +
  971.  /******************/
  972.  /* Chip Revisions */
  973.  /******************/
  974. @@ -972,33 +1002,78 @@
  975.     }
  976.  }
  977.  
  978. -static void ath9k_hw_set_sifs_time(struct ath_hw *ah, u32 us)
  979. +void ath9k_hw_set_sifs_time(struct ath_hw *ah, u32 us)
  980.  {
  981.     u32 val = ath9k_hw_mac_to_clks(ah, us - 2);
  982. -   val = min(val, (u32) 0xFFFF);
  983. +   val &= AR_D_GBL_IFS_SIFS_M;
  984.     REG_WRITE(ah, AR_D_GBL_IFS_SIFS, val);
  985.  }
  986. +EXPORT_SYMBOL(ath9k_hw_set_sifs_time);
  987.  
  988.  void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
  989.  {
  990.     u32 val = ath9k_hw_mac_to_clks(ah, us);
  991. -   val = min(val, (u32) 0xFFFF);
  992. +   val &= AR_D_GBL_IFS_SLOT_M;
  993.     REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
  994.  }
  995. +EXPORT_SYMBOL(ath9k_hw_setslottime);
  996.  
  997.  void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
  998.  {
  999.     u32 val = ath9k_hw_mac_to_clks(ah, us);
  1000. -   val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
  1001.     REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
  1002.  }
  1003. +EXPORT_SYMBOL(ath9k_hw_set_ack_timeout);
  1004.  
  1005.  void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
  1006.  {
  1007.     u32 val = ath9k_hw_mac_to_clks(ah, us);
  1008. -   val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
  1009.     REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
  1010.  }
  1011. +EXPORT_SYMBOL(ath9k_hw_set_cts_timeout);
  1012. +
  1013. +void ath9k_hw_set_eifs_timeout(struct ath_hw *ah, u32 us)
  1014. +{
  1015. +   u32 val = ath9k_hw_mac_to_clks(ah, us);
  1016. +   val &= AR_D_GBL_IFS_EIFS;
  1017. +   REG_WRITE(ah, AR_D_GBL_IFS_EIFS, val);
  1018. +}
  1019. +EXPORT_SYMBOL(ath9k_hw_set_eifs_timeout);
  1020. +
  1021. +u32 ath9k_hw_get_sifs_time(struct ath_hw *ah)
  1022. +{
  1023. +   u32 val = REG_READ(ah, AR_D_GBL_IFS_SIFS) & AR_D_GBL_IFS_SIFS_M;
  1024. +   return ath9k_hw_mac_to_usecs(ah, val) + 2;
  1025. +}
  1026. +EXPORT_SYMBOL(ath9k_hw_get_sifs_time);
  1027. +
  1028. +u32 ath9k_hw_getslottime(struct ath_hw *ah)
  1029. +{
  1030. +   u32 val = REG_READ(ah, AR_D_GBL_IFS_SLOT) & AR_D_GBL_IFS_SLOT_M;
  1031. +   return ath9k_hw_mac_to_usecs(ah, val);
  1032. +}
  1033. +EXPORT_SYMBOL(ath9k_hw_getslottime);
  1034. +
  1035. +u32 ath9k_hw_get_ack_timeout(struct ath_hw *ah)
  1036. +{
  1037. +   u32 val = MS(REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK);
  1038. +   return ath9k_hw_mac_to_usecs(ah, val);
  1039. +}
  1040. +EXPORT_SYMBOL(ath9k_hw_get_ack_timeout);
  1041. +
  1042. +u32 ath9k_hw_get_cts_timeout(struct ath_hw *ah)
  1043. +{
  1044. +   u32 val = MS(REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);
  1045. +   return ath9k_hw_mac_to_usecs(ah, val);
  1046. +}
  1047. +EXPORT_SYMBOL(ath9k_hw_get_cts_timeout);
  1048. +
  1049. +u32 ath9k_hw_get_eifs_timeout(struct ath_hw *ah)
  1050. +{
  1051. +   u32 val = REG_READ(ah, AR_D_GBL_IFS_EIFS) & AR_D_GBL_IFS_EIFS_M;
  1052. +   return ath9k_hw_mac_to_usecs(ah, val);
  1053. +}
  1054. +EXPORT_SYMBOL(ath9k_hw_get_eifs_timeout);
  1055.  
  1056.  static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
  1057.  {
  1058. @@ -2025,6 +2100,8 @@
  1059.     if (AR_SREV_9565(ah) && common->bt_ant_diversity)
  1060.         REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
  1061.  
  1062. +   ath9k_restore_registers(ah);
  1063. +
  1064.     if (ah->hw->conf.radar_enabled) {
  1065.         /* set HW specific DFS configuration */
  1066.         ah->radar_conf.ext_channel = IS_CHAN_HT40(chan);
  1067. @@ -2173,6 +2250,8 @@
  1068.  
  1069.     REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
  1070.  
  1071. +   ath9k_restore_registers(ah);
  1072. +
  1073.     return true;
  1074.  }
  1075.  
  1076. diff -Naur backports-4.4.2-1/drivers/net/wireless/ath/ath9k/hw.h backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/hw.h
  1077. --- backports-4.4.2-1/drivers/net/wireless/ath/ath9k/hw.h   2016-02-18 22:41:36.000000000 +0100
  1078. +++ backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/hw.h   2016-04-03 13:28:54.000000000 +0200
  1079. @@ -761,6 +761,40 @@
  1080.     TX_CL_CAL         = BIT(2),
  1081.  };
  1082.  
  1083. +/**
  1084. + * reg_ops - describes one specific functionality of a particular register
  1085. + *
  1086. + * @name: name of the register as used in debugfs
  1087. + * @address: memory address of the register
  1088. + * @mask: mask for the specific functionality we are exposing. One single addresses
  1089. + *        may have multiple reg_ops, one for each mask/functionality.
  1090. + * @description: human readable description of the functionality
  1091. + */
  1092. +struct reg_ops {
  1093. +   const char *name;
  1094. +   unsigned int address;
  1095. +   unsigned int mask;
  1096. +   const char *description;
  1097. +};
  1098. +
  1099. +/**
  1100. + * reg_ops_instance - describes a specific configuration of a reg_ops register
  1101. + *
  1102. + * @regops: the register functionality we are referencing
  1103. + * @valueset: did the user write a custom value to this register?
  1104. + * @value: the value the user wrote to the register
  1105. + * @owner: the interface on which the custom value was set
  1106. + *
  1107. + * @next: pointer to next reg_ops_instance, to create linked lists
  1108. + */
  1109. +struct reg_ops_instance {
  1110. +   struct reg_ops *regops;
  1111. +   char valueset;
  1112. +   unsigned int value;
  1113. +   struct ath9k_htc_priv *owner;
  1114. +   struct reg_ops_instance *next;
  1115. +};
  1116. +
  1117.  /* ah_flags */
  1118.  #define AH_USE_EEPROM   0x1
  1119.  #define AH_UNPLUGGED    0x2 /* The card has been physically removed. */
  1120. @@ -972,6 +1006,9 @@
  1121.  
  1122.     struct ath_dynack dynack;
  1123.  
  1124. +   /** Linked list of (possibly) manually overwritten registers */
  1125. +   struct reg_ops_instance *modified_registers;
  1126. +
  1127.     bool tpc_enabled;
  1128.     u8 tx_power[Ar5416RateSize];
  1129.     u8 tx_power_stbc[Ar5416RateSize];
  1130. @@ -1066,6 +1103,18 @@
  1131.  
  1132.  bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
  1133.  
  1134. +void ath9k_hw_set_sifs_time(struct ath_hw *ah, u32 us);
  1135. +void ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
  1136. +void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us);
  1137. +void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us);
  1138. +void ath9k_hw_set_eifs_timeout(struct ath_hw *ah, u32 us);
  1139. +
  1140. +u32 ath9k_hw_get_sifs_time(struct ath_hw *ah);
  1141. +u32 ath9k_hw_getslottime(struct ath_hw *ah);
  1142. +u32 ath9k_hw_get_ack_timeout(struct ath_hw *ah);
  1143. +u32 ath9k_hw_get_cts_timeout(struct ath_hw *ah);
  1144. +u32 ath9k_hw_get_eifs_timeout(struct ath_hw *ah);
  1145. +
  1146.  /* Generic hw timer primitives */
  1147.  struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
  1148.                       void (*trigger)(void *),
  1149. diff -Naur backports-4.4.2-1/drivers/net/wireless/ath/ath9k/Kconfig backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/Kconfig
  1150. --- backports-4.4.2-1/drivers/net/wireless/ath/ath9k/Kconfig    2016-02-18 22:41:36.000000000 +0100
  1151. +++ backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/Kconfig    2016-04-03 13:28:55.000000000 +0200
  1152. @@ -167,6 +167,7 @@
  1153.         select BPAUTO_LEDS_CLASS
  1154.         select BPAUTO_NEW_LEDS
  1155.         select ATH9K_COMMON
  1156. +       select ATH9K_HTC_DEBUGFS
  1157.         ---help---
  1158.      Support for Atheros HTC based cards.
  1159.      Chipsets supported: AR9271
  1160. @@ -177,6 +178,6 @@
  1161.  
  1162.  config ATH9K_HTC_DEBUGFS
  1163.     bool "Atheros ath9k_htc debugging"
  1164. -   depends on ATH9K_HTC && DEBUG_FS
  1165. +   depends on DEBUG_FS
  1166.     ---help---
  1167.       Say Y, if you need access to ath9k_htc's statistics.
  1168. diff -Naur backports-4.4.2-1/drivers/net/wireless/ath/ath9k/wmi.c backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/wmi.c
  1169. --- backports-4.4.2-1/drivers/net/wireless/ath/ath9k/wmi.c  2016-02-18 22:41:35.000000000 +0100
  1170. +++ backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/wmi.c  2016-04-03 13:28:54.000000000 +0200
  1171. @@ -83,6 +83,14 @@
  1172.         return "WMI_RX_STATS_CMDID";
  1173.     case WMI_BITRATE_MASK_CMDID:
  1174.         return "WMI_BITRATE_MASK_CMDID";
  1175. +   case WMI_DEBUGMSG_CMDID:
  1176. +       return "WMI_DEBUGMSG_CMDID";
  1177. +   case WMI_REACTIVEJAM_CMDID:
  1178. +       return "WMI_REACTIVEJAM_CMDID";
  1179. +   case WMI_FASTREPLY_CMDID:
  1180. +       return "WMI_FASTREPLY_CMDID";
  1181. +   case WMI_CONSTANTJAM_CMDID:
  1182. +       return "WMI_CONSTANTJAM_CMDID";
  1183.     }
  1184.  
  1185.     return "Bogus";
  1186. diff -Naur backports-4.4.2-1/drivers/net/wireless/ath/ath9k/wmi.h backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/wmi.h
  1187. --- backports-4.4.2-1/drivers/net/wireless/ath/ath9k/wmi.h  2016-02-18 22:41:36.000000000 +0100
  1188. +++ backports-4.4.2-1-modwifi/drivers/net/wireless/ath/ath9k/wmi.h  2016-04-03 13:28:54.000000000 +0200
  1189. @@ -113,6 +113,12 @@
  1190.     WMI_RX_STATS_CMDID,
  1191.     WMI_BITRATE_MASK_CMDID,
  1192.     WMI_REG_RMW_CMDID,
  1193. +
  1194. +   /* Custom commands added */
  1195. +   WMI_DEBUGMSG_CMDID = 0x0080,
  1196. +   WMI_REACTIVEJAM_CMDID,
  1197. +   WMI_FASTREPLY_CMDID,
  1198. +   WMI_CONSTANTJAM_CMDID,
  1199.  };
  1200.  
  1201.  enum wmi_event_id {
  1202. @@ -145,6 +151,65 @@
  1203.     struct list_head list;
  1204.  };
  1205.  
  1206. +struct wmi_debugmsg_cmd {
  1207. +   __be16 offset;
  1208. +} __packed;
  1209. +
  1210. +struct wmi_debugmsg_resp {
  1211. +   /** Length of zero signifies that no more data is available */
  1212. +   u8 length;
  1213. +   /** Debug message(s) **/
  1214. +   u8 buffer[40];
  1215. +} __packed;
  1216. +
  1217. +struct wmi_reactivejam_cmd {
  1218. +   u8 bssid[6];
  1219. +   u32 mduration;
  1220. +} __packed;
  1221. +
  1222. +struct wmi_constantjam_cmd {
  1223. +   /** A value from CONSTJAM_REQUEST to denote the request */
  1224. +   u8 request;
  1225. +   /** Set to 1 to disable CS and inter-frame-timeouts */
  1226. +   u8 conf_radio;
  1227. +   /** Length of the packet which is continuously transmitted */
  1228. +   u16 len;
  1229. +} __packed;
  1230. +
  1231. +struct wmi_constantjam_resp {
  1232. +   /** Is 1 when jammer is running, 0 otherwise */
  1233. +   u8 status;
  1234. +} __packed;
  1235. +
  1236. +enum CONSTJAM_REQUEST {
  1237. +   CONSTJAM_START,
  1238. +   CONSTJAM_STOP,
  1239. +   CONSTJAM_STATUS
  1240. +};
  1241. +
  1242. +struct wmi_fastreply_cmd {
  1243. +   u8 type;
  1244. +   union {
  1245. +       // transmit response packet in multiple commands
  1246. +       struct {
  1247. +           u8 length;
  1248. +           u8 offset;
  1249. +           u8 datalen;
  1250. +           u8 data[40];
  1251. +       } pkt;
  1252. +       // command to start monitoring
  1253. +       struct {
  1254. +           u32 mduration;
  1255. +           u8 source[6];
  1256. +       } start;
  1257. +   };
  1258. +} __packed;
  1259. +
  1260. +enum FASTREPLY_TYPE {
  1261. +   FASTREPLY_PKT,
  1262. +   FASTREPLY_START
  1263. +};
  1264. +
  1265.  struct wmi {
  1266.     struct ath9k_htc_priv *drv_priv;
  1267.     struct htc_target *htc;