mac.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2021 pureLiFi
  4. */
  5. #include <linux/netdevice.h>
  6. #include <linux/etherdevice.h>
  7. #include <linux/slab.h>
  8. #include <linux/usb.h>
  9. #include <linux/gpio.h>
  10. #include <linux/jiffies.h>
  11. #include <net/ieee80211_radiotap.h>
  12. #include "chip.h"
  13. #include "mac.h"
  14. #include "usb.h"
  15. static const struct ieee80211_rate plfxlc_rates[] = {
  16. { .bitrate = 10,
  17. .hw_value = PURELIFI_CCK_RATE_1M,
  18. .flags = 0 },
  19. { .bitrate = 20,
  20. .hw_value = PURELIFI_CCK_RATE_2M,
  21. .hw_value_short = PURELIFI_CCK_RATE_2M
  22. | PURELIFI_CCK_PREA_SHORT,
  23. .flags = IEEE80211_RATE_SHORT_PREAMBLE },
  24. { .bitrate = 55,
  25. .hw_value = PURELIFI_CCK_RATE_5_5M,
  26. .hw_value_short = PURELIFI_CCK_RATE_5_5M
  27. | PURELIFI_CCK_PREA_SHORT,
  28. .flags = IEEE80211_RATE_SHORT_PREAMBLE },
  29. { .bitrate = 110,
  30. .hw_value = PURELIFI_CCK_RATE_11M,
  31. .hw_value_short = PURELIFI_CCK_RATE_11M
  32. | PURELIFI_CCK_PREA_SHORT,
  33. .flags = IEEE80211_RATE_SHORT_PREAMBLE },
  34. { .bitrate = 60,
  35. .hw_value = PURELIFI_OFDM_RATE_6M,
  36. .flags = 0 },
  37. { .bitrate = 90,
  38. .hw_value = PURELIFI_OFDM_RATE_9M,
  39. .flags = 0 },
  40. { .bitrate = 120,
  41. .hw_value = PURELIFI_OFDM_RATE_12M,
  42. .flags = 0 },
  43. { .bitrate = 180,
  44. .hw_value = PURELIFI_OFDM_RATE_18M,
  45. .flags = 0 },
  46. { .bitrate = 240,
  47. .hw_value = PURELIFI_OFDM_RATE_24M,
  48. .flags = 0 },
  49. { .bitrate = 360,
  50. .hw_value = PURELIFI_OFDM_RATE_36M,
  51. .flags = 0 },
  52. { .bitrate = 480,
  53. .hw_value = PURELIFI_OFDM_RATE_48M,
  54. .flags = 0 },
  55. { .bitrate = 540,
  56. .hw_value = PURELIFI_OFDM_RATE_54M,
  57. .flags = 0 }
  58. };
  59. static const struct ieee80211_channel plfxlc_channels[] = {
  60. { .center_freq = 2412, .hw_value = 1 },
  61. { .center_freq = 2417, .hw_value = 2 },
  62. { .center_freq = 2422, .hw_value = 3 },
  63. { .center_freq = 2427, .hw_value = 4 },
  64. { .center_freq = 2432, .hw_value = 5 },
  65. { .center_freq = 2437, .hw_value = 6 },
  66. { .center_freq = 2442, .hw_value = 7 },
  67. { .center_freq = 2447, .hw_value = 8 },
  68. { .center_freq = 2452, .hw_value = 9 },
  69. { .center_freq = 2457, .hw_value = 10 },
  70. { .center_freq = 2462, .hw_value = 11 },
  71. { .center_freq = 2467, .hw_value = 12 },
  72. { .center_freq = 2472, .hw_value = 13 },
  73. { .center_freq = 2484, .hw_value = 14 },
  74. };
  75. int plfxlc_mac_preinit_hw(struct ieee80211_hw *hw, const u8 *hw_address)
  76. {
  77. SET_IEEE80211_PERM_ADDR(hw, hw_address);
  78. return 0;
  79. }
  80. int plfxlc_mac_init_hw(struct ieee80211_hw *hw)
  81. {
  82. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  83. struct plfxlc_chip *chip = &mac->chip;
  84. int r;
  85. r = plfxlc_chip_init_hw(chip);
  86. if (r) {
  87. dev_warn(plfxlc_mac_dev(mac), "init hw failed (%d)\n", r);
  88. return r;
  89. }
  90. dev_dbg(plfxlc_mac_dev(mac), "irq_disabled (%d)\n", irqs_disabled());
  91. regulatory_hint(hw->wiphy, "00");
  92. return r;
  93. }
  94. void plfxlc_mac_release(struct plfxlc_mac *mac)
  95. {
  96. plfxlc_chip_release(&mac->chip);
  97. lockdep_assert_held(&mac->lock);
  98. }
  99. int plfxlc_op_start(struct ieee80211_hw *hw)
  100. {
  101. plfxlc_hw_mac(hw)->chip.usb.initialized = 1;
  102. return 0;
  103. }
  104. void plfxlc_op_stop(struct ieee80211_hw *hw)
  105. {
  106. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  107. clear_bit(PURELIFI_DEVICE_RUNNING, &mac->flags);
  108. }
  109. int plfxlc_restore_settings(struct plfxlc_mac *mac)
  110. {
  111. int beacon_interval, beacon_period;
  112. struct sk_buff *beacon;
  113. spin_lock_irq(&mac->lock);
  114. beacon_interval = mac->beacon.interval;
  115. beacon_period = mac->beacon.period;
  116. spin_unlock_irq(&mac->lock);
  117. if (mac->type != NL80211_IFTYPE_ADHOC)
  118. return 0;
  119. if (mac->vif) {
  120. beacon = ieee80211_beacon_get(mac->hw, mac->vif, 0);
  121. if (beacon) {
  122. /*beacon is hardcoded in firmware */
  123. kfree_skb(beacon);
  124. /* Returned skb is used only once and lowlevel
  125. * driver is responsible for freeing it.
  126. */
  127. }
  128. }
  129. plfxlc_set_beacon_interval(&mac->chip, beacon_interval,
  130. beacon_period, mac->type);
  131. spin_lock_irq(&mac->lock);
  132. mac->beacon.last_update = jiffies;
  133. spin_unlock_irq(&mac->lock);
  134. return 0;
  135. }
  136. static void plfxlc_mac_tx_status(struct ieee80211_hw *hw,
  137. struct sk_buff *skb,
  138. int ackssi,
  139. struct tx_status *tx_status)
  140. {
  141. struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  142. int success = 1;
  143. ieee80211_tx_info_clear_status(info);
  144. if (tx_status)
  145. success = !tx_status->failure;
  146. if (success)
  147. info->flags |= IEEE80211_TX_STAT_ACK;
  148. else
  149. info->flags &= ~IEEE80211_TX_STAT_ACK;
  150. info->status.ack_signal = 50;
  151. ieee80211_tx_status_irqsafe(hw, skb);
  152. }
  153. void plfxlc_mac_tx_to_dev(struct sk_buff *skb, int error)
  154. {
  155. struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  156. struct ieee80211_hw *hw = info->rate_driver_data[0];
  157. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  158. struct sk_buff_head *q = NULL;
  159. ieee80211_tx_info_clear_status(info);
  160. skb_pull(skb, sizeof(struct plfxlc_ctrlset));
  161. if (unlikely(error ||
  162. (info->flags & IEEE80211_TX_CTL_NO_ACK))) {
  163. ieee80211_tx_status_irqsafe(hw, skb);
  164. return;
  165. }
  166. q = &mac->ack_wait_queue;
  167. skb_queue_tail(q, skb);
  168. while (skb_queue_len(q)/* > PURELIFI_MAC_MAX_ACK_WAITERS*/) {
  169. plfxlc_mac_tx_status(hw, skb_dequeue(q),
  170. mac->ack_pending ?
  171. mac->ack_signal : 0,
  172. NULL);
  173. mac->ack_pending = 0;
  174. }
  175. }
  176. static int plfxlc_fill_ctrlset(struct plfxlc_mac *mac, struct sk_buff *skb)
  177. {
  178. unsigned int frag_len = skb->len;
  179. struct plfxlc_ctrlset *cs;
  180. u32 temp_payload_len = 0;
  181. unsigned int tmp;
  182. u32 temp_len = 0;
  183. if (skb_headroom(skb) < sizeof(struct plfxlc_ctrlset)) {
  184. dev_dbg(plfxlc_mac_dev(mac), "Not enough hroom(1)\n");
  185. return 1;
  186. }
  187. cs = (void *)skb_push(skb, sizeof(struct plfxlc_ctrlset));
  188. temp_payload_len = frag_len;
  189. temp_len = temp_payload_len +
  190. sizeof(struct plfxlc_ctrlset) -
  191. sizeof(cs->id) - sizeof(cs->len);
  192. /* Data packet lengths must be multiple of four bytes and must
  193. * not be a multiple of 512 bytes. First, it is attempted to
  194. * append the data packet in the tailroom of the skb. In rare
  195. * occasions, the tailroom is too small. In this case, the
  196. * content of the packet is shifted into the headroom of the skb
  197. * by memcpy. Headroom is allocated at startup (below in this
  198. * file). Therefore, there will be always enough headroom. The
  199. * call skb_headroom is an additional safety which might be
  200. * dropped.
  201. */
  202. /* check if 32 bit aligned and align data */
  203. tmp = skb->len & 3;
  204. if (tmp) {
  205. if (skb_tailroom(skb) < (3 - tmp)) {
  206. if (skb_headroom(skb) >= 4 - tmp) {
  207. u8 len;
  208. u8 *src_pt;
  209. u8 *dest_pt;
  210. len = skb->len;
  211. src_pt = skb->data;
  212. dest_pt = skb_push(skb, 4 - tmp);
  213. memmove(dest_pt, src_pt, len);
  214. } else {
  215. return -ENOBUFS;
  216. }
  217. } else {
  218. skb_put(skb, 4 - tmp);
  219. }
  220. temp_len += 4 - tmp;
  221. }
  222. /* check if not multiple of 512 and align data */
  223. tmp = skb->len & 0x1ff;
  224. if (!tmp) {
  225. if (skb_tailroom(skb) < 4) {
  226. if (skb_headroom(skb) >= 4) {
  227. u8 len = skb->len;
  228. u8 *src_pt = skb->data;
  229. u8 *dest_pt = skb_push(skb, 4);
  230. memmove(dest_pt, src_pt, len);
  231. } else {
  232. /* should never happen because
  233. * sufficient headroom was reserved
  234. */
  235. return -ENOBUFS;
  236. }
  237. } else {
  238. skb_put(skb, 4);
  239. }
  240. temp_len += 4;
  241. }
  242. cs->id = cpu_to_be32(USB_REQ_DATA_TX);
  243. cs->len = cpu_to_be32(temp_len);
  244. cs->payload_len_nw = cpu_to_be32(temp_payload_len);
  245. return 0;
  246. }
  247. static void plfxlc_op_tx(struct ieee80211_hw *hw,
  248. struct ieee80211_tx_control *control,
  249. struct sk_buff *skb)
  250. {
  251. struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  252. struct plfxlc_header *plhdr = (void *)skb->data;
  253. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  254. struct plfxlc_usb *usb = &mac->chip.usb;
  255. unsigned long flags;
  256. int r;
  257. r = plfxlc_fill_ctrlset(mac, skb);
  258. if (r)
  259. goto fail;
  260. info->rate_driver_data[0] = hw;
  261. if (plhdr->frametype == IEEE80211_FTYPE_DATA) {
  262. u8 *dst_mac = plhdr->dmac;
  263. u8 sidx;
  264. bool found = false;
  265. struct plfxlc_usb_tx *tx = &usb->tx;
  266. for (sidx = 0; sidx < MAX_STA_NUM; sidx++) {
  267. if (!(tx->station[sidx].flag & STATION_CONNECTED_FLAG))
  268. continue;
  269. if (memcmp(tx->station[sidx].mac, dst_mac, ETH_ALEN))
  270. continue;
  271. found = true;
  272. break;
  273. }
  274. /* Default to broadcast address for unknown MACs */
  275. if (!found)
  276. sidx = STA_BROADCAST_INDEX;
  277. /* Stop OS from sending packets, if the queue is half full */
  278. if (skb_queue_len(&tx->station[sidx].data_list) > 60)
  279. ieee80211_stop_queues(plfxlc_usb_to_hw(usb));
  280. /* Schedule packet for transmission if queue is not full */
  281. if (skb_queue_len(&tx->station[sidx].data_list) > 256)
  282. goto fail;
  283. skb_queue_tail(&tx->station[sidx].data_list, skb);
  284. plfxlc_send_packet_from_data_queue(usb);
  285. } else {
  286. spin_lock_irqsave(&usb->tx.lock, flags);
  287. r = plfxlc_usb_wreq_async(&mac->chip.usb, skb->data, skb->len,
  288. USB_REQ_DATA_TX, plfxlc_tx_urb_complete, skb);
  289. spin_unlock_irqrestore(&usb->tx.lock, flags);
  290. if (r)
  291. goto fail;
  292. }
  293. return;
  294. fail:
  295. dev_kfree_skb(skb);
  296. }
  297. static int plfxlc_filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
  298. struct ieee80211_rx_status *stats)
  299. {
  300. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  301. struct sk_buff_head *q;
  302. int i, position = 0;
  303. unsigned long flags;
  304. struct sk_buff *skb;
  305. bool found = false;
  306. if (!ieee80211_is_ack(rx_hdr->frame_control))
  307. return 0;
  308. dev_dbg(plfxlc_mac_dev(mac), "ACK Received\n");
  309. /* code based on zy driver, this logic may need fix */
  310. q = &mac->ack_wait_queue;
  311. spin_lock_irqsave(&q->lock, flags);
  312. skb_queue_walk(q, skb) {
  313. struct ieee80211_hdr *tx_hdr;
  314. position++;
  315. if (mac->ack_pending && skb_queue_is_first(q, skb))
  316. continue;
  317. if (mac->ack_pending == 0)
  318. break;
  319. tx_hdr = (struct ieee80211_hdr *)skb->data;
  320. if (likely(ether_addr_equal(tx_hdr->addr2, rx_hdr->addr1))) {
  321. found = 1;
  322. break;
  323. }
  324. }
  325. if (found) {
  326. for (i = 1; i < position; i++)
  327. skb = __skb_dequeue(q);
  328. if (i == position) {
  329. plfxlc_mac_tx_status(hw, skb,
  330. mac->ack_pending ?
  331. mac->ack_signal : 0,
  332. NULL);
  333. mac->ack_pending = 0;
  334. }
  335. mac->ack_pending = skb_queue_len(q) ? 1 : 0;
  336. mac->ack_signal = stats->signal;
  337. }
  338. spin_unlock_irqrestore(&q->lock, flags);
  339. return 1;
  340. }
  341. int plfxlc_mac_rx(struct ieee80211_hw *hw, const u8 *buffer,
  342. unsigned int length)
  343. {
  344. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  345. struct ieee80211_rx_status stats;
  346. const struct rx_status *status;
  347. unsigned int payload_length;
  348. struct plfxlc_usb_tx *tx;
  349. struct sk_buff *skb;
  350. int need_padding;
  351. __le16 fc;
  352. int sidx;
  353. /* Packet blockade during disabled interface. */
  354. if (!mac->vif)
  355. return 0;
  356. status = (struct rx_status *)buffer;
  357. memset(&stats, 0, sizeof(stats));
  358. stats.flag = 0;
  359. stats.freq = 2412;
  360. stats.band = NL80211_BAND_LC;
  361. mac->rssi = -15 * be16_to_cpu(status->rssi) / 10;
  362. stats.signal = mac->rssi;
  363. if (status->rate_idx > 7)
  364. stats.rate_idx = 0;
  365. else
  366. stats.rate_idx = status->rate_idx;
  367. mac->crc_errors = be64_to_cpu(status->crc_error_count);
  368. /* TODO bad frame check for CRC error*/
  369. if (plfxlc_filter_ack(hw, (struct ieee80211_hdr *)buffer, &stats) &&
  370. !mac->pass_ctrl)
  371. return 0;
  372. buffer += sizeof(struct rx_status);
  373. payload_length = get_unaligned_be32(buffer);
  374. if (payload_length > 1560) {
  375. dev_err(plfxlc_mac_dev(mac), " > MTU %u\n", payload_length);
  376. return 0;
  377. }
  378. buffer += sizeof(u32);
  379. fc = get_unaligned((__le16 *)buffer);
  380. need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc);
  381. tx = &mac->chip.usb.tx;
  382. for (sidx = 0; sidx < MAX_STA_NUM - 1; sidx++) {
  383. if (memcmp(&buffer[10], tx->station[sidx].mac, ETH_ALEN))
  384. continue;
  385. if (tx->station[sidx].flag & STATION_CONNECTED_FLAG) {
  386. tx->station[sidx].flag |= STATION_HEARTBEAT_FLAG;
  387. break;
  388. }
  389. }
  390. if (sidx == MAX_STA_NUM - 1) {
  391. for (sidx = 0; sidx < MAX_STA_NUM - 1; sidx++) {
  392. if (tx->station[sidx].flag & STATION_CONNECTED_FLAG)
  393. continue;
  394. memcpy(tx->station[sidx].mac, &buffer[10], ETH_ALEN);
  395. tx->station[sidx].flag |= STATION_CONNECTED_FLAG;
  396. tx->station[sidx].flag |= STATION_HEARTBEAT_FLAG;
  397. break;
  398. }
  399. }
  400. switch (buffer[0]) {
  401. case IEEE80211_STYPE_PROBE_REQ:
  402. dev_dbg(plfxlc_mac_dev(mac), "Probe request\n");
  403. break;
  404. case IEEE80211_STYPE_ASSOC_REQ:
  405. dev_dbg(plfxlc_mac_dev(mac), "Association request\n");
  406. break;
  407. case IEEE80211_STYPE_AUTH:
  408. dev_dbg(plfxlc_mac_dev(mac), "Authentication req\n");
  409. break;
  410. case IEEE80211_FTYPE_DATA:
  411. dev_dbg(plfxlc_mac_dev(mac), "802.11 data frame\n");
  412. break;
  413. }
  414. skb = dev_alloc_skb(payload_length + (need_padding ? 2 : 0));
  415. if (!skb)
  416. return -ENOMEM;
  417. if (need_padding)
  418. /* Make sure that the payload data is 4 byte aligned. */
  419. skb_reserve(skb, 2);
  420. skb_put_data(skb, buffer, payload_length);
  421. memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
  422. ieee80211_rx_irqsafe(hw, skb);
  423. return 0;
  424. }
  425. static int plfxlc_op_add_interface(struct ieee80211_hw *hw,
  426. struct ieee80211_vif *vif)
  427. {
  428. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  429. static const char * const iftype80211[] = {
  430. [NL80211_IFTYPE_STATION] = "Station",
  431. [NL80211_IFTYPE_ADHOC] = "Adhoc"
  432. };
  433. if (mac->type != NL80211_IFTYPE_UNSPECIFIED)
  434. return -EOPNOTSUPP;
  435. if (vif->type == NL80211_IFTYPE_ADHOC ||
  436. vif->type == NL80211_IFTYPE_STATION) {
  437. dev_dbg(plfxlc_mac_dev(mac), "%s %s\n", __func__,
  438. iftype80211[vif->type]);
  439. mac->type = vif->type;
  440. mac->vif = vif;
  441. return 0;
  442. }
  443. dev_dbg(plfxlc_mac_dev(mac), "unsupported iftype\n");
  444. return -EOPNOTSUPP;
  445. }
  446. static void plfxlc_op_remove_interface(struct ieee80211_hw *hw,
  447. struct ieee80211_vif *vif)
  448. {
  449. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  450. mac->type = NL80211_IFTYPE_UNSPECIFIED;
  451. mac->vif = NULL;
  452. }
  453. static int plfxlc_op_config(struct ieee80211_hw *hw, u32 changed)
  454. {
  455. return 0;
  456. }
  457. #define SUPPORTED_FIF_FLAGS \
  458. (FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \
  459. FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)
  460. static void plfxlc_op_configure_filter(struct ieee80211_hw *hw,
  461. unsigned int changed_flags,
  462. unsigned int *new_flags,
  463. u64 multicast)
  464. {
  465. struct plfxlc_mc_hash hash = {
  466. .low = multicast,
  467. .high = multicast >> 32,
  468. };
  469. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  470. unsigned long flags;
  471. /* Only deal with supported flags */
  472. *new_flags &= SUPPORTED_FIF_FLAGS;
  473. /* If multicast parameter
  474. * (as returned by plfxlc_op_prepare_multicast)
  475. * has changed, no bit in changed_flags is set. To handle this
  476. * situation, we do not return if changed_flags is 0. If we do so,
  477. * we will have some issue with IPv6 which uses multicast for link
  478. * layer address resolution.
  479. */
  480. if (*new_flags & (FIF_ALLMULTI))
  481. plfxlc_mc_add_all(&hash);
  482. spin_lock_irqsave(&mac->lock, flags);
  483. mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL);
  484. mac->pass_ctrl = !!(*new_flags & FIF_CONTROL);
  485. mac->multicast_hash = hash;
  486. spin_unlock_irqrestore(&mac->lock, flags);
  487. /* no handling required for FIF_OTHER_BSS as we don't currently
  488. * do BSSID filtering
  489. */
  490. /* FIXME: in future it would be nice to enable the probe response
  491. * filter (so that the driver doesn't see them) until
  492. * FIF_BCN_PRBRESP_PROMISC is set. however due to atomicity here, we'd
  493. * have to schedule work to enable prbresp reception, which might
  494. * happen too late. For now we'll just listen and forward them all the
  495. * time.
  496. */
  497. }
  498. static void plfxlc_op_bss_info_changed(struct ieee80211_hw *hw,
  499. struct ieee80211_vif *vif,
  500. struct ieee80211_bss_conf *bss_conf,
  501. u64 changes)
  502. {
  503. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  504. int associated;
  505. dev_dbg(plfxlc_mac_dev(mac), "changes: %llx\n", changes);
  506. if (mac->type != NL80211_IFTYPE_ADHOC) { /* for STATION */
  507. associated = is_valid_ether_addr(bss_conf->bssid);
  508. goto exit_all;
  509. }
  510. /* for ADHOC */
  511. associated = true;
  512. if (changes & BSS_CHANGED_BEACON) {
  513. struct sk_buff *beacon = ieee80211_beacon_get(hw, vif, 0);
  514. if (beacon) {
  515. /*beacon is hardcoded in firmware */
  516. kfree_skb(beacon);
  517. /*Returned skb is used only once and
  518. * low-level driver is
  519. * responsible for freeing it.
  520. */
  521. }
  522. }
  523. if (changes & BSS_CHANGED_BEACON_ENABLED) {
  524. u16 interval = 0;
  525. u8 period = 0;
  526. if (bss_conf->enable_beacon) {
  527. period = bss_conf->dtim_period;
  528. interval = bss_conf->beacon_int;
  529. }
  530. spin_lock_irq(&mac->lock);
  531. mac->beacon.period = period;
  532. mac->beacon.interval = interval;
  533. mac->beacon.last_update = jiffies;
  534. spin_unlock_irq(&mac->lock);
  535. plfxlc_set_beacon_interval(&mac->chip, interval,
  536. period, mac->type);
  537. }
  538. exit_all:
  539. spin_lock_irq(&mac->lock);
  540. mac->associated = associated;
  541. spin_unlock_irq(&mac->lock);
  542. }
  543. static int plfxlc_get_stats(struct ieee80211_hw *hw,
  544. struct ieee80211_low_level_stats *stats)
  545. {
  546. stats->dot11ACKFailureCount = 0;
  547. stats->dot11RTSFailureCount = 0;
  548. stats->dot11FCSErrorCount = 0;
  549. stats->dot11RTSSuccessCount = 0;
  550. return 0;
  551. }
  552. static const char et_strings[][ETH_GSTRING_LEN] = {
  553. "phy_rssi",
  554. "phy_rx_crc_err"
  555. };
  556. static int plfxlc_get_et_sset_count(struct ieee80211_hw *hw,
  557. struct ieee80211_vif *vif, int sset)
  558. {
  559. if (sset == ETH_SS_STATS)
  560. return ARRAY_SIZE(et_strings);
  561. return 0;
  562. }
  563. static void plfxlc_get_et_strings(struct ieee80211_hw *hw,
  564. struct ieee80211_vif *vif,
  565. u32 sset, u8 *data)
  566. {
  567. if (sset == ETH_SS_STATS)
  568. memcpy(data, et_strings, sizeof(et_strings));
  569. }
  570. static void plfxlc_get_et_stats(struct ieee80211_hw *hw,
  571. struct ieee80211_vif *vif,
  572. struct ethtool_stats *stats, u64 *data)
  573. {
  574. struct plfxlc_mac *mac = plfxlc_hw_mac(hw);
  575. data[0] = mac->rssi;
  576. data[1] = mac->crc_errors;
  577. }
  578. static int plfxlc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
  579. {
  580. return 0;
  581. }
  582. static const struct ieee80211_ops plfxlc_ops = {
  583. .tx = plfxlc_op_tx,
  584. .start = plfxlc_op_start,
  585. .stop = plfxlc_op_stop,
  586. .add_interface = plfxlc_op_add_interface,
  587. .remove_interface = plfxlc_op_remove_interface,
  588. .set_rts_threshold = plfxlc_set_rts_threshold,
  589. .config = plfxlc_op_config,
  590. .configure_filter = plfxlc_op_configure_filter,
  591. .bss_info_changed = plfxlc_op_bss_info_changed,
  592. .get_stats = plfxlc_get_stats,
  593. .get_et_sset_count = plfxlc_get_et_sset_count,
  594. .get_et_stats = plfxlc_get_et_stats,
  595. .get_et_strings = plfxlc_get_et_strings,
  596. };
  597. struct ieee80211_hw *plfxlc_mac_alloc_hw(struct usb_interface *intf)
  598. {
  599. struct ieee80211_hw *hw;
  600. struct plfxlc_mac *mac;
  601. hw = ieee80211_alloc_hw(sizeof(struct plfxlc_mac), &plfxlc_ops);
  602. if (!hw) {
  603. dev_dbg(&intf->dev, "out of memory\n");
  604. return NULL;
  605. }
  606. set_wiphy_dev(hw->wiphy, &intf->dev);
  607. mac = plfxlc_hw_mac(hw);
  608. memset(mac, 0, sizeof(*mac));
  609. spin_lock_init(&mac->lock);
  610. mac->hw = hw;
  611. mac->type = NL80211_IFTYPE_UNSPECIFIED;
  612. memcpy(mac->channels, plfxlc_channels, sizeof(plfxlc_channels));
  613. memcpy(mac->rates, plfxlc_rates, sizeof(plfxlc_rates));
  614. mac->band.n_bitrates = ARRAY_SIZE(plfxlc_rates);
  615. mac->band.bitrates = mac->rates;
  616. mac->band.n_channels = ARRAY_SIZE(plfxlc_channels);
  617. mac->band.channels = mac->channels;
  618. hw->wiphy->bands[NL80211_BAND_LC] = &mac->band;
  619. hw->conf.chandef.width = NL80211_CHAN_WIDTH_20;
  620. ieee80211_hw_set(hw, RX_INCLUDES_FCS);
  621. ieee80211_hw_set(hw, SIGNAL_DBM);
  622. ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
  623. ieee80211_hw_set(hw, MFP_CAPABLE);
  624. hw->wiphy->interface_modes =
  625. BIT(NL80211_IFTYPE_STATION) |
  626. BIT(NL80211_IFTYPE_ADHOC);
  627. hw->max_signal = 100;
  628. hw->queues = 1;
  629. /* 4 for 32 bit alignment if no tailroom */
  630. hw->extra_tx_headroom = sizeof(struct plfxlc_ctrlset) + 4;
  631. /* Tell mac80211 that we support multi rate retries */
  632. hw->max_rates = IEEE80211_TX_MAX_RATES;
  633. hw->max_rate_tries = 18; /* 9 rates * 2 retries/rate */
  634. skb_queue_head_init(&mac->ack_wait_queue);
  635. mac->ack_pending = 0;
  636. plfxlc_chip_init(&mac->chip, hw, intf);
  637. SET_IEEE80211_DEV(hw, &intf->dev);
  638. return hw;
  639. }