smd.c (33ca8a53f262b4af40611bea331b8c87d133af72) smd.c (f42cf8d6a3ec934551ac0f20f4654dccb11fa30d)
1/*
2 * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES

--- 7 unchanged lines hidden (view full) ---

16
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19#include <linux/etherdevice.h>
20#include <linux/firmware.h>
21#include <linux/bitops.h>
22#include "smd.h"
23
1/*
2 * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES

--- 7 unchanged lines hidden (view full) ---

16
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19#include <linux/etherdevice.h>
20#include <linux/firmware.h>
21#include <linux/bitops.h>
22#include "smd.h"
23
24struct wcn36xx_cfg_val {
25 u32 cfg_id;
26 u32 value;
27};
28
29#define WCN36XX_CFG_VAL(id, val) \
30{ \
31 .cfg_id = WCN36XX_HAL_CFG_ ## id, \
32 .value = val \
33}
34
35static struct wcn36xx_cfg_val wcn36xx_cfg_vals[] = {
36 WCN36XX_CFG_VAL(CURRENT_TX_ANTENNA, 1),
37 WCN36XX_CFG_VAL(CURRENT_RX_ANTENNA, 1),
38 WCN36XX_CFG_VAL(LOW_GAIN_OVERRIDE, 0),
39 WCN36XX_CFG_VAL(POWER_STATE_PER_CHAIN, 785),
40 WCN36XX_CFG_VAL(CAL_PERIOD, 5),
41 WCN36XX_CFG_VAL(CAL_CONTROL, 1),
42 WCN36XX_CFG_VAL(PROXIMITY, 0),
43 WCN36XX_CFG_VAL(NETWORK_DENSITY, 3),
44 WCN36XX_CFG_VAL(MAX_MEDIUM_TIME, 6000),
45 WCN36XX_CFG_VAL(MAX_MPDUS_IN_AMPDU, 64),
46 WCN36XX_CFG_VAL(RTS_THRESHOLD, 2347),
47 WCN36XX_CFG_VAL(SHORT_RETRY_LIMIT, 6),
48 WCN36XX_CFG_VAL(LONG_RETRY_LIMIT, 6),
49 WCN36XX_CFG_VAL(FRAGMENTATION_THRESHOLD, 8000),
50 WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_ZERO, 5),
51 WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_ONE, 10),
52 WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_TWO, 15),
53 WCN36XX_CFG_VAL(FIXED_RATE, 0),
54 WCN36XX_CFG_VAL(RETRYRATE_POLICY, 4),
55 WCN36XX_CFG_VAL(RETRYRATE_SECONDARY, 0),
56 WCN36XX_CFG_VAL(RETRYRATE_TERTIARY, 0),
57 WCN36XX_CFG_VAL(FORCE_POLICY_PROTECTION, 5),
58 WCN36XX_CFG_VAL(FIXED_RATE_MULTICAST_24GHZ, 1),
59 WCN36XX_CFG_VAL(FIXED_RATE_MULTICAST_5GHZ, 5),
60 WCN36XX_CFG_VAL(DEFAULT_RATE_INDEX_5GHZ, 5),
61 WCN36XX_CFG_VAL(MAX_BA_SESSIONS, 40),
62 WCN36XX_CFG_VAL(PS_DATA_INACTIVITY_TIMEOUT, 200),
63 WCN36XX_CFG_VAL(PS_ENABLE_BCN_FILTER, 1),
64 WCN36XX_CFG_VAL(PS_ENABLE_RSSI_MONITOR, 1),
65 WCN36XX_CFG_VAL(NUM_BEACON_PER_RSSI_AVERAGE, 20),
66 WCN36XX_CFG_VAL(STATS_PERIOD, 10),
67 WCN36XX_CFG_VAL(CFP_MAX_DURATION, 30000),
68 WCN36XX_CFG_VAL(FRAME_TRANS_ENABLED, 0),
69 WCN36XX_CFG_VAL(BA_THRESHOLD_HIGH, 128),
70 WCN36XX_CFG_VAL(MAX_BA_BUFFERS, 2560),
71 WCN36XX_CFG_VAL(DYNAMIC_PS_POLL_VALUE, 0),
72 WCN36XX_CFG_VAL(TX_PWR_CTRL_ENABLE, 1),
73 WCN36XX_CFG_VAL(ENABLE_CLOSE_LOOP, 1),
74 WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
75 WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10),
76 WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0),
77};
78
79static int put_cfg_tlv_u32(struct wcn36xx *wcn, size_t *len, u32 id, u32 value)
80{
81 struct wcn36xx_hal_cfg *entry;
82 u32 *val;
83
84 if (*len + sizeof(*entry) + sizeof(u32) >= WCN36XX_HAL_BUF_SIZE) {
85 wcn36xx_err("Not enough room for TLV entry\n");
86 return -ENOMEM;

--- 320 unchanged lines hidden (view full) ---

407 rsp->start_rsp_params.stations,
408 rsp->start_rsp_params.bssids);
409
410 return 0;
411}
412
413int wcn36xx_smd_start(struct wcn36xx *wcn)
414{
24static int put_cfg_tlv_u32(struct wcn36xx *wcn, size_t *len, u32 id, u32 value)
25{
26 struct wcn36xx_hal_cfg *entry;
27 u32 *val;
28
29 if (*len + sizeof(*entry) + sizeof(u32) >= WCN36XX_HAL_BUF_SIZE) {
30 wcn36xx_err("Not enough room for TLV entry\n");
31 return -ENOMEM;

--- 320 unchanged lines hidden (view full) ---

352 rsp->start_rsp_params.stations,
353 rsp->start_rsp_params.bssids);
354
355 return 0;
356}
357
358int wcn36xx_smd_start(struct wcn36xx *wcn)
359{
415 struct wcn36xx_hal_mac_start_req_msg msg_body, *body;
360 struct wcn36xx_hal_mac_start_req_msg msg_body;
416 int ret = 0;
361 int ret = 0;
417 int i;
418 size_t len;
419
420 mutex_lock(&wcn->hal_mutex);
421 INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_REQ);
422
423 msg_body.params.type = DRIVER_TYPE_PRODUCTION;
424 msg_body.params.len = 0;
425
426 PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
427
362
363 mutex_lock(&wcn->hal_mutex);
364 INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_REQ);
365
366 msg_body.params.type = DRIVER_TYPE_PRODUCTION;
367 msg_body.params.len = 0;
368
369 PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
370
428 body = (struct wcn36xx_hal_mac_start_req_msg *)wcn->hal_buf;
429 len = body->header.len;
430
431 for (i = 0; i < ARRAY_SIZE(wcn36xx_cfg_vals); i++) {
432 ret = put_cfg_tlv_u32(wcn, &len, wcn36xx_cfg_vals[i].cfg_id,
433 wcn36xx_cfg_vals[i].value);
434 if (ret)
435 goto out;
436 }
437 body->header.len = len;
438 body->params.len = len - sizeof(*body);
439
440 wcn36xx_dbg(WCN36XX_DBG_HAL, "hal start type %d\n",
441 msg_body.params.type);
442
371 wcn36xx_dbg(WCN36XX_DBG_HAL, "hal start type %d\n",
372 msg_body.params.type);
373
443 ret = wcn36xx_smd_send_and_wait(wcn, body->header.len);
374 ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
444 if (ret) {
445 wcn36xx_err("Sending hal_start failed\n");
446 goto out;
447 }
448
449 ret = wcn36xx_smd_start_rsp(wcn, wcn->hal_buf, wcn->hal_rsp_len);
450 if (ret) {
451 wcn36xx_err("hal_start response failed err=%d\n", ret);

--- 1244 unchanged lines hidden (view full) ---

1696
1697 if (packet_type == WCN36XX_HAL_KEEP_ALIVE_NULL_PKT) {
1698 msg_body.bss_index = vif_priv->bss_index;
1699 msg_body.packet_type = WCN36XX_HAL_KEEP_ALIVE_NULL_PKT;
1700 msg_body.time_period = WCN36XX_KEEP_ALIVE_TIME_PERIOD;
1701 } else if (packet_type == WCN36XX_HAL_KEEP_ALIVE_UNSOLICIT_ARP_RSP) {
1702 /* TODO: it also support ARP response type */
1703 } else {
375 if (ret) {
376 wcn36xx_err("Sending hal_start failed\n");
377 goto out;
378 }
379
380 ret = wcn36xx_smd_start_rsp(wcn, wcn->hal_buf, wcn->hal_rsp_len);
381 if (ret) {
382 wcn36xx_err("hal_start response failed err=%d\n", ret);

--- 1244 unchanged lines hidden (view full) ---

1627
1628 if (packet_type == WCN36XX_HAL_KEEP_ALIVE_NULL_PKT) {
1629 msg_body.bss_index = vif_priv->bss_index;
1630 msg_body.packet_type = WCN36XX_HAL_KEEP_ALIVE_NULL_PKT;
1631 msg_body.time_period = WCN36XX_KEEP_ALIVE_TIME_PERIOD;
1632 } else if (packet_type == WCN36XX_HAL_KEEP_ALIVE_UNSOLICIT_ARP_RSP) {
1633 /* TODO: it also support ARP response type */
1634 } else {
1704 wcn36xx_warn("unknow keep alive packet type %d\n", packet_type);
1635 wcn36xx_warn("unknown keep alive packet type %d\n", packet_type);
1705 ret = -EINVAL;
1706 goto out;
1707 }
1708
1709 PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
1710
1711 ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
1712 if (ret) {

--- 523 unchanged lines hidden ---
1636 ret = -EINVAL;
1637 goto out;
1638 }
1639
1640 PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
1641
1642 ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
1643 if (ret) {

--- 523 unchanged lines hidden ---