wlan.c 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
  4. * All rights reserved.
  5. */
  6. #include <linux/if_ether.h>
  7. #include <linux/ip.h>
  8. #include <net/dsfield.h>
  9. #include "cfg80211.h"
  10. #include "wlan_cfg.h"
  11. #define WAKE_UP_TRIAL_RETRY 10000
  12. static inline bool is_wilc1000(u32 id)
  13. {
  14. return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
  15. }
  16. static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
  17. {
  18. mutex_lock(&wilc->hif_cs);
  19. if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP && wilc->power_save_mode)
  20. chip_wakeup(wilc);
  21. }
  22. static inline void release_bus(struct wilc *wilc, enum bus_release release)
  23. {
  24. if (release == WILC_BUS_RELEASE_ALLOW_SLEEP && wilc->power_save_mode)
  25. chip_allow_sleep(wilc);
  26. mutex_unlock(&wilc->hif_cs);
  27. }
  28. static void wilc_wlan_txq_remove(struct wilc *wilc, u8 q_num,
  29. struct txq_entry_t *tqe)
  30. {
  31. list_del(&tqe->list);
  32. wilc->txq_entries -= 1;
  33. wilc->txq[q_num].count--;
  34. }
  35. static struct txq_entry_t *
  36. wilc_wlan_txq_remove_from_head(struct wilc *wilc, u8 q_num)
  37. {
  38. struct txq_entry_t *tqe = NULL;
  39. unsigned long flags;
  40. spin_lock_irqsave(&wilc->txq_spinlock, flags);
  41. if (!list_empty(&wilc->txq[q_num].txq_head.list)) {
  42. tqe = list_first_entry(&wilc->txq[q_num].txq_head.list,
  43. struct txq_entry_t, list);
  44. list_del(&tqe->list);
  45. wilc->txq_entries -= 1;
  46. wilc->txq[q_num].count--;
  47. }
  48. spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
  49. return tqe;
  50. }
  51. static void wilc_wlan_txq_add_to_tail(struct net_device *dev, u8 q_num,
  52. struct txq_entry_t *tqe)
  53. {
  54. unsigned long flags;
  55. struct wilc_vif *vif = netdev_priv(dev);
  56. struct wilc *wilc = vif->wilc;
  57. spin_lock_irqsave(&wilc->txq_spinlock, flags);
  58. list_add_tail(&tqe->list, &wilc->txq[q_num].txq_head.list);
  59. wilc->txq_entries += 1;
  60. wilc->txq[q_num].count++;
  61. spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
  62. complete(&wilc->txq_event);
  63. }
  64. static void wilc_wlan_txq_add_to_head(struct wilc_vif *vif, u8 q_num,
  65. struct txq_entry_t *tqe)
  66. {
  67. unsigned long flags;
  68. struct wilc *wilc = vif->wilc;
  69. mutex_lock(&wilc->txq_add_to_head_cs);
  70. spin_lock_irqsave(&wilc->txq_spinlock, flags);
  71. list_add(&tqe->list, &wilc->txq[q_num].txq_head.list);
  72. wilc->txq_entries += 1;
  73. wilc->txq[q_num].count++;
  74. spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
  75. mutex_unlock(&wilc->txq_add_to_head_cs);
  76. complete(&wilc->txq_event);
  77. }
  78. #define NOT_TCP_ACK (-1)
  79. static inline void add_tcp_session(struct wilc_vif *vif, u32 src_prt,
  80. u32 dst_prt, u32 seq)
  81. {
  82. struct tcp_ack_filter *f = &vif->ack_filter;
  83. if (f->tcp_session < 2 * MAX_TCP_SESSION) {
  84. f->ack_session_info[f->tcp_session].seq_num = seq;
  85. f->ack_session_info[f->tcp_session].bigger_ack_num = 0;
  86. f->ack_session_info[f->tcp_session].src_port = src_prt;
  87. f->ack_session_info[f->tcp_session].dst_port = dst_prt;
  88. f->tcp_session++;
  89. }
  90. }
  91. static inline void update_tcp_session(struct wilc_vif *vif, u32 index, u32 ack)
  92. {
  93. struct tcp_ack_filter *f = &vif->ack_filter;
  94. if (index < 2 * MAX_TCP_SESSION &&
  95. ack > f->ack_session_info[index].bigger_ack_num)
  96. f->ack_session_info[index].bigger_ack_num = ack;
  97. }
  98. static inline void add_tcp_pending_ack(struct wilc_vif *vif, u32 ack,
  99. u32 session_index,
  100. struct txq_entry_t *txqe)
  101. {
  102. struct tcp_ack_filter *f = &vif->ack_filter;
  103. u32 i = f->pending_base + f->pending_acks_idx;
  104. if (i < MAX_PENDING_ACKS) {
  105. f->pending_acks[i].ack_num = ack;
  106. f->pending_acks[i].txqe = txqe;
  107. f->pending_acks[i].session_index = session_index;
  108. txqe->ack_idx = i;
  109. f->pending_acks_idx++;
  110. }
  111. }
  112. static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
  113. {
  114. void *buffer = tqe->buffer;
  115. const struct ethhdr *eth_hdr_ptr = buffer;
  116. int i;
  117. unsigned long flags;
  118. struct wilc_vif *vif = netdev_priv(dev);
  119. struct wilc *wilc = vif->wilc;
  120. struct tcp_ack_filter *f = &vif->ack_filter;
  121. const struct iphdr *ip_hdr_ptr;
  122. const struct tcphdr *tcp_hdr_ptr;
  123. u32 ihl, total_length, data_offset;
  124. spin_lock_irqsave(&wilc->txq_spinlock, flags);
  125. if (eth_hdr_ptr->h_proto != htons(ETH_P_IP))
  126. goto out;
  127. ip_hdr_ptr = buffer + ETH_HLEN;
  128. if (ip_hdr_ptr->protocol != IPPROTO_TCP)
  129. goto out;
  130. ihl = ip_hdr_ptr->ihl << 2;
  131. tcp_hdr_ptr = buffer + ETH_HLEN + ihl;
  132. total_length = ntohs(ip_hdr_ptr->tot_len);
  133. data_offset = tcp_hdr_ptr->doff << 2;
  134. if (total_length == (ihl + data_offset)) {
  135. u32 seq_no, ack_no;
  136. seq_no = ntohl(tcp_hdr_ptr->seq);
  137. ack_no = ntohl(tcp_hdr_ptr->ack_seq);
  138. for (i = 0; i < f->tcp_session; i++) {
  139. u32 j = f->ack_session_info[i].seq_num;
  140. if (i < 2 * MAX_TCP_SESSION &&
  141. j == seq_no) {
  142. update_tcp_session(vif, i, ack_no);
  143. break;
  144. }
  145. }
  146. if (i == f->tcp_session)
  147. add_tcp_session(vif, 0, 0, seq_no);
  148. add_tcp_pending_ack(vif, ack_no, i, tqe);
  149. }
  150. out:
  151. spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
  152. }
  153. static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
  154. {
  155. struct wilc_vif *vif = netdev_priv(dev);
  156. struct wilc *wilc = vif->wilc;
  157. struct tcp_ack_filter *f = &vif->ack_filter;
  158. u32 i = 0;
  159. u32 dropped = 0;
  160. unsigned long flags;
  161. spin_lock_irqsave(&wilc->txq_spinlock, flags);
  162. for (i = f->pending_base;
  163. i < (f->pending_base + f->pending_acks_idx); i++) {
  164. u32 index;
  165. u32 bigger_ack_num;
  166. if (i >= MAX_PENDING_ACKS)
  167. break;
  168. index = f->pending_acks[i].session_index;
  169. if (index >= 2 * MAX_TCP_SESSION)
  170. break;
  171. bigger_ack_num = f->ack_session_info[index].bigger_ack_num;
  172. if (f->pending_acks[i].ack_num < bigger_ack_num) {
  173. struct txq_entry_t *tqe;
  174. tqe = f->pending_acks[i].txqe;
  175. if (tqe) {
  176. wilc_wlan_txq_remove(wilc, tqe->q_num, tqe);
  177. tqe->status = 1;
  178. if (tqe->tx_complete_func)
  179. tqe->tx_complete_func(tqe->priv,
  180. tqe->status);
  181. kfree(tqe);
  182. dropped++;
  183. }
  184. }
  185. }
  186. f->pending_acks_idx = 0;
  187. f->tcp_session = 0;
  188. if (f->pending_base == 0)
  189. f->pending_base = MAX_TCP_SESSION;
  190. else
  191. f->pending_base = 0;
  192. spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
  193. while (dropped > 0) {
  194. wait_for_completion_timeout(&wilc->txq_event,
  195. msecs_to_jiffies(1));
  196. dropped--;
  197. }
  198. }
  199. void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
  200. {
  201. vif->ack_filter.enabled = value;
  202. }
  203. static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
  204. u32 buffer_size)
  205. {
  206. struct txq_entry_t *tqe;
  207. struct wilc *wilc = vif->wilc;
  208. netdev_dbg(vif->ndev, "Adding config packet ...\n");
  209. if (wilc->quit) {
  210. netdev_dbg(vif->ndev, "Return due to clear function\n");
  211. complete(&wilc->cfg_event);
  212. return 0;
  213. }
  214. tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
  215. if (!tqe) {
  216. complete(&wilc->cfg_event);
  217. return 0;
  218. }
  219. tqe->type = WILC_CFG_PKT;
  220. tqe->buffer = buffer;
  221. tqe->buffer_size = buffer_size;
  222. tqe->tx_complete_func = NULL;
  223. tqe->priv = NULL;
  224. tqe->q_num = AC_VO_Q;
  225. tqe->ack_idx = NOT_TCP_ACK;
  226. tqe->vif = vif;
  227. wilc_wlan_txq_add_to_head(vif, AC_VO_Q, tqe);
  228. return 1;
  229. }
  230. static bool is_ac_q_limit(struct wilc *wl, u8 q_num)
  231. {
  232. u8 factors[NQUEUES] = {1, 1, 1, 1};
  233. u16 i;
  234. unsigned long flags;
  235. struct wilc_tx_queue_status *q = &wl->tx_q_limit;
  236. u8 end_index;
  237. u8 q_limit;
  238. bool ret = false;
  239. spin_lock_irqsave(&wl->txq_spinlock, flags);
  240. if (!q->initialized) {
  241. for (i = 0; i < AC_BUFFER_SIZE; i++)
  242. q->buffer[i] = i % NQUEUES;
  243. for (i = 0; i < NQUEUES; i++) {
  244. q->cnt[i] = AC_BUFFER_SIZE * factors[i] / NQUEUES;
  245. q->sum += q->cnt[i];
  246. }
  247. q->end_index = AC_BUFFER_SIZE - 1;
  248. q->initialized = 1;
  249. }
  250. end_index = q->end_index;
  251. q->cnt[q->buffer[end_index]] -= factors[q->buffer[end_index]];
  252. q->cnt[q_num] += factors[q_num];
  253. q->sum += (factors[q_num] - factors[q->buffer[end_index]]);
  254. q->buffer[end_index] = q_num;
  255. if (end_index > 0)
  256. q->end_index--;
  257. else
  258. q->end_index = AC_BUFFER_SIZE - 1;
  259. if (!q->sum)
  260. q_limit = 1;
  261. else
  262. q_limit = (q->cnt[q_num] * FLOW_CONTROL_UPPER_THRESHOLD / q->sum) + 1;
  263. if (wl->txq[q_num].count <= q_limit)
  264. ret = true;
  265. spin_unlock_irqrestore(&wl->txq_spinlock, flags);
  266. return ret;
  267. }
  268. static inline u8 ac_classify(struct wilc *wilc, struct sk_buff *skb)
  269. {
  270. u8 q_num = AC_BE_Q;
  271. u8 dscp;
  272. switch (skb->protocol) {
  273. case htons(ETH_P_IP):
  274. dscp = ipv4_get_dsfield(ip_hdr(skb)) & 0xfc;
  275. break;
  276. case htons(ETH_P_IPV6):
  277. dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & 0xfc;
  278. break;
  279. default:
  280. return q_num;
  281. }
  282. switch (dscp) {
  283. case 0x08:
  284. case 0x20:
  285. case 0x40:
  286. q_num = AC_BK_Q;
  287. break;
  288. case 0x80:
  289. case 0xA0:
  290. case 0x28:
  291. q_num = AC_VI_Q;
  292. break;
  293. case 0xC0:
  294. case 0xD0:
  295. case 0xE0:
  296. case 0x88:
  297. case 0xB8:
  298. q_num = AC_VO_Q;
  299. break;
  300. }
  301. return q_num;
  302. }
  303. static inline int ac_balance(struct wilc *wl, u8 *ratio)
  304. {
  305. u8 i, max_count = 0;
  306. if (!ratio)
  307. return -EINVAL;
  308. for (i = 0; i < NQUEUES; i++)
  309. if (wl->txq[i].fw.count > max_count)
  310. max_count = wl->txq[i].fw.count;
  311. for (i = 0; i < NQUEUES; i++)
  312. ratio[i] = max_count - wl->txq[i].fw.count;
  313. return 0;
  314. }
  315. static inline void ac_update_fw_ac_pkt_info(struct wilc *wl, u32 reg)
  316. {
  317. wl->txq[AC_BK_Q].fw.count = FIELD_GET(BK_AC_COUNT_FIELD, reg);
  318. wl->txq[AC_BE_Q].fw.count = FIELD_GET(BE_AC_COUNT_FIELD, reg);
  319. wl->txq[AC_VI_Q].fw.count = FIELD_GET(VI_AC_COUNT_FIELD, reg);
  320. wl->txq[AC_VO_Q].fw.count = FIELD_GET(VO_AC_COUNT_FIELD, reg);
  321. wl->txq[AC_BK_Q].fw.acm = FIELD_GET(BK_AC_ACM_STAT_FIELD, reg);
  322. wl->txq[AC_BE_Q].fw.acm = FIELD_GET(BE_AC_ACM_STAT_FIELD, reg);
  323. wl->txq[AC_VI_Q].fw.acm = FIELD_GET(VI_AC_ACM_STAT_FIELD, reg);
  324. wl->txq[AC_VO_Q].fw.acm = FIELD_GET(VO_AC_ACM_STAT_FIELD, reg);
  325. }
  326. static inline u8 ac_change(struct wilc *wilc, u8 *ac)
  327. {
  328. do {
  329. if (wilc->txq[*ac].fw.acm == 0)
  330. return 0;
  331. (*ac)++;
  332. } while (*ac < NQUEUES);
  333. return 1;
  334. }
  335. int wilc_wlan_txq_add_net_pkt(struct net_device *dev,
  336. struct tx_complete_data *tx_data, u8 *buffer,
  337. u32 buffer_size,
  338. void (*tx_complete_fn)(void *, int))
  339. {
  340. struct txq_entry_t *tqe;
  341. struct wilc_vif *vif = netdev_priv(dev);
  342. struct wilc *wilc;
  343. u8 q_num;
  344. wilc = vif->wilc;
  345. if (wilc->quit) {
  346. tx_complete_fn(tx_data, 0);
  347. return 0;
  348. }
  349. if (!wilc->initialized) {
  350. tx_complete_fn(tx_data, 0);
  351. return 0;
  352. }
  353. tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
  354. if (!tqe) {
  355. tx_complete_fn(tx_data, 0);
  356. return 0;
  357. }
  358. tqe->type = WILC_NET_PKT;
  359. tqe->buffer = buffer;
  360. tqe->buffer_size = buffer_size;
  361. tqe->tx_complete_func = tx_complete_fn;
  362. tqe->priv = tx_data;
  363. tqe->vif = vif;
  364. q_num = ac_classify(wilc, tx_data->skb);
  365. tqe->q_num = q_num;
  366. if (ac_change(wilc, &q_num)) {
  367. tx_complete_fn(tx_data, 0);
  368. kfree(tqe);
  369. return 0;
  370. }
  371. if (is_ac_q_limit(wilc, q_num)) {
  372. tqe->ack_idx = NOT_TCP_ACK;
  373. if (vif->ack_filter.enabled)
  374. tcp_process(dev, tqe);
  375. wilc_wlan_txq_add_to_tail(dev, q_num, tqe);
  376. } else {
  377. tx_complete_fn(tx_data, 0);
  378. kfree(tqe);
  379. }
  380. return wilc->txq_entries;
  381. }
  382. int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
  383. u32 buffer_size,
  384. void (*tx_complete_fn)(void *, int))
  385. {
  386. struct txq_entry_t *tqe;
  387. struct wilc_vif *vif = netdev_priv(dev);
  388. struct wilc *wilc;
  389. wilc = vif->wilc;
  390. if (wilc->quit) {
  391. tx_complete_fn(priv, 0);
  392. return 0;
  393. }
  394. if (!wilc->initialized) {
  395. tx_complete_fn(priv, 0);
  396. return 0;
  397. }
  398. tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
  399. if (!tqe) {
  400. tx_complete_fn(priv, 0);
  401. return 0;
  402. }
  403. tqe->type = WILC_MGMT_PKT;
  404. tqe->buffer = buffer;
  405. tqe->buffer_size = buffer_size;
  406. tqe->tx_complete_func = tx_complete_fn;
  407. tqe->priv = priv;
  408. tqe->q_num = AC_BE_Q;
  409. tqe->ack_idx = NOT_TCP_ACK;
  410. tqe->vif = vif;
  411. wilc_wlan_txq_add_to_tail(dev, AC_VO_Q, tqe);
  412. return 1;
  413. }
  414. static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc, u8 q_num)
  415. {
  416. struct txq_entry_t *tqe = NULL;
  417. unsigned long flags;
  418. spin_lock_irqsave(&wilc->txq_spinlock, flags);
  419. if (!list_empty(&wilc->txq[q_num].txq_head.list))
  420. tqe = list_first_entry(&wilc->txq[q_num].txq_head.list,
  421. struct txq_entry_t, list);
  422. spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
  423. return tqe;
  424. }
  425. static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
  426. struct txq_entry_t *tqe,
  427. u8 q_num)
  428. {
  429. unsigned long flags;
  430. spin_lock_irqsave(&wilc->txq_spinlock, flags);
  431. if (!list_is_last(&tqe->list, &wilc->txq[q_num].txq_head.list))
  432. tqe = list_next_entry(tqe, list);
  433. else
  434. tqe = NULL;
  435. spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
  436. return tqe;
  437. }
  438. static void wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
  439. {
  440. if (wilc->quit)
  441. return;
  442. mutex_lock(&wilc->rxq_cs);
  443. list_add_tail(&rqe->list, &wilc->rxq_head.list);
  444. mutex_unlock(&wilc->rxq_cs);
  445. }
  446. static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
  447. {
  448. struct rxq_entry_t *rqe = NULL;
  449. mutex_lock(&wilc->rxq_cs);
  450. if (!list_empty(&wilc->rxq_head.list)) {
  451. rqe = list_first_entry(&wilc->rxq_head.list, struct rxq_entry_t,
  452. list);
  453. list_del(&rqe->list);
  454. }
  455. mutex_unlock(&wilc->rxq_cs);
  456. return rqe;
  457. }
  458. void chip_allow_sleep(struct wilc *wilc)
  459. {
  460. u32 reg = 0;
  461. const struct wilc_hif_func *hif_func = wilc->hif_func;
  462. u32 wakeup_reg, wakeup_bit;
  463. u32 to_host_from_fw_reg, to_host_from_fw_bit;
  464. u32 from_host_to_fw_reg, from_host_to_fw_bit;
  465. u32 trials = 100;
  466. int ret;
  467. if (wilc->io_type == WILC_HIF_SDIO) {
  468. wakeup_reg = WILC_SDIO_WAKEUP_REG;
  469. wakeup_bit = WILC_SDIO_WAKEUP_BIT;
  470. from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
  471. from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
  472. to_host_from_fw_reg = WILC_SDIO_FW_TO_HOST_REG;
  473. to_host_from_fw_bit = WILC_SDIO_FW_TO_HOST_BIT;
  474. } else {
  475. wakeup_reg = WILC_SPI_WAKEUP_REG;
  476. wakeup_bit = WILC_SPI_WAKEUP_BIT;
  477. from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
  478. from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
  479. to_host_from_fw_reg = WILC_SPI_FW_TO_HOST_REG;
  480. to_host_from_fw_bit = WILC_SPI_FW_TO_HOST_BIT;
  481. }
  482. while (--trials) {
  483. ret = hif_func->hif_read_reg(wilc, to_host_from_fw_reg, &reg);
  484. if (ret)
  485. return;
  486. if ((reg & to_host_from_fw_bit) == 0)
  487. break;
  488. }
  489. if (!trials)
  490. pr_warn("FW not responding\n");
  491. /* Clear bit 1 */
  492. ret = hif_func->hif_read_reg(wilc, wakeup_reg, &reg);
  493. if (ret)
  494. return;
  495. if (reg & wakeup_bit) {
  496. reg &= ~wakeup_bit;
  497. ret = hif_func->hif_write_reg(wilc, wakeup_reg, reg);
  498. if (ret)
  499. return;
  500. }
  501. ret = hif_func->hif_read_reg(wilc, from_host_to_fw_reg, &reg);
  502. if (ret)
  503. return;
  504. if (reg & from_host_to_fw_bit) {
  505. reg &= ~from_host_to_fw_bit;
  506. ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg, reg);
  507. if (ret)
  508. return;
  509. }
  510. }
  511. EXPORT_SYMBOL_GPL(chip_allow_sleep);
  512. void chip_wakeup(struct wilc *wilc)
  513. {
  514. u32 ret = 0;
  515. u32 clk_status_val = 0, trials = 0;
  516. u32 wakeup_reg, wakeup_bit;
  517. u32 clk_status_reg, clk_status_bit;
  518. u32 from_host_to_fw_reg, from_host_to_fw_bit;
  519. const struct wilc_hif_func *hif_func = wilc->hif_func;
  520. if (wilc->io_type == WILC_HIF_SDIO) {
  521. wakeup_reg = WILC_SDIO_WAKEUP_REG;
  522. wakeup_bit = WILC_SDIO_WAKEUP_BIT;
  523. clk_status_reg = WILC_SDIO_CLK_STATUS_REG;
  524. clk_status_bit = WILC_SDIO_CLK_STATUS_BIT;
  525. from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
  526. from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
  527. } else {
  528. wakeup_reg = WILC_SPI_WAKEUP_REG;
  529. wakeup_bit = WILC_SPI_WAKEUP_BIT;
  530. clk_status_reg = WILC_SPI_CLK_STATUS_REG;
  531. clk_status_bit = WILC_SPI_CLK_STATUS_BIT;
  532. from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
  533. from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
  534. }
  535. /* indicate host wakeup */
  536. ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg,
  537. from_host_to_fw_bit);
  538. if (ret)
  539. return;
  540. /* Set wake-up bit */
  541. ret = hif_func->hif_write_reg(wilc, wakeup_reg,
  542. wakeup_bit);
  543. if (ret)
  544. return;
  545. while (trials < WAKE_UP_TRIAL_RETRY) {
  546. ret = hif_func->hif_read_reg(wilc, clk_status_reg,
  547. &clk_status_val);
  548. if (ret) {
  549. pr_err("Bus error %d %x\n", ret, clk_status_val);
  550. return;
  551. }
  552. if (clk_status_val & clk_status_bit)
  553. break;
  554. trials++;
  555. }
  556. if (trials >= WAKE_UP_TRIAL_RETRY) {
  557. pr_err("Failed to wake-up the chip\n");
  558. return;
  559. }
  560. /* Sometimes spi fail to read clock regs after reading
  561. * writing clockless registers
  562. */
  563. if (wilc->io_type == WILC_HIF_SPI)
  564. wilc->hif_func->hif_reset(wilc);
  565. }
  566. EXPORT_SYMBOL_GPL(chip_wakeup);
  567. void host_wakeup_notify(struct wilc *wilc)
  568. {
  569. acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
  570. wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
  571. release_bus(wilc, WILC_BUS_RELEASE_ONLY);
  572. }
  573. EXPORT_SYMBOL_GPL(host_wakeup_notify);
  574. void host_sleep_notify(struct wilc *wilc)
  575. {
  576. acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
  577. wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
  578. release_bus(wilc, WILC_BUS_RELEASE_ONLY);
  579. }
  580. EXPORT_SYMBOL_GPL(host_sleep_notify);
  581. int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
  582. {
  583. int i, entries = 0;
  584. u8 k, ac;
  585. u32 sum;
  586. u32 reg;
  587. u8 ac_desired_ratio[NQUEUES] = {0, 0, 0, 0};
  588. u8 ac_preserve_ratio[NQUEUES] = {1, 1, 1, 1};
  589. u8 *num_pkts_to_add;
  590. u8 vmm_entries_ac[WILC_VMM_TBL_SIZE];
  591. u32 offset = 0;
  592. bool max_size_over = 0, ac_exist = 0;
  593. int vmm_sz = 0;
  594. struct txq_entry_t *tqe_q[NQUEUES];
  595. int ret = 0;
  596. int counter;
  597. int timeout;
  598. u32 *vmm_table = wilc->vmm_table;
  599. u8 ac_pkt_num_to_chip[NQUEUES] = {0, 0, 0, 0};
  600. const struct wilc_hif_func *func;
  601. int srcu_idx;
  602. u8 *txb = wilc->tx_buffer;
  603. struct wilc_vif *vif;
  604. if (wilc->quit)
  605. goto out_update_cnt;
  606. if (ac_balance(wilc, ac_desired_ratio))
  607. return -EINVAL;
  608. mutex_lock(&wilc->txq_add_to_head_cs);
  609. srcu_idx = srcu_read_lock(&wilc->srcu);
  610. list_for_each_entry_rcu(vif, &wilc->vif_list, list)
  611. wilc_wlan_txq_filter_dup_tcp_ack(vif->ndev);
  612. srcu_read_unlock(&wilc->srcu, srcu_idx);
  613. for (ac = 0; ac < NQUEUES; ac++)
  614. tqe_q[ac] = wilc_wlan_txq_get_first(wilc, ac);
  615. i = 0;
  616. sum = 0;
  617. max_size_over = 0;
  618. num_pkts_to_add = ac_desired_ratio;
  619. do {
  620. ac_exist = 0;
  621. for (ac = 0; (ac < NQUEUES) && (!max_size_over); ac++) {
  622. if (!tqe_q[ac])
  623. continue;
  624. ac_exist = 1;
  625. for (k = 0; (k < num_pkts_to_add[ac]) &&
  626. (!max_size_over) && tqe_q[ac]; k++) {
  627. if (i >= (WILC_VMM_TBL_SIZE - 1)) {
  628. max_size_over = 1;
  629. break;
  630. }
  631. if (tqe_q[ac]->type == WILC_CFG_PKT)
  632. vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
  633. else if (tqe_q[ac]->type == WILC_NET_PKT)
  634. vmm_sz = ETH_ETHERNET_HDR_OFFSET;
  635. else
  636. vmm_sz = HOST_HDR_OFFSET;
  637. vmm_sz += tqe_q[ac]->buffer_size;
  638. vmm_sz = ALIGN(vmm_sz, 4);
  639. if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE) {
  640. max_size_over = 1;
  641. break;
  642. }
  643. vmm_table[i] = vmm_sz / 4;
  644. if (tqe_q[ac]->type == WILC_CFG_PKT)
  645. vmm_table[i] |= BIT(10);
  646. cpu_to_le32s(&vmm_table[i]);
  647. vmm_entries_ac[i] = ac;
  648. i++;
  649. sum += vmm_sz;
  650. tqe_q[ac] = wilc_wlan_txq_get_next(wilc,
  651. tqe_q[ac],
  652. ac);
  653. }
  654. }
  655. num_pkts_to_add = ac_preserve_ratio;
  656. } while (!max_size_over && ac_exist);
  657. if (i == 0)
  658. goto out_unlock;
  659. vmm_table[i] = 0x0;
  660. acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
  661. counter = 0;
  662. func = wilc->hif_func;
  663. do {
  664. ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
  665. if (ret)
  666. break;
  667. if ((reg & 0x1) == 0) {
  668. ac_update_fw_ac_pkt_info(wilc, reg);
  669. break;
  670. }
  671. counter++;
  672. if (counter > 200) {
  673. counter = 0;
  674. ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
  675. break;
  676. }
  677. } while (!wilc->quit);
  678. if (ret)
  679. goto out_release_bus;
  680. timeout = 200;
  681. do {
  682. ret = func->hif_block_tx(wilc,
  683. WILC_VMM_TBL_RX_SHADOW_BASE,
  684. (u8 *)vmm_table,
  685. ((i + 1) * 4));
  686. if (ret)
  687. break;
  688. ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
  689. if (ret)
  690. break;
  691. do {
  692. ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
  693. if (ret)
  694. break;
  695. if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
  696. entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
  697. break;
  698. }
  699. } while (--timeout);
  700. if (timeout <= 0) {
  701. ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
  702. break;
  703. }
  704. if (ret)
  705. break;
  706. if (entries == 0) {
  707. ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
  708. if (ret)
  709. break;
  710. reg &= ~BIT(0);
  711. ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
  712. }
  713. } while (0);
  714. if (ret)
  715. goto out_release_bus;
  716. if (entries == 0) {
  717. /*
  718. * No VMM space available in firmware so retry to transmit
  719. * the packet from tx queue.
  720. */
  721. ret = WILC_VMM_ENTRY_FULL_RETRY;
  722. goto out_release_bus;
  723. }
  724. release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
  725. offset = 0;
  726. i = 0;
  727. do {
  728. struct txq_entry_t *tqe;
  729. u32 header, buffer_offset;
  730. char *bssid;
  731. u8 mgmt_ptk = 0;
  732. if (vmm_table[i] == 0 || vmm_entries_ac[i] >= NQUEUES)
  733. break;
  734. tqe = wilc_wlan_txq_remove_from_head(wilc, vmm_entries_ac[i]);
  735. if (!tqe)
  736. break;
  737. ac_pkt_num_to_chip[vmm_entries_ac[i]]++;
  738. vif = tqe->vif;
  739. le32_to_cpus(&vmm_table[i]);
  740. vmm_sz = FIELD_GET(WILC_VMM_BUFFER_SIZE, vmm_table[i]);
  741. vmm_sz *= 4;
  742. if (tqe->type == WILC_MGMT_PKT)
  743. mgmt_ptk = 1;
  744. header = (FIELD_PREP(WILC_VMM_HDR_TYPE, tqe->type) |
  745. FIELD_PREP(WILC_VMM_HDR_MGMT_FIELD, mgmt_ptk) |
  746. FIELD_PREP(WILC_VMM_HDR_PKT_SIZE, tqe->buffer_size) |
  747. FIELD_PREP(WILC_VMM_HDR_BUFF_SIZE, vmm_sz));
  748. cpu_to_le32s(&header);
  749. memcpy(&txb[offset], &header, 4);
  750. if (tqe->type == WILC_CFG_PKT) {
  751. buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
  752. } else if (tqe->type == WILC_NET_PKT) {
  753. int prio = tqe->q_num;
  754. bssid = tqe->vif->bssid;
  755. buffer_offset = ETH_ETHERNET_HDR_OFFSET;
  756. memcpy(&txb[offset + 4], &prio, sizeof(prio));
  757. memcpy(&txb[offset + 8], bssid, 6);
  758. } else {
  759. buffer_offset = HOST_HDR_OFFSET;
  760. }
  761. memcpy(&txb[offset + buffer_offset],
  762. tqe->buffer, tqe->buffer_size);
  763. offset += vmm_sz;
  764. i++;
  765. tqe->status = 1;
  766. if (tqe->tx_complete_func)
  767. tqe->tx_complete_func(tqe->priv, tqe->status);
  768. if (tqe->ack_idx != NOT_TCP_ACK &&
  769. tqe->ack_idx < MAX_PENDING_ACKS)
  770. vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL;
  771. kfree(tqe);
  772. } while (--entries);
  773. for (i = 0; i < NQUEUES; i++)
  774. wilc->txq[i].fw.count += ac_pkt_num_to_chip[i];
  775. acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
  776. ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
  777. if (ret)
  778. goto out_release_bus;
  779. ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
  780. out_release_bus:
  781. release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
  782. out_unlock:
  783. mutex_unlock(&wilc->txq_add_to_head_cs);
  784. out_update_cnt:
  785. *txq_count = wilc->txq_entries;
  786. return ret;
  787. }
  788. static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size)
  789. {
  790. int offset = 0;
  791. u32 header;
  792. u32 pkt_len, pkt_offset, tp_len;
  793. int is_cfg_packet;
  794. u8 *buff_ptr;
  795. do {
  796. buff_ptr = buffer + offset;
  797. header = get_unaligned_le32(buff_ptr);
  798. is_cfg_packet = FIELD_GET(WILC_PKT_HDR_CONFIG_FIELD, header);
  799. pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
  800. tp_len = FIELD_GET(WILC_PKT_HDR_TOTAL_LEN_FIELD, header);
  801. pkt_len = FIELD_GET(WILC_PKT_HDR_LEN_FIELD, header);
  802. if (pkt_len == 0 || tp_len == 0)
  803. break;
  804. if (pkt_offset & IS_MANAGMEMENT) {
  805. buff_ptr += HOST_HDR_OFFSET;
  806. wilc_wfi_mgmt_rx(wilc, buff_ptr, pkt_len,
  807. pkt_offset & IS_MGMT_AUTH_PKT);
  808. } else {
  809. if (!is_cfg_packet) {
  810. wilc_frmw_to_host(wilc, buff_ptr, pkt_len,
  811. pkt_offset);
  812. } else {
  813. struct wilc_cfg_rsp rsp;
  814. buff_ptr += pkt_offset;
  815. wilc_wlan_cfg_indicate_rx(wilc, buff_ptr,
  816. pkt_len,
  817. &rsp);
  818. if (rsp.type == WILC_CFG_RSP) {
  819. if (wilc->cfg_seq_no == rsp.seq_no)
  820. complete(&wilc->cfg_event);
  821. } else if (rsp.type == WILC_CFG_RSP_STATUS) {
  822. wilc_mac_indicate(wilc);
  823. }
  824. }
  825. }
  826. offset += tp_len;
  827. } while (offset < size);
  828. }
  829. static void wilc_wlan_handle_rxq(struct wilc *wilc)
  830. {
  831. int size;
  832. u8 *buffer;
  833. struct rxq_entry_t *rqe;
  834. while (!wilc->quit) {
  835. rqe = wilc_wlan_rxq_remove(wilc);
  836. if (!rqe)
  837. break;
  838. buffer = rqe->buffer;
  839. size = rqe->buffer_size;
  840. wilc_wlan_handle_rx_buff(wilc, buffer, size);
  841. kfree(rqe);
  842. }
  843. if (wilc->quit)
  844. complete(&wilc->cfg_event);
  845. }
  846. static void wilc_unknown_isr_ext(struct wilc *wilc)
  847. {
  848. wilc->hif_func->hif_clear_int_ext(wilc, 0);
  849. }
  850. static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
  851. {
  852. u32 offset = wilc->rx_buffer_offset;
  853. u8 *buffer = NULL;
  854. u32 size;
  855. u32 retries = 0;
  856. int ret = 0;
  857. struct rxq_entry_t *rqe;
  858. size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, int_status) << 2;
  859. while (!size && retries < 10) {
  860. wilc->hif_func->hif_read_size(wilc, &size);
  861. size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, size) << 2;
  862. retries++;
  863. }
  864. if (size <= 0)
  865. return;
  866. if (WILC_RX_BUFF_SIZE - offset < size)
  867. offset = 0;
  868. buffer = &wilc->rx_buffer[offset];
  869. wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM);
  870. ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
  871. if (ret)
  872. return;
  873. offset += size;
  874. wilc->rx_buffer_offset = offset;
  875. rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
  876. if (!rqe)
  877. return;
  878. rqe->buffer = buffer;
  879. rqe->buffer_size = size;
  880. wilc_wlan_rxq_add(wilc, rqe);
  881. wilc_wlan_handle_rxq(wilc);
  882. }
  883. void wilc_handle_isr(struct wilc *wilc)
  884. {
  885. u32 int_status;
  886. acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
  887. wilc->hif_func->hif_read_int(wilc, &int_status);
  888. if (int_status & DATA_INT_EXT)
  889. wilc_wlan_handle_isr_ext(wilc, int_status);
  890. if (!(int_status & (ALL_INT_EXT)))
  891. wilc_unknown_isr_ext(wilc);
  892. release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
  893. }
  894. EXPORT_SYMBOL_GPL(wilc_handle_isr);
  895. int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
  896. u32 buffer_size)
  897. {
  898. u32 offset;
  899. u32 addr, size, size2, blksz;
  900. u8 *dma_buffer;
  901. int ret = 0;
  902. u32 reg = 0;
  903. blksz = BIT(12);
  904. dma_buffer = kmalloc(blksz, GFP_KERNEL);
  905. if (!dma_buffer)
  906. return -EIO;
  907. offset = 0;
  908. pr_debug("%s: Downloading firmware size = %d\n", __func__, buffer_size);
  909. acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
  910. wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
  911. reg &= ~BIT(10);
  912. ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
  913. wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
  914. if (reg & BIT(10))
  915. pr_err("%s: Failed to reset\n", __func__);
  916. release_bus(wilc, WILC_BUS_RELEASE_ONLY);
  917. do {
  918. addr = get_unaligned_le32(&buffer[offset]);
  919. size = get_unaligned_le32(&buffer[offset + 4]);
  920. acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
  921. offset += 8;
  922. while (((int)size) && (offset < buffer_size)) {
  923. if (size <= blksz)
  924. size2 = size;
  925. else
  926. size2 = blksz;
  927. memcpy(dma_buffer, &buffer[offset], size2);
  928. ret = wilc->hif_func->hif_block_tx(wilc, addr,
  929. dma_buffer, size2);
  930. if (ret)
  931. break;
  932. addr += size2;
  933. offset += size2;
  934. size -= size2;
  935. }
  936. release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
  937. if (ret) {
  938. pr_err("%s Bus error\n", __func__);
  939. goto fail;
  940. }
  941. pr_debug("%s Offset = %d\n", __func__, offset);
  942. } while (offset < buffer_size);
  943. fail:
  944. kfree(dma_buffer);
  945. return ret;
  946. }
  947. int wilc_wlan_start(struct wilc *wilc)
  948. {
  949. u32 reg = 0;
  950. int ret;
  951. u32 chipid;
  952. if (wilc->io_type == WILC_HIF_SDIO) {
  953. reg = 0;
  954. reg |= BIT(3);
  955. } else if (wilc->io_type == WILC_HIF_SPI) {
  956. reg = 1;
  957. }
  958. acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
  959. ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
  960. if (ret)
  961. goto release;
  962. reg = 0;
  963. if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
  964. reg |= WILC_HAVE_SDIO_IRQ_GPIO;
  965. ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
  966. if (ret)
  967. goto release;
  968. wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
  969. ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
  970. if (ret)
  971. goto release;
  972. wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
  973. if ((reg & BIT(10)) == BIT(10)) {
  974. reg &= ~BIT(10);
  975. wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
  976. wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
  977. }
  978. reg |= BIT(10);
  979. ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
  980. wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
  981. release:
  982. release_bus(wilc, WILC_BUS_RELEASE_ONLY);
  983. return ret;
  984. }
  985. int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
  986. {
  987. u32 reg = 0;
  988. int ret;
  989. acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
  990. ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, &reg);
  991. if (ret) {
  992. netdev_err(vif->ndev, "Error while reading reg\n");
  993. goto release;
  994. }
  995. ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
  996. (reg | WILC_ABORT_REQ_BIT));
  997. if (ret) {
  998. netdev_err(vif->ndev, "Error while writing reg\n");
  999. goto release;
  1000. }
  1001. ret = wilc->hif_func->hif_read_reg(wilc, WILC_FW_HOST_COMM, &reg);
  1002. if (ret) {
  1003. netdev_err(vif->ndev, "Error while reading reg\n");
  1004. goto release;
  1005. }
  1006. reg = BIT(0);
  1007. ret = wilc->hif_func->hif_write_reg(wilc, WILC_FW_HOST_COMM, reg);
  1008. if (ret) {
  1009. netdev_err(vif->ndev, "Error while writing reg\n");
  1010. goto release;
  1011. }
  1012. ret = 0;
  1013. release:
  1014. /* host comm is disabled - we can't issue sleep command anymore: */
  1015. release_bus(wilc, WILC_BUS_RELEASE_ONLY);
  1016. return ret;
  1017. }
  1018. void wilc_wlan_cleanup(struct net_device *dev)
  1019. {
  1020. struct txq_entry_t *tqe;
  1021. struct rxq_entry_t *rqe;
  1022. u8 ac;
  1023. struct wilc_vif *vif = netdev_priv(dev);
  1024. struct wilc *wilc = vif->wilc;
  1025. wilc->quit = 1;
  1026. for (ac = 0; ac < NQUEUES; ac++) {
  1027. while ((tqe = wilc_wlan_txq_remove_from_head(wilc, ac))) {
  1028. if (tqe->tx_complete_func)
  1029. tqe->tx_complete_func(tqe->priv, 0);
  1030. kfree(tqe);
  1031. }
  1032. }
  1033. while ((rqe = wilc_wlan_rxq_remove(wilc)))
  1034. kfree(rqe);
  1035. kfree(wilc->vmm_table);
  1036. wilc->vmm_table = NULL;
  1037. kfree(wilc->rx_buffer);
  1038. wilc->rx_buffer = NULL;
  1039. kfree(wilc->tx_buffer);
  1040. wilc->tx_buffer = NULL;
  1041. wilc->hif_func->hif_deinit(wilc);
  1042. }
  1043. static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type,
  1044. u32 drv_handler)
  1045. {
  1046. struct wilc *wilc = vif->wilc;
  1047. struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
  1048. int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr);
  1049. if (type == WILC_CFG_SET)
  1050. cfg->hdr.cmd_type = 'W';
  1051. else
  1052. cfg->hdr.cmd_type = 'Q';
  1053. cfg->hdr.seq_no = wilc->cfg_seq_no % 256;
  1054. cfg->hdr.total_len = cpu_to_le16(t_len);
  1055. cfg->hdr.driver_handler = cpu_to_le32(drv_handler);
  1056. wilc->cfg_seq_no = cfg->hdr.seq_no;
  1057. if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len))
  1058. return -1;
  1059. return 0;
  1060. }
  1061. int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
  1062. u32 buffer_size, int commit, u32 drv_handler)
  1063. {
  1064. u32 offset;
  1065. int ret_size;
  1066. struct wilc *wilc = vif->wilc;
  1067. mutex_lock(&wilc->cfg_cmd_lock);
  1068. if (start)
  1069. wilc->cfg_frame_offset = 0;
  1070. offset = wilc->cfg_frame_offset;
  1071. ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
  1072. wid, buffer, buffer_size);
  1073. offset += ret_size;
  1074. wilc->cfg_frame_offset = offset;
  1075. if (!commit) {
  1076. mutex_unlock(&wilc->cfg_cmd_lock);
  1077. return ret_size;
  1078. }
  1079. netdev_dbg(vif->ndev, "%s: seqno[%d]\n", __func__, wilc->cfg_seq_no);
  1080. if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
  1081. ret_size = 0;
  1082. if (!wait_for_completion_timeout(&wilc->cfg_event,
  1083. WILC_CFG_PKTS_TIMEOUT)) {
  1084. netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
  1085. ret_size = 0;
  1086. }
  1087. wilc->cfg_frame_offset = 0;
  1088. wilc->cfg_seq_no += 1;
  1089. mutex_unlock(&wilc->cfg_cmd_lock);
  1090. return ret_size;
  1091. }
  1092. int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
  1093. u32 drv_handler)
  1094. {
  1095. u32 offset;
  1096. int ret_size;
  1097. struct wilc *wilc = vif->wilc;
  1098. mutex_lock(&wilc->cfg_cmd_lock);
  1099. if (start)
  1100. wilc->cfg_frame_offset = 0;
  1101. offset = wilc->cfg_frame_offset;
  1102. ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid);
  1103. offset += ret_size;
  1104. wilc->cfg_frame_offset = offset;
  1105. if (!commit) {
  1106. mutex_unlock(&wilc->cfg_cmd_lock);
  1107. return ret_size;
  1108. }
  1109. if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
  1110. ret_size = 0;
  1111. if (!wait_for_completion_timeout(&wilc->cfg_event,
  1112. WILC_CFG_PKTS_TIMEOUT)) {
  1113. netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
  1114. ret_size = 0;
  1115. }
  1116. wilc->cfg_frame_offset = 0;
  1117. wilc->cfg_seq_no += 1;
  1118. mutex_unlock(&wilc->cfg_cmd_lock);
  1119. return ret_size;
  1120. }
  1121. int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
  1122. u32 count)
  1123. {
  1124. int i;
  1125. int ret = 0;
  1126. u32 drv = wilc_get_vif_idx(vif);
  1127. if (mode == WILC_GET_CFG) {
  1128. for (i = 0; i < count; i++) {
  1129. if (!wilc_wlan_cfg_get(vif, !i,
  1130. wids[i].id,
  1131. (i == count - 1),
  1132. drv)) {
  1133. ret = -ETIMEDOUT;
  1134. break;
  1135. }
  1136. }
  1137. for (i = 0; i < count; i++) {
  1138. wids[i].size = wilc_wlan_cfg_get_val(vif->wilc,
  1139. wids[i].id,
  1140. wids[i].val,
  1141. wids[i].size);
  1142. }
  1143. } else if (mode == WILC_SET_CFG) {
  1144. for (i = 0; i < count; i++) {
  1145. if (!wilc_wlan_cfg_set(vif, !i,
  1146. wids[i].id,
  1147. wids[i].val,
  1148. wids[i].size,
  1149. (i == count - 1),
  1150. drv)) {
  1151. ret = -ETIMEDOUT;
  1152. break;
  1153. }
  1154. }
  1155. }
  1156. return ret;
  1157. }
  1158. static int init_chip(struct net_device *dev)
  1159. {
  1160. u32 chipid;
  1161. u32 reg;
  1162. int ret = 0;
  1163. struct wilc_vif *vif = netdev_priv(dev);
  1164. struct wilc *wilc = vif->wilc;
  1165. acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
  1166. chipid = wilc_get_chipid(wilc, true);
  1167. if ((chipid & 0xfff) != 0xa0) {
  1168. ret = wilc->hif_func->hif_read_reg(wilc,
  1169. WILC_CORTUS_RESET_MUX_SEL,
  1170. &reg);
  1171. if (ret) {
  1172. netdev_err(dev, "fail read reg 0x1118\n");
  1173. goto release;
  1174. }
  1175. reg |= BIT(0);
  1176. ret = wilc->hif_func->hif_write_reg(wilc,
  1177. WILC_CORTUS_RESET_MUX_SEL,
  1178. reg);
  1179. if (ret) {
  1180. netdev_err(dev, "fail write reg 0x1118\n");
  1181. goto release;
  1182. }
  1183. ret = wilc->hif_func->hif_write_reg(wilc,
  1184. WILC_CORTUS_BOOT_REGISTER,
  1185. WILC_CORTUS_BOOT_FROM_IRAM);
  1186. if (ret) {
  1187. netdev_err(dev, "fail write reg 0xc0000\n");
  1188. goto release;
  1189. }
  1190. }
  1191. release:
  1192. release_bus(wilc, WILC_BUS_RELEASE_ONLY);
  1193. return ret;
  1194. }
  1195. u32 wilc_get_chipid(struct wilc *wilc, bool update)
  1196. {
  1197. u32 chipid = 0;
  1198. u32 rfrevid = 0;
  1199. if (wilc->chipid == 0 || update) {
  1200. wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
  1201. wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
  1202. &rfrevid);
  1203. if (!is_wilc1000(chipid)) {
  1204. wilc->chipid = 0;
  1205. return wilc->chipid;
  1206. }
  1207. if (chipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
  1208. if (rfrevid != 0x1)
  1209. chipid = WILC_1000_BASE_ID_2A_REV1;
  1210. } else if (chipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
  1211. if (rfrevid == 0x4)
  1212. chipid = WILC_1000_BASE_ID_2B_REV1;
  1213. else if (rfrevid != 0x3)
  1214. chipid = WILC_1000_BASE_ID_2B_REV2;
  1215. }
  1216. wilc->chipid = chipid;
  1217. }
  1218. return wilc->chipid;
  1219. }
  1220. int wilc_wlan_init(struct net_device *dev)
  1221. {
  1222. int ret = 0;
  1223. struct wilc_vif *vif = netdev_priv(dev);
  1224. struct wilc *wilc;
  1225. wilc = vif->wilc;
  1226. wilc->quit = 0;
  1227. if (!wilc->hif_func->hif_is_init(wilc)) {
  1228. acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
  1229. ret = wilc->hif_func->hif_init(wilc, false);
  1230. release_bus(wilc, WILC_BUS_RELEASE_ONLY);
  1231. if (ret)
  1232. goto fail;
  1233. }
  1234. if (!wilc->vmm_table)
  1235. wilc->vmm_table = kcalloc(WILC_VMM_TBL_SIZE, sizeof(u32), GFP_KERNEL);
  1236. if (!wilc->vmm_table) {
  1237. ret = -ENOBUFS;
  1238. goto fail;
  1239. }
  1240. if (!wilc->tx_buffer)
  1241. wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL);
  1242. if (!wilc->tx_buffer) {
  1243. ret = -ENOBUFS;
  1244. goto fail;
  1245. }
  1246. if (!wilc->rx_buffer)
  1247. wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL);
  1248. if (!wilc->rx_buffer) {
  1249. ret = -ENOBUFS;
  1250. goto fail;
  1251. }
  1252. if (init_chip(dev)) {
  1253. ret = -EIO;
  1254. goto fail;
  1255. }
  1256. return 0;
  1257. fail:
  1258. kfree(wilc->vmm_table);
  1259. wilc->vmm_table = NULL;
  1260. kfree(wilc->rx_buffer);
  1261. wilc->rx_buffer = NULL;
  1262. kfree(wilc->tx_buffer);
  1263. wilc->tx_buffer = NULL;
  1264. return ret;
  1265. }