iwinfo: bump version

This commit is contained in:
coolsnowwolf 2021-07-30 15:13:53 +08:00
parent 1214d8dc98
commit 8c55064b3a
68 changed files with 103878 additions and 2 deletions

View File

@ -24,8 +24,11 @@ PKG_CONFIG_DEPENDS := \
CONFIG_PACKAGE_kmod-brcm-wl-mini \ CONFIG_PACKAGE_kmod-brcm-wl-mini \
CONFIG_PACKAGE_kmod-brcm-wl-mimo \ CONFIG_PACKAGE_kmod-brcm-wl-mimo \
CONFIG_PACKAGE_kmod-mt7615d_dbdc \ CONFIG_PACKAGE_kmod-mt7615d_dbdc \
CONFIG_PACKAGE_kmod-qtn-pcie2 \
CONFIG_PACKAGE_kmod-cfg80211 CONFIG_PACKAGE_kmod-cfg80211
PKG_BUILD_DEPENDS:=libtirpc
IWINFO_ABI_VERSION:=20210430 IWINFO_ABI_VERSION:=20210430
include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package.mk
@ -35,7 +38,7 @@ define Package/libiwinfo
SECTION:=libs SECTION:=libs
CATEGORY:=Libraries CATEGORY:=Libraries
TITLE:=Generalized Wireless Information Library (iwinfo) TITLE:=Generalized Wireless Information Library (iwinfo)
DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny +libuci +libubus DEPENDS:=+PACKAGE_kmod-cfg80211:libnl-tiny +libuci +libubus +PACKAGE_kmod-qtn-pcie2:libtirpc
ABI_VERSION:=$(IWINFO_ABI_VERSION) ABI_VERSION:=$(IWINFO_ABI_VERSION)
endef endef
@ -72,6 +75,7 @@ endef
define Build/Configure define Build/Configure
$(CP) ./files/* $(PKG_BUILD_DIR)
endef endef
IWINFO_BACKENDS := \ IWINFO_BACKENDS := \
@ -79,11 +83,13 @@ IWINFO_BACKENDS := \
$(if $(CONFIG_PACKAGE_kmod-brcm-wl-mini),wl) \ $(if $(CONFIG_PACKAGE_kmod-brcm-wl-mini),wl) \
$(if $(CONFIG_PACKAGE_kmod-brcm-wl-mimo),wl) \ $(if $(CONFIG_PACKAGE_kmod-brcm-wl-mimo),wl) \
$(if $(CONFIG_PACKAGE_kmod-mt7615d_dbdc),ra) \ $(if $(CONFIG_PACKAGE_kmod-mt7615d_dbdc),ra) \
$(if $(CONFIG_PACKAGE_kmod-qtn-pcie2),qtnawifi) \
$(if $(CONFIG_PACKAGE_kmod-cfg80211),nl80211) $(if $(CONFIG_PACKAGE_kmod-cfg80211),nl80211)
TARGET_CFLAGS += \ TARGET_CFLAGS += \
-I$(STAGING_DIR)/usr/include/libnl-tiny \ -I$(STAGING_DIR)/usr/include/libnl-tiny \
-I$(STAGING_DIR)/usr/include \ -I$(STAGING_DIR)/usr/include \
-I$(STAGING_DIR)/usr/include/tirpc \
-D_GNU_SOURCE -D_GNU_SOURCE
MAKE_FLAGS += \ MAKE_FLAGS += \

View File

@ -0,0 +1,774 @@
#include <fcntl.h>
#include <endian.h>
#if __BYTE_ORDER == __BIG_ENDIAN
#define _BYTE_ORDER _BIG_ENDIAN
#elif __BYTE_ORDER == __LITTLE_ENDIAN
#define _BYTE_ORDER _LITTLE_ENDIAN
#else
#error "__BYTE_ORDER undefined"
#endif
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "qcsapi_output.h"
#include "./libqcsapi_client/qcsapi_rpc_common/client/find_host_addr.h"
#include "qcsapi.h"
#include "./libqcsapi_client/qcsapi_rpc/client/qcsapi_rpc_client.h"
#include "./libqcsapi_client/qcsapi_rpc/generated/qcsapi_rpc.h"
#include "./libqcsapi_client/qcsapi_rpc_common/common/rpc_pci.h"
#include "qcsapi_driver.h"
#include "call_qcsapi.h"
#include "iwinfo.h"
#include "iwinfo/utils.h"
#define MAX_RETRY_TIMES 5
#define WIFINAME "wifi0"
enum qtnawifi_client {
QTNAWIFI_USE_TCP_CLIENT = 0,
QTNAWIFI_USE_UDP_CLIENT,
QTNAWIFI_USE_PCIE_CLIENT,
QTNAWIFI_UNKNOW_CLIENT
};
static int qtnawifi_use_client = QTNAWIFI_USE_TCP_CLIENT;
static CLIENT *clnt;
int qtnawifi_get_pcie_client(void)
{
int retry = 0;
char *host;
host = "localhost";
while (retry++ < MAX_RETRY_TIMES) {
clnt = clnt_pci_create(host, QCSAPI_PROG, QCSAPI_VERS, NULL);
if (clnt == NULL) {
clnt_pcreateerror(host);
sleep(1);
continue;
} else
client_qcsapi_set_rpcclient(clnt);
}
/* could not find host or create a client, exit */
if (retry >= MAX_RETRY_TIMES)
return -1;
return 0;
}
int qtnawifi_get_rpc_client(void)
{
int retry = 0;
const char *host="1.1.1.2";
/* setup RPC based on udp protocol */
while (retry++ < MAX_RETRY_TIMES) {
if (qtnawifi_use_client == QTNAWIFI_USE_TCP_CLIENT ) {
clnt = clnt_create(host, QCSAPI_PROG, QCSAPI_VERS, "tcp");
} else {
clnt = clnt_create(host, QCSAPI_PROG, QCSAPI_VERS, "udp");
}
if (clnt == NULL) {
clnt_pcreateerror(host);
sleep(1);
continue;
} else {
client_qcsapi_set_rpcclient(clnt);
break;
}
}
/* could not find host or create a client, exit */
if (retry >= MAX_RETRY_TIMES)
return -1;
return 0;
}
static char * qtnawifi_isvap(const char *ifname, const char *wifiname)
{
return 0;
}
#define ADDR_LEN 18
static int qtnawifi_iswifi(const char *ifname)
{
return 0;
}
static int qtnawifi_set_ipaddr(const char *ifname, const char *ip)
{
struct ifreq ifr;
struct sockaddr_in *addr;
int fd = 0;
int ret =-1;
strcpy(ifr.ifr_name, ifname);
if((fd = socket(AF_INET, SOCK_STREAM, 0))<0){
return -1;
}
addr = (struct sockaddr_in *)&(ifr.ifr_addr);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr(ip);
ret = ioctl(fd, SIOCSIFADDR, &ifr);
close(fd);
if(ret < 0)
return -1;
return 0;
}
static int qtnawifi_host_detect(const char *ifname)
{
int skfd = 0;
int ret = 0;
struct ifreq ifr;
if(strncmp(ifname, "host", 4) != 0)
return 0;
skfd = socket(AF_INET, SOCK_DGRAM, 0);
if(skfd < 0)
goto err;
strcpy(ifr.ifr_name, ifname);
if(ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0 )
goto err;
if(ifr.ifr_flags & IFF_UP) {
ret = 1;
goto err;
}
err:
close(skfd);
return ret;
}
int qtnawifi_probe(const char *ifname)
{
int ret;
if(qtnawifi_host_detect(ifname))
{
/* FIXME: unknow error if use PCIE */
if(qtnawifi_use_client == QTNAWIFI_USE_PCIE_CLIENT) {
ret = qtnawifi_get_pcie_client();
} else {
ret = qtnawifi_get_rpc_client();
}
if(!ret)
return 1;
}
return 0;
}
void qtnawifi_close(void)
{
if(clnt)
clnt_destroy(clnt);
clnt = NULL;
/* Nop */
}
int qtnawifi_get_mode(const char *ifname, int *buf)
{
int ret;
qcsapi_wifi_mode current_wifi_mode;
ret = qcsapi_wifi_get_mode(WIFINAME, &current_wifi_mode);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_mode error, return: %d\n", ret);
return -1;
}
switch (current_wifi_mode)
{
case qcsapi_mode_not_defined:
*buf = IWINFO_OPMODE_UNKNOWN;
break;
case qcsapi_access_point:
*buf = IWINFO_OPMODE_MASTER;
break;
case qcsapi_station:
*buf = IWINFO_OPMODE_CLIENT;
break;
case qcsapi_nosuch_mode:
default:
*buf = IWINFO_OPMODE_UNKNOWN;
break;
}
/* Current support AP Mode only */
// *buf = IWINFO_OPMODE_WDS;
// *buf = IWINFO_OPMODE_UNKNOWN;
return 0;
}
int qtnawifi_get_ssid(const char *ifname, char *buf)
{
int ret;
ret = qcsapi_wifi_get_SSID(WIFINAME, (qcsapi_SSID *)buf);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_SSID error, return: %d\n", ret);
return -1;
}
return 0;
}
int qtnawifi_get_bssid(const char *ifname, char *buf)
{
int ret;
uint8_t bssid[MAC_ADDR_SIZE];
ret = qcsapi_wifi_get_BSSID(WIFINAME, (qcsapi_mac_addr *)bssid);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_SSID error, return: %d\n", ret);
return -1;
}
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
(uint8_t)bssid[0], (uint8_t)bssid[1],
(uint8_t)bssid[2], (uint8_t)bssid[3],
(uint8_t)bssid[4], (uint8_t)bssid[5]);
return 0;
}
static int qtnawifi_freq2channel(int freq)
{
if (freq == 2484)
return 14;
else if (freq < 2484)
return (freq - 2407) / 5;
else if (freq >= 4910 && freq <= 4980)
return (freq - 4000) / 5;
else if (freq > 58319 && freq < 64801)
return (freq - 56160) / 2160;
else
return (freq - 5000) / 5;
}
static int qtnawifi_channel2freq(int channel, const char *band)
{
if (!band || band[0] != 'a')
{
if (channel == 14)
return 2484;
else if (channel < 14)
return (channel * 5) + 2407;
}
else if ((channel < 5) && (band[0] == 'a' && band[1] == 'd'))
{
return (channel * 2160) + 56160;
}
else
{
if (channel >= 182 && channel <= 196)
return (channel * 5) + 4000;
else
return (channel * 5) + 5000;
}
return 0;
}
int qtnawifi_get_channel(const char *ifname, int *buf)
{
int ret;
if(!qtnawifi_host_detect(ifname))
return -1;
ret = qcsapi_wifi_get_channel(WIFINAME, (qcsapi_unsigned_int *)buf);
if (ret < 0) {
printf("Qcsapi qtnawifi_get_channel error, return: %d\n", ret);
return -1;
}
return 0;
}
int qtnawifi_get_frequency(const char *ifname, int *buf)
{
int ret;
unsigned int channel;
char *hwmode="ac";
if(!qtnawifi_host_detect(ifname))
return -1;
ret = qcsapi_wifi_get_channel(WIFINAME, (qcsapi_unsigned_int *)&channel);
if (ret < 0) {
printf("Qcsapi qtnawifi_get_channel error, return: %d\n", ret);
return -1;
}
*buf = qtnawifi_channel2freq(channel, hwmode);
return 0;
}
int qtnawifi_get_txpower(const char *ifname, int *buf)
{
int ret;
int txpower;
if(!qtnawifi_host_detect(ifname))
return -1;
unsigned int channel=149; /* use default channel 149 */
ret = qcsapi_wifi_get_tx_power(WIFINAME, channel, &txpower);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_tx_power error, return: %d\n", ret);
return -1;
}
*buf = txpower;
return 0;
}
int qtnawifi_get_bitrate(const char *ifname, int *buf)
{
*buf= 1733 * 1000;
return 0;
}
int qtnawifi_get_signal(const char *ifname, int *buf)
{
int ret;
int rssi;
if(!qtnawifi_host_detect(ifname))
return -1;
ret = qcsapi_wifi_get_rssi_by_chain(WIFINAME, 0, &rssi);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_rssi_by_chain error, return: %d\n", ret);
return -1;
}
*buf = rssi;
return 0;
}
int qtnawifi_get_noise(const char *ifname, int *buf)
{
int ret;
int noise;
if(!qtnawifi_host_detect(ifname))
return -1;
ret = qcsapi_wifi_get_noise(WIFINAME, &noise);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_noise error, return: %d\n", ret);
return -1;
}
*buf = noise;
return 0;
}
int qtnawifi_get_quality(const char *ifname, int *buf)
{
*buf = 90;
return 0;
}
int qtnawifi_get_quality_max(const char *ifname, int *buf)
{
*buf = 100;
return 0;
}
int qtnawifi_get_encryption(const char *ifname, char *buf)
{
int ret;
uint32_t wsec, wauth, wpa;
char beacon_type[16];
char encryption_modes[36];
char authentication_mode[36];
struct iwinfo_crypto_entry *c = (struct iwinfo_crypto_entry *)buf;
if(!qtnawifi_host_detect(ifname))
return -1;
ret = qcsapi_wifi_get_beacon_type(WIFINAME, &beacon_type[0]);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_beacon_type error, return: %d\n", ret);
return -1;
}
ret = qcsapi_wifi_get_WPA_encryption_modes(WIFINAME, &encryption_modes[0]);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_WPA_encryption_modes error, return: %d\n", ret);
return -1;
}
ret = qcsapi_wifi_get_IEEE11i_authentication_mode(WIFINAME, &authentication_mode[0]);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_WPA_encryption_modes error, return: %d\n", ret);
return -1;
}
c->enabled = 0;
c->wpa_version = 0;
if(strstr(beacon_type, "Basic"))
{
c->auth_algs |= IWINFO_AUTH_OPEN;
c->auth_suites |= IWINFO_KMGMT_NONE;
}
if(strstr(beacon_type, "WPA") ) {
c->enabled = 1;
c->wpa_version |= 0x1;
}
if(strstr(beacon_type, "11i") ) {
c->enabled = 1;
c->wpa_version |= 0x2;
}
if(strstr(encryption_modes, "AESEncryption") ) {
c->pair_ciphers |= IWINFO_CIPHER_CCMP;
}
if(strstr(encryption_modes, "TKIPEncryption") ) {
c->pair_ciphers |= IWINFO_CIPHER_TKIP;
}
c -> group_ciphers = c -> pair_ciphers;
if(strstr(authentication_mode, "PSKAuthentication") ) {
c->auth_suites |= IWINFO_KMGMT_PSK;
}
if(strstr(authentication_mode, "EAPAuthentication") ) {
c->auth_suites |= IWINFO_KMGMT_8021x;
}
return 0;
}
int qtnawifi_get_phyname(const char *ifname, char *buf)
{
if((strncmp(ifname,"host",4) == 0))
strcpy(buf, ifname);
return 0;
}
#define IP_ADDR_STR_LEN 16
int qtnawifi_rssi2signal(int signal)
{
if (signal < -110)
signal = -110;
else if (signal > -40)
signal = -40;
return (signal + 110);
}
int qtnawifi_get_assoclist(const char *ifname, char *buf, int *len)
{
int ret;
int i;
int bl = 0;
unsigned int association_count = 0;
uint8_t mac_addr[ETHER_ADDR_LEN];
char ip_addr[IP_ADDR_STR_LEN + 1];
unsigned int link_quality;
int rssi,noise;
u_int64_t rx_bytes, tx_bytes;
u_int32_t rx_packets, tx_packets;
unsigned int bw;
unsigned int tx_rate, rx_rate;
unsigned int tx_mcs, rx_mcs;
unsigned int time_associated = 0;
if(!qtnawifi_host_detect(ifname))
return -1;
ret = qcsapi_wifi_get_count_associations(WIFINAME, &association_count);
if (ret < 0) {
return -1;
}
if(association_count < 0 || association_count > 256)
return -1;
for(i = 0; i < association_count; i++) {
int association_index = i;
struct iwinfo_assoclist_entry entry;
memset(&entry, 0, sizeof(entry));
ret = qcsapi_wifi_get_associated_device_mac_addr(WIFINAME, association_index, mac_addr);
//ret = qcsapi_wifi_get_associated_device_ip_addr(WIFINAME, association_index, ip_addr);
ret = qcsapi_wifi_get_link_quality(WIFINAME, association_index, &link_quality);
ret = qcsapi_wifi_get_rssi_in_dbm_per_association(WIFINAME, association_index, &rssi);
ret = qcsapi_wifi_get_hw_noise_per_association(WIFINAME, association_index, &noise);
ret = qcsapi_wifi_get_rx_bytes_per_association(WIFINAME, association_index, &rx_bytes);
ret = qcsapi_wifi_get_tx_bytes_per_association(WIFINAME, association_index, &tx_bytes);
ret = qcsapi_wifi_get_rx_packets_per_association(WIFINAME, association_index, &rx_packets);
ret = qcsapi_wifi_get_tx_packets_per_association(WIFINAME, association_index, &tx_packets);
ret = qcsapi_wifi_get_bw_per_association(WIFINAME, association_index, &bw);
ret = qcsapi_wifi_get_tx_phy_rate_per_association(WIFINAME, association_index, &tx_rate);
ret = qcsapi_wifi_get_rx_phy_rate_per_association(WIFINAME, association_index, &rx_rate);
ret = qcsapi_wifi_get_tx_mcs_per_association(WIFINAME,association_index, &tx_mcs);
ret = qcsapi_wifi_get_rx_mcs_per_association(WIFINAME,association_index, &rx_mcs);
ret = qcsapi_wifi_get_time_associated_per_association(WIFINAME, association_index, &time_associated);
entry.signal = rssi;
entry.noise = noise;
entry.inactive = time_associated * 1000;
memcpy(&entry.mac, mac_addr, sizeof(entry.mac));
entry.tx_packets = tx_packets;
entry.rx_packets = rx_packets;
entry.rx_bytes = rx_packets;
entry.tx_bytes = tx_packets;
entry.tx_retries = 0;
if(bw <= 40)
entry.tx_rate.is_40mhz = 1;
if(bw > 40)
entry.tx_rate.is_vht = 1;
entry.tx_rate.rate = tx_rate * 1000;
entry.tx_rate.mcs = tx_mcs;
entry.tx_rate.mhz = bw;
entry.tx_rate.nss = 0;
entry.tx_rate.is_short_gi = 0;
if(bw <= 40)
entry.rx_rate.is_40mhz = 1;
if(bw > 40)
entry.rx_rate.is_vht = 1;
entry.rx_rate.rate = rx_rate * 1000;
entry.rx_rate.mcs = rx_mcs;
entry.rx_rate.mhz = bw;
entry.rx_rate.nss = 0;
entry.rx_rate.is_short_gi = 0;
memcpy(&buf[bl], &entry, sizeof(struct iwinfo_assoclist_entry));
bl += sizeof(struct iwinfo_assoclist_entry);
}
*len = bl;
return 0;
}
int qtnawifi_get_txpwrlist(const char *ifname, char *buf, int *len)
{
struct iwinfo_txpwrlist_entry entry;
uint8_t dbm[11] = { 0, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24 };
uint8_t mw[11] = { 1, 3, 6, 10, 15, 25, 39, 63, 100, 158, 251 };
int i;
for (i = 0; i < 11; i++)
{
entry.dbm = dbm[i];
entry.mw = mw[i];
memcpy(&buf[i*sizeof(entry)], &entry, sizeof(entry));
}
*len = 11 * sizeof(entry);
return 0;
}
int qtnawifi_get_scanlist(const char *ifname, char *buf, int *len)
{
int ret;
char *res;
DIR *proc;
struct dirent *e;
ret = -1;
return ret;
}
int qtnawifi_get_freqlist(const char *ifname, char *buf, int *len)
{
int i, bl;
struct iwinfo_freqlist_entry qtnawifi_channel_entry[] = {
{.mhz=5180, .channel=36},
{.mhz=5200, .channel=40},
{.mhz=5220, .channel=44},
{.mhz=5240, .channel=48},
{.mhz=5260, .channel=52},
{.mhz=5280, .channel=56},
{.mhz=5300, .channel=60},
{.mhz=5320, .channel=64},
{.mhz=5500, .channel=100},
{.mhz=5520, .channel=104},
{.mhz=5540, .channel=108},
{.mhz=5560, .channel=112},
{.mhz=5580, .channel=116},
{.mhz=5600, .channel=120},
{.mhz=5620, .channel=124},
{.mhz=5640, .channel=128},
{.mhz=5660, .channel=132},
{.mhz=5680, .channel=136},
{.mhz=5700, .channel=140},
{.mhz=5745, .channel=149},
{.mhz=5765, .channel=153},
{.mhz=5785, .channel=157},
{.mhz=5805, .channel=161},
{.mhz=5825, .channel=165}
};
if(!qtnawifi_host_detect(ifname))
return -1;
bl = 0;
for(i = 0; i < ARRAY_SIZE(qtnawifi_channel_entry); i++)
{
memcpy(&buf[bl], &qtnawifi_channel_entry[i], sizeof(struct iwinfo_freqlist_entry));
bl += sizeof(struct iwinfo_freqlist_entry);
}
*len = bl;
return 0;
}
int qtnawifi_get_country(const char *ifname, char *buf)
{
return -1;
}
int qtnawifi_get_countrylist(const char *ifname, char *buf, int *len)
{
return -1;
}
int qtnawifi_get_hwmodelist(const char *ifname, int *buf)
{
*buf |= IWINFO_80211_A;
*buf |= IWINFO_80211_N;
*buf |= IWINFO_80211_AC;
return 0;
}
#define QCA_HTMODE_ADD(MODESTR, MODEVAL) if(strstr(prot, MODESTR)) *buf |= MODEVAL;
int qtnawifi_get_htmodelist(const char *ifname, int *buf)
{
*buf |= IWINFO_HTMODE_VHT20 | IWINFO_HTMODE_VHT40 |
IWINFO_HTMODE_VHT80;
return 0;
}
int qtnawifi_get_mbssid_support(const char *ifname, int *buf)
{
*buf = 0;
return 0;
}
int qtnawifi_get_hardware_id(const char *ifname, char *buf)
{
return -1;
}
static const struct iwinfo_hardware_entry *
qtnawifi_get_hardware_entry(const char *ifname)
{
struct iwinfo_hardware_id id;
if (qtnawifi_get_hardware_id(ifname, (char *)&id))
return NULL;
return iwinfo_hardware(&id);
}
int qtnawifi_get_hardware_name(const char *ifname, char *buf)
{
const struct iwinfo_hardware_entry *hw;
if (!(hw = qtnawifi_get_hardware_entry(ifname)))
sprintf(buf, "Quantenna");
else
sprintf(buf, "%s %s", hw->vendor_name, hw->device_name);
return 0;
}
int qtnawifi_get_txpower_offset(const char *ifname, int *buf)
{
return -1;
}
int qtnawifi_get_frequency_offset(const char *ifname, int *buf)
{
return -1;
}
const struct iwinfo_ops qtnawifi_ops = {
.name = "qtnawifi",
.probe = qtnawifi_probe,
.channel = qtnawifi_get_channel,
.frequency = qtnawifi_get_frequency,
.frequency_offset = qtnawifi_get_frequency_offset,
.txpower = qtnawifi_get_txpower,
.txpower_offset = qtnawifi_get_txpower_offset,
.bitrate = qtnawifi_get_bitrate,
.signal = qtnawifi_get_signal,
.noise = qtnawifi_get_noise,
.quality = qtnawifi_get_quality,
.quality_max = qtnawifi_get_quality_max,
.mbssid_support = qtnawifi_get_mbssid_support,
.hwmodelist = qtnawifi_get_hwmodelist,
.htmodelist = qtnawifi_get_htmodelist,
.mode = qtnawifi_get_mode,
.ssid = qtnawifi_get_ssid,
.bssid = qtnawifi_get_bssid,
.country = qtnawifi_get_country,
.hardware_id = qtnawifi_get_hardware_id,
.hardware_name = qtnawifi_get_hardware_name,
.encryption = qtnawifi_get_encryption,
.phyname = qtnawifi_get_phyname,
.assoclist = qtnawifi_get_assoclist,
.txpwrlist = qtnawifi_get_txpwrlist,
.scanlist = qtnawifi_get_scanlist,
.freqlist = qtnawifi_get_freqlist,
.countrylist = qtnawifi_get_countrylist,
.close = qtnawifi_close
};

View File

@ -0,0 +1,88 @@
CFLAGS += -I.
COMMON_PROG_OBJS = \
call_qcsapi.o \
qcsapi_driver.o \
qcsapi_output.o \
qcsapi_sem.o \
qcsapi_util.o
SOCKET_PROG_OBJS = \
$(COMMON_PROG_OBJS) \
qcsapi_rpc/client/socket/qcsapi_socket_rpc_client.o \
qcsapi_rpc_common/client/find_host_addr.o \
SOCKET_C_SAMPLE_OBJS = \
qcsapi_rpc_sample/c_rpc_qcsapi_sample.o \
qcsapi_rpc_common/client/find_host_addr.o \
PCIE_PROG_OBJS = \
$(COMMON_PROG_OBJS) \
qcsapi_rpc/client/pcie/qcsapi_pcie_rpc_client.o \
qcsapi_rpc_common/client/rpc_pci_clnt.o \
SOCKET_RAW_PROG_OBJS = \
$(COMMON_PROG_OBJS) \
qcsapi_rpc/client/socket_raw/qcsapi_socketraw_rpc_client.o \
qcsapi_rpc_common/client/rpc_raw_clnt.o \
qcsapi_rpc_common/common/rpc_raw.o
LIB_OBJS = \
qcsapi_rpc/generated/qcsapi_rpc_xdr.o \
qcsapi_rpc/generated/qcsapi_rpc_clnt_adapter.o \
TARGETS = c_rpc_qcsapi_sample \
qcsapi_sockrpc \
qcsapi_sockrpc_static \
qcsapi_pcie \
qcsapi_pcie_static \
qcsapi_sockraw \
qcsapi_sockraw_static \
$(LIB_REALNAME)
CFLAGS += -DPCIE_RPC_TYPE=RPC_TYPE_QCSAPI_PCIE
all: $(TARGETS)
-include $(shell find . -name \*.d)
LIB_NAME = qcsapi_client
LIB_LDNAME = lib$(LIB_NAME).so
LIB_SONAME = $(LIB_LDNAME).1
LIB_REALNAME = $(LIB_LDNAME).1.0.1
LDFLAGS += -L. -l$(LIB_NAME)
c_rpc_qcsapi_sample: ${SOCKET_C_SAMPLE_OBJS:%=build/%} $(LIB_REALNAME)
${CC} $(filter %.o, $^) $(LDFLAGS) -o $@
qcsapi_pcie: ${PCIE_PROG_OBJS:%=build/%} $(LIB_REALNAME)
${CC} $(filter %.o, $^) $(LDFLAGS) -o $@
qcsapi_pcie_static: ${PCIE_PROG_OBJS:%=build/%} ${LIB_OBJS}
${CC} $(filter %.o, $^) -o $@
qcsapi_sockrpc: ${SOCKET_PROG_OBJS:%=build/%} $(LIB_REALNAME)
${CC} $(filter %.o, $^) $(LDFLAGS) -o $@
qcsapi_sockrpc_static: ${SOCKET_PROG_OBJS:%=build/%} ${LIB_OBJS}
${CC} $(filter %.o, $^) -o $@
qcsapi_sockraw: ${SOCKET_RAW_PROG_OBJS:%=build/%} $(LIB_REALNAME)
${CC} $(filter %.o, $^) $(LDFLAGS) -o $@
qcsapi_sockraw_static: ${SOCKET_RAW_PROG_OBJS:%=build/%} ${LIB_OBJS}
${CC} $(filter %.o, $^) -o $@
$(LIB_REALNAME): ${LIB_OBJS:%=build/%}
${CC} -shared -s -o $@ -Wl,-soname,$(LIB_SONAME) -lc $^
cd ${@D} ; ln -fs $(LIB_REALNAME) $(LIB_SONAME)
cd ${@D} ; ln -fs $(LIB_SONAME) $(LIB_LDNAME)
build/%.o: %.c
@mkdir -p ${@D}
${CC} ${CFLAGS} $< -c -o $@ -MD -MF $@.d
clean:
rm -rf build $(LIB_LDNAME)* $(TARGETS) $(LIB_OBJS)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
/*SH1
*******************************************************************************
** **
** Copyright (c) 2009 - 2011 Quantenna Communications Inc **
** **
** File : qcsapi.h **
** Description : **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#ifndef _CALL_QCSAPI_H
#define _CALL_QCSAPI_H
#include "qcsapi_output.h"
extern int qcsapi_main(qcsapi_output *print, int argc, char **argv);
#endif /* _CALL_QCSAPI_H */

View File

@ -0,0 +1,52 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2009 - 2011 Quantenna Communications Inc **
** **
** File : call_qcsapi_local.c **
** Description : tiny wrapper to invoke call_qcsapi locally, from main() **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#ifndef __QCSAPI_FIND_HOST_ADDR_H__
#define __QCSAPI_FIND_HOST_ADDR_H__
extern const char* client_qcsapi_find_host_addr(int *argc, char ***argv);
extern void client_qcsapi_find_host_errmsg(const char *progname);
#endif /* __QCSAPI_FIND_HOST_ADDR_H__ */

View File

@ -0,0 +1,8 @@
/*
* Copyright (c) 2015 Quantenna Communications, Inc.
* All rights reserved.
*/
#ifndef __QCSAPI_QFTC_H__
#define __QCSAPI_QFTC_H__
extern int qftc_start(const char *file_path_name, const char *sif_name, const uint8_t *dmac_addr);
#endif

View File

@ -0,0 +1,268 @@
/*
* (C) Copyright 2014 Quantenna Communications Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Header file which describes the Ruby and Topaz platforms.
* Used by both run-time and boot loader images.
*
* Do not put run-time specific definitions in this file.
*/
#ifndef __COMMON_MEM_H
#define __COMMON_MEM_H
#include "ruby_config.h"
/* Platform memory */
/* SRAM */
#define RUBY_SRAM_UNIFIED_BEGIN 0x98000000
#define RUBY_SRAM_UNIFIED_NOCACHE_BEGIN 0xf8000000
#define RUBY_SRAM_FLIP_BEGIN 0x88000000
#define RUBY_SRAM_FLIP_NOCACHE_BEGIN 0x60000000
#define RUBY_SRAM_NOFLIP_BEGIN 0x80000000
#define RUBY_SRAM_NOFLIP_NOCACHE_BEGIN 0x60000000
#define RUBY_SRAM_BANK_SIZE (64 * 1024)
#ifdef TOPAZ_PLATFORM
#define RUBY_SRAM_SIZE (8 * RUBY_SRAM_BANK_SIZE)
#define RUBY_SRAM_BANK_SAFE_SIZE RUBY_SRAM_BANK_SIZE
#else
#define RUBY_SRAM_END_BANK_GUARD_SIZE 32
#define RUBY_SRAM_SIZE (4 * RUBY_SRAM_BANK_SIZE)
#define RUBY_SRAM_BANK_SAFE_SIZE (RUBY_SRAM_BANK_SIZE - RUBY_SRAM_END_BANK_GUARD_SIZE)
#endif
/* DDR */
#define RUBY_DRAM_UNIFIED_BEGIN 0x80000000
#define RUBY_DRAM_UNIFIED_NOCACHE_BEGIN 0xd0000000
#define RUBY_DRAM_FLIP_BEGIN 0x80000000
#define RUBY_DRAM_FLIP_NOCACHE_BEGIN 0x40000000
#define RUBY_DRAM_NOFLIP_BEGIN 0x0
#define RUBY_DRAM_NOFLIP_NOCACHE_BEGIN 0x40000000
#define RUBY_MAX_DRAM_SIZE DDR_128MB
#define RUBY_MIN_DRAM_SIZE DDR_64MB
#if TOPAZ_MMAP_UNIFIED
#define RUBY_SRAM_BEGIN RUBY_SRAM_UNIFIED_BEGIN
#define RUBY_SRAM_BUS_BEGIN RUBY_SRAM_UNIFIED_BEGIN
#define RUBY_SRAM_NOCACHE_BEGIN RUBY_SRAM_UNIFIED_NOCACHE_BEGIN
#define RUBY_DRAM_BEGIN RUBY_DRAM_UNIFIED_BEGIN
#define RUBY_DRAM_BUS_BEGIN RUBY_DRAM_UNIFIED_BEGIN
#define RUBY_DRAM_NOCACHE_BEGIN RUBY_DRAM_UNIFIED_NOCACHE_BEGIN
#elif RUBY_MMAP_FLIP
#define RUBY_SRAM_BEGIN RUBY_SRAM_FLIP_BEGIN
#define RUBY_SRAM_BUS_BEGIN RUBY_SRAM_NOFLIP_BEGIN
#define RUBY_SRAM_NOCACHE_BEGIN RUBY_SRAM_FLIP_NOCACHE_BEGIN
#define RUBY_DRAM_BEGIN RUBY_DRAM_FLIP_BEGIN
#define RUBY_DRAM_BUS_BEGIN RUBY_DRAM_NOFLIP_BEGIN
#define RUBY_DRAM_NOCACHE_BEGIN RUBY_DRAM_FLIP_NOCACHE_BEGIN
#else
#define RUBY_SRAM_BEGIN RUBY_SRAM_NOFLIP_BEGIN
#define RUBY_SRAM_BUS_BEGIN RUBY_SRAM_NOFLIP_BEGIN
#define RUBY_SRAM_NOCACHE_BEGIN RUBY_SRAM_NOFLIP_NOCACHE_BEGIN
#define RUBY_DRAM_BEGIN RUBY_DRAM_NOFLIP_BEGIN
#define RUBY_DRAM_BUS_BEGIN RUBY_DRAM_NOFLIP_BEGIN
#define RUBY_DRAM_NOCACHE_BEGIN RUBY_DRAM_NOFLIP_NOCACHE_BEGIN
#endif
/*****************************************************************************/
/* SPI memory mapped */
/*****************************************************************************/
#define RUBY_SPI_FLASH_ADDR 0x90000000
/* Hardware */
#define RUBY_HARDWARE_BEGIN 0xC0000000
#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
/* Config space */
#define CONFIG_ARC_CONF_SIZE (8 * 1024)
/* Config area for Universal H/W ID */
#define CONFIG_ARC_CONF_BASE (0x80000000 + CONFIG_ARC_CONF_SIZE)
#define CONFIG_ARC_KERNEL_PAGE_SIZE (8 * 1024)
#define RUBY_KERNEL_LOAD_DRAM_BEGIN (RUBY_DRAM_BEGIN + 0x3000000)
/* DDR layout */
#define CONFIG_ARC_NULL_BASE 0x00000000
#define CONFIG_ARC_NULL_SIZE (64 * 1024)
#define CONFIG_ARC_NULL_END (CONFIG_ARC_NULL_BASE + CONFIG_ARC_NULL_SIZE)
/* PCIe BDA area */
#define CONFIG_ARC_PCIE_BASE (RUBY_DRAM_BEGIN + CONFIG_ARC_NULL_END)
#define CONFIG_ARC_PCIE_SIZE (64 * 1024) /* minimal PCI BAR size */
#if ((CONFIG_ARC_PCIE_BASE & (64 * 1024 - 1)) != 0)
#error "The reserved region for PCIe BAR should 64k aligned!"
#endif
/*
* CONFIG_ARC_MUC_STACK_OFFSET_UBOOT must be equal to CONFIG_ARC_MUC_STACK_OFFSET
* and RUBY_CRUMBS_OFFSET_UBOOT must be equal to RUBY_CRUMBS_OFFSET.
* Their values can be obtained with host/utilities/ruby_mem_helper.
*/
#if TOPAZ_RX_ACCELERATE
/* Must be equal to CONFIG_ARC_MUC_STACK_OFFSET */
#define CONFIG_ARC_MUC_STACK_OFFSET_UBOOT (0x0003F7C0)
/* MuC stack, included in CONFIG_ARC_MUC_SRAM_SIZE */
#define CONFIG_ARC_MUC_STACK_SIZE (4 * 1024)
#else
/* Must be equal to CONFIG_ARC_MUC_STACK_OFFSET */
#define CONFIG_ARC_MUC_STACK_OFFSET_UBOOT (0x0003FFA0)
/* MuC stack, included in CONFIG_ARC_MUC_SRAM_SIZE */
#define CONFIG_ARC_MUC_STACK_SIZE (6 * 1024)
#endif
#define CONFIG_ARC_MUC_STACK_INIT_UBOOT (RUBY_SRAM_BEGIN + CONFIG_ARC_MUC_STACK_OFFSET_UBOOT)
#ifdef TOPAZ_PLATFORM
/* Must be equal to RUBY_CRUMBS_OFFSET */
#define RUBY_CRUMBS_OFFSET_UBOOT (0x0003FFC0)
#else
#define RUBY_CRUMBS_OFFSET_UBOOT (0x0003FFA0)
#endif
#define RUBY_CRUMBS_ADDR_UBOOT (RUBY_SRAM_BEGIN + RUBY_CRUMBS_OFFSET_UBOOT)
/*
* Crumb structure, sits at the end of SRAM. Each core can use it to
* store the last run function to detect bus hangs.
*/
#ifndef __ASSEMBLY__
struct ruby_crumbs_percore {
unsigned long blink;
unsigned long status32;
unsigned long sp;
};
struct ruby_crumbs_mem_section {
unsigned long start;
unsigned long end;
};
struct ruby_crumbs {
struct ruby_crumbs_percore lhost;
struct ruby_crumbs_percore muc;
struct ruby_crumbs_percore dsp;
/*
* allow (somewhat) intelligent parsing of muc stacks by
* specifying the text section
*/
struct ruby_crumbs_mem_section muc_dram;
struct ruby_crumbs_mem_section muc_sram;
/*
* magic token; if set incorrectly we probably have
* random values after power-on
*/
unsigned long magic;
};
#define RUBY_CRUMBS_MAGIC 0x7c97be8f
#endif /* __ASSEMBLY__ */
/* Utility functions */
#ifndef __ASSEMBLY__
#if defined(AUC_BUILD) || defined(RUBY_MINI)
#define NO_RUBY_WEAK 1
#else
#define NO_RUBY_WEAK 0
#endif
#define RUBY_BAD_BUS_ADDR ((unsigned long)0)
#define RUBY_BAD_VIRT_ADDR ((void*)RUBY_BAD_BUS_ADDR)
#define RUBY_ERROR_ADDR ((unsigned long)0xefefefef)
#if defined(__CHECKER__)
#define RUBY_INLINE static inline __attribute__((always_inline))
#define RUBY_WEAK(name) RUBY_INLINE
#elif defined(__GNUC__)
/*GCC*/
#define RUBY_INLINE static inline __attribute__((always_inline))
#if NO_RUBY_WEAK
#define RUBY_WEAK(name) RUBY_INLINE
#else
#define RUBY_WEAK(name) __attribute__((weak))
#endif
#else
/*MCC*/
#define RUBY_INLINE static _Inline
#if NO_RUBY_WEAK
#define RUBY_WEAK(name) RUBY_INLINE
#else
#define RUBY_WEAK(name) pragma Weak(name);
#endif
#pragma Offwarn(428)
#endif
#define ____in_mem_range(addr, start, size) \
(((addr) >= (start)) && ((addr) < (start) + (size)))
#if defined(STATIC_CHECK) || defined(__CHECKER__)
RUBY_INLINE int __in_mem_range(unsigned long addr, unsigned long start, unsigned long size)
{
return (((addr) >= (start)) && ((addr) < (start) + (size)));
}
#else
#define __in_mem_range ____in_mem_range
#endif
#if RUBY_MMAP_FLIP
RUBY_INLINE unsigned long virt_to_bus(const void *addr)
{
unsigned long ret = (unsigned long)addr;
if (__in_mem_range(ret, RUBY_SRAM_FLIP_BEGIN, RUBY_SRAM_SIZE)) {
ret = ret - RUBY_SRAM_FLIP_BEGIN + RUBY_SRAM_NOFLIP_BEGIN;
} else if (__in_mem_range(ret, RUBY_DRAM_FLIP_BEGIN, RUBY_MAX_DRAM_SIZE)) {
ret = ret - RUBY_DRAM_FLIP_BEGIN + RUBY_DRAM_NOFLIP_BEGIN;
} else if (ret < RUBY_HARDWARE_BEGIN) {
ret = RUBY_BAD_BUS_ADDR;
}
return ret;
}
RUBY_WEAK(bus_to_virt) void* bus_to_virt(unsigned long addr)
{
unsigned long ret = addr;
if (__in_mem_range(ret, RUBY_SRAM_NOFLIP_BEGIN, RUBY_SRAM_SIZE)) {
ret = ret - RUBY_SRAM_NOFLIP_BEGIN + RUBY_SRAM_FLIP_BEGIN;
} else if (__in_mem_range(ret, RUBY_DRAM_NOFLIP_BEGIN, RUBY_MAX_DRAM_SIZE)) {
ret = ret - RUBY_DRAM_NOFLIP_BEGIN + RUBY_DRAM_FLIP_BEGIN;
} else if (ret < RUBY_HARDWARE_BEGIN) {
ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
}
return (void*)ret;
}
#else
/* Map 1:1, (x) address must be upper then 0x8000_0000. */
#define virt_to_bus(x) ((unsigned long)(x))
#define bus_to_virt(x) ((void *)(x))
#endif /* #if RUBY_MMAP_FLIP */
#ifndef __GNUC__
/* MCC */
#pragma Popwarn()
#endif
#endif /* #ifndef __ASSEMBLY__ */
#endif /* __COMMON_MEM_H */

View File

@ -0,0 +1,8 @@
#define TOPAZ_PLATFORM
#define TOPAZ_FPGA_PLATFORM 0
#define TOPAZ_EMAC_NULL_BUF_WR
#undef TOPAZ_FPGA_UMCTL1
#define PLATFORM_WMAC_MODE ap
#undef PLATFORM_DEFAULT_BOARD_ID
#define ARC_HW_REV_NEEDS_TLBMISS_FIX
#define TOPAZ_VNET_WR_STAGING 0

View File

@ -0,0 +1,14 @@
#ifndef _PCI_RPC_H
#define _PCI_RPC_H
#include "rpc_pci_nlm.h"
extern CLIENT *
clnt_pci_create (const char *hostname,
u_long prog,
u_long vers,
const char *proto);
extern SVCXPRT *svc_pci_create (int sock);
#endif

View File

@ -0,0 +1,26 @@
#ifndef __PCI_NLM_H__
#define __PCI_NLM_H__
/*
* We seperate the netlink type for client and server here.
* If the netlink type is conflicted with customers', they just need to modify
* NETLINK_RPC_PCI_CLNT and the type define in the PCIe RC driver and the netlink
* type in the rpc server and PCIe EP driver will not be affected.
*/
#define NETLINK_RPC_PCI_CLNT 31
#define NETLINK_RPC_PCI_SVC 31
#define PCIMSGSIZE (64 * 1024 - 1)
/*
* Nelink Message types.
*/
#define RPC_TYPE_CALL_QCSAPI_PCIE 0x0100
#define RPC_TYPE_QCSAPI_PCIE 0x0200
#define NETLINK_TYPE_SVC_REGISTER (PCIE_RPC_TYPE | 0x0010)
#define NETLINK_TYPE_SVC_RESPONSE (PCIE_RPC_TYPE | 0x0011)
#define NETLINK_TYPE_CLNT_REGISTER (PCIE_RPC_TYPE | 0x0010)
#define NETLINK_TYPE_CLNT_REQUEST (PCIE_RPC_TYPE | 0x0011)
#endif

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2015 Quantenna Communications, Inc.
* All rights reserved.
*/
#ifndef RPC_RAW_H
#define RPC_RAW_H
#include <rpc/rpc.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
#endif
#define QRPC_RAW_SOCK_PROT 11
#define QFTP_RAW_SOCK_PROT 22
#define ETH_P_OUI_EXT 0x88B7
#define QUANTENNA_OUI 0x002686
#define QFTP_DATA_PKT_HDR_SIZE (sizeof(struct q_raw_ethoui_hdr) +\
sizeof(struct qftp_data_pkt) - 1)
#define QFTP_ACK_NACK_FRAME_LEN (sizeof(struct q_raw_ethoui_hdr) +\
sizeof(struct qftp_ack_nack_pkt))
/* QFT */
#define QFTP_FRAME_TYPE_NACK 0
#define QFTP_FRAME_TYPE_ACK 1
#define QFTP_FRAME_TYPE_CONNECT 2
#define QFTP_FRAME_TYPE_DATA 3
/* RPC QCSAPI */
#define QRPC_FRAME_TYPE_COMPLETE 4
#define QRPC_FRAME_TYPE_FRAG 5
#define QRPC_BUFFER_LEN (16 * 1024)
#define QRPC_QCSAPI_RPCD_SID 0
#define QRPC_CALL_QCSAPI_RPCD_SID 1
struct q_raw_ethoui_hdr {
struct ethhdr eth_hdr;
uint8_t prot_id[5]; /* Protocol Identifier */
uint8_t _pad1;
} __attribute__ ((packed));
/* QRPC frames */
struct qrpc_frame_hdr {
struct q_raw_ethoui_hdr qhdr;
uint8_t sub_type;
uint8_t sid;
uint16_t seq;
} __attribute__ ((packed));
struct qrpc_raw_ethpkt {
struct qrpc_frame_hdr fhdr;
char payload[ETH_FRAME_LEN - sizeof(struct qrpc_frame_hdr)];
} __attribute__ ((packed));
/* QFTP frame payloads */
struct qftp_raw_ethpkt {
struct q_raw_ethoui_hdr hdr;
char payload[ETH_FRAME_LEN - sizeof(struct q_raw_ethoui_hdr)];
} __attribute__ ((packed));
struct qftp_connect_pkt {
uint16_t sub_type;
uint16_t seq;
uint32_t image_size;
char image_name[1];
} __attribute__ ((packed));
struct qftp_data_pkt {
uint16_t sub_type;
uint16_t seq;
char data[1];
} __attribute__ ((packed));
struct qftp_ack_nack_pkt {
uint16_t sub_type;
uint16_t seq;
} __attribute__ ((packed));
extern CLIENT *qrpc_clnt_raw_create(u_long prog, u_long vers,
const char *const srcif_name, const uint8_t * dmac_addr, uint8_t sess_id);
extern SVCXPRT *qrpc_svc_raw_create(int sock, const char *const bind_interface, uint8_t sess_id);
extern int qrpc_set_prot_filter(const int sock, const short prot);
extern int qrpc_raw_bind(const int sock, const char *const if_name, const int protocol);
extern int str_to_mac(const char *txt_mac, uint8_t * mac);
extern int qrpc_clnt_raw_config_dst(const int sock, const char *const srcif_name,
struct sockaddr_ll *dst_addr,
const uint8_t *dmac_addr,
struct q_raw_ethoui_hdr *pkt_outbuf,
uint8_t qprot);
extern int qrpc_raw_read_timeout(const int sock_fd, const int timeout);
#endif

View File

@ -0,0 +1,182 @@
/*
* (C) Copyright 2010 Quantenna Communications Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Header file which describes Ruby platform.
* Has to be used by both kernel and bootloader.
*/
#ifndef __RUBY_CONFIG_H
#define __RUBY_CONFIG_H
#include "topaz_config.h"
/*******************************************************************/
#if TOPAZ_MMAP_UNIFIED
#define RUBY_MMAP_FLIP 0
#else
#if !(defined(MUC_BUILD) || defined(DSP_BUILD) || defined(AUC_BUILD))
#define RUBY_MMAP_FLIP 1
#else
#define RUBY_MMAP_FLIP 0
#endif
#endif
/* Set to 1 if MuC need to enable TLB, otherwise set to 0 */
#define RUBY_MUC_TLB_ENABLE 1
/*******************************************************************/
#ifdef RUBY_PLATFORM
#if RUBY_FPGA_PLATFORM
#define RUBY_SERIAL_BAUD 38400
#define RUBY_FIXED_DEV_CLK 12500000
#define RUBY_FIXED_CPU_CLK 40000000
#define RUBY_FPGA_DDR
#else
#define RUBY_SERIAL_BAUD 115200
#define RUBY_FIXED_DEV_CLK 125000000
#define RUBY_FIXED_CPU_CLK 400000000
#define RUBY_ASIC_DDR
#endif /* #if RUBY_FPGA_PLATFORM */
#define UPF_SPD_FLAG 0
#define DEFAULT_BAUD RUBY_SERIAL_BAUD
#endif /* #ifdef RUBY_PLATFORM */
/*******************************************************************/
/* Define some constants for Linux ARC kernel */
#define CONFIG_ARC700_SERIAL_BAUD RUBY_SERIAL_BAUD
#define CONFIG_ARC700_CLK RUBY_FIXED_CPU_CLK
#define CONFIG_ARC700_DEV_CLK RUBY_FIXED_DEV_CLK
/*******************************************************************/
/* RGMII related defines */
#define CONFIG_ARCH_RUBY_ENET_RGMII
#define CONFIG_ARCH_RGMII_DEFAULT 0x8F8F8F8F
#define CONFIG_ARCH_RGMII_DLL_TIMING 0x8F8D8F8F
#define CONFIG_ARCH_RGMII_S1P8NS_H1P9NS 0x8F891F1F
#define CONFIG_ARCH_RGMII_NODELAY 0x1F1F1F1F
#define CONFIG_ARCH_RGMII_710F CONFIG_ARCH_RGMII_NODELAY
#define CONFIG_ARCH_RGMII_P1RX00TX0E 0x0E8E1F1F
/* EMAC related defines */
/* EMAC flags */
#define EMAC_NOT_IN_USE (0)
#define EMAC_IN_USE (BIT(0))
#define EMAC_PHY_NOT_IN_USE (BIT(1)) // do not initialize/access phy mdio
#define EMAC_PHY_FORCE_10MB (BIT(2))
#define EMAC_PHY_FORCE_100MB (BIT(3))
#define EMAC_PHY_FORCE_1000MB (BIT(4))
#define EMAC_PHY_FORCE_HDX (BIT(5))
#define EMAC_PHY_RESET (BIT(6)) // force PHY reset
#define EMAC_PHY_MII (BIT(7)) // default is rgmii
#define EMAC_PHY_AUTO_MASK (EMAC_PHY_FORCE_10MB | EMAC_PHY_FORCE_100MB | EMAC_PHY_FORCE_1000MB)
#define EMAC_PHY_AR8236 (BIT(8))
#define EMAC_PHY_AR8327 (BIT(9))
#define EMAC_PHY_GPIO1_RESET (BIT(10))
#define EMAC_PHY_GPIO13_RESET (BIT(11))
#define EMAC_PHY_NO_COC (BIT(12)) // do not adjust link speed for power savings
#define EMAC_PHY_MV88E6071 (BIT(13))
#define EMAC_PHY_FPGAA_ONLY (BIT(15))
#define EMAC_PHY_FPGAB_ONLY (BIT(16))
#define EMAC_PHY_RTL8363SB_P0 (BIT(18))
#define EMAC_PHY_RTL8363SB_P1 (BIT(19))
#define EMAC_BONDED (BIT(20))
#define EMAC_PHY_RTL8365MB (BIT(21))
#define EMAC_PHY_RTL8211DS (BIT(22))
#define EMAC_PHY_CUSTOM (BIT(31))
#define EMAC_MV88E6071 (EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_NOT_IN_USE | \
EMAC_PHY_NO_COC | EMAC_PHY_FORCE_100MB | EMAC_PHY_MV88E6071)
#define EMAC_SLOW_PHY (EMAC_PHY_FORCE_10MB|EMAC_PHY_FORCE_100MB|EMAC_PHY_MII)
/* force phy addr scan */
#define EMAC_PHY_ADDR_SCAN (32) // scan bus for addr
/* Flash memory sizes */
#define FLASH_32MB (32*1024*1024)
#define FLASH_16MB (16*1024*1024)
#define FLASH_8MB (8*1024*1024)
#define FLASH_4MB (4*1024*1024)
#define FLASH_2MB (2*1024*1024)
#define FLASH_64KB (64*1024)
#define DEFAULT_FLASH_SIZE (FLASH_8MB)
#define FLASH_SIZE_JEDEC (0)
/* DDR memory sizes */
#define DDR_256MB (256*1024*1024)
#define DDR_128MB (128*1024*1024)
#define DDR_64MB (64*1024*1024)
#define DDR_32MB (32*1024*1024)
#define DDR_AUTO (0)
#define DEFAULT_DDR_SIZE (DDR_64MB)
/* Other DDR defines */
#define DDR3_800MHz 800
#define DDR3_640MHz 640
#define DDR3_500MHz 500
#define DDR3_400MHz 400
#define DDR3_320MHz 320
#define DDR_400 400
#define DDR_320 320
#define DDR_250 250
#define DDR_200 200
#define DDR_160 160
#define DDR_125 125
#define DEFAULT_DDR_SPEED (DDR_160)
#define DDR_32_MICRON 0
#define DDR_16_MICRON 1
#define DDR_16_ETRON 2
#define DDR_16_SAMSUNG 3
#define DDR_32_ETRON 4
#define DDR_32_SAMSUNG 5
#define DDR_16_HYNIX 6
#define DDR3_16_WINBOND 7
#define DDR3_32_WINBOND 8
#define DEFAULT_DDR_CFG (DDR_16_MICRON)
/* UART1 defines */
#define UART1_NOT_IN_USE 0
#define UART1_IN_USE 1
#define PCIE_NOT_IN_USE 0
#define PCIE_IN_USE (BIT(0))
#define PCIE_USE_PHY_LOOPBK (BIT(1))
#define PCIE_RC_MODE (BIT(2))
#define PCIE_ENDPOINT (PCIE_IN_USE | PCIE_USE_PHY_LOOPBK)
#define PCIE_ROOTCOMPLEX (PCIE_IN_USE | PCIE_RC_MODE | PCIE_USE_PHY_LOOPBK)
/*******************************************************************/
#define CONFIG_USE_SPI1_FOR_IPC PLATFORM_REG_SWITCH(1, 0)
#endif // #ifndef __RUBY_CONFIG_H

View File

@ -0,0 +1,532 @@
/*
* (C) Copyright 2010 Quantenna Communications Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Header file which describes Ruby platform.
* Has to be used by runtime firmware.
*/
#ifndef __RUBY_MEM_H
#define __RUBY_MEM_H
#include "common_mem.h"
/* FIXME: Move CPU related macros to a separate header file. */
#define ARC_DCACHE_LINE_LENGTH 32
/* NEVTBD - put in real XYMEM values */
#define RUBY_DSP_XYMEM_BEGIN 0xD0000000
#define RUBY_DSP_XYMEM_END 0xDFFFFFFF
/* SRAM layout */
#define RUBY_CRUMBS_SIZE 64 /* bytes at the very end of sram for crash tracing */
#ifdef TOPAZ_PLATFORM
#ifdef QTN_RC_ENABLE_HDP
#define TOPAZ_HBM_BUF_EMAC_RX_COUNT_S (14)
#define TOPAZ_HBM_BUF_WMAC_RX_COUNT_S (0)
#else
#define TOPAZ_HBM_BUF_EMAC_RX_COUNT_S (13)
#define TOPAZ_HBM_BUF_WMAC_RX_COUNT_S (11)
#endif
#define TOPAZ_HBM_EMAC_TX_DONE_COUNT_S (12)
#define TOPAZ_HBM_BUF_EMAC_RX_COUNT (1 << TOPAZ_HBM_BUF_EMAC_RX_COUNT_S)
#define TOPAZ_HBM_BUF_WMAC_RX_COUNT (1 << TOPAZ_HBM_BUF_WMAC_RX_COUNT_S)
#define TOPAZ_HBM_EMAC_TX_DONE_COUNT (1 << TOPAZ_HBM_EMAC_TX_DONE_COUNT_S)
/* dedicated SRAM space for HBM pointer pools */
#define TOPAZ_HBM_POOL_PTR_SIZE 4 /* sizeof(void *), 32 bit arch */
#define TOPAZ_HBM_POOL_EMAC_RX_START 0x00000000
#define TOPAZ_HBM_POOL_EMAC_RX_SIZE (TOPAZ_HBM_BUF_EMAC_RX_COUNT * TOPAZ_HBM_POOL_PTR_SIZE)
#define TOPAZ_HBM_POOL_EMAC_RX_END (TOPAZ_HBM_POOL_EMAC_RX_START + TOPAZ_HBM_POOL_EMAC_RX_SIZE)
#define TOPAZ_HBM_POOL_WMAC_RX_START TOPAZ_HBM_POOL_EMAC_RX_END
#define TOPAZ_HBM_POOL_WMAC_RX_SIZE (TOPAZ_HBM_BUF_WMAC_RX_COUNT * TOPAZ_HBM_POOL_PTR_SIZE)
#define TOPAZ_HBM_POOL_WMAC_RX_END (TOPAZ_HBM_POOL_WMAC_RX_START + TOPAZ_HBM_POOL_WMAC_RX_SIZE)
#define TOPAZ_HBM_POOL_EMAC_TX_DONE_START TOPAZ_HBM_POOL_WMAC_RX_END
#define TOPAZ_HBM_POOL_EMAC_TX_DONE_SIZE (TOPAZ_HBM_EMAC_TX_DONE_COUNT * TOPAZ_HBM_POOL_PTR_SIZE)
#define TOPAZ_HBM_POOL_EMAC_TX_DONE_END (TOPAZ_HBM_POOL_EMAC_TX_DONE_START + TOPAZ_HBM_POOL_EMAC_TX_DONE_SIZE)
#define TOPAZ_FWT_SW_START TOPAZ_HBM_POOL_EMAC_TX_DONE_END
#define TOPAZ_FWT_SW_SIZE (4096)
#define TOPAZ_FWT_SW_END (TOPAZ_FWT_SW_START + TOPAZ_FWT_SW_SIZE)
#define CONFIG_MUC_EXTRA_RES_BASE TOPAZ_FWT_SW_END
#define CONFIG_MUC_EXTRA_RESERVE_SIZE (8 * 1024)
#define CONFIG_MUC_EXTRA_RES_END (CONFIG_MUC_EXTRA_RES_BASE + CONFIG_MUC_EXTRA_RESERVE_SIZE)
#define CONFIG_ARC_KERNEL_SRAM_B1_BASE ROUNDUP(CONFIG_MUC_EXTRA_RES_END, CONFIG_ARC_KERNEL_PAGE_SIZE)
#define CONFIG_ARC_KERNEL_SRAM_B1_SIZE (22 * 1024)
#define CONFIG_ARC_KERNEL_SRAM_B1_END (CONFIG_ARC_KERNEL_SRAM_B1_BASE + CONFIG_ARC_KERNEL_SRAM_B1_SIZE)
#define CONFIG_ARC_KERNEL_SRAM_B2_BASE CONFIG_ARC_KERNEL_SRAM_B1_END
#define CONFIG_ARC_KERNEL_SRAM_B2_END (ROUNDUP(CONFIG_ARC_KERNEL_SRAM_B2_BASE, RUBY_SRAM_BANK_SIZE) - \
ROUNDUP(TOPAZ_VNET_WR_STAGING_RESERVE, CONFIG_ARC_KERNEL_PAGE_SIZE))
#define CONFIG_ARC_KERNEL_SRAM_B2_SIZE (CONFIG_ARC_KERNEL_SRAM_B2_END - CONFIG_ARC_KERNEL_SRAM_B2_BASE)
#define TOPAZ_VNET_WR_STAGING_1_START CONFIG_ARC_KERNEL_SRAM_B2_END
#define TOPAZ_VNET_WR_STAGING_1_SIZE TOPAZ_VNET_WR_STAGING_RESERVE
#define TOPAZ_VNET_WR_STAGING_1_END (TOPAZ_VNET_WR_STAGING_1_START + TOPAZ_VNET_WR_STAGING_1_SIZE)
#define TOPAZ_VNET_WR_STAGING_2_START ROUNDUP(TOPAZ_VNET_WR_STAGING_1_END, RUBY_SRAM_BANK_SIZE)
#define TOPAZ_VNET_WR_STAGING_2_SIZE TOPAZ_VNET_WR_STAGING_RESERVE
#define TOPAZ_VNET_WR_STAGING_2_END (TOPAZ_VNET_WR_STAGING_2_START + TOPAZ_VNET_WR_STAGING_2_SIZE)
#if TOPAZ_VNET_WR_STAGING_2_START != (2 * RUBY_SRAM_BANK_SIZE)
#error SRAM linkmap error forming topaz sram wr staging
#endif
#define CONFIG_ARC_MUC_SRAM_B1_BASE ROUNDUP(TOPAZ_VNET_WR_STAGING_2_END, CONFIG_ARC_KERNEL_PAGE_SIZE)
#define CONFIG_ARC_MUC_SRAM_B1_END ROUNDUP(CONFIG_ARC_MUC_SRAM_B1_BASE + 1, RUBY_SRAM_BANK_SIZE)
#define CONFIG_ARC_MUC_SRAM_B1_SIZE (CONFIG_ARC_MUC_SRAM_B1_END - CONFIG_ARC_MUC_SRAM_B1_BASE)
#define CONFIG_ARC_MUC_SRAM_B2_BASE ROUNDUP(CONFIG_ARC_MUC_SRAM_B1_END, RUBY_SRAM_BANK_SIZE)
#define CONFIG_ARC_MUC_SRAM_B2_SIZE (RUBY_SRAM_BANK_SAFE_SIZE - RUBY_CRUMBS_SIZE)
#define CONFIG_ARC_MUC_SRAM_B2_END (CONFIG_ARC_MUC_SRAM_B2_BASE + CONFIG_ARC_MUC_SRAM_B2_SIZE)
#define CONFIG_ARC_AUC_SRAM_BASE ROUNDUP(CONFIG_ARC_MUC_SRAM_B2_END, RUBY_SRAM_BANK_SIZE)
#define CONFIG_ARC_AUC_SRAM_SIZE (3 * RUBY_SRAM_BANK_SIZE)
#define CONFIG_ARC_AUC_SRAM_END (CONFIG_ARC_AUC_SRAM_BASE + CONFIG_ARC_AUC_SRAM_SIZE)
#define CONFIG_ARC_SRAM_END CONFIG_ARC_AUC_SRAM_END
/* MU TxBF qmatrix is stored at the last bank of SRAM, DSP writes to it, has to use SRAM BUS addr */
#define CONFIG_ARC_MU_QMAT_BASE (RUBY_SRAM_BUS_BEGIN + 0X70000)
#define CONFIG_ARC_MU_QMAT_SIZE RUBY_SRAM_BANK_SIZE
#define CONFIG_ARC_MU_QMAT_END (CONFIG_ARC_MU_QMAT_BASE + CONFIG_ARC_MU_QMAT_SIZE)
#else /* Ruby */
#define CONFIG_ARC_KERNEL_SRAM_B1_BASE 0x00000000
#define CONFIG_ARC_KERNEL_SRAM_B1_SIZE RUBY_SRAM_BANK_SAFE_SIZE
#define CONFIG_ARC_KERNEL_SRAM_B1_END (CONFIG_ARC_KERNEL_SRAM_B1_BASE + CONFIG_ARC_KERNEL_SRAM_B1_SIZE)
#define CONFIG_ARC_KERNEL_SRAM_B2_BASE (CONFIG_ARC_KERNEL_SRAM_B1_BASE + RUBY_SRAM_BANK_SIZE)
#define CONFIG_ARC_KERNEL_SRAM_B2_SIZE RUBY_SRAM_BANK_SAFE_SIZE
#define CONFIG_ARC_KERNEL_SRAM_B2_END (CONFIG_ARC_KERNEL_SRAM_B2_BASE + CONFIG_ARC_KERNEL_SRAM_B2_SIZE)
#define CONFIG_ARC_MUC_SRAM_B1_BASE ROUNDUP(CONFIG_ARC_KERNEL_SRAM_B2_END, RUBY_SRAM_BANK_SIZE)
#define CONFIG_ARC_MUC_SRAM_B1_SIZE RUBY_SRAM_BANK_SAFE_SIZE
#define CONFIG_ARC_MUC_SRAM_B1_END (CONFIG_ARC_MUC_SRAM_B1_BASE + CONFIG_ARC_MUC_SRAM_B1_SIZE)
#define CONFIG_ARC_MUC_SRAM_B2_BASE ROUNDUP(CONFIG_ARC_MUC_SRAM_B1_END, RUBY_SRAM_BANK_SIZE)
#define CONFIG_ARC_MUC_SRAM_B2_SIZE (RUBY_SRAM_BANK_SAFE_SIZE - RUBY_CRUMBS_SIZE)
#define CONFIG_ARC_MUC_SRAM_B2_END (CONFIG_ARC_MUC_SRAM_B2_BASE + CONFIG_ARC_MUC_SRAM_B2_SIZE)
#endif /* TOPAZ_PLATFORM */
#if TOPAZ_RX_ACCELERATE
/* TODO FIXME - MuC crashed when copying data between SRAM and DDR */
#define CONFIG_ARC_MUC_STACK_OFFSET (CONFIG_ARC_MUC_SRAM_B2_END - 2048)
#else
#define CONFIG_ARC_MUC_STACK_OFFSET (CONFIG_ARC_MUC_SRAM_B2_END)
#endif
#if CONFIG_ARC_MUC_STACK_OFFSET_UBOOT != CONFIG_ARC_MUC_STACK_OFFSET
#error "CONFIG_ARC_MUC_STACK_OFFSET_UBOOT must be equal to CONFIG_ARC_MUC_STACK_OFFSET!"
#endif
#define CONFIG_ARC_MUC_STACK_INIT (RUBY_SRAM_BEGIN + CONFIG_ARC_MUC_STACK_OFFSET)
#define RUBY_CRUMBS_OFFSET (CONFIG_ARC_MUC_SRAM_B2_END)
#if RUBY_CRUMBS_OFFSET != RUBY_CRUMBS_OFFSET_UBOOT
#error "RUBY_CRUMBS_OFFSET_UBOOT must be equal to RUBY_CRUMBS_OFFSET!"
#endif
#define RUBY_CRUMBS_ADDR (RUBY_SRAM_BEGIN + RUBY_CRUMBS_OFFSET)
/* DDR layout */
#define CONFIG_ARC_PCIE_RSVD_SIZE (64 * 1024)
#define CONFIG_ARC_DSP_BASE (CONFIG_ARC_NULL_END + CONFIG_ARC_PCIE_RSVD_SIZE)
#define CONFIG_ARC_DSP_SIZE (768 * 1024)
#define CONFIG_ARC_DSP_END (CONFIG_ARC_DSP_BASE + CONFIG_ARC_DSP_SIZE)
#define CONFIG_ARC_MUC_BASE CONFIG_ARC_DSP_END
#ifdef TOPAZ_128_NODE_MODE
#define CONFIG_ARC_MUC_SIZE ((3 * 1024 * 1024) + (528 * 1024))
#else
#define CONFIG_ARC_MUC_SIZE ((2 * 1024 * 1024) + (768 * 1024))
#endif
#define MUC_DRAM_RX_RESVERED_RELOC_SIZE (8 * 1024)
#define CONFIG_ARC_MUC_END (CONFIG_ARC_MUC_BASE + CONFIG_ARC_MUC_SIZE)
#define CONFIG_ARC_MUC_MAPPED_BASE CONFIG_ARC_MUC_BASE
#define CONFIG_ARC_MUC_MAPPED_SIZE (RUBY_MAX_DRAM_SIZE - CONFIG_ARC_MUC_MAPPED_BASE)
#ifdef TOPAZ_PLATFORM
#define CONFIG_ARC_AUC_BASE CONFIG_ARC_MUC_END
#define CONFIG_ARC_AUC_SIZE (1024 * 1024 + 768 * 1024 + 40 * 1024)
#define CONFIG_ARC_AUC_END (CONFIG_ARC_AUC_BASE + CONFIG_ARC_AUC_SIZE)
#define TOPAZ_HBM_BUF_ALIGN (1 * 1024)
#define TOPAZ_HBM_BUF_EMAC_RX_POOL 0
#define TOPAZ_HBM_BUF_WMAC_RX_POOL 1
#define TOPAZ_HBM_AUC_FEEDBACK_POOL 2
#define TOPAZ_HBM_EMAC_TX_DONE_POOL 3
#define TOPAZ_HBM_BUF_EMAC_RX_SIZE (4 * 1024)
#define TOPAZ_HBM_BUF_WMAC_RX_SIZE (17 * 1024)
#define TOPAZ_HBM_BUF_META_SIZE 64 /* keep it 2^n */
#define TOPAZ_HBM_POOL_GUARD_SIZE (64 * 1024)
#define TOPAZ_HBM_BUF_EMAC_RX_TOTAL (TOPAZ_HBM_BUF_EMAC_RX_COUNT * \
TOPAZ_HBM_BUF_EMAC_RX_SIZE)
#define TOPAZ_HBM_BUF_WMAC_RX_TOTAL (TOPAZ_HBM_BUF_WMAC_RX_COUNT * \
TOPAZ_HBM_BUF_WMAC_RX_SIZE)
#define TOPAZ_HBM_BUF_META_BASE CONFIG_ARC_AUC_END
#define TOPAZ_HBM_BUF_META_EMAC_RX_BASE (TOPAZ_HBM_BUF_META_BASE + TOPAZ_HBM_BUF_META_SIZE)
#define TOPAZ_HBM_BUF_META_EMAC_RX_BASE_VIRT (RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_META_EMAC_RX_BASE)
#define TOPAZ_HBM_BUF_META_EMAC_RX_TOTAL (TOPAZ_HBM_BUF_EMAC_RX_COUNT * \
TOPAZ_HBM_BUF_META_SIZE)
#define TOPAZ_HBM_BUF_META_EMAC_RX_END (TOPAZ_HBM_BUF_META_EMAC_RX_BASE + \
TOPAZ_HBM_BUF_META_EMAC_RX_TOTAL)
#define TOPAZ_HBM_BUF_META_WMAC_RX_BASE (TOPAZ_HBM_BUF_META_EMAC_RX_END + TOPAZ_HBM_BUF_META_SIZE)
#define TOPAZ_HBM_BUF_META_WMAC_RX_BASE_VIRT (RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_META_WMAC_RX_BASE)
#define TOPAZ_HBM_BUF_META_WMAC_RX_TOTAL (TOPAZ_HBM_BUF_WMAC_RX_COUNT * \
TOPAZ_HBM_BUF_META_SIZE)
#define TOPAZ_HBM_BUF_META_WMAC_RX_END (TOPAZ_HBM_BUF_META_WMAC_RX_BASE + \
TOPAZ_HBM_BUF_META_WMAC_RX_TOTAL)
#define TOPAZ_HBM_BUF_META_END (TOPAZ_HBM_BUF_META_WMAC_RX_END + TOPAZ_HBM_BUF_META_SIZE)
#define TOPAZ_HBM_BUF_META_TOTAL (TOPAZ_HBM_BUF_META_END - TOPAZ_HBM_BUF_META_BASE)
#define TOPAZ_HBM_BUF_BASE ROUNDUP(TOPAZ_HBM_BUF_META_END, TOPAZ_HBM_BUF_ALIGN)
#define TOPAZ_HBM_BUF_EMAC_RX_BASE (TOPAZ_HBM_BUF_BASE + TOPAZ_HBM_POOL_GUARD_SIZE)
#define TOPAZ_HBM_BUF_EMAC_RX_BASE_VIRT (RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_EMAC_RX_BASE)
#define TOPAZ_HBM_BUF_EMAC_RX_END (TOPAZ_HBM_BUF_EMAC_RX_BASE + \
TOPAZ_HBM_BUF_EMAC_RX_TOTAL)
#define TOPAZ_HBM_BUF_WMAC_RX_BASE (TOPAZ_HBM_BUF_EMAC_RX_END + TOPAZ_HBM_POOL_GUARD_SIZE)
#define TOPAZ_HBM_BUF_WMAC_RX_BASE_VIRT (RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_WMAC_RX_BASE)
#define TOPAZ_HBM_BUF_WMAC_RX_END (TOPAZ_HBM_BUF_WMAC_RX_BASE + \
TOPAZ_HBM_BUF_WMAC_RX_TOTAL)
#define TOPAZ_HBM_BUF_END (TOPAZ_HBM_BUF_WMAC_RX_END + TOPAZ_HBM_POOL_GUARD_SIZE)
#define TOPAZ_FWT_MCAST_ENTRIES 2048
#define TOPAZ_FWT_MCAST_FF_ENTRIES 8 /* one per vap */
#define TOPAZ_FWT_MCAST_IPMAP_ENT_SIZE 64 /* sizeof(struct topaz_fwt_sw_ipmap) */
#define TOPAZ_FWT_MCAST_TQE_ENT_SIZE 20 /* sizeof(struct topaz_fwt_sw_mcast_entry) */
/* Tables are cache-line aligned to ensure proper memory flushing. */
#define TOPAZ_FWT_MCAST_IPMAP_SIZE \
ROUNDUP(TOPAZ_FWT_MCAST_ENTRIES * TOPAZ_FWT_MCAST_IPMAP_ENT_SIZE, \
ARC_DCACHE_LINE_LENGTH)
#define TOPAZ_FWT_MCAST_TQE_SIZE \
ROUNDUP(TOPAZ_FWT_MCAST_ENTRIES * TOPAZ_FWT_MCAST_TQE_ENT_SIZE, \
ARC_DCACHE_LINE_LENGTH)
#define TOPAZ_FWT_MCAST_TQE_FF_SIZE \
ROUNDUP(TOPAZ_FWT_MCAST_FF_ENTRIES * TOPAZ_FWT_MCAST_TQE_ENT_SIZE, \
ARC_DCACHE_LINE_LENGTH)
#define TOPAZ_FWT_MCAST_IPMAP_BASE TOPAZ_HBM_BUF_END
#define TOPAZ_FWT_MCAST_IPMAP_END (TOPAZ_FWT_MCAST_IPMAP_BASE + TOPAZ_FWT_MCAST_IPMAP_SIZE)
#define TOPAZ_FWT_MCAST_TQE_BASE TOPAZ_FWT_MCAST_IPMAP_END
#define TOPAZ_FWT_MCAST_TQE_END (TOPAZ_FWT_MCAST_TQE_BASE + TOPAZ_FWT_MCAST_TQE_SIZE)
#define TOPAZ_FWT_MCAST_TQE_FF_BASE TOPAZ_FWT_MCAST_TQE_END
#define TOPAZ_FWT_MCAST_TQE_FF_END (TOPAZ_FWT_MCAST_TQE_FF_BASE + TOPAZ_FWT_MCAST_TQE_FF_SIZE)
#define TOPAZ_FWT_MCAST_END TOPAZ_FWT_MCAST_TQE_FF_END
/* Offset from DDR beginning, from which memory start to belong to Linux */
#define CONFIG_ARC_KERNEL_MEM_BASE TOPAZ_FWT_MCAST_END
#if TOPAZ_HBM_BUF_EMAC_RX_BASE & (TOPAZ_HBM_BUF_ALIGN - 1)
#error EMAC Buffer start not aligned
#endif
#if TOPAZ_HBM_BUF_WMAC_RX_BASE & (TOPAZ_HBM_BUF_ALIGN - 1)
#error WMAC Buffer start not aligned
#endif
#else
/* Offset from DDR beginning, from which memory start to belong to Linux */
#define CONFIG_ARC_KERNEL_MEM_BASE CONFIG_ARC_MUC_END
#endif
#define CONFIG_ARC_UBOOT_RESERVED_SPACE (8 * 1024)
/* Linux kernel u-boot image start address, for uncompressed images */
#define CONFIG_ARC_KERNEL_BOOT_BASE ROUNDUP(CONFIG_ARC_KERNEL_MEM_BASE, \
CONFIG_ARC_KERNEL_PAGE_SIZE)
/* Linux kernel image start */
#define CONFIG_ARC_KERNEL_BASE (CONFIG_ARC_KERNEL_BOOT_BASE + CONFIG_ARC_UBOOT_RESERVED_SPACE)
#define CONFIG_ARC_KERNEL_MAX_SIZE (RUBY_MAX_DRAM_SIZE - CONFIG_ARC_KERNEL_MEM_BASE)
#define CONFIG_ARC_KERNEL_MIN_SIZE (RUBY_MIN_DRAM_SIZE - CONFIG_ARC_KERNEL_MEM_BASE)
/* AuC tightly coupled memory specification */
#define TOPAZ_AUC_IMEM_ADDR 0xE5000000
#define TOPAZ_AUC_IMEM_SIZE (32 * 1024)
/* BBIC4 RevB AuC DMEM bottom 4KB: 0xE510_0000 to 0xE510_0FFF is aliased with Wmac1 TCM 0xE514_0000
* exclude the bottom 4K from DMEM, and reduce the size from 16KB to 12KB
*/
#define TOPAZ_AUC_DMEM_ADDR 0xE5101000
#define TOPAZ_AUC_DMEM_SIZE (12 * 1024)
#define TOPAZ_REVB_DMEM_SIZE_RESERVED (4 *1024)
/***************/
/* Utility functions */
#ifndef __ASSEMBLY__
#if defined(__CHECKER__)
#define __sram_text
#define __sram_data
#elif defined(__GNUC__)
/*GCC*/
#if defined(CONFIG_ARCH_RUBY_NUMA) && defined(__KERNEL__) && defined(__linux__)
/* Kernel is compiled with -mlong-calls option, so we can make calls between code fragments placed in different memories */
#define __sram_text_sect_name ".sram.text"
#define __sram_data_sect_name ".sram.data"
#if defined(PROFILE_LINUX_EP) || defined(TOPAZ_PLATFORM)
# define __sram_text
# define __sram_data
#else
# define __sram_text __attribute__ ((__section__ (__sram_text_sect_name)))
# define __sram_data __attribute__ ((__section__ (__sram_data_sect_name)))
#endif
#else
#define __sram_text_sect_name ".text"
#define __sram_data_sect_name ".data"
#define __sram_text
#define __sram_data
#endif
#else
#pragma Offwarn(428)
#endif
RUBY_INLINE int is_valid_mem_addr(unsigned long addr)
{
if (__in_mem_range(addr, RUBY_SRAM_BEGIN, RUBY_SRAM_SIZE)) {
return 1;
} else if (__in_mem_range(addr, RUBY_DRAM_BEGIN, RUBY_MAX_DRAM_SIZE)) {
return 1;
}
return 0;
}
#if TOPAZ_MMAP_UNIFIED
RUBY_WEAK(virt_to_nocache) void* virt_to_nocache(const void *addr)
{
unsigned long ret = (unsigned long)addr;
if (__in_mem_range(ret, RUBY_SRAM_BEGIN, RUBY_SRAM_SIZE)) {
ret = ret - RUBY_SRAM_BEGIN + RUBY_SRAM_NOCACHE_BEGIN;
} else if (__in_mem_range(ret, RUBY_DRAM_BEGIN, RUBY_MAX_DRAM_SIZE)) {
ret = ret - RUBY_DRAM_BEGIN + RUBY_DRAM_NOCACHE_BEGIN;
} else if (ret < RUBY_HARDWARE_BEGIN) {
ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
}
return (void*)ret;
}
RUBY_WEAK(nocache_to_virt) void* nocache_to_virt(const void *addr)
{
unsigned long ret = (unsigned long)addr;
if (__in_mem_range(ret, RUBY_SRAM_NOCACHE_BEGIN, RUBY_SRAM_SIZE)) {
ret = ret - RUBY_SRAM_NOCACHE_BEGIN + RUBY_SRAM_BEGIN;
} else if (__in_mem_range(ret, RUBY_DRAM_NOCACHE_BEGIN, RUBY_MAX_DRAM_SIZE)) {
ret = ret - RUBY_DRAM_NOCACHE_BEGIN + RUBY_DRAM_BEGIN;
} else if (ret < RUBY_HARDWARE_BEGIN) {
ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
}
return (void*)ret;
}
#endif
#if RUBY_MUC_TLB_ENABLE
#if TOPAZ_MMAP_UNIFIED
#define muc_to_nocache virt_to_nocache
#define nocache_to_muc nocache_to_virt
#else
RUBY_WEAK(muc_to_nocache) void* muc_to_nocache(const void *addr)
{
unsigned long ret = (unsigned long)addr;
if (__in_mem_range(ret, RUBY_SRAM_NOFLIP_BEGIN, RUBY_SRAM_SIZE)) {
ret = ret - RUBY_SRAM_NOFLIP_BEGIN + RUBY_SRAM_NOFLIP_NOCACHE_BEGIN;
} else if (__in_mem_range(ret, RUBY_DRAM_NOFLIP_BEGIN, RUBY_MAX_DRAM_SIZE)) {
ret = ret - RUBY_DRAM_NOFLIP_BEGIN + RUBY_DRAM_NOFLIP_NOCACHE_BEGIN;
} else if (ret < RUBY_HARDWARE_BEGIN) {
ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
}
return (void*)ret;
}
RUBY_WEAK(nocache_to_muc) void* nocache_to_muc(const void *addr)
{
unsigned long ret = (unsigned long)addr;
if (__in_mem_range(ret, RUBY_SRAM_NOFLIP_NOCACHE_BEGIN, RUBY_SRAM_SIZE)) {
ret = ret - RUBY_SRAM_NOFLIP_NOCACHE_BEGIN + RUBY_SRAM_NOFLIP_BEGIN;
} else if (__in_mem_range(ret, RUBY_DRAM_NOFLIP_NOCACHE_BEGIN, RUBY_MAX_DRAM_SIZE)) {
ret = ret - RUBY_DRAM_NOFLIP_NOCACHE_BEGIN + RUBY_DRAM_NOFLIP_BEGIN;
} else if (ret < RUBY_HARDWARE_BEGIN) {
ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
}
return (void*)ret;
}
#endif
#ifndef MUC_BUILD
RUBY_INLINE unsigned long muc_to_lhost(unsigned long addr)
{
void *tmp = nocache_to_muc((void*)addr);
if (tmp != RUBY_BAD_VIRT_ADDR) {
addr = (unsigned long)tmp;
}
return (unsigned long)bus_to_virt(addr);
}
#endif // #ifndef MUC_BUILD
#else
#define muc_to_nocache(x) ((void*)(x))
#define nocache_to_muc(x) ((void*)(x))
#ifndef MUC_BUILD
#define muc_to_lhost(x) ((unsigned long)bus_to_virt((unsigned long)(x)))
#endif // #ifndef MUC_BUILD
#endif // #if RUBY_MUC_TLB_ENABLE
#ifndef __GNUC__
/*MCC*/
#pragma Popwarn()
#endif
#endif // #ifndef __ASSEMBLY__
/*
* "Write memory barrier" instruction emulation.
* Ruby platform has complex net of connected buses.
* Write transactions are buffered.
* qtn_wmb() guarantees that all issued earlier and pending writes
* to system controller, to SRAM and to DDR are completed
* before qtn_wmb() is finished.
* For complete safety Linux's wmb() should be defined
* through qtn_wmb(), but I afraid it would kill performance.
*/
#ifndef __ASSEMBLY__
#define RUBY_SYS_CTL_SAFE_READ_REGISTER 0xE0000000
#if defined(__GNUC__) && defined(__i386__)
#define qtn_wmb() do {} while(0)
static inline unsigned long _qtn_addr_wmb(unsigned long *addr) { return *addr; }
#define qtn_addr_wmb(addr) _qtn_addr_wmb((unsigned long *)(addr))
#define qtn_pipeline_drain() do {} while(0)
#elif defined(__GNUC__)
/*GCC*/
#if defined(__arc__)
#define qtn_wmb() \
({ \
unsigned long temp; \
__asm__ __volatile__ ( \
"ld.di %0, [%1]\n\t" \
"ld.di %0, [%2]\n\t" \
"ld.di %0, [%3]\n\t" \
"sync\n\t" \
: "=r"(temp) \
: "i"(RUBY_DRAM_BEGIN + CONFIG_ARC_KERNEL_MEM_BASE), "i"(RUBY_SRAM_BEGIN + CONFIG_ARC_KERNEL_SRAM_B1_BASE), "i"(RUBY_SYS_CTL_SAFE_READ_REGISTER) \
: "memory"); \
})
#define qtn_addr_wmb(addr) \
({ \
unsigned long temp; \
__asm__ __volatile__ ( \
"ld.di %0, [%1]\n\t" \
"sync\n\t" \
: "=r"(temp) \
: "r"(addr) \
: "memory"); \
temp; \
})
#define qtn_pipeline_drain() \
({ \
__asm__ __volatile__ ( \
"sync\n\t" \
: : : "memory"); \
})
#else
#define qtn_wmb()
#define qtn_addr_wmb(addr) *((volatile uint32_t*)addr)
#define qtn_pipeline_drain()
#endif
#else
/*MCC*/
#if _ARCVER >= 0x31/*ARC7*/
#define _qtn_pipeline_drain() \
sync
#else
#define _qtn_pipeline_drain() \
nop_s; nop_s; nop_s
#endif
_Asm void qtn_wmb(void)
{
/*r12 is temporary register, so we can use it inside this function freely*/
ld.di %r12, [RUBY_DRAM_BEGIN + CONFIG_ARC_MUC_BASE]
ld.di %r12, [RUBY_SRAM_BEGIN + CONFIG_ARC_MUC_SRAM_B1_BASE]
ld.di %r12, [RUBY_SYS_CTL_SAFE_READ_REGISTER]
_qtn_pipeline_drain()
}
_Asm u_int32_t qtn_addr_wmb(unsigned long addr)
{
%reg addr;
ld.di %r0, [addr]
_qtn_pipeline_drain()
}
_Asm void qtn_pipeline_drain(void)
{
_qtn_pipeline_drain()
}
#endif
#endif
/*
* Problem - writing to first half of cache way trash second half.
* Idea is to lock second half.
* Need make sure that invalidation does not unlock these lines (whole
* cache invalidation unlocks), or need to re-lock lines back.
* Also side effect - half of lines will be cached, half - not.
* So may need to shuffle data to make hot data cacheable.
*/
#define TOPAZ_CACHE_WAR_OFFSET 2048
#ifndef __ASSEMBLY__
#ifdef __GNUC__
RUBY_INLINE void qtn_cache_topaz_war_dcache_lock(unsigned long aux_reg, unsigned long val)
{
unsigned long addr;
unsigned long way_iter;
unsigned long line_iter;
asm volatile (
" sr %4, [%3]\n"
" mov %0, 0xA0000000\n"
" mov %1, 0\n"
"1: add %0, %0, 2048\n"
" mov %2, 0\n"
"2: sr %0, [0x49]\n"
" add %0, %0, 32\n"
" add %2, %2, 1\n"
" cmp %2, 64\n"
" bne 2b\n"
" add %1, %1, 1\n"
" cmp %1, 4\n"
" bne 1b\n"
: "=r"(addr), "=r"(way_iter), "=r"(line_iter)
: "r"(aux_reg), "r"(val)
);
}
#else
_Inline _Asm void qtn_cache_topaz_war_dcache_lock(unsigned long aux_reg, unsigned long val)
{
% reg aux_reg, reg val;
sr val, [aux_reg]
mov %r0, 0xA0000000
mov %r1, 0
1: add %r0, %r0, 2048
mov %r2, 0
2: sr %r0, [0x49]
add %r0, %r0, 32
add %r2, %r2, 1
cmp %r2, 64
bne 2b
add %r1, %r1, 1
cmp %r1, 4
bne 1b
}
#endif // #ifdef __GNUC__
#endif // #ifndef __ASSEMBLY__
#endif // #ifndef __RUBY_MEM_H

View File

@ -0,0 +1,160 @@
/*
* (C) Copyright 2012 Quantenna Communications Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef __RUBY_PM_H
#define __RUBY_PM_H
/* Power save levels */
#define BOARD_PM_LEVEL_FORCE_NO (0)
#define BOARD_PM_LEVEL_NO (1)
#define BOARD_PM_LEVEL_SLOW_DOWN (2)
#define BOARD_PM_LEVEL_LATENCY_UP (3)
#define BOARD_PM_LEVEL_DISTANCE_DOWN (4)
#define BOARD_PM_LEVEL_IDLE (5)
#define BOARD_PM_LEVEL_SUSPEND (6)
#define BOARD_PM_LEVEL_INIT BOARD_PM_LEVEL_FORCE_NO
/* Duty level, shared between Lhost and MuC */
#define BOARD_PM_LEVEL_DUTY BOARD_PM_LEVEL_IDLE
/* Names of power save governors */
#define BOARD_PM_GOVERNOR_WLAN "wlan"
#define BOARD_PM_GOVERNOR_QDISC "qdisc"
#define BOARD_PM_GOVERNOR_QCSAPI "qcsapi"
/* wlan timings to switch between modes */
#define BOARD_PM_WLAN_IDLE_TIMEOUT (120 * HZ)
#define BOARD_PM_WLAN_DEFAULT_TIMEOUT (0)
/* qdisc parameters to switch between modes */
#define BOARD_PM_QDISC_TIMER_TIMEOUT (50/*ms*/ * HZ / 1000)
#define BOARD_PM_QDISC_SPEEDUP_THRESHOLD (400)
#define BOARD_PM_QDISC_SLOWDOWN_THRESHOLD (100)
#define BOARD_PM_QDISC_SLOWDOWN_COUNT (80)
#define BOARD_PM_QDISC_SLOWDOWN_TIMEOUT (3 * HZ)
#define BOARD_PM_QDISC_DEFAULT_TIMEOUT (0)
/* Beacon TSF setting */
#define BOARD_PM_WAKE_BEACON_TSF_DEADLINE_PCT (50)
#define BOARD_PM_WAKE_BEACON_TSF_ALERT_PCT (25)
/* Default setting, shared between Lhost and MuC */
#define BOARD_PM_PDUTY_PERIOD_MS_DEFAULT 80
#define BOARD_PM_PDUTY_PCT_LOW_DEFAULT 80
#define BOARD_PM_SUSPEND_PERIOD_MS_DEFAULT 100
#define BOARD_PM_SUSPEND_PCT_LOW_DEFAULT 99
/* Multiple Periods Support */
#define BOARD_PM_PERIOD_CHANGE_INTERVAL 1
#define BOARD_PM_PERIOD_CNT 3
enum qtn_pm_param {
QTN_PM_CURRENT_LEVEL,
QTN_PM_SUSPEND,
QTN_PM_SUSPEND_PERIOD_MS,
QTN_PM_SUSPEND_PCT_LOW,
QTN_PM_SUSPEND_HRESET,
QTN_PM_SUSPEND_ALLCHAINS_DISABLE,
QTN_PM_PDUTY,
QTN_PM_PDUTY_PERIOD_MS,
QTN_PM_PDUTY_PCT_LOW,
QTN_PM_PDUTY_HRESET,
QTN_PM_PDUTY_RXCHAINS_DISABLE,
QTN_PM_MUC_SLEEP,
QTN_PM_RXCHAIN_IDLE_COUNT,
QTN_PM_RXCHAIN_IDLE_LEVEL,
QTN_PM_TXCHAIN_IDLE_COUNT,
QTN_PM_TXCHAIN_IDLE_LEVEL,
QTN_PM_PAUSE_MGMT_PROBERESP,
QTN_PM_PAUSE_MGMT_ASSOCRESP,
QTN_PM_PAUSE_MGMT_AUTH,
/* For Multiple Periods Support */
QTN_PM_PERIOD_CHANGE_INTERVAL, /* How long period setting will be changed(unit: second) */
QTN_PM_PERIOD_CNT, /* How many periods in period group(Max 3) */
QTN_PM_PERIOD_GROUP, /* Period group(Max 3 periods, each <= 255ms, unit: millisecond)*/
QTN_PM_IOCTL_MAX
};
#define QTN_PM_PARAM_NAMES { \
"level", /* QTN_PM_CURRENT_LEVEL */ \
"suspend_level", /* QTN_PM_SUSPEND */ \
"suspend_period", /* QTN_PM_SUSPEND_PERIOD_MS */ \
"suspend_pct", /* QTN_PM_SUSPEND_PCT_LOW */ \
"suspend_hreset", /* QTN_PM_SUSPEND_HRESET */ \
"suspend_allchains", /* QTN_PM_SUSPEND_ALLCHAINS_DISABLE */ \
"pduty_level", /* QTN_PM_PDUTY */ \
"pduty_period", /* QTN_PM_PDUTY_PERIOD_MS */ \
"pduty_pct", /* QTN_PM_PDUTY_PCT_LOW */ \
"pduty_hreset", /* QTN_PM_PDUTY_HRESET */ \
"pduty_rxchains", /* QTN_PM_PDUTY_RXCHAINS_DISABLE */ \
"muc_sleep_level", /* QTN_PM_MUC_SLEEP */ \
"rxchain_count", /* QTN_PM_RXCHAIN_IDLE_COUNT */ \
"rxchain_level", /* QTN_PM_RXCHAIN_IDLE_LEVEL */ \
"txchain_count", /* QTN_PM_TXCHAIN_IDLE_COUNT */ \
"txchain_level", /* QTN_PM_TXCHAIN_IDLE_LEVEL */ \
"pause_proberesp", /* QTN_PM_PAUSE_MGMT_PROBERESP */ \
"pause_assocresp", /* QTN_PM_PAUSE_MGMT_ASSOCRESP */ \
"pause_auth", /* QTN_PM_PAUSE_MGMT_ASSOCRESP */ \
"period_change_interval", /* QTN_PM_PERIOD_CHANGE_INTERVAL */ \
"period_cnt", /* QTN_PM_PERIOD_CNT */ \
"period_group" /* QTN_PM_PERIOD_GROUP */ \
}
#define QTN_PM_PARAM_DEFAULTS { \
BOARD_PM_LEVEL_INIT, /* QTN_PM_CURRENT_LEVEL */ \
BOARD_PM_LEVEL_SUSPEND, /* QTN_PM_SUSPEND */ \
BOARD_PM_SUSPEND_PERIOD_MS_DEFAULT, /* QTN_PM_SUSPEND_PERIOD_MS */ \
BOARD_PM_SUSPEND_PCT_LOW_DEFAULT, /* QTN_PM_SUSPEND_PCT_LOW */ \
1, /* QTN_PM_SUSPEND_HRESET */ \
1, /* QTN_PM_SUSPEND_ALL_CHAINS_DISABLE */ \
BOARD_PM_LEVEL_DUTY, /* QTN_PM_PDUTY */ \
BOARD_PM_PDUTY_PERIOD_MS_DEFAULT, /* QTN_PM_PDUTY_PERIOD_MS */ \
BOARD_PM_PDUTY_PCT_LOW_DEFAULT, /* QTN_PM_PDUTY_PCT_LOW */ \
0, /* QTN_PM_PDUTY_HRESET */ \
1, /* QTN_PM_PDUTY_RXCHAINS_DISABLE */ \
BOARD_PM_LEVEL_LATENCY_UP, /* QTN_PM_MUC_SLEEP */ \
4, /* QTN_PM_RXCHAIN_IDLE_COUNT */ \
BOARD_PM_LEVEL_DISTANCE_DOWN, /* QTN_PM_RXCHAIN_IDLE_LEVEL */ \
4, /* QTN_PM_TXCHAIN_IDLE_COUNT */ \
BOARD_PM_LEVEL_DISTANCE_DOWN, /* QTN_PM_TXCHAIN_IDLE_LEVEL */ \
60000, /* QTN_PM_PAUSE_MGMT_PROBERESP */ \
5000, /* QTN_PM_PAUSE_MGMT_ASSOCRESP */ \
5000, /* QTN_PM_PAUSE_MGMT_AUTH */ \
BOARD_PM_PERIOD_CHANGE_INTERVAL, /* QTN_PM_PERIOD_CHANGE_INTERVAL */ \
BOARD_PM_PERIOD_CNT, /* QTN_PM_PERIOD_CNT */ \
0x50321E /* QTN_PM_PERIOD_GROUP(30ms, 50ms, 80ms) */ \
}
#define QTN_PM_UNPACK_PARAM(x) ((x) & 0xFF)
#define QTN_PM_UNPACK_VALUE(x) ((x) >> 8)
#define QTN_PM_PACK_PARAM_VALUE(p, v) (((p) & 0xFF) | (((v) << 8) & 0xFFFFFF00))
#endif /* __RUBY_PM_H */

View File

@ -0,0 +1,189 @@
/*
* (C) Copyright 2010 Quantenna Communications Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/*
* Header file which describes Topaz platform.
* Has to be used by both kernel and bootloader.
*/
#ifndef __TOPAZ_CONFIG_H
#define __TOPAZ_CONFIG_H
#include "current_platform.h"
#ifdef TOPAZ_PLATFORM
#if !TOPAZ_FPGA_PLATFORM
#undef TOPAZ_ICACHE_WORKAROUND
#endif
#endif
/*
* Control registers move depending on unified + alias bit
*/
#ifdef TOPAZ_PLATFORM
#define TOPAZ_MMAP_UNIFIED 0
#define TOPAZ_MMAP_ALIAS 0
#define TOPAZ_RX_ACCELERATE 1
#else
#define TOPAZ_MMAP_UNIFIED 0
#define TOPAZ_MMAP_ALIAS 0
#define TOPAZ_RX_ACCELERATE 0
#endif
/* If MU-MIMO done in HDP or SDP */
#ifdef TOPAZ_PLATFORM
#define QTN_HDP_MU 1
#else
#define QTN_HDP_MU 0
#endif
#if QTN_HDP_MU
#define QTN_HDP_MU_FCS_WORKROUND 1
#else
#define QTN_HDP_MU_FCS_WORKROUND 0
#endif
#if TOPAZ_MMAP_ALIAS && !TOPAZ_MMAP_UNIFIED
#error Alias map requires unified map
#endif
#if TOPAZ_MMAP_ALIAS
#define TOPAZ_ALIAS_MAP_SWITCH(a, b) (b)
#else
#define TOPAZ_ALIAS_MAP_SWITCH(a, b) (a)
#endif
/* Topaz fixed phy addresses */
#define TOPAZ_FPGAA_PHY0_ADDR 2
#define TOPAZ_FPGAA_PHY1_ADDR 3
#define TOPAZ_FPGAB_PHY0_ADDR 4
#define TOPAZ_FPGAB_PHY1_ADDR 1
#define TOPAZ_PHY0_ADDR 1
#define TOPAZ_PHY1_ADDR 3
#ifndef TOPAZ_FPGA_PLATFORM
#define TOPAZ_FPGA_PLATFORM 0
#endif
#ifndef TOPAZ_VNET_WR_STAGING
#define TOPAZ_VNET_WR_STAGING 0
#endif
#define TOPAZ_VNET_WR_DMA_CHANNELS 2
#define TOPAZ_VNET_WR_STAGING_BUF_COUNT_PER_CHAIN 10
#define TOPAZ_VNET_WR_STAGING_BUF_SIZE 0x600
#if TOPAZ_VNET_WR_STAGING
#define TOPAZ_VNET_WR_STAGING_ALIGN 0x80
#define TOPAZ_VNET_WR_STAGING_GAP TOPAZ_VNET_WR_STAGING_ALIGN
#define TOPAZ_VNET_WR_STAGING_RESERVE ((TOPAZ_VNET_WR_STAGING_BUF_COUNT_PER_CHAIN * \
TOPAZ_VNET_WR_STAGING_BUF_SIZE) + \
TOPAZ_VNET_WR_STAGING_GAP)
#else
#define TOPAZ_VNET_WR_STAGING_RESERVE 0
#endif
#ifdef TOPAZ_PLATFORM
/* Definition indicates that Topaz platform is FPGA */
#if TOPAZ_FPGA_PLATFORM
/* CLK speeds are in MHz and 1/10th the speed of actual ASIC */
#define TOPAZ_SERIAL_BAUD 38400
#define TOPAZ_APB_CLK 12500000
#define TOPAZ_AHB_CLK 25000000
#define TOPAZ_CPU_CLK 50000000
#define RUBY_FPGA_DDR
#else
#define TOPAZ_SERIAL_BAUD 115200
#define TOPAZ_APB_CLK 125000000
#define TOPAZ_AHB_CLK 250000000
#define TOPAZ_CPU_CLK 500000000
#define RUBY_ASIC_DDR
#endif /* #if TOPAZ_FPGA_PLATFORM */
/*
* Setting UPF_SPD_FLAG gives a developer the option to set the
* flag to match a UPF_ define from <linux>/include/linux/serial_core.h
* or set the value to 0 to use the default baud rate setting DEFAULT_BAUD
*/
#define UPF_SPD_FLAG 0
#define DEFAULT_BAUD TOPAZ_SERIAL_BAUD
/*
* Re-use Ruby defines to simplify the number of changes required
* to compile new binaries for Topaz
*/
#define RUBY_SERIAL_BAUD TOPAZ_SERIAL_BAUD
#define RUBY_FIXED_DEV_CLK TOPAZ_APB_CLK
#define RUBY_FIXED_CPU_CLK TOPAZ_CPU_CLK
#ifdef PLATFORM_DEFAULT_BOARD_ID
#define DEFAULT_BOARD_ID PLATFORM_DEFAULT_BOARD_ID
#else
/* Default board id used to match Topaz setting if there is no SPI Flash */
#define DEFAULT_BOARD_ID QTN_TOPAZ_BB_BOARD
#endif /* TOPAZ_DEFAULT_BOARD_ID */
#ifndef PLATFORM_ARC7_MMU_VER
#define PLATFORM_ARC7_MMU_VER 2
#endif
#define CONFIG_RUBY_BROKEN_IPC_IRQS 0
#define RUBY_IPC_HI_IRQ(bit_num) ((bit_num) + 8)
#define RUBY_M2L_IPC_HI_IRQ(bit_num) (bit_num)
#define PLATFORM_REG_SWITCH(reg1, reg2) (reg2)
#define writel_topaz(a, b) writel(a, b)
#define writel_ruby(a, b)
#define QTN_VLAN_LLC_ENCAP 1
#define TOPAZ_128_NODE_MODE 1
#define TOPAZ_ETH_REFLECT_SW_FWD 0
#define DSP_ENABLE_STATS 1
#else
#ifndef PLATFORM_ARC7_MMU_VER
#define PLATFORM_ARC7_MMU_VER 2
#endif
/*
* For BBIC3.
* Workaround for IPC interrupt hw flaw. When receiver dynamically masks/unmasks
* interrupt, the transmitter cannot distinguish whether interrupt was acked or just masked.
*/
#define CONFIG_RUBY_BROKEN_IPC_IRQS 1
#define RUBY_IPC_HI_IRQ(bit_num) ((bit_num) + 16)
#define RUBY_M2L_IPC_HI_IRQ(bit_num) ((bit_num) + 16)
#define PLATFORM_REG_SWITCH(reg1, reg2) (reg1)
#define writel_topaz(a, b)
#define writel_ruby(a, b) writel(a, b)
#define QTN_VLAN_LLC_ENCAP 0
#endif /* #ifdef TOPAZ_PLATFORM */
#endif /* #ifndef __TOPAZ_CONFIG_H */

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2015 Quantenna Communications, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This code is taken from u-boot/include/image.h file
*/
#ifndef UBOOT_HEADER_H
#define UBOOT_HEADER_H
#ifndef __ASSEMBLY__
#define IH_MAGIC 0x27051956 /* Image Magic Number */
#define IH_NMLEN 32 /* Image Name Length */
/*
* Legacy format image header,
* all data in network byte order (aka natural aka bigendian).
*/
typedef struct image_header {
uint32_t ih_magic; /* Image Header Magic Number */
uint32_t ih_hcrc; /* Image Header CRC Checksum */
uint32_t ih_time; /* Image Creation Timestamp */
uint32_t ih_size; /* Image Data Size */
uint32_t ih_load; /* Data Load Address */
uint32_t ih_ep; /* Entry Point Address */
uint32_t ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;
static inline uint32_t image_get_header_size(void)
{
#define MAX_KNOWN_PAGE_SIZE 8192
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
return ROUND_UP(sizeof(image_header_t), MAX_KNOWN_PAGE_SIZE);
}
struct early_flash_config {
uint32_t method;
uint32_t ipaddr;
uint32_t serverip;
uint8_t built_time_utc_sec[11];
uint8_t uboot_type;
} __attribute__ ((packed));
#endif /* __ASSEMBLY__ */
#define RUBY_BOOT_METHOD_TRYLOOP 0
#define RUBY_BOOT_METHOD_TFTP 1
#define RUBY_BOOT_METHOD_BOOTP 2
#define RUBY_BOOT_METHOD_MAX 3
#endif /* UBOOT_HEADER_H */

View File

@ -0,0 +1,135 @@
/*-
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $Id: compat.h 2601 2007-07-24 14:14:47Z kelmo $
*/
#ifndef _ATH_COMPAT_H_
#define _ATH_COMPAT_H_
/* Compatibility with older Linux kernels */
#if defined(__KERNEL__) || (defined(__linux__) && __linux__)
#include <linux/types.h>
#endif
#if !defined(__KERNEL__) || !defined (__bitwise)
#define __le16 u_int16_t
#define __le32 u_int32_t
#define __le64 u_int64_t
#define __be16 u_int16_t
#define __be32 u_int32_t
#define __be64 u_int64_t
#define __force
#endif
#ifndef container_of
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#endif
/*
* BSD/Linux compatibility shims. These are used mainly to
* minimize differences when importing necesary BSD code.
*/
#ifndef NBBY
#define NBBY 8 /* number of bits/byte */
#endif
/* roundup() appears in Linux 2.6.18 */
#ifdef __KERNEL__
#include <linux/kernel.h>
#endif
#ifndef roundup
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */
#endif
#ifndef howmany
#define howmany(x, y) (((x)+((y)-1))/(y))
#endif
/* Bit map related macros. */
#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
#ifndef __packed
#define __packed __attribute__((__packed__))
#endif
#define __printflike(_a,_b) \
__attribute__ ((__format__ (__printf__, _a, _b)))
#define __offsetof(t,m) offsetof(t,m)
#ifndef ALIGNED_POINTER
/*
* ALIGNED_POINTER is a boolean macro that checks whether an address
* is valid to fetch data elements of type t from on this architecture.
* This does not reflect the optimal alignment, just the possibility
* (within reasonable limits).
*
*/
#define ALIGNED_POINTER(p,t) 1
#endif
#ifdef __KERNEL__
#define KASSERT(exp, msg) do { \
if (unlikely(!(exp))) { \
printk msg; \
BUG(); \
} \
} while (0)
#endif /* __KERNEL__ */
/*
* NetBSD/FreeBSD defines for file version.
*/
#define __FBSDID(_s)
#define __KERNEL_RCSID(_n,_s)
/*
* Fixes for Linux API changes
*/
#ifdef __KERNEL__
#include <linux/version.h>
#define ATH_REGISTER_SYSCTL_TABLE(t) register_sysctl_table(t)
#endif /* __KERNEL__ */
/* FIXME: this needs changing if we need to support TCM/SRAM for time critical code */
#define __tcm_text
#endif /* _ATH_COMPAT_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,211 @@
/*-
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id: ieee80211_crypto.h 1441 2006-02-06 16:03:21Z mrenzmann $
*/
#ifndef _NET80211_IEEE80211_CRYPTO_H_
#define _NET80211_IEEE80211_CRYPTO_H_
/*
* 802.11 protocol crypto-related definitions.
*/
#define IEEE80211_KEYBUF_SIZE 16
#define IEEE80211_MICBUF_SIZE (8 + 8) /* space for both tx+rx keys */
#define IEEE80211_QOS_TID_MAX 16
#define IEEE80211_RSC_NON_QOS (IEEE80211_QOS_TID_MAX)
#define IEEE80211_RSC_ROBUST_MGMT (IEEE80211_QOS_TID_MAX + 1)
#define IEEE80211_RSC_MAX (IEEE80211_QOS_TID_MAX + 2)
/*
* Old WEP-style key. Deprecated.
*/
struct ieee80211_wepkey {
u_int wk_len; /* key length in bytes */
u_int8_t wk_key[IEEE80211_KEYBUF_SIZE];
};
struct ieee80211_cipher;
/*
* Crypto key state. There is sufficient room for all supported
* ciphers (see below). The underlying ciphers are handled
* separately through loadable cipher modules that register with
* the generic crypto support. A key has a reference to an instance
* of the cipher; any per-key state is hung off wk_private by the
* cipher when it is attached. Ciphers are automatically called
* to detach and cleanup any such state when the key is deleted.
*
* The generic crypto support handles encap/decap of cipher-related
* frame contents for both hardware- and software-based implementations.
* A key requiring software crypto support is automatically flagged and
* the cipher is expected to honor this and do the necessary work.
* Ciphers such as TKIP may also support mixed hardware/software
* encrypt/decrypt and MIC processing.
*
* Note: This definition must be the same as qtn_key.
*/
struct ieee80211_key {
u_int8_t wk_keylen; /* key length in bytes */
u_int8_t wk_flags;
#define IEEE80211_KEY_XMIT 0x01 /* key used for xmit */
#define IEEE80211_KEY_RECV 0x02 /* key used for recv */
#define IEEE80211_KEY_GROUP 0x04 /* key used for WPA group operation */
#define IEEE80211_KEY_SWCRYPT 0x10 /* host-based encrypt/decrypt */
#define IEEE80211_KEY_SWMIC 0x20 /* host-based enmic/demic */
#define IEEE80211_KEY_VLANGROUP 0x40 /* VLAN group key */
u_int16_t wk_keyix; /* key index */
u_int8_t wk_key[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE];
#define wk_txmic wk_key + IEEE80211_KEYBUF_SIZE + 0
#define wk_rxmic wk_key + IEEE80211_KEYBUF_SIZE + 8
u_int64_t wk_keyrsc[IEEE80211_RSC_MAX]; /* key receive sequence counter */
u_int64_t wk_keytsc; /* key transmit sequence counter */
u_int32_t wk_ciphertype;
const struct ieee80211_cipher *wk_cipher;
void *wk_private; /* private cipher state */
};
#define IEEE80211_KEY_COMMON /* common flags passed in by apps */\
(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP)
/*
* NB: these values are ordered carefully; there are lots of
* of implications in any reordering. In particular beware
* that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
*/
#define IEEE80211_CIPHER_WEP 0
#define IEEE80211_CIPHER_TKIP 1
#define IEEE80211_CIPHER_AES_OCB 2
#define IEEE80211_CIPHER_AES_CCM 3
#define IEEE80211_CIPHER_AES_CMAC 4
#define IEEE80211_CIPHER_CKIP 5
#define IEEE80211_CIPHER_NONE 6 /* pseudo value */
#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1)
#define IEEE80211_KEYIX_NONE ((u_int8_t) - 1)
#if defined(__KERNEL__) || defined(_KERNEL)
struct ieee80211com;
struct ieee80211vap;
struct ieee80211_node;
struct sk_buff;
void ieee80211_crypto_attach(struct ieee80211com *);
void ieee80211_crypto_detach(struct ieee80211com *);
void ieee80211_crypto_vattach(struct ieee80211vap *);
void ieee80211_crypto_vdetach(struct ieee80211vap *);
int ieee80211_crypto_newkey(struct ieee80211vap *, int, int,
struct ieee80211_key *);
int ieee80211_crypto_delkey(struct ieee80211vap *, struct ieee80211_key *,
struct ieee80211_node *);
int ieee80211_crypto_setkey(struct ieee80211vap *, struct ieee80211_key *,
const u_int8_t macaddr[IEEE80211_ADDR_LEN], struct ieee80211_node *);
void ieee80211_crypto_delglobalkeys(struct ieee80211vap *);
/*
* Template for a supported cipher. Ciphers register with the
* crypto code and are typically loaded as separate modules
* (the null cipher is always present).
* XXX may need refcnts
*/
struct ieee80211_cipher {
const char *ic_name; /* printable name */
u_int ic_cipher; /* IEEE80211_CIPHER_* */
u_int ic_header; /* size of privacy header (bytes) */
u_int ic_trailer; /* size of privacy trailer (bytes) */
u_int ic_miclen; /* size of mic trailer (bytes) */
void *(*ic_attach)(struct ieee80211vap *, struct ieee80211_key *);
void (*ic_detach)(struct ieee80211_key *);
int (*ic_setkey)(struct ieee80211_key *);
int (*ic_encap)(struct ieee80211_key *, struct sk_buff *, u_int8_t);
int (*ic_decap)(struct ieee80211_key *, struct sk_buff *, int);
int (*ic_enmic)(struct ieee80211_key *, struct sk_buff *, int);
int (*ic_demic)(struct ieee80211_key *, struct sk_buff *, int);
};
extern const struct ieee80211_cipher ieee80211_cipher_none;
void ieee80211_crypto_register(const struct ieee80211_cipher *);
void ieee80211_crypto_unregister(const struct ieee80211_cipher *);
int ieee80211_crypto_available(u_int);
struct ieee80211_key *ieee80211_crypto_encap(struct ieee80211_node *,
struct sk_buff *);
struct ieee80211_key *ieee80211_crypto_decap(struct ieee80211_node *,
struct sk_buff *, int);
/*
* Check and remove any MIC.
*/
static __inline int
ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
struct sk_buff *skb, int hdrlen)
{
const struct ieee80211_cipher *cip = k->wk_cipher;
return (cip->ic_miclen > 0 ? cip->ic_demic(k, skb, hdrlen) : 1);
}
/*
* Add any MIC.
*/
static __inline int
ieee80211_crypto_enmic(struct ieee80211vap *vap, struct ieee80211_key *k,
struct sk_buff *skb, int force)
{
const struct ieee80211_cipher *cip = k->wk_cipher;
return (cip->ic_miclen > 0 ? cip->ic_enmic(k, skb, force) : 1);
}
/*
* Reset key state to an unused state. The crypto
* key allocation mechanism ensures other state (e.g.
* key data) is properly setup before a key is used.
*/
static __inline void
ieee80211_crypto_resetkey(struct ieee80211vap *vap, struct ieee80211_key *k,
u_int16_t ix)
{
k->wk_cipher = &ieee80211_cipher_none;;
k->wk_private = k->wk_cipher->ic_attach(vap, k);
k->wk_keyix = ix;
k->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
}
/*
* Crypto-related notification methods.
*/
void ieee80211_notify_replay_failure(struct ieee80211vap *,
const struct ieee80211_frame *, const struct ieee80211_key *,
u_int64_t rsc);
void ieee80211_notify_michael_failure(struct ieee80211vap *,
const struct ieee80211_frame *, u_int keyix);
#endif /* defined(__KERNEL__) || defined(_KERNEL) */
#endif /* _NET80211_IEEE80211_CRYPTO_H_ */

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2012 Quantenna Communications, Inc.
* All rights reserved.
*
* Common DFS re-entry definitions.
*/
#ifndef _IEEE80211_DFS_REENTRY_H
#define _IEEE80211_DFS_REENTRY_H
/*
* DFS-reentry
*/
#define IEEE80211_PICK_DOMIAN_MASK 0x0007
#define IEEE80211_PICK_ALL 0x0001 /* pick channel from all available channels */
#define IEEE80211_PICK_DFS 0x0002 /* pick channel from available DFS channel */
#define IEEE80211_PICK_NONDFS 0x0004 /* pick channel from available non-DFS channel */
#define IEEE80211_PICK_CONTROL_MASK 0x00F8
#define IEEE80211_PICK_SCAN_FLUSH 0x0008
#define IEEE80211_PICK_BG_ACTIVE 0x0010
#define IEEE80211_PICK_BG_PASSIVE_FAST 0x0020
#define IEEE80211_PICK_BG_PASSIVE_NORMAL 0x0040
#define IEEE80211_PICK_BG_PASSIVE_SLOW 0x0080
#define IEEE80211_PICK_BG_MODE_MASK 0x00F0
#define IEEE80211_PICK_ALGORITHM_MASK 0xFF00
#define IEEE80211_PICK_CLEAREST 0x0100 /* pick clearest channel */
#define IEEE80211_PICK_REENTRY 0x0200 /* pick channel again after DFS process */
#define IEEE80211_PICK_NOPICK 0x0400 /* do not pick channel */
#define IEEE80211_PICK_NOPICK_BG 0x0800 /* scan background and do not pick channel */
#define IEEE80211_PICK_DEFAULT (IEEE80211_PICK_ALL | IEEE80211_PICK_CLEAREST)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2012 Quantenna Communications, Inc.
* All rights reserved.
*
* Common QOS definitions.
*/
#ifndef _IEEE80211_QOS_H
#define _IEEE80211_QOS_H
/* WME stream classes */
#define WME_AC_BE 0 /* best effort */
#define WME_AC_BK 1 /* background */
#define WME_AC_VI 2 /* video */
#define WME_AC_VO 3 /* voice */
enum {
IEEE80211_WMMPARAMS_CWMIN = 1,
IEEE80211_WMMPARAMS_CWMAX = 2,
IEEE80211_WMMPARAMS_AIFS = 3,
IEEE80211_WMMPARAMS_TXOPLIMIT = 4,
IEEE80211_WMMPARAMS_ACM = 5,
IEEE80211_WMMPARAMS_NOACKPOLICY = 6,
};
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,740 @@
/*SH1
*******************************************************************************
** **
** Copyright (c) 2009 - 2012 Quantenna Communications, Inc. **
** **
** File : qcsapi_driver.h **
** Description : **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#ifndef _QCSAPI_DRIVER_H
#define _QCSAPI_DRIVER_H
#include "qcsapi_output.h"
/*
* get_api and set_api expect an interface (wifi0, eth1_0, etc.)
* get_system_value and set_system_value do NOT expect an interface. They apply to the entire device.
*/
typedef enum {
e_qcsapi_get_api = 1,
e_qcsapi_set_api,
e_qcsapi_get_system_value,
e_qcsapi_set_system_value,
/*GET API without interface name and other parameters as input*/
e_qcsapi_get_api_without_ifname_parameter,
/*SET API with interface name as parameter, but without other parameters as input*/
e_qcsapi_set_api_without_parameter,
/*GET API without interface name as parameter*/
e_qcsapi_get_api_without_ifname,
/*SET API without interface name as parameter*/
e_qcsapi_set_api_without_ifname,
e_qcsapi_nosuch_typeof_api = 0,
} qcsapi_typeof_api;
typedef enum {
e_qcsapi_option = 1,
e_qcsapi_counter,
e_qcsapi_rates,
e_qcsapi_modulation,
e_qcsapi_index,
e_qcsapi_select_SSID,
e_qcsapi_SSID_index,
e_qcsapi_LED,
e_qcsapi_file_path_config,
e_qcsapi_tdls_params,
e_qcsapi_tdls_oper,
e_qcsapi_board_parameter,
e_qcsapi_extender_params,
e_qcsapi_none,
e_qcsapi_nosuch_generic_parameter = 0
} qcsapi_generic_parameter_type;
/* enum to describe type of configuration and monitoring parameters */
typedef enum {
e_qcsapi_integer = 1,
e_qcsapi_unsigned_int,
e_qcsapi_wifi_mode,
e_qcsapi_SSID_param,
e_qcsapi_mac_addr,
e_qcsapi_string,
e_qcsapi_nosuch_specific_parameter = 0
} qcsapi_specific_parameter_type;
/*
* Abstract handle to reference a QCSAPI.
* Each QCSAPI entry point has a corresponding enum,
* but a few additional enum's are defined.
*/
typedef enum {
e_qcsapi_errno_get_message = 1,
e_qcsapi_first_entry_point = e_qcsapi_errno_get_message,
e_qcsapi_store_ipaddr,
e_qcsapi_interface_enable,
e_qcsapi_interface_get_BSSID,
e_qcsapi_interface_get_mac_addr,
e_qcsapi_interface_set_mac_addr,
e_qcsapi_interface_get_counter,
e_qcsapi_interface_get_counter64,
e_qcsapi_interface_get_status,
e_qcsapi_interface_get_ip4,
e_qcsapi_pm_get_counter,
e_qcsapi_pm_get_elapsed_time,
e_qcsapi_flash_image_update,
e_qcsapi_firmware_get_version,
e_qcsapi_system_get_time_since_start,
e_qcsapi_get_system_status,
e_qcsapi_get_random_seed,
e_qcsapi_set_random_seed,
e_qcsapi_led_get,
e_qcsapi_led_set,
e_qcsapi_led_pwm_enable,
e_qcsapi_led_brightness,
e_qcsapi_gpio_get_config,
e_qcsapi_gpio_set_config,
e_qcsapi_gpio_monitor_reset_device,
e_qcsapi_gpio_enable_wps_push_button,
e_qcsapi_file_path_get_config,
e_qcsapi_file_path_set_config,
e_qcsapi_wifi_set_wifi_macaddr,
e_qcsapi_wifi_create_restricted_bss,
e_qcsapi_wifi_create_bss,
e_qcsapi_wifi_remove_bss,
e_qcsapi_wifi_get_primary_interface,
e_qcsapi_wifi_get_interface_by_index,
e_qcsapi_wifi_get_mode,
e_qcsapi_wifi_set_mode,
e_qcsapi_wifi_reload_in_mode,
e_qcsapi_wifi_rfenable,
e_qcsapi_service_control,
e_qcsapi_wfa_cert,
e_qcsapi_wifi_rfstatus,
e_qcsapi_wifi_startprod,
e_qcsapi_wifi_get_bw,
e_qcsapi_wifi_set_bw,
e_qcsapi_wifi_get_BSSID,
e_qcsapi_wifi_get_config_BSSID,
e_qcsapi_wifi_ssid_set_bssid,
e_qcsapi_wifi_ssid_get_bssid,
e_qcsapi_wifi_get_SSID,
e_qcsapi_wifi_set_SSID,
e_qcsapi_wifi_get_channel,
e_qcsapi_wifi_set_channel,
e_qcsapi_wifi_get_auto_channel,
e_qcsapi_wifi_set_auto_channel,
e_qcsapi_wifi_get_standard,
e_qcsapi_wifi_get_dtim,
e_qcsapi_wifi_set_dtim,
e_qcsapi_wifi_get_assoc_limit,
e_qcsapi_wifi_set_assoc_limit,
e_qcsapi_wifi_get_bss_assoc_limit,
e_qcsapi_wifi_set_bss_assoc_limit,
e_qcsapi_interface_set_ip4,
e_qcsapi_wifi_get_list_channels,
e_qcsapi_wifi_get_mode_switch,
e_qcsapi_wifi_get_noise,
e_qcsapi_wifi_get_rssi_by_chain,
e_qcsapi_wifi_get_avg_snr,
e_qcsapi_wifi_get_phy_mode,
e_qcsapi_wifi_set_phy_mode,
e_qcsapi_wifi_get_option,
e_qcsapi_wifi_set_option,
e_qcsapi_wifi_get_rates,
e_qcsapi_wifi_set_rates,
e_qcsapi_wifi_get_max_bitrate,
e_qcsapi_wifi_set_max_bitrate,
e_qcsapi_wifi_get_beacon_type,
e_qcsapi_wifi_set_beacon_type,
e_qcsapi_wifi_get_beacon_interval,
e_qcsapi_wifi_set_beacon_interval,
e_qcsapi_get_board_parameter,
e_qcsapi_wifi_get_list_regulatory_regions,
e_qcsapi_wifi_get_regulatory_tx_power,
e_qcsapi_wifi_get_configured_tx_power,
e_qcsapi_wifi_set_regulatory_channel,
e_qcsapi_wifi_set_regulatory_region,
e_qcsapi_wifi_get_regulatory_region,
e_qcsapi_wifi_overwrite_country_code,
e_qcsapi_wifi_get_list_regulatory_channels,
e_qcsapi_wifi_get_list_regulatory_bands,
e_qcsapi_wifi_get_regulatory_db_version,
e_qcsapi_wifi_set_regulatory_tx_power_cap,
e_qcsapi_wifi_restore_regulatory_tx_power,
e_qcsapi_wifi_set_chan_pri_inactive,
e_qcsapi_wifi_set_chan_disabled,
e_qcsapi_wifi_get_chan_disabled,
e_qcsapi_wifi_get_tx_power,
e_qcsapi_wifi_set_tx_power,
e_qcsapi_wifi_get_tx_power_ext,
e_qcsapi_wifi_set_tx_power_ext,
e_qcsapi_wifi_get_chan_power_table,
e_qcsapi_wifi_set_chan_power_table,
e_qcsapi_wifi_get_bw_power,
e_qcsapi_wifi_set_bw_power,
e_qcsapi_wifi_get_bf_power,
e_qcsapi_wifi_set_bf_power,
e_qcsapi_wifi_get_power_selection,
e_qcsapi_wifi_set_power_selection,
e_qcsapi_wifi_get_carrier_interference,
e_qcsapi_wifi_get_congestion_idx,
e_qcsapi_wifi_get_supported_tx_power_levels,
e_qcsapi_wifi_get_current_tx_power_level,
e_qcsapi_wifi_set_power_constraint,
e_qcsapi_wifi_get_power_constraint,
e_qcsapi_wifi_set_tpc_interval,
e_qcsapi_wifi_get_tpc_interval,
e_qcsapi_wifi_get_assoc_records,
e_qcsapi_wifi_get_list_DFS_channels,
e_qcsapi_wifi_is_channel_DFS,
e_qcsapi_wifi_get_DFS_alt_channel,
e_qcsapi_wifi_set_DFS_alt_channel,
e_qcsapi_wifi_set_DFS_reentry,
e_qcsapi_wifi_get_scs_cce_channels,
e_qcsapi_wifi_get_dfs_cce_channels,
e_qcsapi_wifi_get_csw_records,
e_qcsapi_wifi_get_radar_status,
e_qcsapi_wifi_get_WEP_key_index,
e_qcsapi_wifi_set_WEP_key_index,
e_qcsapi_wifi_get_WEP_key_passphrase,
e_qcsapi_wifi_set_WEP_key_passphrase,
e_qcsapi_wifi_get_WEP_encryption_level,
e_qcsapi_wifi_get_basic_encryption_modes,
e_qcsapi_wifi_set_basic_encryption_modes,
e_qcsapi_wifi_get_basic_authentication_mode,
e_qcsapi_wifi_set_basic_authentication_mode,
e_qcsapi_wifi_get_WEP_key,
e_qcsapi_wifi_set_WEP_key,
e_qcsapi_wifi_get_WPA_encryption_modes,
e_qcsapi_wifi_set_WPA_encryption_modes,
e_qcsapi_wifi_get_WPA_authentication_mode,
e_qcsapi_wifi_set_WPA_authentication_mode,
e_qcsapi_wifi_get_interworking,
e_qcsapi_wifi_set_interworking,
e_qcsapi_wifi_get_80211u_params,
e_qcsapi_wifi_set_80211u_params,
e_qcsapi_security_get_nai_realms,
e_qcsapi_security_add_nai_realm,
e_qcsapi_security_del_nai_realm,
e_qcsapi_security_add_roaming_consortium,
e_qcsapi_security_del_roaming_consortium,
e_qcsapi_security_get_roaming_consortium,
e_qcsapi_security_get_venue_name,
e_qcsapi_security_add_venue_name,
e_qcsapi_security_del_venue_name,
e_qcsapi_security_get_oper_friendly_name,
e_qcsapi_security_add_oper_friendly_name,
e_qcsapi_security_del_oper_friendly_name,
e_qcsapi_security_add_hs20_conn_capab,
e_qcsapi_security_get_hs20_conn_capab,
e_qcsapi_security_del_hs20_conn_capab,
e_qcsapi_wifi_get_hs20_status,
e_qcsapi_wifi_set_hs20_status,
e_qcsapi_wifi_get_hs20_params,
e_qcsapi_wifi_set_hs20_params,
e_qcsapi_wifi_get_proxy_arp,
e_qcsapi_wifi_set_proxy_arp,
e_qcsapi_wifi_get_l2_ext_filter,
e_qcsapi_wifi_set_l2_ext_filter,
e_qcsapi_remove_11u_param,
e_qcsapi_remove_hs20_param,
e_qcsapi_wifi_get_IEEE11i_encryption_modes,
e_qcsapi_wifi_set_IEEE11i_encryption_modes,
e_qcsapi_wifi_get_IEEE11i_authentication_mode,
e_qcsapi_wifi_set_IEEE11i_authentication_mode,
e_qcsapi_wifi_get_michael_errcnt,
e_qcsapi_wifi_get_pre_shared_key,
e_qcsapi_wifi_set_pre_shared_key,
e_qcsapi_wifi_add_radius_auth_server_cfg,
e_qcsapi_wifi_del_radius_auth_server_cfg,
e_qcsapi_wifi_get_radius_auth_server_cfg,
e_qcsapi_wifi_set_own_ip_addr,
e_qcsapi_wifi_set_own_ip_address,
e_qcsapi_wifi_get_psk_auth_failures,
e_qcsapi_wifi_get_key_passphrase,
e_qcsapi_wifi_set_key_passphrase,
e_qcsapi_wifi_get_group_key_interval,
e_qcsapi_wifi_set_group_key_interval,
e_qcsapi_wifi_get_pmf,
e_qcsapi_wifi_set_pmf,
e_qcsapi_wifi_get_count_associations,
e_qcsapi_wifi_get_associated_device_mac_addr,
e_qcsapi_wifi_get_associated_device_ip_addr,
e_qcsapi_wifi_get_link_quality,
e_qcsapi_wifi_get_rssi_per_association,
e_qcsapi_wifi_get_rssi_in_dbm_per_association,
e_qcsapi_wifi_get_snr_per_association,
e_qcsapi_wifi_get_hw_noise_per_association,
e_qcsapi_wifi_get_rx_bytes_per_association,
e_qcsapi_wifi_get_tx_bytes_per_association,
e_qcsapi_wifi_get_rx_packets_per_association,
e_qcsapi_wifi_get_tx_packets_per_association,
e_qcsapi_wifi_get_tx_err_packets_per_association,
e_qcsapi_wifi_get_bw_per_association,
e_qcsapi_wifi_get_tx_phy_rate_per_association,
e_qcsapi_wifi_get_rx_phy_rate_per_association,
e_qcsapi_wifi_get_tx_mcs_per_association,
e_qcsapi_wifi_get_rx_mcs_per_association,
e_qcsapi_wifi_get_achievable_tx_phy_rate_per_association,
e_qcsapi_wifi_get_achievable_rx_phy_rate_per_association,
e_qcsapi_wifi_get_auth_enc_per_association,
e_qcsapi_wifi_get_tput_caps,
e_qcsapi_wifi_get_connection_mode,
e_qcsapi_wifi_get_vendor_per_association,
e_qcsapi_wifi_get_max_mimo,
e_qcsapi_wifi_get_node_counter,
e_qcsapi_wifi_get_node_param,
e_qcsapi_wifi_get_node_stats,
e_qcsapi_wifi_get_max_queued,
e_qcsapi_wifi_disassociate,
e_qcsapi_wifi_associate,
e_qcsapi_wifi_get_wpa_status,
e_qcsapi_wifi_get_auth_state,
e_qcsapi_wifi_get_disconn_info,
e_qcsapi_wifi_reset_disconn_info,
e_qcsapi_wps_registrar_report_button_press,
e_qcsapi_wps_registrar_report_pin,
e_qcsapi_wps_registrar_get_pp_devname,
e_qcsapi_wps_registrar_set_pp_devname,
e_qcsapi_wps_enrollee_report_button_press,
e_qcsapi_wps_enrollee_report_pin,
e_qcsapi_wps_enrollee_generate_pin,
e_qcsapi_wps_get_ap_pin,
e_qcsapi_wps_set_ap_pin,
e_qcsapi_wps_save_ap_pin,
e_qcsapi_wps_enable_ap_pin,
e_qcsapi_wps_get_sta_pin,
e_qcsapi_wps_get_state,
e_qcsapi_wps_get_configured_state,
e_qcsapi_wps_set_configured_state,
e_qcsapi_wps_get_runtime_state,
e_qcsapi_wps_get_allow_pbc_overlap_status,
e_qcsapi_wps_allow_pbc_overlap,
e_qcsapi_wps_get_param,
e_qcsapi_wps_set_param,
e_qcsapi_wps_set_access_control,
e_qcsapi_wps_get_access_control,
e_qcsapi_non_wps_set_pp_enable,
e_qcsapi_non_wps_get_pp_enable,
e_qcsapi_wps_cancel,
e_qcsapi_wps_set_pbc_in_srcm,
e_qcsapi_wps_get_pbc_in_srcm,
e_qcsapi_wps_timeout,
e_qcsapi_wps_on_hidden_ssid,
e_qcsapi_wps_on_hidden_ssid_status,
e_qcsapi_wps_upnp_enable,
e_qcsapi_wps_upnp_status,
e_qcsapi_wps_registrar_set_dfl_pbc_bss,
e_qcsapi_wps_registrar_get_dfl_pbc_bss,
e_qcsapi_wifi_set_dwell_times,
e_qcsapi_wifi_get_dwell_times,
e_qcsapi_wifi_set_bgscan_dwell_times,
e_qcsapi_wifi_get_bgscan_dwell_times,
e_qcsapi_wifi_start_scan,
e_qcsapi_wifi_cancel_scan,
e_qcsapi_wifi_get_scan_status,
e_qcsapi_wifi_get_cac_status,
e_qcsapi_wifi_wait_scan_completes,
e_qcsapi_wifi_set_scan_chk_inv,
e_qcsapi_wifi_get_scan_chk_inv,
e_qcsapi_SSID_create_SSID,
e_qcsapi_SSID_remove_SSID,
e_qcsapi_SSID_verify_SSID,
e_qcsapi_SSID_rename_SSID,
e_qcsapi_SSID_get_SSID_list,
e_qcsapi_SSID_get_protocol,
e_qcsapi_SSID_set_protocol,
e_qcsapi_SSID_get_encryption_modes,
e_qcsapi_SSID_set_encryption_modes,
e_qcsapi_SSID_get_group_encryption,
e_qcsapi_SSID_set_group_encryption,
e_qcsapi_SSID_get_authentication_mode,
e_qcsapi_SSID_set_authentication_mode,
e_qcsapi_SSID_get_pre_shared_key,
e_qcsapi_SSID_set_pre_shared_key,
e_qcsapi_SSID_get_key_passphrase,
e_qcsapi_SSID_set_key_passphrase,
e_qcsapi_SSID_get_pmf,
e_qcsapi_SSID_set_pmf,
e_qcsapi_SSID_get_wps_SSID,
e_qcsapi_wifi_vlan_config,
e_qcsapi_wifi_show_vlan_config,
e_qcsapi_enable_vlan_pass_through,
e_qcsapi_br_vlan_promisc,
e_qcsapi_add_ipff,
e_qcsapi_del_ipff,
e_qcsapi_get_ipff,
e_qcsapi_wifi_disable_wps,
e_qcsapi_wifi_get_results_AP_scan,
e_qcsapi_wifi_get_count_APs_scanned,
e_qcsapi_wifi_get_properties_AP,
e_qcsapi_wifi_get_mac_address_filtering,
e_qcsapi_wifi_set_mac_address_filtering,
e_qcsapi_wifi_is_mac_address_authorized,
e_qcsapi_wifi_get_authorized_mac_addresses,
e_qcsapi_wifi_get_denied_mac_addresses,
e_qcsapi_wifi_authorize_mac_address,
e_qcsapi_wifi_deny_mac_address,
e_qcsapi_wifi_remove_mac_address,
e_qcsapi_wifi_clear_mac_address_filters,
e_qcsapi_wifi_set_mac_address_reserve,
e_qcsapi_wifi_get_mac_address_reserve,
e_qcsapi_wifi_clear_mac_address_reserve,
e_qcsapi_wifi_backoff_fail_max,
e_qcsapi_wifi_backoff_timeout,
e_qcsapi_wifi_get_time_associated_per_association,
e_qcsapi_wifi_wds_add_peer,
e_qcsapi_wifi_wds_remove_peer,
e_qcsapi_wifi_wds_get_peer_address,
e_qcsapi_wifi_wds_set_psk,
e_qcsapi_wifi_wds_set_mode,
e_qcsapi_wifi_wds_get_mode,
e_qcsapi_wifi_qos_get_param,
e_qcsapi_wifi_qos_set_param,
e_qcsapi_wifi_get_wmm_ac_map,
e_qcsapi_wifi_set_wmm_ac_map,
e_qcsapi_wifi_get_dscp_8021p_map,
e_qcsapi_wifi_set_dscp_8021p_map,
e_qcsapi_wifi_get_dscp_ac_map,
e_qcsapi_wifi_set_dscp_ac_map,
e_qcsapi_wifi_get_priority,
e_qcsapi_wifi_set_priority,
e_qcsapi_wifi_get_airfair,
e_qcsapi_wifi_set_airfair,
e_qcsapi_config_get_parameter,
e_qcsapi_config_update_parameter,
e_qcsapi_config_get_ssid_parameter,
e_qcsapi_config_update_ssid_parameter,
e_qcsapi_bootcfg_get_parameter,
e_qcsapi_bootcfg_update_parameter,
e_qcsapi_bootcfg_commit,
e_qcsapi_wifi_start_cca,
e_qcsapi_wifi_get_mcs_rate,
e_qcsapi_wifi_set_mcs_rate,
e_qcsapi_wifi_enable_scs,
e_qcsapi_wifi_scs_switch_channel,
e_qcsapi_wifi_set_scs_verbose,
e_qcsapi_wifi_get_scs_status,
e_qcsapi_wifi_set_scs_smpl_enable,
e_qcsapi_wifi_set_scs_smpl_dwell_time,
e_qcsapi_wifi_set_scs_smpl_intv,
e_qcsapi_wifi_set_scs_intf_detect_intv,
e_qcsapi_wifi_set_scs_thrshld,
e_qcsapi_wifi_set_scs_report_only,
e_qcsapi_wifi_get_scs_report_stat,
e_qcsapi_wifi_set_scs_cca_intf_smth_fctr,
e_qcsapi_wifi_set_scs_chan_mtrc_mrgn,
e_qcsapi_wifi_get_scs_dfs_reentry_request,
e_qcsapi_wifi_get_scs_cca_intf,
e_qcsapi_wifi_get_scs_param,
e_qcsapi_wifi_set_scs_stats,
e_qcsapi_wifi_start_ocac,
e_qcsapi_wifi_stop_ocac,
e_qcsapi_wifi_get_ocac_status,
e_qcsapi_wifi_set_ocac_threshold,
e_qcsapi_wifi_set_ocac_dwell_time,
e_qcsapi_wifi_set_ocac_duration,
e_qcsapi_wifi_set_ocac_cac_time,
e_qcsapi_wifi_set_ocac_report_only,
e_qcsapi_wifi_start_dfs_s_radio,
e_qcsapi_wifi_stop_dfs_s_radio,
e_qcsapi_wifi_get_dfs_s_radio_status,
e_qcsapi_wifi_get_dfs_s_radio_availability,
e_qcsapi_wifi_set_dfs_s_radio_threshold,
e_qcsapi_wifi_set_dfs_s_radio_dwell_time,
e_qcsapi_wifi_set_dfs_s_radio_duration,
e_qcsapi_wifi_set_dfs_s_radio_cac_time,
e_qcsapi_wifi_set_dfs_s_radio_report_only,
e_qcsapi_wifi_set_dfs_s_radio_wea_duration,
e_qcsapi_wifi_set_dfs_s_radio_wea_cac_time,
e_qcsapi_wifi_set_ap_isolate,
e_qcsapi_wifi_get_ap_isolate,
e_qcsapi_wifi_get_pairing_id,
e_qcsapi_wifi_set_pairing_id,
e_qcsapi_wifi_get_pairing_enable,
e_qcsapi_wifi_set_pairing_enable,
e_qcsapi_wifi_get_rts_threshold,
e_qcsapi_wifi_set_rts_threshold,
e_qcsapi_wifi_set_txqos_sched_tbl,
e_qcsapi_wifi_get_txqos_sched_tbl,
e_qcsapi_wifi_set_vendor_fix,
e_qcsapi_power_save,
e_qcsapi_qpm_level,
e_qcsapi_get_interface_stats,
e_qcsapi_get_phy_stats,
e_qcsapi_reset_all_stats,
e_qcsapi_eth_phy_power_off,
e_qcsapi_test_traffic,
e_qcsapi_aspm_l1,
e_qcsapi_l1,
e_qcsapi_get_temperature,
e_qcsapi_telnet_enable,
e_qcsapi_restore_default_config,
e_qcsapi_set_soc_macaddr,
e_qcsapi_run_script,
e_qcsapi_qtm,
e_qcsapi_set_accept_oui_filter,
e_qcsapi_get_accept_oui_filter,
e_qcsapi_get_swfeat_list,
e_qcsapi_wifi_set_vht,
e_qcsapi_wifi_get_vht,
e_qcsapi_last_entry_point = e_qcsapi_wifi_get_vht,
e_qcsapi_help, /* dummy APIs; used to send messages within the driver programs */
e_qcsapi_exit,
e_qcsapi_aging,
/* qcsapi cal mode */
e_qcsapi_calcmd_set_test_mode,
e_qcsapi_calcmd_show_test_packet,
e_qcsapi_calcmd_send_test_packet,
e_qcsapi_calcmd_stop_test_packet,
e_qcsapi_calcmd_send_dc_cw_signal,
e_qcsapi_calcmd_stop_dc_cw_signal,
e_qcsapi_calcmd_get_test_mode_antenna_sel,
e_qcsapi_calcmd_get_test_mode_mcs,
e_qcsapi_calcmd_get_test_mode_bw,
e_qcsapi_calcmd_get_tx_power,
e_qcsapi_calcmd_set_tx_power,
e_qcsapi_calcmd_get_test_mode_rssi,
e_qcsapi_calcmd_set_mac_filter,
e_qcsapi_calcmd_get_antenna_count,
e_qcsapi_calcmd_clear_counter,
e_qcsapi_calcmd_get_info,
e_qcsapi_wifi_disable_dfs_channels,
e_qcsapi_get_carrier_id,
e_qcsapi_set_carrier_id,
e_qcsapi_wifi_enable_tdls,
e_qcsapi_wifi_enable_tdls_over_qhop,
e_qcsapi_wifi_get_tdls_status,
e_qcsapi_wifi_set_tdls_params,
e_qcsapi_wifi_get_tdls_params,
e_qcsapi_wifi_tdls_operate,
e_qcsapi_get_spinor_jedecid,
e_qcsapi_get_custom_value,
e_qcsapi_wifi_get_mlme_stats_per_mac,
e_qcsapi_wifi_get_mlme_stats_per_association,
e_qcsapi_wifi_get_mlme_stats_macs_list,
e_qcsapi_get_nss_cap,
e_qcsapi_set_nss_cap,
e_qcsapi_get_security_defer_mode,
e_qcsapi_set_security_defer_mode,
e_qcsapi_apply_security_config,
e_qcsapi_wifi_set_intra_bss_isolate,
e_qcsapi_wifi_get_intra_bss_isolate,
e_qcsapi_wifi_set_bss_isolate,
e_qcsapi_wifi_get_bss_isolate,
e_qcsapi_wowlan_host_state,
e_qcsapi_wowlan_match_type,
e_qcsapi_wowlan_L2_type,
e_qcsapi_wowlan_udp_port,
e_qcsapi_wowlan_pattern,
e_qcsapi_wowlan_get_host_state,
e_qcsapi_wowlan_get_match_type,
e_qcsapi_wowlan_get_L2_type,
e_qcsapi_wowlan_get_udp_port,
e_qcsapi_wowlan_get_pattern,
e_qcsapi_wifi_set_extender_params,
e_qcsapi_wifi_get_extender_status,
e_qcsapi_wifi_enable_bgscan,
e_qcsapi_wifi_get_bgscan_status,
e_qcsapi_get_uboot_info,
e_qcsapi_wifi_get_disassoc_reason,
e_qcsapi_wifi_get_tx_amsdu,
e_qcsapi_wifi_set_tx_amsdu,
e_qcsapi_is_startprod_done,
e_qcsapi_wifi_disassociate_sta,
e_qcsapi_wifi_reassociate,
e_qcsapi_get_bb_param,
e_qcsapi_set_bb_param,
e_qcsapi_wifi_set_scan_buf_max_size,
e_qcsapi_wifi_get_scan_buf_max_size,
e_qcsapi_wifi_set_scan_table_max_len,
e_qcsapi_wifi_get_scan_table_max_len,
e_qcsapi_wifi_set_enable_mu,
e_qcsapi_wifi_get_enable_mu,
e_qcsapi_wifi_set_mu_use_precode,
e_qcsapi_wifi_get_mu_use_precode,
e_qcsapi_wifi_set_mu_use_eq,
e_qcsapi_wifi_get_mu_use_eq,
e_qcsapi_wifi_get_mu_groups,
e_qcsapi_get_emac_switch,
e_qcsapi_set_emac_switch,
e_qcsapi_eth_dscp_map,
e_qcsapi_send_file,
e_qcsapi_wifi_verify_repeater_mode,
e_qcsapi_wifi_set_ap_interface_name,
e_qcsapi_wifi_get_ap_interface_name,
e_qcsapi_set_optim_stats,
e_qcsapi_set_sys_time,
e_qcsapi_get_sys_time,
e_qcsapi_get_eth_info,
e_qcsapi_wifi_block_bss,
e_qcsapi_nosuch_api = 0
} qcsapi_entry_point;
typedef struct qcsapi_generic_parameter {
qcsapi_generic_parameter_type generic_parameter_type;
/*
* Selected QCSAPI entry points take BOTH a Service Set ID (SSID) AND and index
*/
qcsapi_unsigned_int index;
union
{
qcsapi_counter_type counter;
qcsapi_option_type option;
qcsapi_rate_type typeof_rates;
qcsapi_mimo_type modulation;
qcsapi_board_parameter_type board_param;
char the_SSID[ IW_ESSID_MAX_SIZE + 10 ];
qcsapi_tdls_type type_of_tdls;
qcsapi_tdls_oper tdls_oper;
qcsapi_extender_type type_of_extender;
} parameter_type;
} qcsapi_generic_parameter;
typedef struct call_qcsapi_bundle {
qcsapi_entry_point caller_qcsapi;
const char *caller_interface;
qcsapi_generic_parameter caller_generic_parameter;
qcsapi_output *caller_output;
} call_qcsapi_bundle;
typedef struct qcsapi_entry
{
qcsapi_entry_point e_entry_point;
qcsapi_typeof_api e_typeof_api;
qcsapi_generic_parameter_type e_generic_param_type;
qcsapi_specific_parameter_type e_specific_param_type;
} qcsapi_entry;
#ifdef __cplusplus
extern "C" {
#endif
extern const struct qcsapi_entry *entry_point_enum_to_table_entry( qcsapi_entry_point this_entry_point );
extern int lookup_generic_parameter_type(
qcsapi_entry_point qcsapi_selection,
qcsapi_generic_parameter_type *p_generic_parameter_type
);
#ifdef __cplusplus
}
#endif
#endif /* _QCSAPI_DRIVER_H */

View File

@ -0,0 +1,144 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2009 - 2011 Quantenna Communications Inc **
** **
** File : call_qcsapi_local.c **
** Description : tiny wrapper to invoke call_qcsapi locally, from main() **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#include "qcsapi_output.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int qcsapi_output_stdio_fn(struct qcsapi_output* qo,
enum qcsapi_print_type out_type, const char * format, va_list args)
{
FILE *file = stderr;
int rv;
if (out_type == OUT) {
file = stdout;
} else {
file = stderr;
}
rv = vfprintf(file, format, args);
return rv;
}
int qcsapi_output_buf_fn(struct qcsapi_output* qo,
enum qcsapi_print_type out_type, const char * format, va_list args)
{
const ssize_t realloc_threshold = 512;
ssize_t limit;
int ret;
struct qcsapi_output_bufinfo *bi = NULL;
if (out_type == OUT) {
bi = &qo->out;
} else {
bi = &qo->err;
}
limit = bi->bufsize - bi->bytes_written - 1;
if ((qo->flags & QCSAPI_OUTPUT_REALLOC) &&
(*bi->buf == NULL ||
limit < realloc_threshold)) {
char *newbuf;
ssize_t newbufsize;
newbufsize = bi->bufsize;
if (newbufsize < realloc_threshold)
newbufsize = realloc_threshold;
newbufsize <<= 1;
newbuf = realloc(*bi->buf, newbufsize);
if (newbuf == NULL) {
return -ENOMEM;
}
*bi->buf = newbuf;
bi->bufsize = newbufsize;
limit = bi->bufsize - bi->bytes_written - 1;
}
if (limit <= 0) {
ret = 0;
} else {
ret = vsnprintf(&(*bi->buf)[bi->bytes_written], limit, format, args);
bi->bytes_written += ret;
(*bi->buf)[bi->bytes_written] = '\0';
}
return ret;
}
struct qcsapi_output qcsapi_output_stdio_adapter(void)
{
struct qcsapi_output qo = {0};
qo.func = qcsapi_output_stdio_fn;
return qo;
}
struct qcsapi_output qcsapi_output_buf_adapter(
char **outbuf, size_t outbufsize,
char **errbuf, size_t errbufsize,
int realloc_allowed)
{
struct qcsapi_output qo;
qo.func = qcsapi_output_buf_fn;
qo.flags = realloc_allowed ? QCSAPI_OUTPUT_REALLOC : 0;
qo.out.buf = outbuf;
qo.out.bufsize = outbufsize;
qo.out.bytes_written = 0;
qo.err.buf = errbuf;
qo.err.bufsize = errbufsize;
qo.err.bytes_written = 0;
return qo;
}

View File

@ -0,0 +1,98 @@
/*SH1
*******************************************************************************
** **
** Copyright (c) 2009 - 2011 Quantenna Communications Inc **
** **
** File : qcsapi.h **
** Description : **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#ifndef _QCSAPI_OUTPUT_H
#define _QCSAPI_OUTPUT_H
#include <sys/types.h>
#include <stdarg.h>
enum qcsapi_print_type {
OUT,
ERR,
};
struct qcsapi_output_bufinfo {
char **buf;
ssize_t bufsize;
ssize_t bytes_written;
};
typedef struct qcsapi_output {
int (*func)(struct qcsapi_output*, enum qcsapi_print_type, const char *, va_list args);
struct qcsapi_output_bufinfo out;
struct qcsapi_output_bufinfo err;
#define QCSAPI_OUTPUT_REALLOC 0x1
int flags;
} qcsapi_output;
extern struct qcsapi_output qcsapi_output_stdio_adapter(void);
extern struct qcsapi_output qcsapi_output_buf_adapter(char **stdout_buf, size_t stdout_bufsize,
char **stderr_buf, size_t stderr_bufsize, int realloc_allowed);
static inline int print_out(struct qcsapi_output *output, const char *format, ...)
{
int ret;
va_list args;
va_start(args, format);
ret = output->func(output, OUT, format, args);
va_end(args);
return ret;
}
static inline int print_err(struct qcsapi_output *output, const char *format, ...)
{
int ret;
va_list args;
va_start(args, format);
ret = output->func(output, ERR, format, args);
va_end(args);
return ret;
}
#endif /* _QCSAPI_OUTPUT_H */

View File

@ -0,0 +1,77 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2009 - 2011 Quantenna Communications Inc **
** **
** File : call_qcsapi_local.c **
** Description : tiny wrapper to invoke call_qcsapi locally, from main() **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#include <stdio.h>
#include <call_qcsapi.h>
#include <qcsapi_output.h>
#include <qcsapi_rpc/client/qcsapi_rpc_client.h>
#include <qcsapi_rpc/generated/qcsapi_rpc.h>
#include <qcsapi_rpc_common/common/rpc_pci.h>
int main(int argc, char **argv)
{
int ret;
char *host;
CLIENT *clnt;
struct qcsapi_output output;
output = qcsapi_output_stdio_adapter();
host = "localhost";
clnt = clnt_pci_create(host, QCSAPI_PROG, QCSAPI_VERS, NULL);
if (clnt == NULL) {
clnt_pcreateerror(host);
exit (1);
}
client_qcsapi_set_rpcclient(clnt);
ret = qcsapi_main(&output, argc, argv);
clnt_destroy(clnt);
return ret;
}

View File

@ -0,0 +1,61 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2011 Quantenna Communications Inc **
** **
** File : call_qcsapi_sockrpcd.c **
** Description : Wrapper from rpc server daemon to call_qcsapi, **
** starting from an rpcgen generated server stub. **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#ifndef __QCSAPI_RPC_CLIENT_H__
#define __QCSAPI_RPC_CLIENT_H__
#include <rpc/rpc.h>
typedef void (*client_qcsapi_callback_pre_t)(const char *);
typedef void (*client_qcsapi_callback_post_t)(const char *, int was_error);
typedef void (*client_qcsapi_callback_reconnect_t)(const char *);
extern void client_qcsapi_set_rpcclient(CLIENT * clnt);
extern void client_qcsapi_set_callbacks(client_qcsapi_callback_pre_t,
client_qcsapi_callback_post_t,
client_qcsapi_callback_reconnect_t);
#endif /* __QCSAPI_RPC_CLIENT_H__ */

View File

@ -0,0 +1,114 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2009 - 2011 Quantenna Communications Inc **
** **
** File : call_qcsapi_local.c **
** Description : tiny wrapper to invoke call_qcsapi locally, from main() **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#include <stdio.h>
#include <call_qcsapi.h>
#include <qcsapi_output.h>
#include <qcsapi_rpc_common/client/find_host_addr.h>
#include <qcsapi_rpc/client/qcsapi_rpc_client.h>
#include <qcsapi_rpc/generated/qcsapi_rpc.h>
#include <string.h>
static int client_qcsapi_get_udp_retry_timeout(int *argc, char ***argv)
{
int timeout = -1;
if (argc && argv && *argc >= 2 && strcmp((*argv)[1], "--udp-retry-timeout") == 0) {
timeout = atoi((const char *)(*argv)[2]);
/* move program argv[0] */
(*argv)[2] = (*argv)[0];
/* skip over --host <arg> args */
*argc = *argc - 2;
*argv = &(*argv)[2];
}
return timeout;
}
int main(int argc, char **argv)
{
int ret;
const char *host;
int udp_retry_timeout;
CLIENT *clnt;
struct qcsapi_output output;
output = qcsapi_output_stdio_adapter();
host = client_qcsapi_find_host_addr(&argc, &argv);
if (!host) {
client_qcsapi_find_host_errmsg(argv[0]);
exit(1);
}
udp_retry_timeout = client_qcsapi_get_udp_retry_timeout(&argc, &argv);
clnt = clnt_create(host, QCSAPI_PROG, QCSAPI_VERS, "udp");
if (clnt == NULL) {
clnt = clnt_create(host, QCSAPI_PROG, QCSAPI_VERS, "tcp");
} else {
if (udp_retry_timeout>0) {
struct timeval value;
value.tv_sec = (time_t)udp_retry_timeout;
value.tv_usec = (suseconds_t)0;
clnt_control(clnt, CLSET_RETRY_TIMEOUT, (char *)&value);
}
}
if (clnt == NULL) {
clnt_pcreateerror(host);
exit(1);
}
client_qcsapi_set_rpcclient(clnt);
ret = qcsapi_main(&output, argc, argv);
clnt_destroy(clnt);
return ret;
}

View File

@ -0,0 +1,88 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2014 Quantenna Communications Inc **
** **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#include <call_qcsapi.h>
#include <qcsapi_output.h>
#include <qcsapi_rpc/client/qcsapi_rpc_client.h>
#include <qcsapi_rpc/generated/qcsapi_rpc.h>
#include <qcsapi_rpc_common/common/rpc_raw.h>
#include <unistd.h>
int main(int argc, char **argv)
{
CLIENT *clnt;
struct qcsapi_output output;
uint8_t dst_mac[ETH_HLEN];
int ret;
if (geteuid()) {
printf("QRPC: only root can do that\n");
exit(1);
}
if (argc < 3) {
printf("QRPC: <src_ifname> <dst_mac_addr>\n");
exit(1);
}
if (str_to_mac(argv[2], dst_mac) < 0) {
printf("QRPC: Wrong destination MAC address format. "
"Use the following format: XX:XX:XX:XX:XX:XX\n");
exit(1);
}
output = qcsapi_output_stdio_adapter();
clnt = qrpc_clnt_raw_create(QCSAPI_PROG, QCSAPI_VERS, argv[1], dst_mac, QRPC_QCSAPI_RPCD_SID);
if (clnt == NULL) {
clnt_pcreateerror("QRPC: ");
exit (1);
}
client_qcsapi_set_rpcclient(clnt);
argv[2] = argv[0];
ret = qcsapi_main(&output, argc - 2, &argv[2]);
clnt_destroy(clnt);
return ret;
}

View File

@ -0,0 +1,157 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2009 - 2011 Quantenna Communications Inc **
** **
** File : call_qcsapi_local.c **
** Description : tiny wrapper to invoke call_qcsapi locally, from main() **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#include <qcsapi_rpc_common/client/find_host_addr.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define QCSAPI_HOST_ENV_VAR "QCSAPI_RPC_TARGET"
static const char * const cfg_file_paths[] = {
"/mnt/jffs2/rmt_ip.conf",
"/etc/qcsapi_target_ip.conf",
NULL /* last entry must be null */
};
#define MAX_HOSTNAME_SIZE 128
void client_qcsapi_find_host_errmsg(const char *progname)
{
int i;
fprintf(stderr, "No remote host configured! Remote host config is\n");
fprintf(stderr, "evaluated in the following order:\n");
fprintf(stderr, " 1) Command line parameter:\n");
fprintf(stderr, " %s --host <host> <args>\n", progname);
fprintf(stderr, " 2) Environment variable:\n");
fprintf(stderr, " export %s=<host>\n", QCSAPI_HOST_ENV_VAR);
fprintf(stderr, " %s <args>\n", progname);
fprintf(stderr, " 3) Configuration files, in order:\n");
for (i = 0; cfg_file_paths[i]; i++) {
fprintf(stderr, " %s\n", cfg_file_paths[i]);
}
}
static void trim_trailing_space(char *buf)
{
int i;
for (i = strlen(buf) - 1; isspace(buf[i]); i--) {
buf[i] = '\0';
}
}
static const char *first_nonspace(const char *buf)
{
while (*buf && isspace(*buf)) {
buf++;
}
return buf;
}
static const char * client_qcsapi_find_host_read_file(const char * const filename)
{
static char hostbuf[MAX_HOSTNAME_SIZE];
const char* host = NULL;
char* fret;
FILE *file = fopen(filename, "r");
if (file == NULL) {
/* files may legitimately not exist */
return NULL;
}
/* assume the file contains the target host on the first line */
fret = fgets(hostbuf, MAX_HOSTNAME_SIZE, file);
if (fret || feof(file)) {
trim_trailing_space(hostbuf);
host = first_nonspace(hostbuf);
} else {
fprintf(stderr, "%s: error reading file '%s': %s\n",
__FUNCTION__, filename, strerror(errno));
}
fclose(file);
return host;
}
const char* client_qcsapi_find_host_addr(int *argc, char ***argv)
{
int i;
const char *host;
/* check for command line arguments */
if (argc && argv && *argc >= 2 && strcmp((*argv)[1], "--host") == 0) {
host = (*argv)[2];
/* move program argv[0] */
(*argv)[2] = (*argv)[0];
/* skip over --host <arg> args */
*argc = *argc - 2;
*argv = &(*argv)[2];
return host;
}
/* check for environment variables */
host = getenv(QCSAPI_HOST_ENV_VAR);
if (host) {
return host;
}
/* check for config files */
for (i = 0; cfg_file_paths[i]; i++) {
host = client_qcsapi_find_host_read_file(cfg_file_paths[i]);
if (host) {
return host;
}
}
return NULL;
}

View File

@ -0,0 +1,52 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2009 - 2011 Quantenna Communications Inc **
** **
** File : call_qcsapi_local.c **
** Description : tiny wrapper to invoke call_qcsapi locally, from main() **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#ifndef __QCSAPI_FIND_HOST_ADDR_H__
#define __QCSAPI_FIND_HOST_ADDR_H__
extern const char* client_qcsapi_find_host_addr(int *argc, char ***argv);
extern void client_qcsapi_find_host_errmsg(const char *progname);
#endif /* __QCSAPI_FIND_HOST_ADDR_H__ */

View File

@ -0,0 +1,227 @@
/*
* Copyright (c) 2015 Quantenna Communications, Inc.
* All rights reserved.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#ifndef _GNU_SOURCE
#include <libgen.h>
#endif
#include <string.h>
#include "qcsapi_rpc_common/common/rpc_raw.h"
#define QFTC_READ_TIMEOUT_MS (250)
#define QFTC_CONNECT_RET_LIMIT 5
#define QFTC_RECV_RETRY_LIMIT 4
static struct qftc_cfg_t {
struct qftp_raw_ethpkt *send_buf;
struct qftp_raw_ethpkt *recv_buf;
struct qftp_ack_nack_pkt *recv_payload;
struct qftp_data_pkt *send_payload;
struct sockaddr_ll dst_addr;
int if_index;
int sock_fd;
int fd;
} qftc_cfg;
static void qftc_clean(void)
{
free(qftc_cfg.send_buf);
free(qftc_cfg.recv_buf);
if (qftc_cfg.fd >= 0)
close(qftc_cfg.fd);
if (qftc_cfg.sock_fd >= 0)
close(qftc_cfg.sock_fd);
}
static int qftc_init(const char *file_path_name, const char *sif_name, const uint8_t *dmac_addr)
{
qftc_cfg.sock_fd = -1;
qftc_cfg.send_buf = NULL;
qftc_cfg.recv_buf = NULL;
qftc_cfg.fd = open(file_path_name, O_RDONLY);
if (qftc_cfg.fd < 0) {
printf("Failed to open %s file\n", file_path_name);
return -1;
}
qftc_cfg.sock_fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (qftc_cfg.sock_fd < 0)
return -1;
if (qrpc_set_prot_filter(qftc_cfg.sock_fd, QFTP_RAW_SOCK_PROT) < 0) {
return -1;
}
qftc_cfg.send_buf = malloc(sizeof(*qftc_cfg.send_buf));
qftc_cfg.recv_buf = malloc(sizeof(*qftc_cfg.recv_buf));
if (!qftc_cfg.send_buf || !qftc_cfg.recv_buf) {
return -1;
}
qftc_cfg.send_payload = (struct qftp_data_pkt *)&qftc_cfg.send_buf->payload;
qftc_cfg.recv_payload = (struct qftp_ack_nack_pkt *)&qftc_cfg.recv_buf->payload;
qftc_cfg.if_index = qrpc_clnt_raw_config_dst(qftc_cfg.sock_fd, sif_name,
&qftc_cfg.dst_addr, dmac_addr,
(struct q_raw_ethoui_hdr *)
qftc_cfg.send_buf,
QFTP_RAW_SOCK_PROT);
if (qftc_cfg.if_index < 0) {
return -1;
}
return 0;
}
static uint32_t qftc_compose_connect_cmd(struct qftp_connect_pkt * const connect_payload,
const char *file_path_name)
{
struct stat file_stat;
memset(&file_stat, 0, sizeof(file_stat));
if (!stat(file_path_name, &file_stat) && (file_stat.st_mode & S_IFREG)) {
connect_payload->sub_type = QFTP_FRAME_TYPE_CONNECT;
connect_payload->seq = 0;
connect_payload->image_size = file_stat.st_size;
strcpy(connect_payload->image_name, basename((char *)file_path_name));
return (sizeof(struct qftp_connect_pkt) +
strlen(connect_payload->image_name));
}
return 0;
}
static uint32_t qftc_compose_data_cmd(void)
{
ssize_t read_bytes;
const size_t max_data_len = ETH_FRAME_LEN - QFTP_DATA_PKT_HDR_SIZE;
read_bytes = read(qftc_cfg.fd, qftc_cfg.send_payload->data, max_data_len);
qftc_cfg.send_payload->sub_type = QFTP_FRAME_TYPE_DATA;
++qftc_cfg.send_payload->seq;
return read_bytes;
}
static int qftc_send_cmd(const uint32_t cmd_size)
{
ssize_t sent_bytes;
do {
sent_bytes = sendto(qftc_cfg.sock_fd, qftc_cfg.send_buf, cmd_size, 0,
(struct sockaddr *)&qftc_cfg.dst_addr,
sizeof(qftc_cfg.dst_addr));
} while (sent_bytes < 0 && errno == EINTR);
return sent_bytes;
}
static int qftc_recv_cmd(void)
{
struct sockaddr_ll lladdr;
socklen_t addrlen = sizeof(lladdr);
ssize_t bytes_recv = -1;
int retry_count = 0;
memset(&lladdr, 0, sizeof(lladdr));
do {
if (!qrpc_raw_read_timeout(qftc_cfg.sock_fd, QFTC_READ_TIMEOUT_MS)) {
do {
bytes_recv = recvfrom(qftc_cfg.sock_fd, qftc_cfg.recv_buf,
sizeof(*qftc_cfg.recv_buf),
MSG_DONTWAIT, (struct sockaddr *)&lladdr,
&addrlen);
} while (bytes_recv < 0 && errno == EINTR);
} else if (++retry_count > QFTC_RECV_RETRY_LIMIT) {
break;
}
} while ((lladdr.sll_ifindex != qftc_cfg.if_index) || (lladdr.sll_pkttype != PACKET_HOST));
return retry_count > QFTC_RECV_RETRY_LIMIT ? -1 : bytes_recv;
}
static int qftc_connect(const char *file_path_name)
{
uint32_t connect_cmd_hdr_size;
ssize_t bytes_recv;
int retry_count = 0;
int op_failed = 0;
connect_cmd_hdr_size = qftc_compose_connect_cmd((struct qftp_connect_pkt *)
&qftc_cfg.send_buf->payload,
file_path_name);
if (!connect_cmd_hdr_size) {
return -1;
}
connect_cmd_hdr_size += sizeof(struct q_raw_ethoui_hdr);
do {
/* Sending CONNECT command */
if (qftc_send_cmd(connect_cmd_hdr_size) < 0) {
op_failed = 1;
break;
}
/* Waiting for ACK */
bytes_recv = qftc_recv_cmd();
if ((bytes_recv >= (ssize_t)QFTP_ACK_NACK_FRAME_LEN) ||
(qftc_cfg.recv_payload->sub_type == QFTP_FRAME_TYPE_ACK)) {
break;
}
} while (++retry_count < QFTC_CONNECT_RET_LIMIT);
if (op_failed || retry_count >= QFTC_CONNECT_RET_LIMIT)
return -1;
return 0;
}
int qftc_start(const char *file_path_name, const char *sif_name, const uint8_t *dmac_addr)
{
ssize_t read_bytes;
int op_failed = 0;
if (qftc_init(file_path_name, sif_name, dmac_addr) < 0 ||
qftc_connect(file_path_name) < 0) {
qftc_clean();
return -1;
}
read_bytes = qftc_compose_data_cmd();
/* Start transmitting image file */
while (read_bytes > 0) {
/* Sending DATA command */
if (qftc_send_cmd(QFTP_DATA_PKT_HDR_SIZE + read_bytes) < 0) {
op_failed = 1;
break;
}
/* Receiving ACK */
if ((qftc_recv_cmd() < 0) ||
(qftc_cfg.send_payload->seq != qftc_cfg.recv_payload->seq) ||
(qftc_cfg.recv_payload->sub_type != QFTP_FRAME_TYPE_ACK)) {
op_failed = 1;
break;
}
read_bytes = qftc_compose_data_cmd();
}
qftc_clean();
if (op_failed || (read_bytes < 0))
return -1;
return 0;
}

View File

@ -0,0 +1,8 @@
/*
* Copyright (c) 2015 Quantenna Communications, Inc.
* All rights reserved.
*/
#ifndef __QCSAPI_QFTC_H__
#define __QCSAPI_QFTC_H__
extern int qftc_start(const char *file_path_name, const char *sif_name, const uint8_t *dmac_addr);
#endif

View File

@ -0,0 +1,504 @@
/*
* Copyright (C) 1987, Sun Microsystems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
* * Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <alloca.h>
#include <errno.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netdb.h>
#include <linux/netlink.h>
#include <rpc/clnt.h>
#include <poll.h>
#include <assert.h>
#include <qcsapi_rpc_common/common/rpc_pci.h>
#ifndef PCIE_RPC_TYPE
#error "Not configure PCIE_RPC_TYPE"
#else
#if (PCIE_RPC_TYPE != RPC_TYPE_CALL_QCSAPI_PCIE) && (PCIE_RPC_TYPE != RPC_TYPE_QCSAPI_PCIE)
#error "Configuration invalid value for PCIE_RPC_TYPE"
#endif
#endif
/*
* Private data kept per client handle
*/
struct cu_data {
int cu_sock;
struct sockaddr_nl cu_saddr;
struct sockaddr_nl cu_daddr;
//struct sockaddr_in cu_raddr;
//int cu_rlen;
int cu_slen;
int cu_dlen;
struct timeval cu_wait;
struct timeval cu_total;
struct rpc_err cu_error;
XDR cu_outxdrs;
u_int cu_xdrpos;
u_int cu_sendsz;
u_int cu_recvsz;
char *cu_outbuf;
char *cu_inbuf;
struct nlmsghdr *cu_reqnlh;
struct nlmsghdr *cu_respnlh;
};
static CLIENT *_clnt_pci_create(int sock_fd,
struct sockaddr_nl *src,
struct sockaddr_nl *dst,
u_long prog, u_long vers);
/*
* Generic client creation: takes (hostname, program-number, protocol) and
* returns client handle. Default options are set, which the user can
* change using the rpc equivalent of ioctl()'s.
*/
CLIENT *clnt_pci_create(const char *hostname,
u_long prog, u_long vers, const char *proto)
{
CLIENT *client;
struct sockaddr_nl src_addr, dest_addr;
int sock_fd;
sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_RPC_PCI_CLNT);
if (sock_fd < 0)
goto err;
memset(&src_addr, 0, sizeof(src_addr));
src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid(); /* self pid */
bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.nl_family = AF_NETLINK;
dest_addr.nl_pid = 0; /* For Linux Kernel */
dest_addr.nl_groups = 0; /* unicast */
client = _clnt_pci_create(sock_fd, &src_addr, &dest_addr, prog, vers);
if (client == NULL)
close(sock_fd);
return client;
err:
#if 0
if (errno) {
struct rpc_createerr *ce = &get_rpc_createerr();
ce->cf_stat = RPC_SYSTEMERROR;
ce->cf_error.re_errno = error;
return NULL;
}
#endif
return NULL;
}
extern u_long _create_xid(void);
/*
* PCI bases client side rpc operations
*/
static enum clnt_stat clnt_pci_call(CLIENT *, u_long, xdrproc_t, caddr_t,
xdrproc_t, caddr_t, struct timeval);
static void clnt_pci_abort(void);
static void clnt_pci_geterr(CLIENT *, struct rpc_err *);
static bool_t clnt_pci_freeres(CLIENT *, xdrproc_t, caddr_t);
static bool_t clnt_pci_control(CLIENT *, int, char *);
static void clnt_pci_destroy(CLIENT *);
static const struct clnt_ops pci_ops = {
clnt_pci_call,
clnt_pci_abort,
clnt_pci_geterr,
clnt_pci_freeres,
clnt_pci_destroy,
clnt_pci_control
};
/*
* Create a UDP based client handle.
* If *sockp<0, *sockp is set to a newly created UPD socket.
* If raddr->sin_port is 0 a binder on the remote machine
* is consulted for the correct port number.
* NB: It is the clients responsibility to close *sockp.
* NB: The rpch->cl_auth is initialized to null authentication.
* Caller may wish to set this something more useful.
*
* wait is the amount of time used between retransmitting a call if
* no response has been heard; retransmission occurs until the actual
* rpc call times out.
*
* sendsz and recvsz are the maximum allowable packet sizes that can be
* sent and received.
*/
static CLIENT *_clnt_pci_create(int sock_fd,
struct sockaddr_nl *src,
struct sockaddr_nl *dst,
u_long prog, u_long vers)
{
struct timeval wait;
CLIENT *cl;
struct cu_data *cu = NULL;
struct rpc_msg call_msg;
struct nlmsghdr *preqnlh, *prespnlh;
struct iovec iov;
struct msghdr msg;
//u_int sendsz, recvsz;
wait.tv_sec = 5;
wait.tv_usec = 0;
cl = (CLIENT *) malloc(sizeof(CLIENT));
//sendsz = ((PCIMSGSIZE + 3) / 4) * 4;
//recvsz = ((PCIMSGSIZE + 3) / 4) * 4;
cu = (struct cu_data *)calloc(1, sizeof(*cu));
/* Allocate memory for nlm headers */
preqnlh = (struct nlmsghdr *)calloc(1, NLMSG_SPACE(PCIMSGSIZE));
prespnlh = (struct nlmsghdr *)calloc(1, NLMSG_SPACE(PCIMSGSIZE));
if (cl == NULL || cu == NULL || preqnlh == NULL || prespnlh == NULL) {
fprintf(stderr, "pci_clnt_create out of memory\n");
goto fooy;
}
cl->cl_ops = (struct clnt_ops *)&pci_ops;
cl->cl_private = (caddr_t) cu;
cu->cu_saddr = *src;
cu->cu_daddr = *dst;
cu->cu_slen = sizeof(cu->cu_saddr);
cu->cu_dlen = sizeof(cu->cu_daddr);
cu->cu_wait = wait;
cu->cu_total.tv_sec = -1;
cu->cu_total.tv_usec = -1;
cu->cu_sendsz = PCIMSGSIZE;
cu->cu_recvsz = PCIMSGSIZE;
// setup req/resp netlink headers
cu->cu_reqnlh = preqnlh;
cu->cu_respnlh = prespnlh;
memset(preqnlh, 0, NLMSG_SPACE(PCIMSGSIZE));
preqnlh->nlmsg_len = NLMSG_SPACE(PCIMSGSIZE);
preqnlh->nlmsg_pid = getpid();
preqnlh->nlmsg_flags = NLM_F_REQUEST;
cu->cu_outbuf = NLMSG_DATA(preqnlh);
memset(prespnlh, 0, NLMSG_SPACE(PCIMSGSIZE));
prespnlh->nlmsg_len = NLMSG_SPACE(PCIMSGSIZE);
prespnlh->nlmsg_pid = getpid();
prespnlh->nlmsg_flags = NLM_F_REQUEST;
cu->cu_inbuf = NLMSG_DATA(prespnlh);
call_msg.rm_xid = getpid(); //_create_xid ();
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = prog;
call_msg.rm_call.cb_vers = vers;
xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, PCIMSGSIZE, XDR_ENCODE);
if (!xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
goto fooy;
}
cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
cu->cu_sock = sock_fd;
cl->cl_auth = authnone_create();
// Register the client. May not be necessary. FIXME
preqnlh->nlmsg_len = 0;
preqnlh->nlmsg_type = NETLINK_TYPE_CLNT_REGISTER;
iov.iov_base = (void *)cu->cu_reqnlh;
iov.iov_len = NLMSG_SPACE(0);
memset((caddr_t) & msg, 0, sizeof(msg));
msg.msg_name = (void *)&cu->cu_daddr;
msg.msg_namelen = cu->cu_dlen;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
sendmsg(cu->cu_sock, &msg, 0);
return cl;
fooy:
if (cu)
free((caddr_t) cu);
if (cl)
free((caddr_t) cl);
if (preqnlh)
free((caddr_t) preqnlh);
if (prespnlh)
free((caddr_t) prespnlh);
return (CLIENT *) NULL;
}
enum clnt_stat clnt_pci_call(cl, proc, xargs, argsp, xresults, resultsp,
utimeout)
CLIENT *cl; /* client handle */
u_long proc; /* procedure number */
xdrproc_t xargs; /* xdr routine for args */
caddr_t argsp; /* pointer to args */
xdrproc_t xresults; /* xdr routine for results */
caddr_t resultsp; /* pointer to results */
struct timeval utimeout; /* seconds to wait before giving up */
{
struct cu_data *cu = (struct cu_data *)cl->cl_private;
XDR *xdrs;
int outlen = 0;
int inlen;
//socklen_t fromlen;
struct pollfd fd;
int milliseconds = (cu->cu_wait.tv_sec * 1000) +
(cu->cu_wait.tv_usec / 1000);
//struct sockaddr_in from;
struct rpc_msg reply_msg;
XDR reply_xdrs;
struct timeval time_waited;
bool_t ok;
int nrefreshes = 2; /* number of times to refresh cred */
struct timeval timeout;
//int anyup; /* any network interface up */
struct iovec iov;
struct msghdr msg;
//int ret;
//printf("In clnt_pci_call\n");
if (cu->cu_total.tv_usec == -1) {
timeout = utimeout; /* use supplied timeout */
} else {
timeout = cu->cu_total; /* use default timeout */
}
time_waited.tv_sec = 0;
time_waited.tv_usec = 0;
call_again:
xdrs = &(cu->cu_outxdrs);
if (xargs == NULL)
goto get_reply;
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, cu->cu_xdrpos);
/*
* the transaction is the first thing in the out buffer
*/
(*(uint32_t *) (cu->cu_outbuf))++;
if ((!XDR_PUTLONG(xdrs, (long *)&proc)) ||
(!AUTH_MARSHALL(cl->cl_auth, xdrs)) || (!(*xargs) (xdrs, argsp)))
return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
outlen = (int)XDR_GETPOS(xdrs);
// Set up the netlink msg headers
cu->cu_reqnlh->nlmsg_len = outlen;
iov.iov_base = (void *)cu->cu_reqnlh;
iov.iov_len = NLMSG_SPACE(outlen);
memset((caddr_t) & msg, 0, sizeof(msg));
msg.msg_name = (void *)&cu->cu_daddr;
msg.msg_namelen = cu->cu_dlen;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
cu->cu_reqnlh->nlmsg_type = NETLINK_TYPE_CLNT_REQUEST;
assert(outlen <= PCIMSGSIZE);
//send_again:
//ret = sendmsg(cu->cu_sock, &msg, 0);
sendmsg(cu->cu_sock, &msg, 0);
//perror("sendmsg");
//fprintf(stderr, "sendmsg data len %d, sent %d\n", outlen, ret );
/*
* report error if it could not send.
{
cu->cu_error.re_errno = errno;
return (cu->cu_error.re_status = RPC_CANTSEND);
}
*/
/*
* Hack to provide rpc-based message passing
*/
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
return (cu->cu_error.re_status = RPC_TIMEDOUT);
}
// Set up the netlink msg headers
iov.iov_base = (void *)cu->cu_respnlh;
iov.iov_len = cu->cu_respnlh->nlmsg_len;
msg.msg_name = (void *)&cu->cu_daddr;
msg.msg_namelen = cu->cu_dlen;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
get_reply:
/*
* sub-optimal code appears here because we have
* some clock time to spare while the packets are in flight.
* (We assume that this is actually only executed once.)
*/
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = resultsp;
reply_msg.acpted_rply.ar_results.proc = xresults;
fd.fd = cu->cu_sock;
fd.events = POLLIN;
for (;;) {
switch (poll(&fd, 1, milliseconds)) {
case 0:
time_waited.tv_sec += cu->cu_wait.tv_sec;
time_waited.tv_usec += cu->cu_wait.tv_usec;
while (time_waited.tv_usec >= 1000000) {
time_waited.tv_sec++;
time_waited.tv_usec -= 1000000;
}
if ((time_waited.tv_sec < timeout.tv_sec) ||
((time_waited.tv_sec == timeout.tv_sec) &&
(time_waited.tv_usec < timeout.tv_usec))) {
//goto send_again;
}
return (cu->cu_error.re_status = RPC_TIMEDOUT);
/*
* buggy in other cases because time_waited is not being
* updated.
*/
case -1:
if (errno == EINTR)
continue;
cu->cu_error.re_errno = errno;
return (cu->cu_error.re_status = RPC_CANTRECV);
}
do {
iov.iov_len = NLMSG_SPACE(PCIMSGSIZE);
inlen = recvmsg(cu->cu_sock, &msg, 0);
} while (inlen < 0 && errno == EINTR);
if (inlen < 0) {
if (errno == EWOULDBLOCK)
continue;
cu->cu_error.re_errno = errno;
return (cu->cu_error.re_status = RPC_CANTRECV);
}
if (inlen < NLMSG_HDRLEN)
continue;
/* see if reply transaction id matches sent id.
Don't do this if we only wait for a replay */
if (xargs != NULL && (*((u_int32_t *) (cu->cu_inbuf))
!= *((u_int32_t *) (cu->cu_outbuf))))
continue;
/* we now assume we have the proper reply */
break;
}
/*
* now decode and validate the response
*/
xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int) inlen, XDR_DECODE);
ok = xdr_replymsg(&reply_xdrs, &reply_msg);
/* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
if (ok) {
_seterr_reply(&reply_msg, &(cu->cu_error));
if (cu->cu_error.re_status == RPC_SUCCESS) {
if (!AUTH_VALIDATE(cl->cl_auth,
&reply_msg.acpted_rply.ar_verf)) {
cu->cu_error.re_status = RPC_AUTHERROR;
cu->cu_error.re_why = AUTH_INVALIDRESP;
}
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
xdrs->x_op = XDR_FREE;
(void)xdr_opaque_auth(xdrs,
&(reply_msg.acpted_rply.
ar_verf));
}
} /* end successful completion */
else {
/* maybe our credentials need to be refreshed ... */
if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth, &reply_msg)) {
nrefreshes--;
goto call_again;
}
} /* end of unsuccessful completion */
} /* end of valid reply message */
else {
cu->cu_error.re_status = RPC_CANTDECODERES;
}
return cu->cu_error.re_status;
return 0;
}
void clnt_pci_geterr(CLIENT * cl, struct rpc_err *errp)
{
}
bool_t clnt_pci_freeres(CLIENT * cl, xdrproc_t xdr_res, caddr_t res_ptr)
{
return 0;
}
void clnt_pci_abort(void)
{
}
bool_t clnt_pci_control(CLIENT * cl, int request, char *info)
{
return 0;
}
void clnt_pci_destroy(CLIENT * cl)
{
struct cu_data *cu = (struct cu_data *)cl->cl_private;
if (cu->cu_sock >= 0) {
close(cu->cu_sock);
}
XDR_DESTROY(&(cu->cu_outxdrs));
free((caddr_t) cu->cu_reqnlh);
free((caddr_t) cu->cu_respnlh);
free((caddr_t) cu);
free((caddr_t) cl);
}

View File

@ -0,0 +1,358 @@
/*
* Copyright (C) 1987, Sun Microsystems, Inc.
* Copyright (C) 2014 Quantenna Communications Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
* * Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <linux/if_packet.h>
#include <linux/if.h>
#include <unistd.h>
#include <poll.h>
#include <errno.h>
#include <qcsapi_rpc_common/common/rpc_raw.h>
#define QRPC_CLNT_RAW_POLL_TIMEOUT 5000
enum clnt_stat qrpc_clnt_raw_call(CLIENT *cl, u_long proc, xdrproc_t xargs,
caddr_t argsp, xdrproc_t xresults, caddr_t resultsp, struct timeval utimeout);
void qrpc_clnt_raw_abort(void);
void qrpc_clnt_raw_geterr(CLIENT *cl, struct rpc_err *errp);
bool_t qrpc_clnt_raw_freeres(CLIENT *cl, xdrproc_t xdr_res, caddr_t res_ptr);
void qrpc_clnt_raw_destroy(CLIENT *cl);
bool_t qrpc_clnt_raw_control(CLIENT *cl, int request, char *info);
struct qrpc_clnt_raw_priv {
struct sockaddr_ll dst_addr;
struct rpc_err rpc_error;
XDR xdrs_out;
XDR xdrs_in;
uint8_t *outbuf;
uint8_t *out_pktbuf;
uint8_t *inbuf;
uint8_t *in_pktbuf;
struct qrpc_frame_hdr out_hdr;
uint32_t xdrs_outpos;
int raw_sock;
uint8_t sess_id;
};
static const struct clnt_ops qrpc_clnt_raw_ops = {
qrpc_clnt_raw_call,
qrpc_clnt_raw_abort,
qrpc_clnt_raw_geterr,
qrpc_clnt_raw_freeres,
qrpc_clnt_raw_destroy,
qrpc_clnt_raw_control
};
static void qrpc_clnt_raw_free_priv(struct qrpc_clnt_raw_priv *const priv)
{
free(priv->outbuf);
free(priv->out_pktbuf);
free(priv->inbuf);
free(priv->in_pktbuf);
if (priv->raw_sock >= 0)
close(priv->raw_sock);
free(priv);
}
CLIENT *qrpc_clnt_raw_create(u_long prog, u_long vers,
const char *const srcif_name, const uint8_t * dmac_addr, uint8_t sess_id)
{
CLIENT *client;
int rawsock_fd;
struct qrpc_clnt_raw_priv *priv;
struct rpc_msg call_msg;
rawsock_fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (rawsock_fd < 0)
return NULL;
if (qrpc_set_prot_filter(rawsock_fd, QRPC_RAW_SOCK_PROT) < 0) {
close(rawsock_fd);
return NULL;
}
priv = calloc(1, sizeof(*priv));
if (!priv) {
close(rawsock_fd);
return NULL;
}
priv->raw_sock = rawsock_fd;
priv->outbuf = calloc(1, QRPC_BUFFER_LEN);
priv->inbuf = calloc(1, QRPC_BUFFER_LEN);
priv->out_pktbuf = calloc(1, ETH_FRAME_LEN);
priv->in_pktbuf = calloc(1, ETH_FRAME_LEN);
if (!priv->outbuf || !priv->inbuf || !priv->out_pktbuf || !priv->in_pktbuf) {
qrpc_clnt_raw_free_priv(priv);
return NULL;
}
if (qrpc_clnt_raw_config_dst(rawsock_fd, srcif_name, &priv->dst_addr,
dmac_addr, &priv->out_hdr.qhdr,
QRPC_RAW_SOCK_PROT) < 0) {
qrpc_clnt_raw_free_priv(priv);
return NULL;
}
client = calloc(1, sizeof(*client));
if (!client) {
qrpc_clnt_raw_free_priv(priv);
return NULL;
}
client->cl_ops = (struct clnt_ops *)&qrpc_clnt_raw_ops;
client->cl_private = (caddr_t) priv;
client->cl_auth = authnone_create();
xdrmem_create(&priv->xdrs_in, (char *)priv->inbuf + sizeof(struct qrpc_frame_hdr),
QRPC_BUFFER_LEN - sizeof(struct qrpc_frame_hdr), XDR_DECODE);
xdrmem_create(&priv->xdrs_out, (char *)priv->outbuf,
QRPC_BUFFER_LEN, XDR_ENCODE);
call_msg.rm_xid = getpid();
call_msg.rm_direction = CALL;
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
call_msg.rm_call.cb_prog = prog;
call_msg.rm_call.cb_vers = vers;
if (!xdr_callhdr(&priv->xdrs_out, &call_msg)) {
qrpc_clnt_raw_free_priv(priv);
free(client);
return NULL;
}
priv->xdrs_outpos = XDR_GETPOS(&(priv->xdrs_out));
priv->sess_id = sess_id;
return client;
}
static int qrpc_clnt_raw_call_send(struct qrpc_clnt_raw_priv *const priv, const int len)
{
int ret;
static const uint16_t payload_max = ETH_FRAME_LEN - sizeof(struct qrpc_frame_hdr);
uint16_t pkt_nr;
uint16_t i;
uint16_t payload_done = 0;
struct qrpc_frame_hdr *hdr;
pkt_nr = (len + payload_max - 1) / payload_max;
for (i = 0; i < pkt_nr; i++) {
uint16_t payload_len = MIN((uint16_t)len - payload_done, payload_max);
/* build an EthII frame */
priv->out_hdr.sub_type = ((i != pkt_nr - 1) ? QRPC_FRAME_TYPE_FRAG
: QRPC_FRAME_TYPE_COMPLETE);
priv->out_hdr.sid = priv->sess_id;
hdr = (struct qrpc_frame_hdr *)priv->out_pktbuf;
memcpy(hdr, &priv->out_hdr, sizeof(priv->out_hdr));
memcpy(hdr + 1, priv->outbuf + payload_done, payload_len);
payload_done += payload_len;
do {
ret = sendto(priv->raw_sock, priv->out_pktbuf, sizeof(struct qrpc_frame_hdr) + payload_len, 0,
(struct sockaddr *)&priv->dst_addr, sizeof(priv->dst_addr));
} while (ret < 0 && errno == EINTR);
if ((uint16_t)ret != sizeof(struct qrpc_frame_hdr) + payload_len) {
priv->rpc_error.re_status = RPC_CANTSEND;
return -1;
}
}
return 0;
}
static int qrpc_clnt_raw_call_recv(struct qrpc_clnt_raw_priv *const priv)
{
struct pollfd fds;
struct sockaddr_ll lladdr;
socklen_t addrlen = sizeof(lladdr);
int ret;
uint16_t payload_done = sizeof(struct qrpc_frame_hdr);
struct qrpc_frame_hdr hdr;
do {
fds.fd = priv->raw_sock;
fds.events = POLLIN;
do {
ret = poll(&fds, 1, QRPC_CLNT_RAW_POLL_TIMEOUT);
} while (ret < 0 && errno == EINTR);
if (!ret) {
priv->rpc_error.re_status = RPC_TIMEDOUT;
return -1;
}
if (ret < 0) {
priv->rpc_error.re_status = RPC_SYSTEMERROR;
return -1;
}
do {
ret = recvfrom(priv->raw_sock, priv->in_pktbuf, ETH_FRAME_LEN,
0, (struct sockaddr *)&lladdr, &addrlen);
} while (ret < 0 && errno == EINTR);
if (lladdr.sll_pkttype != PACKET_HOST) {
priv->rpc_error.re_status = RPC_TIMEDOUT;
return -1;
}
if ((ret < (int)sizeof(struct qrpc_frame_hdr))
|| (ret - sizeof(struct qrpc_frame_hdr) + payload_done > QRPC_BUFFER_LEN)) {
priv->rpc_error.re_status = RPC_CANTRECV;
return -1;
}
/* assemble the buffer */
memcpy(&hdr, priv->in_pktbuf, sizeof(struct qrpc_frame_hdr));
memcpy(priv->inbuf + payload_done, priv->in_pktbuf + sizeof(struct qrpc_frame_hdr),
ret - sizeof(struct qrpc_frame_hdr));
payload_done += (ret - sizeof(struct qrpc_frame_hdr));
} while (hdr.sub_type == QRPC_FRAME_TYPE_FRAG);
memcpy(priv->inbuf, &hdr, sizeof(struct qrpc_frame_hdr));
return 0;
}
enum clnt_stat qrpc_clnt_raw_call(CLIENT *cl, u_long proc, xdrproc_t xargs, caddr_t argsp,
xdrproc_t xresults, caddr_t resultsp,
struct timeval utimeout)
{
struct qrpc_clnt_raw_priv *priv = (struct qrpc_clnt_raw_priv *)cl->cl_private;
XDR *xdrs_out = &priv->xdrs_out;
XDR *xdrs_in = &priv->xdrs_in;
struct rpc_msg reply_msg;
struct timeval curr_time;
struct qrpc_frame_hdr *hdr;
uint16_t tmp;
if (xargs) {
xdrs_out->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs_out, priv->xdrs_outpos);
if ((!XDR_PUTLONG(xdrs_out, (long *)&proc)) ||
(!AUTH_MARSHALL(cl->cl_auth, xdrs_out)) ||
(!(*xargs) (xdrs_out, argsp))) {
priv->rpc_error.re_status = RPC_CANTENCODEARGS;
return priv->rpc_error.re_status;
}
tmp = ntohs(priv->out_hdr.seq);
priv->out_hdr.seq = htons(tmp + 1);
if (qrpc_clnt_raw_call_send(priv, XDR_GETPOS(xdrs_out)) < 0) {
return priv->rpc_error.re_status;
}
}
if (gettimeofday(&curr_time, NULL) < 0) {
priv->rpc_error.re_status = RPC_SYSTEMERROR;
return priv->rpc_error.re_status;
}
utimeout.tv_sec += curr_time.tv_sec;
/* Waiting for reply */
do {
if (qrpc_clnt_raw_call_recv(priv) < 0) {
if (priv->rpc_error.re_status == RPC_TIMEDOUT)
continue;
else
break;
}
hdr = (struct qrpc_frame_hdr *)priv->inbuf;
if (xargs && priv->out_hdr.seq != hdr->seq) {
continue;
}
xdrs_in->x_op = XDR_DECODE;
XDR_SETPOS(xdrs_in, 0);
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = resultsp;
reply_msg.acpted_rply.ar_results.proc = xresults;
if (xdr_replymsg(xdrs_in, &reply_msg)) {
if (reply_msg.rm_xid != (unsigned long)getpid()) {
continue;
}
_seterr_reply(&reply_msg, &priv->rpc_error);
if (priv->rpc_error.re_status == RPC_SUCCESS) {
if (!AUTH_VALIDATE(cl->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
priv->rpc_error.re_status = RPC_AUTHERROR;
priv->rpc_error.re_why = AUTH_INVALIDRESP;
}
break;
}
} else {
priv->rpc_error.re_status = RPC_CANTDECODERES;
}
} while ((gettimeofday(&curr_time, NULL) == 0) && (curr_time.tv_sec < utimeout.tv_sec));
return priv->rpc_error.re_status;
}
void qrpc_clnt_raw_abort(void)
{
}
void qrpc_clnt_raw_geterr(CLIENT *cl, struct rpc_err *errp)
{
struct qrpc_clnt_raw_priv *priv = (struct qrpc_clnt_raw_priv *)cl->cl_private;
*errp = priv->rpc_error;
}
bool_t qrpc_clnt_raw_freeres(CLIENT *cl, xdrproc_t xdr_res, caddr_t res_ptr)
{
return FALSE;
}
void qrpc_clnt_raw_destroy(CLIENT *cl)
{
struct qrpc_clnt_raw_priv *priv = (struct qrpc_clnt_raw_priv *)cl->cl_private;
if (priv) {
XDR_DESTROY(&priv->xdrs_out);
XDR_DESTROY(&priv->xdrs_in);
qrpc_clnt_raw_free_priv(priv);
}
free(cl);
}
bool_t qrpc_clnt_raw_control(CLIENT *cl, int request, char *info)
{
return FALSE;
}

View File

@ -0,0 +1,14 @@
#ifndef _PCI_RPC_H
#define _PCI_RPC_H
#include "rpc_pci_nlm.h"
extern CLIENT *
clnt_pci_create (const char *hostname,
u_long prog,
u_long vers,
const char *proto);
extern SVCXPRT *svc_pci_create (int sock);
#endif

View File

@ -0,0 +1,26 @@
#ifndef __PCI_NLM_H__
#define __PCI_NLM_H__
/*
* We seperate the netlink type for client and server here.
* If the netlink type is conflicted with customers', they just need to modify
* NETLINK_RPC_PCI_CLNT and the type define in the PCIe RC driver and the netlink
* type in the rpc server and PCIe EP driver will not be affected.
*/
#define NETLINK_RPC_PCI_CLNT 31
#define NETLINK_RPC_PCI_SVC 31
#define PCIMSGSIZE (64 * 1024 - 1)
/*
* Nelink Message types.
*/
#define RPC_TYPE_CALL_QCSAPI_PCIE 0x0100
#define RPC_TYPE_QCSAPI_PCIE 0x0200
#define NETLINK_TYPE_SVC_REGISTER (PCIE_RPC_TYPE | 0x0010)
#define NETLINK_TYPE_SVC_RESPONSE (PCIE_RPC_TYPE | 0x0011)
#define NETLINK_TYPE_CLNT_REGISTER (PCIE_RPC_TYPE | 0x0010)
#define NETLINK_TYPE_CLNT_REQUEST (PCIE_RPC_TYPE | 0x0011)
#endif

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 2015 Quantenna Communications, Inc.
* All rights reserved.
*/
#include <linux/if_ether.h>
#include <linux/filter.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <poll.h>
#include <errno.h>
#include <stdio.h>
#include <qcsapi_rpc_common/common/rpc_raw.h>
#include <string.h>
int qrpc_set_prot_filter(const int sock, const short prot)
{
struct sock_filter filter[] = {
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, ETH_ALEN * 2), /* read packet type id */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
ETH_P_OUI_EXT, 0, 5), /* if OUI Extended Ethertype */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, ETH_HLEN), /* read OUI */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
QUANTENNA_OUI << 8, 0, 3), /* if QUANTENNA OUI */
BPF_STMT(BPF_LD + BPF_B + BPF_ABS, ETH_HLEN + 4), /* read protocol */
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K,
prot, 0, 1), /* if matches */
BPF_STMT(BPF_RET + BPF_K, ETH_FRAME_LEN), /* accept packet */
BPF_STMT(BPF_RET + BPF_K, 0) /* else ignore packet */
};
struct sock_fprog fp;
fp.filter = filter;
fp.len = ARRAY_SIZE(filter);
if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &fp, sizeof(fp)) < 0) {
printf("Cannot set rpc packet filter\n");
return -1;
}
return 0;
}
int qrpc_clnt_raw_config_dst(const int sock, const char *const srcif_name,
struct sockaddr_ll *dst_addr,
const uint8_t *dmac_addr,
struct q_raw_ethoui_hdr *pkt_outbuf,
uint8_t qprot)
{
struct ifreq ifreq;
struct ethhdr *const eth_packet = &pkt_outbuf->eth_hdr;
memset(&ifreq, 0, sizeof(ifreq));
strncpy(ifreq.ifr_name, srcif_name, IFNAMSIZ - 1);
if (ioctl(sock, SIOCGIFINDEX, &ifreq) < 0) {
printf("%s interface doesn't exist\n", srcif_name);
return -1;
}
dst_addr->sll_family = AF_PACKET;
dst_addr->sll_protocol = htons(ETH_P_OUI_EXT);
dst_addr->sll_ifindex = ifreq.ifr_ifindex;
dst_addr->sll_halen = ETH_ALEN;
memcpy(dst_addr->sll_addr, dmac_addr, ETH_ALEN);
memcpy(eth_packet->h_dest, dst_addr->sll_addr, ETH_ALEN);
if (ioctl(sock, SIOCGIFHWADDR, &ifreq) < 0)
return -1;
memcpy(eth_packet->h_source, ifreq.ifr_addr.sa_data, ETH_ALEN);
eth_packet->h_proto = htons(ETH_P_OUI_EXT);
pkt_outbuf->prot_id[0] = QUANTENNA_OUI >> 16;
pkt_outbuf->prot_id[1] = QUANTENNA_OUI >> 8;
pkt_outbuf->prot_id[2] = QUANTENNA_OUI & 0xFF;
pkt_outbuf->prot_id[3] = 0;
pkt_outbuf->prot_id[4] = qprot;
return dst_addr->sll_ifindex;
}
int qrpc_raw_read_timeout(const int sock_fd, const int timeout)
{
struct pollfd fds;
int ret;
fds.fd = sock_fd;
fds.events = POLLIN;
do {
ret = poll(&fds, 1, timeout);
} while (ret < 0 && errno == EINTR);
if (ret <= 0) {
return -1;
}
return 0;
}
int qrpc_raw_bind(const int sock, const char *const if_name, const int protocol)
{
struct sockaddr_ll addr;
struct ifreq ifreq;
memset(&ifreq, 0, sizeof(ifreq));
strncpy(ifreq.ifr_name, if_name, IFNAMSIZ - 1);
if (ioctl(sock, SIOCGIFINDEX, &ifreq) < 0)
return -1;
memset(&addr, 0, sizeof(addr));
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(protocol);
addr.sll_ifindex = ifreq.ifr_ifindex;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
return -1;
return 0;
}
int str_to_mac(const char *txt_mac, uint8_t *mac)
{
uint32_t mac_buf[ETH_ALEN];
int ret;
if (!txt_mac || !mac)
return -1;
ret = sscanf(txt_mac, "%02x:%02x:%02x:%02x:%02x:%02x", &mac_buf[0], &mac_buf[1],
&mac_buf[2], &mac_buf[3], &mac_buf[4], &mac_buf[5]);
if (ret != ETH_ALEN)
return -1;
while (ret) {
mac[ret - 1] = (uint8_t)mac_buf[ret - 1];
--ret;
}
return 0;
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2015 Quantenna Communications, Inc.
* All rights reserved.
*/
#ifndef RPC_RAW_H
#define RPC_RAW_H
#include <rpc/rpc.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
#endif
#define QRPC_RAW_SOCK_PROT 11
#define QFTP_RAW_SOCK_PROT 22
#define ETH_P_OUI_EXT 0x88B7
#define QUANTENNA_OUI 0x002686
#define QFTP_DATA_PKT_HDR_SIZE (sizeof(struct q_raw_ethoui_hdr) +\
sizeof(struct qftp_data_pkt) - 1)
#define QFTP_ACK_NACK_FRAME_LEN (sizeof(struct q_raw_ethoui_hdr) +\
sizeof(struct qftp_ack_nack_pkt))
/* QFT */
#define QFTP_FRAME_TYPE_NACK 0
#define QFTP_FRAME_TYPE_ACK 1
#define QFTP_FRAME_TYPE_CONNECT 2
#define QFTP_FRAME_TYPE_DATA 3
/* RPC QCSAPI */
#define QRPC_FRAME_TYPE_COMPLETE 4
#define QRPC_FRAME_TYPE_FRAG 5
#define QRPC_BUFFER_LEN (16 * 1024)
#define QRPC_QCSAPI_RPCD_SID 0
#define QRPC_CALL_QCSAPI_RPCD_SID 1
struct q_raw_ethoui_hdr {
struct ethhdr eth_hdr;
uint8_t prot_id[5]; /* Protocol Identifier */
uint8_t _pad1;
} __attribute__ ((packed));
/* QRPC frames */
struct qrpc_frame_hdr {
struct q_raw_ethoui_hdr qhdr;
uint8_t sub_type;
uint8_t sid;
uint16_t seq;
} __attribute__ ((packed));
struct qrpc_raw_ethpkt {
struct qrpc_frame_hdr fhdr;
char payload[ETH_FRAME_LEN - sizeof(struct qrpc_frame_hdr)];
} __attribute__ ((packed));
/* QFTP frame payloads */
struct qftp_raw_ethpkt {
struct q_raw_ethoui_hdr hdr;
char payload[ETH_FRAME_LEN - sizeof(struct q_raw_ethoui_hdr)];
} __attribute__ ((packed));
struct qftp_connect_pkt {
uint16_t sub_type;
uint16_t seq;
uint32_t image_size;
char image_name[1];
} __attribute__ ((packed));
struct qftp_data_pkt {
uint16_t sub_type;
uint16_t seq;
char data[1];
} __attribute__ ((packed));
struct qftp_ack_nack_pkt {
uint16_t sub_type;
uint16_t seq;
} __attribute__ ((packed));
extern CLIENT *qrpc_clnt_raw_create(u_long prog, u_long vers,
const char *const srcif_name, const uint8_t * dmac_addr, uint8_t sess_id);
extern SVCXPRT *qrpc_svc_raw_create(int sock, const char *const bind_interface, uint8_t sess_id);
extern int qrpc_set_prot_filter(const int sock, const short prot);
extern int qrpc_raw_bind(const int sock, const char *const if_name, const int protocol);
extern int str_to_mac(const char *txt_mac, uint8_t * mac);
extern int qrpc_clnt_raw_config_dst(const int sock, const char *const srcif_name,
struct sockaddr_ll *dst_addr,
const uint8_t *dmac_addr,
struct q_raw_ethoui_hdr *pkt_outbuf,
uint8_t qprot);
extern int qrpc_raw_read_timeout(const int sock_fd, const int timeout);
#endif

View File

@ -0,0 +1,303 @@
/*SH1
*******************************************************************************
** **
** Copyright (c) 2009 - 2011 Quantenna Communications Inc **
** **
** File : c_rpc_qcsapi_sample.c **
** Description : **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <net/if.h>
#include "qcsapi_output.h"
#include "../qcsapi_rpc_common/client/find_host_addr.h"
#include "qcsapi.h"
#include "../qcsapi_rpc/client/qcsapi_rpc_client.h"
#include "./qcsapi_rpc/generated/qcsapi_rpc.h"
#include "qcsapi_driver.h"
#include "call_qcsapi.h"
#define MAX_RETRY_TIMES 15
#define WIFINAME "wifi0"
static int s_c_rpc_use_udp = 0;
/*=============================================================================
FUNCTION: c_rpc_qcsapi_wps_push_button
DESCRIPTION: Start the WPS by QCSAPI
ARGUMENTS PASSED:
RETURN VALUE: 0:success, other:error
=============================================================================*/
int c_rpc_qcsapi_wps_push_button()
{
int ret;
qcsapi_mac_addr bssid;
memset(bssid, 0, MAC_ADDR_SIZE);
ret = qcsapi_wps_enrollee_report_button_press(WIFINAME, bssid);
if (ret < 0) {
printf("Qcsapi qcsapi_wps_enrollee_report_button_press error, return: %d\n", ret);
return -1;
}
printf("WPS push button started\n");
return 0;
}
/*=============================================================================
FUNCTION: c_rpc_qcsapi_get_rssi
DESCRIPTION: 1.Check if the association established.
2.If associtied, get the rssi value by QCSAPI
ARGUMENTS PASSED:
RETURN VALUE: 0:success, other:error
=============================================================================*/
int c_rpc_qcsapi_get_rssi()
{
int ret;
int rssi=0;
qcsapi_unsigned_int assoc_cnt;
//Get the association count
//if assoc_cnt is 0, it means not associated
ret = qcsapi_wifi_get_count_associations(WIFINAME, &assoc_cnt);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_count_associations error, return: %d\n", ret);
return -1;
}
//Has the association
if ( assoc_cnt == 0){
printf("Device not associated\n");
} else {
ret = qcsapi_wifi_get_rssi_in_dbm_per_association(WIFINAME, 0, &rssi);
if (ret < 0) {
printf("enrollee report button press return %d\n", ret);
return -1;
}
printf("RSSI: %d dbm\n",rssi);
}
return 0;
}
/*=============================================================================
FUNCTION: c_rpc_qcsapi_get_ssid
DESCRIPTION: Get the current ssid.
If the device is not associated, the ssid could be empty.
ARGUMENTS PASSED:
RETURN VALUE: 0:success, other:error
=============================================================================*/
int c_rpc_qcsapi_get_ssid()
{
int ret;
qcsapi_SSID ssid;
ret = qcsapi_wifi_get_SSID(WIFINAME, ssid);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_SSID error, return: %d\n", ret);
return -1;
}
printf("Current SSID: %s\n",ssid);
return 0;
}
/*=============================================================================
FUNCTION: c_rpc_qcsapi_start_scan
DESCRIPTION: Start the scan.
ARGUMENTS PASSED:
RETURN VALUE: 0:success, other:error
=============================================================================*/
int c_rpc_qcsapi_start_scan()
{
int ret;
ret = qcsapi_wifi_start_scan(WIFINAME);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_start_scan error, return: %d\n", ret);
return -1;
}
printf("Scan started\n");
return 0;
}
/*=============================================================================
FUNCTION: c_rpc_qcsapi_get_ap_properties
DESCRIPTION: Get the scaned AP properties and print.
ARGUMENTS PASSED:
RETURN VALUE: 0:success, other:error
=============================================================================*/
int c_rpc_qcsapi_get_ap_properties()
{
int ret,i;
unsigned int ap_count = 0;
qcsapi_ap_properties ap_current;
//Get the scaned AP count
ret = qcsapi_wifi_get_results_AP_scan(WIFINAME, &ap_count);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_results_AP_scan error, return: %d\n", ret);
return -1;
}
if (ap_count == 0) {
printf("Scaned ap count is 0\n");
return -1;
}
for (i = 0; i < ap_count; i++) {
ret = qcsapi_wifi_get_properties_AP(WIFINAME, i, &ap_current);
if (ret < 0) {
printf("Qcsapi qcsapi_wifi_get_properties_AP error, return: %d\n", ret);
return -1;
}
printf
("AP %02d:\tSSID:%30s\tMAC:%02X:%02X:%02X:%02X:%02X:%02X\tSecurity:%d\tRSSI:%02d\tChannel:%02d\tWPS:%d\n",
i, ap_current.ap_name_SSID, ap_current.ap_mac_addr[0], ap_current.ap_mac_addr[1],
ap_current.ap_mac_addr[2], ap_current.ap_mac_addr[3], ap_current.ap_mac_addr[4],
ap_current.ap_mac_addr[5], ap_current.ap_flags, (ap_current.ap_RSSI-90),
ap_current.ap_channel, ap_current.ap_wps);
}
return 0;
}
/*=============================================================================
FUNCTION: print_help
DESCRIPTION: Print the supported option list
ARGUMENTS PASSED:
RETURN VALUE:
=============================================================================*/
void print_help()
{
printf("RPC Qcsapi Sample:\n");
printf("\t-h: Help\n");
printf("\t-w: Wps push button\n");
printf("\t-r: get Rssi\n");
printf("\t-c: get Current ssid\n");
printf("\t-s: start Scan\n");
printf("\t-g: Get ap properties\n");
printf("\t-u: Use UDP as the transport layer for RPC (default to TCP)\n");
return;
}
/*=============================================================================
FUNCTION: process_option
DESCRIPTION: Process all the options with corresponding functions
ARGUMENTS PASSED: int argc, char **argv
RETURN VALUE:
=============================================================================*/
void process_option(int argc, char **argv)
{
int c;
while ((c = getopt(argc, argv, "hwrcsg")) != -1){
switch (c) {
case 'h': //Help print
print_help();
break;
case 'w': //WPS push button
c_rpc_qcsapi_wps_push_button();
break;
case 'r': //get rssi
c_rpc_qcsapi_get_rssi();
break;
case 'c': //get the current ssid
c_rpc_qcsapi_get_ssid();
break;
case 's': //start scan
c_rpc_qcsapi_start_scan();
break;
case 'g': //get the ap properties list
c_rpc_qcsapi_get_ap_properties();
break;
case 'u': //use UDP as the transport. Default is TCP
s_c_rpc_use_udp = 1;
break;
default:
print_help();
break;
}
}
}
int main(int argc, char **argv)
{
int retry = 0;
const char *host;
CLIENT *clnt;
/* print help if no arguments */
if (argc == 1) {
print_help();
exit(1);
}
/* setup RPC based on udp protocol */
while (retry++ < MAX_RETRY_TIMES) {
host = client_qcsapi_find_host_addr(&argc, &argv);
if (!host) {
client_qcsapi_find_host_errmsg(argv[0]);
sleep(1);
continue;
}
if (!s_c_rpc_use_udp) {
clnt = clnt_create(host, QCSAPI_PROG, QCSAPI_VERS, "tcp");
} else {
clnt = clnt_create(host, QCSAPI_PROG, QCSAPI_VERS, "udp");
}
if (clnt == NULL) {
clnt_pcreateerror(host);
sleep(1);
continue;
} else {
client_qcsapi_set_rpcclient(clnt);
break;
}
}
/* could not find host or create a client, exit */
if (retry >= MAX_RETRY_TIMES)
exit(1);
process_option(argc, argv);
clnt_destroy(clnt);
return 0;
}

View File

@ -0,0 +1,160 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2009 - 2012 Quantenna Communications, Inc. **
** **
** File : qcsapi_sem.c **
** Description : Locking mechanism for QCSAPI **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include "qcsapi.h"
/* Existing path used to generate key for System V semaphore */
#define LOCK_PATH "/lib/libqcsapi.so"
/* The maximum times waiting initialization of semaphore */
#define MAX_TRIES 10
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
unsigned short *array; /* array for GETALL & SETALL */
};
/*
* postop is used to perform V operation on semaphore
* waitop is used to perform P operation on semaphore
*/
static struct sembuf postop, waitop;
static int semid, init_flag;
static int sem_enable = 1;
int
qcsapi_sem_init(void)
{
struct semid_ds seminfo;
union semun arg;
int oflag, i;
if (sem_enable == 0)
return 0;
oflag = IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR;
/* Init semop() structures: postop and waitop */
postop.sem_num = 0;
postop.sem_op = 1;
postop.sem_flg = SEM_UNDO;
waitop.sem_num = 0;
waitop.sem_op = -1;
waitop.sem_flg = SEM_UNDO;
/* Create a new System V semaphore or open a existing semaphore */
if ((semid = semget(ftok(LOCK_PATH, 0), 1, oflag)) >= 0) {
arg.val = 1;
semctl(semid, 0, SETVAL, arg);
/*
* A pair of semops make sem_otime non-zero so that other processes
* can judge that the semaphore has been initialized
*/
semop(semid, &waitop, 1);
semop(semid, &postop, 1);
} else if (errno == EEXIST) {
/*
* The semaphore has been created; wait until it's initialized.
* Once initialized, field sem_otime is non-zero.
*/
oflag = S_IRUSR | S_IWUSR;
semid = semget(ftok(LOCK_PATH, 0), 1, oflag);
arg.buf = &seminfo;
for (i = 0; i < MAX_TRIES; i++) {
semctl(semid, 0, IPC_STAT, arg);
if (arg.buf->sem_otime != 0)
break;
sleep(1);
}
if (i == MAX_TRIES)
return -qcsapi_sem_error;
} else {
return -errno;
}
init_flag = 1;
return 0;
}
void qcsapi_sem_disable(void)
{
sem_enable = 0;
}
void
qcsapi_sem_lock(void)
{
if (sem_enable == 1) {
if (init_flag == 0)
qcsapi_sem_init();
if (init_flag == 1)
semop(semid, &waitop, 1);
}
}
void
qcsapi_sem_unlock(void)
{
if (sem_enable == 1 && init_flag == 1)
semop(semid, &postop, 1);
}

View File

@ -0,0 +1,67 @@
/*SH1
*******************************************************************************
** **
** Copyright (c) 2009 - 2012 Quantenna Communications, Inc. **
** **
** File : qcsapi_sem.h **
** Description : Locking for QCSAPI **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#ifndef _QCSAPI_SEM_H
#define _QCSAPI_SEM_H
#define enter_qcsapi() qcsapi_sem_lock()
#define leave_qcsapi() qcsapi_sem_unlock()
#ifdef __cplusplus
extern "C" {
#endif
extern int qcsapi_sem_init(void);
extern void qcsapi_sem_disable(void);
extern void qcsapi_sem_lock(void);
extern void qcsapi_sem_unlock(void);
#ifdef __cplusplus
}
#endif
#endif /* _QCSAPI_SEM_H */

View File

@ -0,0 +1,148 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2015 Quantenna Communications, Inc. **
** **
** File : qcsapi_util.h **
** Description : utility functions to be used by qcsapi_* and call_qcsapi **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "qcsapi_util.h"
/*
* verify function return negative value when the parameter_value is not valid
*/
int qcsapi_verify_numeric(const char *parameter_value)
{
while (*parameter_value != '\0') {
if (!isdigit(*parameter_value))
return -1;
parameter_value++;
}
return 0;
}
/*
* Conversion from string to unsigned integer.
* Handles invalid strings and integer overflows.
* return:
* 0 - on success
* -1 - on error
*/
int qcsapi_str_to_uint32(const char *str, uint32_t *result)
{
char *endptr = NULL;
uint32_t res;
while (isspace(*str)) {
str++;
}
if (!isdigit(*str)) {
return -1;
}
errno = 0;
res = strtoul(str, &endptr, 10);
if (errno != 0) {
return -1;
}
if (!endptr || endptr == str) {
return -1;
}
while (isspace(*endptr)) {
endptr++;
}
if (*endptr != '\0') {
return -1;
}
*result = res;
return 0;
}
#define QCSAPI_MAX_ETHER_STRING 17
int parse_mac_addr(const char *mac_addr_as_str, qcsapi_mac_addr mac_addr)
{
int i;
int mac_len = strnlen(mac_addr_as_str, QCSAPI_MAX_ETHER_STRING + 1);
unsigned int tmp[sizeof(qcsapi_mac_addr)];
int retval;
if (mac_addr_as_str == NULL)
return -qcsapi_invalid_mac_addr;
if (mac_len > QCSAPI_MAX_ETHER_STRING) {
return -qcsapi_invalid_mac_addr;
}
for (i = 0; i < mac_len; i++) {
if (!(isxdigit(mac_addr_as_str[i]) || (mac_addr_as_str[i] == ':')))
return -qcsapi_invalid_mac_addr;
}
retval = sscanf(mac_addr_as_str, "%x:%x:%x:%x:%x:%x",
&tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
if (retval != sizeof(qcsapi_mac_addr))
return -qcsapi_invalid_mac_addr;
for (i = 0; i < sizeof(qcsapi_mac_addr); i++) {
if (tmp[i] > 0xff)
return -qcsapi_invalid_mac_addr;
}
mac_addr[0] = (uint8_t) tmp[0];
mac_addr[1] = (uint8_t) tmp[1];
mac_addr[2] = (uint8_t) tmp[2];
mac_addr[3] = (uint8_t) tmp[3];
mac_addr[4] = (uint8_t) tmp[4];
mac_addr[5] = (uint8_t) tmp[5];
return 0;
}

View File

@ -0,0 +1,50 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2015 Quantenna Communications, Inc. **
** **
** File : qcsapi_util.h **
** Description : utility functions to be used by qcsapi_* and call_qcsapi **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH0*/
#include <stdint.h>
#include <qcsapi.h>
int qcsapi_verify_numeric(const char *parameter_value);
int qcsapi_str_to_uint32(const char *str, uint32_t *result);
int parse_mac_addr(const char *mac_addr_as_str, qcsapi_mac_addr mac_addr);

View File

@ -0,0 +1,976 @@
/*
* Copyright (c) 2011 Quantenna Communications, Inc.
*/
/*
* This file contains host definitions which are common between the
* host driver and the microcontroller/MAC code.
*/
#ifndef _LHOST_MUC_COMM_H
#define _LHOST_MUC_COMM_H
#include "qtn_uc_comm.h"
#include "qtn_cca.h"
#include "qtn_wmm_ac.h"
#include "net80211/ieee80211.h"
#include "net80211/ieee80211_crypto.h"
#include "muc_txrx_stats.h"
#include "qtn/qvsp_common.h"
#include "qtn/shared_defs.h"
/* packed definitions for each compiler */
#if defined(MUC_BUILD) || defined(DSP_BUILD) || defined(AUC_BUILD)
# define PACKED __packed
# define LM(a,b) (b)
# define lhost_volatile
# define muc_volatile volatile
#else
# define PACKED __attribute__ ((packed))
# define LM(a,b) (a)
# define lhost_volatile volatile
# define muc_volatile
#endif // #if defined(MUC_BUILD) || defined(DSP_BUILD) || defined(AUC_BUILD)
#define HOST_TXD_NUMSEG 2
#define QTN_BBIC_11N 0x30
#define QTN_BBIC_11AC 0x40
#define QTN_VSP_STATS_TID_NUM 4
#define QTN_VSP_TIDS { 6, 5, 0, 1 }
#define QTN_VSP_STATS_TID2IDX {0, 1, -1, -1, -1, 2, 3, -1} /* make sure no tids using same index */
struct qtn_vsp_per_node_stats {
struct qtn_per_tid_stats per_tid_stats[QTN_VSP_STATS_TID_NUM];
};
struct qtn_vsp_stats {
#define QVSP_FAT_MAX 1000
#define QVSP_FAT_NONE ((uint32_t)(-1))
uint32_t fat; /* free airtime */
uint32_t intf_ms; /* interference */
#if TOPAZ_QTM
struct qtn_vsp_per_node_stats per_node_stats[QTN_NCIDX_MAX];
#endif
};
/**
* \brief This enumeration represents the mode in use on the device.
*
* This enumeration is used to set the correct bandwidth.
*/
enum {
QTN_11NAC_DISABLE = 0,
QTN_11NAC_ENABLE = 1,
};
/* Host tx descriptor */
struct host_txdesc {
uint32_t hd_version:8; /* Descriptor version */
uint32_t hd_tid:4; /* packet tid */
uint32_t hd_txstatus:2; /* Transmit status: 1 sent to MuC, 2 tx success */
#define QTN_TXSTATUS_TX_ON_MUC 1
#define QTN_TXSTATUS_TX_SUCCESS 2
uint32_t hd_wmmac:2; /* Reserved for WMM AC*/
uint32_t hd_pktlen:16; /* Pkt len (incl. all headers) */
uint32_t hd_node_idx; /* local node index */
uint16_t hd_seglen[HOST_TXD_NUMSEG]; /* Segment lenghts */
uint32_t hd_segaddr[HOST_TXD_NUMSEG]; /* Phys addr of each seg */
uint32_t hd_ts; /* Timestamp of the pkt */
uint32_t hd_nextpa; /* Phys addr of next host tx descr in fwd dir */
uint32_t hd_nextpa_rev; /* Phys addr of next host tx descr in rev dir */
void *hd_nextva_rev; /* Virtual addr (LHOST view) of next host tx descr in rev dir */
uint32_t hd_pa; /* Physical addr of this host tx descr */
void *hd_va; /* Virtual addr (LHOST view) of this host tx descr */
uint32_t hd_status; /* Status of HTxD */
void (*hd_muc_txdone_cb)(void *, uint32_t, uint32_t); /* MuC callback after txdone */
uint32_t hd_muc_cb_arg1; /* parameter for hd_muc_txdone_cb */
uint32_t hd_muc_cb_arg2; /* parameter for hd_muc_txdone_cb */
uint32_t hd_txtsf; /* record the tsf_lo on that frame was sent successfully */
uint8_t hd_mpdu[128];
uint8_t hd_msdu[128];
uint8_t hd_dma[128];
#define HTXD_FLAG_AMSDU_DEST_CAPABLE 0x00000002 /* Can be used for AMSDU destination (append to) */
#define HTXD_FLAG_AMSDU_SRC_CAPABLE 0x00000004 /* Can be used for AMSDU (copy from) */
#define HTXD_FLAG_NO_UPDATE_NAV 0x00000008 /* Don't update NAV for this frame */
#define HTXD_FLAG_NO_RETRY 0x00000010 /* Don't retry this frame if tx failed */
#define HTXD_FLAG_NO_RETURN 0x00000020 /* Don't return txdesc from MuC to lhost */
#define HTXD_FLAG_IMM_RETURN 0x00000040 /* Immediately return txdesc from Muc to lhost */
uint32_t hd_flags;
};
#define QTN_AMSDU_DEST_CAPABLE_SIZE ETHER_MAX_LEN
#define QTN_AMSDU_DEST_CAPABLE_GUARD_SIZE 64
#define QTN_AMSDU_SRC_FRAME_SIZE (QTN_AMSDU_DEST_CAPABLE_SIZE / 10)
#define QTN_AMSDU_DEST_CAPABLE_OCCUPY_SIZE (QTN_AMSDU_DEST_CAPABLE_SIZE / 3 * 2)
#define HTXD_FLAG_SET(_htxd, _flag) \
(((struct host_txdesc *)(_htxd))->hd_flags |= (_flag))
#define HTXD_FLAG_CLR(_htxd, _flag) \
(((struct host_txdesc *)(_htxd))->hd_flags &= ~(_flag))
#define HTXD_FLAG_GET(_htxd, _flag) \
(((struct host_txdesc *)(_htxd))->hd_flags & (_flag))
#define HTXD_FLAG_ISSET(_htxd, _flag) \
(!!(((struct host_txdesc *)(_htxd))->hd_flags & (_flag)))
#define HTXD_FLAG_KEEP_ONLY(_htxd, _flag) \
(((struct host_txdesc *)(_htxd))->hd_flags &= (_flag))
/* host_ioctl_hifinfo */
#define NAMESIZE 16
#define VERSION_SIZE 16
#define MAC_ADDR_LEN 6
#define MAC_STR_BUF_SIZE 18
#define HOST_NUM_IOCTLQ 1 /* Number of ioctl q's */
/*
* LHost -> MuC TX queues are per node to allow variable backpressure per node.
* One universal management data frame tx mailbox, and one ioctl mailbox
*/
#define HOST_NUM_MGMTQ 1
#define HOST_NUM_DATAQ (QTN_NCIDX_MAX)
#define HOST_NUM_DATASEM 1
#define HOST_IOCTL_INDEX_BASE 0
#define HOST_MGMT_INDEX_BASE (HOST_IOCTL_INDEX_BASE + HOST_NUM_IOCTLQ)
#define HOST_DATA_INDEX_BASE (HOST_MGMT_INDEX_BASE + HOST_NUM_MGMTQ)
#define HOST_NUM_HOSTIFQ (HOST_NUM_DATAQ + HOST_NUM_IOCTLQ + HOST_NUM_MGMTQ)
#define HOST_MBOX_SIZE (sizeof(uint32_t) * HOST_NUM_HOSTIFQ)
#define QTN_PHY_RATE_PROP_SCALE 1024
#define QTN_MUC_NODE_PKT_LIMIT_MIN 16
#define QTN_MUC_NODE_PKT_LIMIT_DEFAULT 64
#define QTN_MUC_NODE_PKT_LIMIT_MAX 128
#define IEEE80211_TXPOW_ENCODE(x) ((255 * 65536) + (x * 256) + 1)
#define IEEE80211_TXPOW_DECODE(x) (((x) - (255 * 65536) - 1) / 256)
#define RF_MIXER_VAL_HI 0x1
#define RF_MIXER_VAL_LO 0x7
#define RF_PGA_VAL_HI 0x3
#define RF_PGA_VAL_LO 0x0
#define IEEE80211_LOWGAIN_TXPOW_MAX 10
#define IEEE80211_LOWGAIN_TXPOW_MIN 9
#define IEEE80211_CHAN_SEC_SHIFT 4
struct host_ioctl_hifinfo {
uint32_t hi_mboxstart; /* Start address for mbox */
uint32_t hi_rxdoneirq; /* IRQ map for rx done */
uint32_t hi_txdoneirq; /* IRQ map for tx done */
uint32_t hi_rxfifo; /* Rx FIFO location */
uint32_t hi_scanirq; /* IRQ map for Scan */
uint32_t hi_scanfifo; /* Scan FIFO location */
uint32_t hi_dspgpios;
uint32_t hi_vsp_stats_phys;
uint32_t hi_vapnode_idx; /* node_idx of the vap node for tx */
uint8_t hi_vapid;
char hi_name[NAMESIZE]; /* Device name */
char hi_version[VERSION_SIZE]; /* basic firmware version */
char hi_algover[VERSION_SIZE]; /* calibration algorithm version */
uint8_t hi_macaddr[MAC_ADDR_LEN];
uint8_t hi_semmap[HOST_NUM_HOSTIFQ]; /* Mapping of semaphores */
};
typedef int (*scan_done_fn)(int sc_devid, void *chan, int type, int status);
struct host_scandesc {
uint8_t sd_type;
uint8_t sd_devid;
uint8_t status;
uint8_t ____pad;
uint8_t* sd_data;
scan_done_fn *sd_ppfn;
struct host_scandesc *sd_next;
};
struct host_rxdesc {
uint8_t hw_desc[128]; /* need to be aligned on 8 bytes */
uint8_t *skbuff;
uint8_t *rd_buffer;
uint32_t rs_statword;
struct host_rxdesc *rd_next;
struct host_rxdesc *rd_pa;
struct host_rxdesc *rd_va;
void *node; /* Where the frame was from */
uint32_t rx_status_word0;
uint32_t rx_status_qosctrl;
uint32_t rx_status_pnlo;
uint32_t rx_status_pnhi;
uint8_t gain_db;
};
struct host_descfifo {
struct host_rxdesc *df_fifo; /* Pointer to first descriptor in linked list */
volatile uint32_t df_numelems; /* Num elems on fifo */
volatile uint32_t df_size; /* Size of fifo */
struct host_rxdesc * volatile hrdstart; /* the ptr to the host_rxdesc linked list ready for indication */
};
struct host_scanfifo {
uint32_t sf_req; /* Pointer to request mailbox */
uint32_t sf_res; /* Pointer to result mailbox */
uint8_t sf_sem; /* Semaphore for Scan fifo */
uint8_t tx_sem; /* Semaphore for Scan fifo */
uint8_t ____pad[2];
};
struct host_rxfifo {
struct host_descfifo *rf_fifo; /* Data Descriptor fifo */
uint8_t rf_sem; /* Semaphore for rx fifo */
uint8_t ____pad[3];
};
struct host_ndp_mesg {
uint8_t macaddr_ta[6];
uint8_t bw;
uint8_t rxgain;
uint8_t mcs;
uint8_t ____pad[3];
};
struct host_ioctl {
lhost_volatile uint32_t ioctl_dev; /* Device to run IOCTL on */
lhost_volatile uint32_t ioctl_command; /* Command type */
lhost_volatile uint32_t ioctl_arg1; /* Single valued arg 1 */
lhost_volatile uint32_t ioctl_arg2; /* Single valued arg 2 */
volatile uint32_t ioctl_argp; /* Argument payload pointer */
volatile uint32_t ioctl_status; /* Status from other side */
volatile uint32_t ioctl_rc; /* Command return code */
lhost_volatile struct host_ioctl *ioctl_next; /* link to next msg in chain */
};
struct qtn_vap_args {
char vap_name[17];
uint8_t vap_id;
uint8_t vap_macaddr[IEEE80211_ADDR_LEN];
};
struct qtn_setparams_args
{
int ni_param;
int ni_value;
int ni_len;
unsigned char ni_data[64];
};
struct qtn_baparams_args {
unsigned char ni_addr[8];
enum ieee80211_ba_state state;
int tid;
int type;
int start_seq_num;
int window_size;
int lifetime;
uint16_t flags;
};
#define QTN_HLINK_RC_DONE 0x00000001
#define QTN_HLINK_RC_ERR 0x00000002
#define QTN_HLINK_STATUS_AVAIL 1
#define IOCTL_DEV_VAPCREATE 4 /* Create a vap */
#define IOCTL_DEV_DEVOPEN 5 /* Bring the device up */
#define IOCTL_DEV_BEACON_START 6 /* Start Beacon */
#define IOCTL_DEV_NEWASSOC 7 /* New associated node */
#define IOCTL_DEV_NEWBSSID 8 /* New associated node */
#define IOCTL_DEV_SEND_NDP_ANNOUNCEMENT 10 /* Send NDP announcement */
#define IOCTL_DEV_SETPARAMS 11 /* Configure Parameters */
#define IOCTL_DEV_GETPARAMS 12 /* Configure Parameters */
#define IOCTL_DEV_BA_ADDED_TX 13
#define IOCTL_DEV_BA_ADDED_RX 14
#define IOCTL_DEV_BA_REMOVED_TX 15
#define IOCTL_DEV_BA_REMOVED_RX 16
#define IOCTL_DEV_CHANGE_CHANNEL 17
#define IOCTL_DEV_SETKEY 18
#define IOCTL_DEV_CALCMD 19 /* Send the cal cmd */
#define IOCTL_DEV_DELKEY 20
#define IOCTL_DEV_CMD 21 /* General commands */
#define IOCTL_DEV_DISASSOC 22 /* Configure node */
#define IOCTL_DEV_SMPS 23 /* MIMO power save mode change */
#define IOCTL_DEV_FORCEMICERROR 24
#define IOCTL_DEV_SET_SCANMODE 25
#define IOCTL_DEV_XMITCTL 26 /* transmission control (turning on or off) */
#define IOCTL_DEV_BEACON_STOP 27 /* Stop transmitting beacons */
#define IOCTL_DEV_SET_MACADDR 30
#define IOCTL_DEV_KILL_MUC 31
#define IOCTL_DEV_DUMP_LOG 32
#define IOCTL_DEV_SET_HRFLAGS 33
#define IOCTL_DEV_SAMPLE_CHANNEL 34
#define IOCTL_DEV_CHANGE_CHAN_DEFERRED 35
#define IOCTL_DEV_WMM_PARAMS 36
#define IOCTL_DEV_VAPDELETE 37 /* Delete a vap */
#define IOCTL_DEV_STORE_TXPOW 38 /* Store the Tx power, short-range workaround*/
#define IOCTL_DEV_USE_RTS_CTS 39 /* Enable-disable RTS-CTS */
#define IOCTL_DEV_RST_QUEUE_DEPTH 40
#define IOCTL_DEV_SET_POWER_SAVE 41 /* send request to MuC to change power save level */
#define IOCTL_DEV_VSP 42 /* Configure QVSP */
#define IOCTL_DEV_SET_11G_ERP 43 /* set 11bg ERP on/off */
#define IOCTL_DEV_BGSCAN_CHANNEL 44
#define IOCTL_DEV_UPDATE_DTLS_PRESENT 45 /* update wheather DTLS session deteced or not */
#define IOCTL_DEV_SET_OCAC 46
#define IOCTL_DEV_MEAS_CHANNEL 47 /* notify MUC to execute measurement */
#define IOCTL_DEV_GET_LINK_MARGIN_INFO 48 /* get rssi info */
#define IOCTL_DEV_SET_TDLS_PARAM 49 /* set tdls related paramters */
#define IOCTL_DEV_GET_TDLS_PARAM 50 /* set tdls related paramters */
#define IOCTL_DEV_POWER_SAVE 51 /* enter/leave power save state */
#define IOCTL_DEV_REMAIN_CHANNEL 52 /* Remain on target channel */
#define IOCTL_DEV_SCS_UPDATE_SCAN_STATS 53
#define IOCTL_DEV_SET_SCANMODE_STA 54
#define IOCTL_DEV_GET_MU_GRP 55 /* get MU groups other releated data */
#define IOCTL_DEV_SET_RX_GAIN_PARAMS 56 /* Set RX gain params */
#define IOCTL_DEV_GET_MU_ENABLE 57 /* get MU enable flag */
#define IOCTL_DEV_GET_PRECODE_ENABLE 58 /* get MU precode enable flag */
#define IOCTL_DEV_GET_MU_USE_EQ 59 /* get EQ enable flag */
#define IOCTL_DEV_SET_CHAN_POWER_TABLE 60 /* Set MuC power table */
#define IOCTL_DEV_ENABLE_VLAN 61 /* Set Global Vlan mode */
#define IOCTL_DEV_NODE_UPDATE 62 /* Update node information again after association */
#define IOCTL_DEV_FWT_SW_SYNC 63 /* sync FWT timestamp base between Lhost and MUC */
#define IOCTL_DEV_CMD_MEMDBG_DUMP 1 /* Dump MuC memory */
#define IOCTL_DEV_CMD_MEMDBG_DUMPCFG 2 /* Configuration for dumping MuC memory */
#define IOCTL_DEV_CMD_MEMDBG_DUMPNODES 3 /* Configuration for dumping MuC nodes */
#define IOCTL_DEV_CMD_SET_DRV_DBG 4 /* Set MUC debug message level*/
#define IOCTL_DEV_CMD_GET_DRV_DBG 5 /* Get MUC debug message level*/
#define IOCTL_DEVATTACH_DEVFLAG_MASK 0xFFFF0000
#define IOCTL_DEVATTACH_DEVFLAG_MASK_S 16
#define IOCTL_DEVATTACH_DEVID_MASK 0x000000FF
#define IOCTL_DEVATTACH_DEV_RFCHIP_FREQID_MASK 0x00000F00
#define IOCTL_DEVATTACH_DEV_RFCHIP_FREQID_MASK_S 8
#define IOCTL_DEVATTACH_DEV_RFCHIP_VERID_MASK 0x0000F000
#define IOCTL_DEVATTACH_DEV_RFCHIP_VERID_MASK_S 12
#define IOCTL_DEVATTACH_IRQNUM 0x000000FF
#define IOCTL_DEVATTACH_IRQREG 0x00000F00
#define IOCTL_DEVATTACH_IRQREG_S 8
#define IOCTL_DEVATTACH_NMBOX_MASK 0x000000FF
#define QTN_CHAN_IEEE (0xFF << 0)
#define QTN_CHAN_IEEE_S (0)
#define QTN_CHAN_PWR (0xFF << 8)
#define QTN_CHAN_PWR_S (8)
#define QTNCHAN_TO_IEEENUM(chan) (MS(chan, QTN_CHAN_IEEE))
#define QTN_CHAN_FLG_DFS 0x20000000
#define QTN_CHAN_FLG_HT40 0x40000000
#define QTN_CHAN_FLG_PRI_HI 0x80000000
#define QTN_CHAN_FLG_RSV01 0x01000000
#define QTN_CHAN_FLG_RSV02 0x02000000
#define QTN_CHAN_FLG_RSV04 0x04000000
#define QTN_CHAN_FLG_RSV08 0x08000000
#define QTN_CHAN_FLG_RSV10 0x10000000
#define QTN_CHAN_FLG_VHT80 0x00800000
#define QTN_BAND_FREQ (0xFF << 0)
#define QTN_BAND_FREQ_S (0)
#define IOCTL_HLINK_DEVATTACH 1 /* Attach device */
#define IOCTL_HLINK_DEVDETACH 2 /* Detach device */
#define IOCTL_HLINK_DEVCHANGE 3 /* Change device state/flags */
#define IOCTL_HLINK_LOGATTACH 4 /* Attach Log */
#define IOCTL_HLINK_TEMP_ATTACH 5 /* Share temperature struct */
#define IOCTL_HLINK_SVCERRATTACH 6 /* Attach svcerr */
#define IOCTL_HLINK_RTNLEVENT 7 /* RTNL event */
#define IOCTL_HLINK_NDP_FRAME 8 /* NDP frame */
#define IOCTL_HLINK_FOPS_REQ 9 /* Recv File I/O req */
#define IOCTL_HLINK_MIC_ERR 10 /* TKIP MIC failure detected */
#define IOCTL_HLINK_BOOTED 11 /* MuC boot complete */
#define IOCTL_HLINK_DROP_BA 12 /* drop BA */
#define IOCTL_HLINK_DISASSOC_STA 13 /* disassociate station with a given aid */
#define IOCTL_HLINK_RFIC_CAUSED_REBOOT 14 /* detected RFIC abnormal reset, reboot the system */
#define IOCTL_HLINK_BA_ADD_START 15 /* start Tx ADDBA REQ sequence */
#define IOCTL_HLINK_PEER_RTS 16 /* Peer RTS enable or disable */
#define IOCTL_HLINK_DYN_WMM 17 /* Dynamic WMM enable or disable */
#define IOCTL_HLINK_TDLS_EVENTS 18 /* TDLS Events from MuCfw */
#define IOCTL_HLINK_RATE_TRAIN 19 /* Per-node rate training hash */
enum {
BW_INVALID = 0,
BW_HT20 = 20,
BW_HT40 = 40,
BW_HT80 = 80,
BW_HT160 = 160
};
/* Fixed bw command offset */
#define QTN_BW_FIXED_BW 0x3
#define QTN_BW_FIXED_BW_S 0
#define QTN_BW_FIXED_EN 0x10
#define QTN_BW_FIXED_EN_S 4
enum {
QTN_DISABLE_PN_VALIDATION = 0,
QTN_ENABLE_PN_VALIDATION = 1
};
struct qtn_csa_info {
uint64_t req_tsf; /* aim to change channels at this tsf */
uint64_t switch_tsf; /* tsf just after channel change completed */
uint32_t pre_notification_tu; /* pre-switch notification to lhost in TU */
uint32_t post_notification_tu; /* post channel change notification */
uint32_t freq_band; /* freqency band info */
uint32_t channel; /* channel to switch to */
#define QTN_CSA_STATUS_MUC_SCHEDULED 0x00000001
#define QTN_CSA_STATUS_MUC_ERROR_SCHED 0x00000010
#define QTN_CSA_STATUS_MUC_PRE 0x00000002
#define QTN_CSA_STATUS_MUC_SWITCHED 0x00000004
#define QTN_CSA_STATUS_MUC_POST 0x00000008
#define QTN_CSA_STATUS_MUC_ERROR_SW 0x00000010
#define QTN_CSA_STATUS_MUC_CANCELLED 0x00000020
#define QTN_CSA_STATUS_MUC_COMPLETE 0x00000040
uint32_t muc_status; /* status written by MuC */
#define QTN_CSA_RESTART_QUEUE 0x00000001
#define QTN_CSA_STATUS_LHOST_PRE_DONE 0x00000002
#define QTN_CSA_STATUS_LHOST_SWITCH_DONE 0x00000004
#define QTN_CSA_STATUS_LHOST_POST_DONE 0x00000008
#define QTN_CSA_CANCEL 0x00000010
#define QTN_CSA_STATUS_LHOST_ACTIVE 0x00000020
#define QTN_CSA_STATUS_LHOST_UNITS_OFFSET 0x00000040
uint32_t lhost_status; /* flags written by lhost */
};
#define MEAS_RPI_HISTOGRAM_SIZE 8
enum meas_reason {
QTN_MEAS_REASON_SUCC = 0,
QTN_MEAS_REASON_OFF_CHANNEL_UNSUPPORT,
QTN_MEAS_REASON_DURATION_TOO_SHORT,
QTN_MEAS_REASON_TIMER_SCHED_FAIL,
QTN_MEAS_REASON_TYPE_UNSUPPORT,
QTN_MEAS_REASON_MAX,
};
enum meas_type {
QTN_MEAS_TYPE_BASIC = 0,
QTN_MEAS_TYPE_CCA,
QTN_MEAS_TYPE_RPI,
QTN_MEAS_TYPE_CHAN_LOAD,
QTN_MEAS_TYPE_NOISE_HIS,
QTN_MEAS_TYPE_MAX,
};
struct meas_time_slice {
uint32_t meas_slice; /* time slice */
uint32_t meas_time_pri; /* prime time count based on meas_slice */
uint32_t meas_time_sec; /* secondary time count based on meas_slice */
};
struct qtn_meas_chan_info {
uint32_t work_channel; /* working channel to return to */
int32_t meas_type; /* measurement type */
int32_t meas_reason; /* measurement reason */
struct meas_time_slice time_slice; /* time slice for measurement long duration */
uint32_t meas_channel;
uint64_t meas_start_tsf;
uint32_t meas_dur_ms;
union {
struct {
uint32_t cca_busy_cnt;
uint32_t cca_try_cnt;
uint32_t cca_try_ms;
uint32_t cca_busy_ms;
} cca_and_chanload;
uint8_t rpi_counts[MEAS_RPI_HISTOGRAM_SIZE];
int32_t basic_radar_num;
uint8_t basic;
} inter_data;
};
enum scs_lot_tsf_pos {
SCS_LOG_TSF_POS_LHOST_TASK_KICKOFF,
SCS_LOG_TSF_POS_LHOST_IOCTL2MUC,
SCS_LOG_TSF_POS_MUC_POLL_IOCTL_FROM_LHOST,
SCS_LOG_TSF_POS_MUC_QOSNULL_SENT,
SCS_LOG_TSF_POS_MUC_SMPL_START_BEFORE_CHAN_CHG,
SCS_LOG_TSF_POS_MUC_SMPL_START_AFTER_CHAN_CHG,
SCS_LOG_TSF_POS_MUC_SMPL_FINISH_BEFORE_CHAN_CHG,
SCS_LOG_TSF_POS_MUC_SMPL_FINISH_AFTER_CHAN_CHG,
SCS_LOG_TSF_POS_LHOST_CCA_INTR,
SCS_LOG_TSF_POS_LHOST_CCA_WORK,
SCS_LOG_TSF_POS_NUM
};
#define IEEE80211_SCS_LOG_TSF(_ic, _sample, _pos) ((_ic)->ic_get_tsf(&((_sample)->tsf[(_pos)])))
#define QDRV_SCS_LOG_TSF(_sample, _pos) (hal_get_tsf(&((_sample)->tsf[(_pos)])))
#define MUC_SCS_LOG_TSF(_qh, _sample, _pos) (hal_get_tsf((_qh), &((_sample)->tsf[(_pos)])))
struct qtn_samp_chan_info {
struct out_cca_info result; /* results structure for CCA measurement */
uint32_t freq_band;
uint32_t samp_channel; /* The channel on which sample will be taken */
uint32_t duration_msecs; /* Duration in milliseconds to stay on off channel */
uint64_t start_tsf; /* tsf at which to start sampling */
#define QTN_CCA_STATUS_IDLE 0x0
#define QTN_CCA_STATUS_HOST_IOCTL_SENT 0x1
#define QTN_CCA_STATUS_MUC_SCHEDULED 0x2
#define QTN_CCA_STATUS_MUC_STARTED 0x3
#define QTN_CCA_STATUS_MUC_COMPLETE 0x4
#define QTN_CCA_STATUS_MUC_CANCELLED 0x5
uint32_t status;
#define QTN_CCA_TYPE_BACKGROUND 0x1
#define QTN_CCA_TYPE_DIRECTLY 0x2
uint32_t type;
uint32_t qosnull_txdesc_host; /* qosnull frame for channel sampling */
uint32_t qosnull_txdesc_bus; /* qosnull frame in phyaddr */
uint16_t qosnull_frame_len; /* the frame length of qosnull */
uint16_t tx_node_idx; /* the node index that qosnull frame to */
uint32_t qosnull_txtsf; /* the tsf_lo read from MAC on that qosnull frame was sent successfully */
uint32_t qosnull_nav; /* the large NAV in qosnull frame */
uint64_t tsf[SCS_LOG_TSF_POS_NUM]; /* timestamps used for precise time control and profiling */
};
#define QTN_SCS_ASSOC_STA_MAX 12
struct qtn_scs_vsp_node_stats {
uint32_t ni_associd;
uint32_t tx_usecs;
uint32_t rx_usecs;
};
struct qtn_scs_vsp_info {
uint32_t num_of_assoc;
struct qtn_scs_vsp_node_stats scs_vsp_node_stats[QTN_SCS_ASSOC_STA_MAX];
};
struct qtn_scs_scan_info {
uint32_t bw_sel;
uint32_t cca_idle;
uint32_t cca_busy;
uint32_t cca_tx;
uint32_t cca_intf;
uint32_t cca_try;
uint32_t bcn_rcvd;
uint32_t crc_err;
uint32_t lpre_err;
uint32_t spre_err;
};
#define QTN_SCS_MAX_OC_INFO 32
struct qtn_scs_oc_info {
uint32_t off_channel;
uint32_t off_chan_bw_sel;
uint32_t off_chan_cca_busy;
uint32_t off_chan_cca_sample_cnt;
uint32_t off_chan_cca_try_cnt;
uint32_t off_chan_beacon_recvd;
uint32_t off_chan_crc_errs;
uint32_t off_chan_sp_errs;
uint32_t off_chan_lp_errs;
};
/* Smart channel selection data shared between Lhost and MuC */
struct qtn_scs_info {
uint32_t oc_info_count;
struct qtn_scs_oc_info oc_info[QTN_SCS_MAX_OC_INFO];
uint32_t bw_sel;
uint32_t cca_try;
uint32_t cca_busy;
uint32_t cca_idle;
uint32_t cca_tx;
uint32_t cca_interference;
uint32_t beacon_recvd;
uint32_t tx_usecs;
uint32_t rx_usecs;
struct qtn_scs_vsp_info scs_vsp_info;
};
struct qtn_scs_info_set {
uint32_t valid_index; /* 0 or 1 */
struct qtn_scs_info scs_info[2];
struct qtn_scs_scan_info scan_info[IEEE80211_CHAN_MAX];
};
struct qtn_remain_chan_info {
uint32_t chipid;
uint32_t data_channel; /* Data channel to return to */
uint32_t off_channel; /* The required remain channel */
uint32_t duration_usecs; /* Duration in microseconds to stay on remain channel */
uint64_t start_tsf; /* tsf at which to switch to remain channel */
#define QTN_REM_CHAN_STATUS_IDLE 0x0
#define QTN_REM_CHAN_STATUS_HOST_IOCTL_SENT 0x1
#define QTN_REM_CHAN_STATUS_MUC_SCHEDULED 0x2
#define QTN_REM_CHAN_STATUS_MUC_STARTED 0x3
#define QTN_REM_CHAN_STATUS_MUC_COMPLETE 0x4
#define QTN_REM_CHAN_STATUS_MUC_CANCELLED 0x5
uint32_t status; /* channel switch status */
uint8_t peer_mac[IEEE80211_ADDR_LEN]; /* peer node mac address */
};
#define QTN_CCA_CNT2MS(_cnt) RUBY_TIMER_MUC_CCA_CNT2MS(_cnt)
#define QTN_CCA_INTV RUBY_TIMER_MUC_CCA_INTV
enum scan_chan_tsf_pos {
SCAN_CHAN_TSF_LHOST_HOSTLINK_IOCTL = 0,
SCAN_CHAN_TSF_MUC_IOCTL_PROCESS,
SCAN_CHAN_TSF_MUC_SEND_START_FRM,
SCAN_CHAN_TSF_MUC_SEND_START_FRM_DONE,
SCAN_CHAN_TSF_MUC_GOTO_OFF_CHAN,
SCAN_CHAN_TSF_MUC_GOTO_OFF_CHAN_DONE,
SCAN_CHAN_TSF_MUC_SEND_PRBREQ_FRM,
SCAN_CHAN_TSF_MUC_SEND_PRBREQ_FRM_DONE,
SCAN_CHAN_TSF_MUC_GOTO_DATA_CHAN,
SCAN_CHAN_TSF_MUC_GOTO_DATA_CHAN_DONE,
SCAN_CHAN_TSF_MUC_SEND_FINISH_FRM,
SCAN_CHAN_TSF_MUC_SEND_FINISH_FRM_DONE,
SCAN_CHAN_TSF_LHOST_INTERRUPT,
SCAN_CHAN_TSF_LHOST_SCANWORK,
SCAN_CHAN_TSF_LOG_NUM
};
struct scan_chan_tsf_dbg {
int pos_index;
char *log_name;
};
#define QDRV_SCAN_LOG_TSF(_scan, _pos) (hal_get_tsf(&((_scan)->tsf[(_pos)])))
#define MUC_SCAN_LOG_TSF(_qh, _scan, _pos) (hal_get_tsf((_qh), &((_scan)->tsf[(_pos)])))
struct qtn_scan_chan_info {
uint32_t freq_band;
uint32_t scan_channel; /* The channel on which sample will be taken */
#define TIME_MARGIN_BEFORE_STARTFRM 3000 /* microseconds, time overhead for others before start frame is sent*/
#define TIME_MARGIN_AFTER_STARTFRM 1000 /* microseconds, time overhead for others after start frame is sent*/
#define TIME_OFFSET_SEND_PROBE_REQ 3000 /* microseconds, the time offset for sending probe_req frame
* after switching to off channel*/
#define TIME_OFFSET_SEND_START_FRM 5000 /* microseconds, the time offset for sending start frame
* after set NETDEV_F_PAUSE_TX flag */
#define TIME_DUR_FOR_ALL_BEACONS 25000 /* microseconds, the time duration for transmitting all beacons */
#define TIME_MIN_WAIT_PROBE_REP 5000 /* microseconds, the minimal time for waiting for the probe
* response frame on scanning channel */
uint32_t dwell_msecs; /* Duration in milliseconds to stay on scanning channel */
#define QTN_SCAN_CHAN_MUC_IDLE 0x0
#define QTN_SCAN_CHAN_MUC_STARTED 0x1
#define QTN_SCAN_CHAN_MUC_PROBING 0x2
#define QTN_SCAN_CHAN_MUC_COMPLETED 0x3
#define QTN_SCAN_CHAN_MUC_FAILED 0x4
#define QTN_SCAN_CHAN_MUC_SCHEDULED 0x5
uint32_t muc_status; /* written only by MuC */
#define QTN_SCAN_CHAN_FLAG_ACTIVE 0x00000001
#define QTN_SCNA_CHAN_FLAG_PASSIVE_FAST 0x00000002
#define QTN_SCNA_CHAN_FLAG_PASSIVE_NORMAL 0x00000004
#define QTN_SCNA_CHAN_FLAG_PASSIVE_SLOW 0x00000008
#define QTN_SCAN_CHAN_TURNOFF_RF 0x00000010
uint32_t scan_flags;
uint32_t start_txdesc_host; /* The frame sent before go scan channel,
* e.g. pwrsav frame in STA mode */
uint32_t start_txdesc_bus; /* Start frame in phyaddr */
uint16_t start_node_idx; /* the node index that frame to */
uint16_t start_frame_len; /* frame length */
uint32_t prbreq_txdesc_host; /* probe request frame for active scanning */
uint32_t prbreq_txdesc_bus; /* probe request frame in phyaddr */
uint16_t prbreq_node_idx; /* the node index that frame to */
uint16_t prbreq_frame_len; /* frame length */
uint32_t finish_txdesc_host; /* The frame sent after back data channel,
* e.g. the frame to announce waking up in STA mode */
uint32_t finish_txdesc_bus; /* Complete frame in phyaddr */
uint16_t finish_node_idx; /* the node index that frame to */
uint16_t finish_frame_len; /* frame length */
uint64_t tsf[SCAN_CHAN_TSF_LOG_NUM];
};
enum qtn_ocac_tsf_log {
OCAC_TSF_LOG_GOTO_OFF_CHAN = 0,
OCAC_TSF_LOG_GOTO_OFF_CHAN_DONE,
OCAC_TSF_LOG_GOTO_DATA_CHAN,
OCAC_TSF_LOG_GOTO_DATA_CHAN_DONE,
OCAC_TSF_LOG_NUM
};
struct qtn_ocac_info {
uint32_t freq_band; /* frequency band, written by lhost */
uint32_t off_channel; /* The off channel, "0" means to stop ocac in MuC, written by lhost*/
uint32_t qosnull_txdesc_host; /* qosnull frame in virtual address, written by lhost */
uint32_t qosnull_txdesc_bus; /* qosnull frame in physical address, written by lhost */
uint16_t qosnull_frame_len; /* the frame length of qosnull */
uint16_t tx_node_idx; /* the node index that qosnull frame to */
uint16_t dwell_time; /* the required time on off channel in one beacon interval, written by lhost */
uint16_t secure_dwell; /* milliseconds, the time on off channel within on off-channel action, using
qosnull frame with large NAV to protect the traffic */
uint16_t threshold_fat; /* the fat threshold to run off-channel CAC, written by lhost */
uint16_t threshold_traffic; /* the traffic threshold to run off-channel CAC, written by lhost */
uint16_t threshold_fat_dec; /* the threshold for consecutive fat decrease, written by lhost */
uint16_t traffic_ctrl; /* whether to send qosnull or not, written by lhost */
uint16_t offset_txhalt; /* milliseconds, the offset after beacon to halt tx, written by lhost */
uint16_t offset_offchan; /* milliseconds, the offset after halt tx to switch off channel, written by lhost */
#define QTN_OCAC_ON_DATA_CHAN 0x1
#define QTN_OCAC_ON_OFF_CHAN 0x2
uint16_t chan_status; /* current on which channel, written by MuC */
uint16_t actual_dwell_time; /* the actual time on off channel, written by MuC */
uint64_t tsf_log[OCAC_TSF_LOG_NUM]; /* event tsf log, written by MuC */
};
struct qtn_rf_rxgain_params
{
uint8_t *gain_entry_tbl;
uint8_t lna_on_indx;
uint8_t max_gain_idx;
uint16_t cs_threshold_value;
};
/* MuC fops requst */
#define MUC_FOPS_MAX_FNAME_SIZE (50)
enum {
MUC_FOPS_OPEN = 0,
MUC_FOPS_READ,
MUC_FOPS_WRITE,
MUC_FOPS_LSEEK,
MUC_FOPS_CLOSE,
};
enum {
MUC_FOPS_PENDING = 0x011ADDED,
MUC_FOPS_DONE = 0xF035D0DE,
};
enum {
MUC_FOPS_RDONLY = 0x0,
MUC_FOPS_WRONLY = 0x1,
MUC_FOPS_RDWR = 0x2,
MUC_FOPS_APPEND = 0x4,
};
struct muc_fops_req {
volatile int32_t ret_val;
volatile int32_t fd;
volatile uint32_t req_state;
volatile char *data_buff;
};
enum qdrv_cmd_muc_memdbgcnf_s {
QDRV_CMD_MUC_MEMDBG_STATUS,
QDRV_CMD_MUC_MEMDBG_FD_MAX,
QDRV_CMD_MUC_MEMDBG_NODE_MAX,
QDRV_CMD_MUC_MEMDBG_DUMP_MAX,
QDRV_CMD_MUC_MEMDBG_RATETBL,
QDRV_CMD_MUC_MEMDBG_MSG_SEND,
QDRV_CMD_MUC_MEMDBG_TRACE,
QDRV_CMD_MUC_MEMDBG_LAST
};
/* The following file indexes and file lists must all be kept in sync */
#define FOPS_FD_EP_SAMPLES 9
#define FOPS_FD_DCACHE_SAMPLES 10
#ifdef PROFILE_MUC_SAMPLE_IPTR_AUC
#define FOPS_FD_IPTR_SAMPLES 15
#else
#define FOPS_FD_IPTR_SAMPLES 11
#endif
#define FOPS_FD_UBOOT_ENV 12
#define LHOST_CAL_FILES { \
NULL, \
"/proc/bootcfg/bf_factor", \
"/tmp/txpower.txt", \
"/proc/bootcfg/txpower.cal", \
"/proc/bootcfg/dc_iq.cal", \
"/mnt/jffs2/mon.out", \
"/mnt/jffs2/gmon.out", \
"/mnt/jffs2/pecount.out", \
"/proc/bootcfg/pdetector.cal", \
"/mnt/jffs2/profile_ep_muc", \
"/mnt/jffs2/profile_dcache_muc",\
"/mnt/jffs2/profile_iptr_muc", \
"/proc/bootcfg/env", \
"/etc/mtest", \
"/proc/bootcfg/rx_iq.cal", \
"/mnt/jffs2/profile_iptr_auc", \
}
#define MUC_CAL_FILES { \
NULL, \
NULL, \
NULL, \
NULL, \
NULL, \
"mon.out", \
"gmon.out", \
NULL, \
NULL, \
NULL, \
NULL, \
NULL, \
NULL, \
}
enum tdls_ioctl_params {
IOCTL_TDLS_STATUS = 1,
IOCTL_TDLS_UAPSD_IND_WND,
IOCTL_TDLS_PTI_CTRL,
IOCTL_TDLS_PTI,
IOCTL_TDLS_PTI_PENDING,
IOCTL_TDLS_DBG_LEVEL,
IOCTL_TDLS_PTI_DELAY,
IOCTL_TDLS_PTI_EVENT = 100
};
struct qtn_tdls_args {
uint8_t ni_macaddr[IEEE80211_ADDR_LEN];
uint16_t ni_ncidx;
uint32_t tdls_cmd;
uint32_t tdls_params;
};
struct qtn_node_args
{
/* header */
uint8_t ni_macaddr[IEEE80211_ADDR_LEN];
uint8_t ni_bssid[IEEE80211_ADDR_LEN];
uint8_t ni_nrates;
uint8_t ni_rates[IEEE80211_RATE_MAXSIZE];
uint8_t ni_htnrates;
uint8_t ni_htrates[IEEE80211_HT_RATE_MAXSIZE];
uint16_t ni_associd; /* assoc response */
uint16_t ni_node_idx;
uint16_t ni_flags; /* special-purpose state */
struct wmm_params wmm_params[WME_NUM_AC];
uint8_t ni_implicit_ba_rx; /* The RX side of the implicit BA. Zero for no implicit RX BA */
uint8_t ni_implicit_ba_tx; /* The TX side of the implicit BA. Zero for no implicit TX BA */
uint16_t ni_implicit_ba_size; /* Size of the implicit BAs */
uint8_t ni_qtn_ie_flags;
uint8_t ni_vendor;
uint8_t ni_bbf_disallowed; /* flag to disallow BBF */
uint8_t ni_std_bf_disallowed; /* flag to disallow standard BF */
uint8_t ni_uapsd; /* U-APSD per-node flags matching WMM STA Qos Info field */
uint8_t ni_htcap[sizeof(struct ieee80211_htcap)]; /* Processed HT capabilities */
uint8_t ni_htinfo[sizeof(struct ieee80211_htinfo)]; /* Processed HT info */
uint8_t ni_vhtcap[sizeof(struct ieee80211_vhtcap)]; /* Processed VHT capabilities */
uint8_t ni_vhtop[sizeof(struct ieee80211_vhtop)]; /* Processed VHT operational info */
struct qtn_node_shared_stats *ni_shared_stats;
uint32_t ni_ver_sw;
uint32_t ni_qtn_flags;
uint32_t ni_tdls_status;
uint8_t ni_mu_grp[sizeof(struct ieee80211_vht_mu_grp)];
uint16_t ni_rsn_caps; /* optional rsn capabilities */
uint8_t rsn_ucastcipher; /* selected unicast cipher */
uint16_t tdls_peer_associd; /* tdls peer AID allocated by AP, unique in BSS */
uint32_t ni_rate_train;
uint32_t ni_rate_train_peer;
};
struct qtn_beacon_args
{
uint32_t pkt_data;
struct wmm_params wmm_params[WME_NUM_AC];
uint32_t bintval;
uint32_t bo_tim;
uint32_t bo_tim_len;
uint32_t bo_tpc_rep;
uint32_t bo_chanswitch;
uint32_t bo_htcap;
uint32_t bo_htinfo;
uint32_t bo_vhtcap;
uint32_t bo_vhtop;
};
struct qtn_key {
u_int8_t wk_keylen; /* key length in bytes */
u_int8_t wk_flags;
#define IEEE80211_KEY_XMIT 0x01 /* key used for xmit */
#define IEEE80211_KEY_RECV 0x02 /* key used for recv */
#define IEEE80211_KEY_GROUP 0x04 /* key used for WPA group operation */
#define IEEE80211_KEY_SWCRYPT 0x10 /* host-based encrypt/decrypt */
#define IEEE80211_KEY_SWMIC 0x20 /* host-based enmic/demic */
u_int16_t wk_keyix; /* key index */
u_int8_t wk_key[IEEE80211_KEYBUF_SIZE + IEEE80211_MICBUF_SIZE];
#define wk_txmic wk_key + IEEE80211_KEYBUF_SIZE + 0 /* XXX can't () right */
#define wk_rxmic wk_key + IEEE80211_KEYBUF_SIZE + 8 /* XXX can't () right */
u_int64_t wk_keyrsc[IEEE80211_RSC_MAX]; /* key receive sequence counter */
u_int64_t wk_keytsc; /* key transmit sequence counter */
u_int32_t wk_cipher; /* cipher */
u_int32_t wk_ncidx; /* node cache index */
};
#define IEEE80211_KEY_COMMON /* common flags passed in by apps */\
(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP)
struct qtn_key_args
{
struct qtn_key key;
uint8_t wk_addr[IEEE80211_ADDR_LEN];
};
struct qtn_power_save_args
{
uint32_t enable;
uint8_t ni_addr[IEEE80211_ADDR_LEN];
};
struct lhost_txdesc
{
struct host_txdesc hw_desc; /* shared between muc and lhost */
struct sk_buff *skb;
struct lhost_txdesc *next;
};
#define MUC_TXSTATUS_READY 0x0
#define MUC_TXSTATUS_DONE 0x1
#define MUC_RXSTATUS_DONE 0x1
#define MUC_RXSTATUS_RXLEN 0xFFFF0000
#define MUC_RXSTATUS_RXLEN_S 16
struct qtn_link_margin_info {
uint32_t mcs;
uint32_t bw;
int rssi_avg;
int reason;
#define QTN_LINK_MARGIN_REASON_SUCC 0
#define QTN_LINK_MARGIN_REASON_NOSUCHNODE 1
uint8_t mac_addr[IEEE80211_ADDR_LEN];
};
#define QTN_RESERVED_DEVIDS 2
#define QTN_WLANID_FROM_DEVID(devid) \
((devid < QTN_RESERVED_DEVIDS)? 0 : (devid - QTN_RESERVED_DEVIDS))
struct qtn_mu_grp_args {
/* MU group ID. 0 means the group is not used and grp_ni is empty*/
uint8_t grp_id;
/* mu QMat installation status */
/* QMat is not installed and not used */
#define MU_QMAT_DISABLED 0
/* QMat is installed and used */
#define MU_QMAT_ENABLED 1
/* QMat is installed, used but not updated */
#define MU_QMAT_FREEZED 2
/* QMat is installed, not used and not updated */
#define MU_QMAT_NOT_USED 3
uint8_t qmat_installed;
/* the index of the grp_ni[], is also the user position */
uint16_t aid[IEEE80211_MU_GRP_NODES_MAX];
uint8_t ncidx[IEEE80211_MU_GRP_NODES_MAX];
/* matrix addr offsets in sram */
unsigned int u0_1ss_u1_1ss;
unsigned int u0_2ss_u1_1ss;
unsigned int u0_3ss_u1_1ss;
unsigned int u0_1ss_u1_2ss;
unsigned int u0_1ss_u1_3ss;
unsigned int u0_2ss_u1_2ss;
/* stats */
uint32_t upd_cnt;
int32_t rank;
};
struct qtn_fwt_sw_params {
uint32_t muc_hz;
uint32_t muc_jiffies_base;
uint64_t *muc_fwt_ts_mirror;
uint64_t *muc_fwt_ts_mirror_bus;
uint64_t m2h_op;
};
#endif // _LHOST_MUC_COMM_H

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2014 Quantenna Communications, Inc.
*/
#ifndef _MUC_SHARE_DEF_H_
#define _MUUC_SHARE_DEF_H_
#include "../common/ruby_mem.h"
#define QTN_FW_WMAC_RX_Q_MGMT 0
#define QTN_FW_WMAC_RX_Q_CTRL 1
#define QTN_FW_WMAC_RX_Q_DATA 2
#define QTN_FW_WMAC_RX_QNUM 3
#define QTN_FW_WMAC_RX_QDEEP_MGMT 9
#define QTN_FW_WMAC_RX_QDEEP_CTRL 9
#define QTN_FW_WMAC_RX_QDEEP_DATA 394
#define QTN_FW_WMAC_RX_DESC_NUM (QTN_FW_WMAC_RX_QDEEP_MGMT + \
QTN_FW_WMAC_RX_QDEEP_CTRL + QTN_FW_WMAC_RX_QDEEP_DATA)
#endif // #ifndef _MUC_SHARE_DEF_H_

View File

@ -0,0 +1,928 @@
/*
* Copyright (c) 2008-2012 Quantenna Communications, Inc.
*/
/*
* This file contains host definitions which are common between the
* host driver and the microcontroller/MAC code.
*/
/**
* The host tx descriptor for an ethernet packet
*/
#ifndef _MUC_TXRX_STATS_H_
#define _MUC_TXRX_STATS_H_
#include <qtn/muc_share_def.h>
#ifdef ENABLE_STATS
#define MUC_UPDATE_STATS(_a, _b) (_a += _b)
#define MUC_SETSTAT(_a, _b) (_a = _b)
#else
#define MUC_UPDATE_STATS(_a, _b)
#define MUC_SETSTAT(_a, _b)
#endif
/**
* \defgroup MUCSTATS MuC generated statistics
*/
/** @{ */
/**
* \brief MuC transmit statistics
*
* These statistics are generated on the MuC, mainly on the transmit datapath.
*/
struct muc_tx_stats {
/**
* The number of times the software failed to enqueue a beacon to the
* hardware.
*
* \note If this value is non-zero it could indicate a very congested
* medium.
*/
u_int32_t bcn_enq_failed;
/**
* The number of times the TX status bit is set.
*/
u_int32_t tx_status_set;
/**
* The number of packets received from the LHost.
*/
u_int32_t pkt_from_host;
/**
* The number of interrupts from the host to indicate data is ready for
* transmit.
*
* \note This number will generally be quite low, as the LHost->MuC
* data path is poll driven rather than interrupt driven.
*/
u_int32_t host_intr;
u_int32_t netbuf_alloc_failed;
/**
* The number of management packets prior to encapsulation.
*
* \note This number should be the same as mgm_after_encap when the system
* is idle.
*/
u_int32_t mgm_before_encap;
/**
* The number of management packets after encapsulation.
*
* \note This number should be the same as mgm_before_encap when the system
* is idle.
*/
u_int32_t mgm_after_encap;
u_int32_t pkt_before_encap;
u_int32_t pkt_after_encap;
/**
* The number of packets held, waiting for BA to complete.
*/
u_int32_t pkt_push_back;
u_int32_t tx_timeout;
/**
* This counter shows the number of MPDUs or AMPDUs which needed to be retried
* by the hardware.
*
* For an MPDU, it indicates that no ACK was received from the peer.
*
* For an AMPDU, it indicates that no BACK was received from the peer.
* In this case, all subframes within the aggregate failed, and the hardware
* has requeued the entire aggregate for retransmission.
*
* If all hardware retries fail, the packet is returned back to the MAC for
* software retries.
*
* \sa tx_sw_retry.
*/
u_int32_t tx_hw_retry;
/**
* This counter shows the number of non-aggregate MPDUs that have been resent
* by software for retransmission after an initial transmission failure.
*
* Transmission failure is when no ACK has been received from the peer after the
* configured number of hardware retries.
*/
u_int32_t tx_sw_retry_noagg;
/**
* This counter shows the number of AMPDUs that have been repackaged
* by software for retransmission after an initial transmission failure.
*
* Transmission failure is when an AMPDU fails to receive a full block
* ACK (some subframes are incorrectly received). The repackaged AMPDU
* contains a subset of the subframes from the original AMPDU.
*/
u_int32_t tx_sw_retry;
u_int32_t tx_xretry;
u_int32_t tx_pspoll_deagg;
/**
* This counter shows the number of packets (AMPDU subframes) for which all retry
* attempts have failed.
*
* \note This counter represents genuine packet loss.
*/
u_int32_t tx_xattempts;
/**
* This counter shows the number of non-aggregate MPDUs for which all retry
* attempts have failed.
*
* \note This counter represents genuine packet loss.
*/
u_int32_t tx_xattempts_noagg;
u_int32_t tx_done_failed;
u_int32_t tx_cca_defer_cnt;
u_int32_t pkt_to_hw;
u_int32_t pkt_to_hw_deferred;
u_int32_t fd_absent;
u_int32_t fd_not_ready;
u_int32_t pkt_fd_available;
u_int32_t pkt_add_node;
u_int32_t pkt_add_q;
u_int32_t pkt_qtn_hardstart;
u_int32_t tx_reserved;
u_int32_t tx_released;
u_int32_t tx_reserve_fail;
u_int32_t tx_release_err;
u_int32_t tx_mu_reserved;
u_int32_t tx_mu_released;
u_int32_t tx_mu_reserve_fail;
u_int32_t tx_mu_release_err;
u_int32_t txalert_mu_ndp_update;
u_int32_t txalert_mu_rpt_poll;
u_int32_t txalert_mu_queue_full;
u_int32_t txalert_mu_queue_fail;
u_int32_t sample_rate_mu;
u_int32_t sample_bw_mu;
u_int32_t txdone_intr;
u_int32_t txalert_intr;
u_int32_t txalert_tasklet;
u_int32_t txalert_bcn_update;
u_int32_t txalert_ndp_update;
u_int32_t tx_ndp_q_occupied;
u_int32_t tx_ndp_start;
u_int32_t txdone_mgmt;
u_int32_t txdone_data;
u_int32_t tx_pwr;
u_int32_t bcn_scheme_power_save;
u_int32_t bcn_scheme;
/**
* This counter shows the number of multicast frames sent while a
* client is in powersave. Multicast frames with powersave are sent
* after the DTIM beacon.
*/
u_int32_t tx_mcast_pwr;
/**
* This counter shows the number of multicast frames queued for
* deferred (DTIM beacon) transmission.
*
* Multicast packets are deferred until the DTIM beacon when we have
* at least one power save client associated.
*/
u_int32_t tx_mcast_defer;
u_int32_t tx_mcast_defer_hwq;
u_int32_t tx_limit_drop;
u_int32_t fd_acquire;
u_int32_t fd_release;
u_int32_t fd_acq_fail;
u_int32_t fd_acq_fail_frms;
u_int32_t fd_acq_hal_fail;
u_int32_t fd_acq_hal_fail_frms;
u_int32_t ba_send;
u_int32_t ba_del;
u_int32_t fd_free_nodeclean;
u_int32_t msdu_expired;
u_int32_t last_ack_ssq;
u_int32_t last_sent_seq;
u_int32_t ampdu_subframe_failure;
u_int32_t ampdu_subframe_done;
u_int32_t tx_window_locked;
u_int32_t tx_window_failed;
u_int32_t tx_restrict_probe;
u_int32_t tx_restrict_mode;
u_int32_t tx_restrict_drop;
u_int32_t tx_restrict_delay;
u_int32_t tx_restrict_send;
u_int32_t tx_sample_pkts;
u_int32_t tx_sample_bytes;
u_int32_t tx_underflow;
u_int32_t tx_hal_enqueued;
u_int32_t txbf_mode;
u_int32_t psel_matrix;
u_int32_t sample_rate;
u_int32_t sample_bw;
uint32_t ra_flags;
u_int32_t fd_balance;
uint32_t invalid_delay;
uint32_t halt_tx;
uint32_t resume_tx;
uint32_t rfctrl_on;
uint32_t rfctrl_off;
uint32_t go_offchan;
uint32_t go_datachan;
uint32_t defer_cc;
uint32_t deferred_cc_done;
uint32_t off_chan_sample;
uint32_t off_chan_scan;
uint32_t off_chan_cac;
uint32_t cca_pri;
uint32_t cca_sec;
uint32_t cca_sec40;
uint32_t cca_busy;
uint32_t cca_fat;
uint32_t cca_intf;
uint32_t cca_trfc;
/**
* These counter show the information of MU frames.
*/
uint32_t mu_prec_snd_tx;
uint32_t mu_prec_snd_wait_done;
uint32_t mu_grp_sel_snd_tx;
uint32_t mu_grp_sel_snd_wait_done;
uint32_t oc_auctx_timeout;
uint32_t oc_auctx_overwrite;
uint32_t oc_auctx_fail;
uint32_t gi_cnt; /* times GI has been set for any node */
uint32_t gi_ncidx; /* last node to have GI set */
uint32_t gi_val; /* SGI enabled state for this node */
uint32_t select_state_ncidx; /* last node to have qn_select state set */
uint32_t select_state_val; /* PPPC state for this node */
uint32_t pppc_scale_cnt; /* times Tx gain scaling has been set for any node */
uint32_t pppc_scale_ncidx; /* last node to have Tx gain scaling set */
uint32_t pppc_scale_val; /* Tx gain scaling for this node (0 is max) */
uint32_t pppc_scale_last_gput; /* The last goodput used by PPPC */
uint32_t pppc_scale_last_gput_idx; /* The PPPC index of the last goodput value */
uint32_t pppc_scale_base_cnt; /* times Tx gain scaling base has been set for any node */
uint32_t pppc_scale_base_20m; /* Combined tx scale bases for different bf/nss cases in 20MHz */
uint32_t pppc_scale_base_40m; /* Combined tx scale bases for different bf/nss cases in 40MHz */
uint32_t pppc_scale_base_80m; /* Combined tx scale bases for different bf/nss cases in 80MHz */
uint32_t pppc_scale_base_copy; /* combined the flags indicating the tx scale bases are copied bfoff 1ss cases */
uint32_t pppc_scale_overstep; /* tx scale exceed the maximum scale indices */
uint32_t pppc_scale_rollback; /* tx scale roll back because scale index over step */
uint32_t pppc_0_gput; /* times pppc comparing goodput and both are zero */
uint32_t tx_max_power;
uint32_t nc_csr_read_count; /* number of times Node Cache was read */
uint32_t nc_csr_write_count; /* number of times Node Cache was written to */
uint32_t nc_csr_done_watermark; /* Node cache done retries high watermark */
uint32_t nc_csr_watermark_count; /* Number of times read retries reached max */
uint32_t auc_dtim_notify;
uint32_t auc_ps_notify;
uint32_t tx_beacon_done;
uint32_t sfs_peer_rts;
uint32_t sfs_peer_rts_flags;
uint32_t sfs_local_rts;
uint32_t sfs_local_rts_flags;
uint32_t sfs_dyn_wmm;
uint32_t sfs_dyn_wmm_flags;
uint32_t auc_wmm_ps_notify;
uint32_t tx_wmm_ps_null_frames;
};
/**
* \brief MuC receive statistics
*
* These statistics are generated on the MuC, mainly on the receive datapath. This set of statistics
* also include low-level debugging facilities used internally.
*/
struct muc_rx_stats {
/**
* This counter shows the number of descriptors taken from the host,
* 'popped' from the top of the list.
*/
u_int32_t rxdesc_pop_from_host;
/**
* This counter shows the number of descriptors pushed to the hardware
* for receive buffers.
*/
u_int32_t rxdesc_push_to_hw;
u_int32_t rxdesc_get_from_queue;
u_int32_t rxdesc_push_to_host;
u_int32_t rxdesc_non_aggr_push_to_host;
u_int32_t rxdesc_flush_to_host;
u_int32_t rxdesc_reuse_push;
u_int32_t rxdesc_reuse_pop;
/**
* This counter shows the number of packets received with a bad duration.
* A bad duration is where the duration field is all 1's - that is,
* a packet which violates the 802.11 standard.
*/
u_int32_t rxdesc_status_bad_dur;
u_int32_t rxdesc_status_bad_len;
u_int32_t rxdesc_slow_status;
u_int32_t rxdesc_fast_status;
u_int32_t rxdesc_status_crc_err;
u_int32_t rxdesc_status_cmic_err;
u_int32_t rxdesc_status_cmic_no_crc_err;
u_int32_t rxdesc_status_retry;
u_int32_t agg_stored;
u_int32_t agg_duplicate;
u_int32_t accel_mpdu;
u_int32_t accel_msdu;
u_int32_t accel_no_buffer;
u_int32_t accel_fwt_lu_timeout;
u_int32_t accel_fwt_false_miss;
u_int32_t accel_mcast_send;
u_int32_t accel_mcast_drop;
u_int32_t accel_no_match;
u_int32_t accel_drop;
u_int32_t accel_err;
u_int32_t rate_train_chk;
u_int32_t rate_train_err;
u_int32_t rate_train_delay;
u_int32_t rate_train_none;
u_int32_t rate_train_hash_bad;
u_int32_t rate_train_hash_good;
/**
* This counter shows the number of MPDUs within an AMPDU that have been
* discarded due to the sequence number being outside ('below') the current
* receive sequence window.
*/
u_int32_t agg_oldpkts;
/**
* This counter shows the number of MPDUs within an AMPDU that have been
* discarded due to the sequence number being off by > 2047 (half the sequence
* space).
*/
u_int32_t agg_very_oldpkts;
u_int32_t agg_evict_in_order;
u_int32_t agg_evict_in_move;
/**
* This counter shows the number of received subframes within the
* receive window that are missing when the window is moved.
*
* This counter represents one source receive packet loss.
*/
u_int32_t agg_evict_empty;
/**
* This counter shows the number of received subframes within the
* receive window that are evicted due to timeout. Timeout is used
* to ensure we don't sit with a stuck receive aggregate window when
* the transmitter has stopped re-transmitting a given subframe.
*/
u_int32_t agg_timeout;
u_int32_t agg_rxwin_reset;
u_int32_t rx_qnum_err;
u_int32_t rx_mgmt;
u_int32_t rx_ctrl;
u_int32_t rx_pspoll;
u_int32_t rx_pwr_mgmt;
u_int32_t rx_delba;
/**
* This counter shows the number of times the powersave bit is set
* in the frame control field of packets received.
*
* \note This counter will generally be one greater than rx_pwr_mgmt_reset
* when we have a single PS client associated and in power save.
*
* \sa rx_pwr_mgmt_reset
*/
u_int32_t rx_pwr_mgmt_set;
/**
* This counter shows the number of times the powersave bit of a
* currently power save client is reset.
*
* \note This counter will generally be one less than rx_pwr_mgmt_set
* when we have a single PS client associated and in power save mode.
*
* \sa rx_pwr_mgmt_set
*/
u_int32_t rx_pwr_mgmt_reset;
/**
* \internal
*
* We have 2-stage process of pushing rx descriptors to the MAC:
*
* 1) On tasklet level we prepare descriptors and save these prepared
* descriptors into intermediate buffer "rxdesc_cache"
*
* 2) In RX ISR context we get buffer from "rxdesc_cache" and push it
* to hardware. Same procedure can be sometimes called within tasklet
* level too. It is because if we failed (e.g. no free descriptors) to
* push descriptor to hw in ISR context, likely we would not receive any
* RX interrupts anymore, so tasklet scheduled which would reschedule
* itself until succeed.
*
* rx_emergency counter incremented if (2) replenishing procedure found
* that hw rx queue have slot for descriptors and fail to retrieve
* descriptor from "rxdesc_cache" to replenish hw queue.
*
* Spike of rx_emergency does not look good.
*
* It's like tasklet was scheduled to replenish hw queue and fail it,
* reschedule itself and fail again and again.
*
* Generally, rx_emergency increasing is legitimate case, for example
* if the system is overloaded by incoming traffic. However, it also can
* be a sign of something bad, like processing of rx frames is stuck somewhere.
*/
u_int32_t rx_emergency;
u_int32_t rx_underflow;
u_int32_t rx_desc_underflow;
u_int32_t rx_desc_linkerr;
u_int32_t rx_notify;
u_int32_t rx_df_numelems;
u_int32_t last_recv_seq;
/**
* This counter shows the number of packets received for an unknown
* node - that is - one which we do not have an association with.
*/
u_int32_t rx_node_not_found;
/**
* This counter shows the number of duplicates of non-QoS packets we
* received and discarded.
*/
u_int32_t rx_non_qos_duplicate;
/**
* This counter shows the number of received NDPs.
*/
u_int32_t rx_11n_ndp;
u_int32_t rx_11ac_ndp;
u_int32_t rx_ndp_inv_slot;
u_int32_t rx_11n_ndp_no_capt;
u_int32_t rx_ndp_sw_processed;
u_int32_t rx_ndp_lockup;
u_int32_t rx_11n_bf_act;
u_int32_t rx_11ac_bf_act;
u_int32_t rx_bf_act_inv_slot;
/**
* This counter shows the number of received AMSDUs. This counter does
* not count the number of subframes within the AMSDU.
*/
u_int32_t rx_amsdu;
u_int32_t rx_data;
u_int32_t prev_rx_data;
u_int32_t rx_recv_qnull;
u_int32_t rx_recv_act;
u_int32_t rx_recv_bcn;
u_int32_t rx_recv_auth;
u_int32_t rx_recv_assoc_req;
u_int32_t rx_recv_assoc_res;
u_int32_t rx_recv_deauth;
u_int32_t rx_recv_disassoc;
/**
* This counter shows the number of packets received where the MCS as
* indicated in the PLCP is invalid (> 76).
*/
u_int32_t rx_mcs_gt_76;
u_int32_t tkip_keys; /* Keep count of TKIP keys installed - for debug */
u_int32_t rx_tkip_mic_err; /* Number of TKIP packets RX with MIC error - the number reported to the higher layers */
u_int32_t icv_errs; /* The number of raw ICV errors reported by the hardware */
u_int32_t tmic_errs; /* The number of raw TMIC errors reported by the hardware */
u_int32_t cmic_errs;
u_int32_t crc_errs;
/**
* This counter shows the number of transmit block ACK agreements
* installed.
*
* If the upper bit is set, at least one implicit block ACK has been
* established with a Quantenna peer.
*
* \note This number only increments - when block ACK agreements are
* removed, this counter does not decrement.
*/
u_int32_t ba_tx;
/**
* This counter shows the number of receive block ACK agreements
* installed.
*
* If the upper bit is set, at least one implicit block ACK has been
* established with a Quantenna peer.
*
* \note This number only increments - when block ACK agreements are
* removed, this counter does not decrement.
*/
u_int32_t ba_rx;
/**
* The number of times a block ACK has been rejected due to an out of
* resource situation.
*/
u_int32_t ba_rx_fail;
u_int32_t sec_oflow;
u_int32_t str_oflow;
u_int32_t oflow_fixup_timeout;
u_int32_t rxdone_intr;
u_int32_t rxtypedone_intr;
u_int32_t ipc_a2m_intr;
u_int32_t tqe_intr;
u_int32_t tqe_in_port_lhost;
u_int32_t tqe_in_port_bad;
u_int32_t tqe_a2m_type_txfb;
u_int32_t tqe_a2m_type_rxpkt;
u_int32_t tqe_a2m_type_unknown;
u_int32_t tqe_reschedule_task;
u_int32_t tqe_desc_unowned;
/**
* \internal
*
* The number of interrupts from the baseband to the MuC.
*
* \note This should not be distributed externally - the following
* fields are for internal debugging ONLY.
*/
u_int32_t bb_intr;
/**
* \internal
*
* The number of DLEAF overflow interrupts from the baseband.
*/
u_int32_t bb_irq_dleaf_oflow;
u_int32_t bb_irq_leaf_uflow;
u_int32_t bb_irq_leaf_ldpc_uflow;
u_int32_t bb_irq_tx_td_oflow_intr;
u_int32_t bb_irq_tx_td_uflow_intr;
u_int32_t bb_irq_rx_sm_wdg_intr;
/* BB spends more than 6.8ms (short GI)/7.55ms (long GI) to receive one packet */
u_int32_t bb_irq_rx_long_dur;
/* BB spends more than 5.4ms (standard defined limit) to receive one 11ac packet. */
u_int32_t bb_irq_rx_11ac_timeout;
u_int32_t bb_irq_tx_sm_wdg_intr;
/**
* \internal
*
* The number of BB state machine watchdogs that have kicked in.
*/
u_int32_t bb_irq_main_sm_wdg_intr;
u_int32_t bb_irq_hready_wdg_intr;
u_int32_t mac_irq_rx_sec_buff_oflow;
u_int32_t mac_irq_rx_strq_oflow;
u_int32_t mac_irq_rx_bb_uflow_intr;
u_int32_t mac_irq_rx_bb_oflow_intr;
u_int32_t bb_irq_hready_wdg_reset;
/**
* \internal
*
* This counter is incremented once at the start of the main watchdog state machine.
*
* \sa sreset_wdg_end
*/
u_int32_t sreset_wdg_begin;
/**
* \internal
*
* This counter is incremented once at the end of the main watchdog state machine.
*
* \sa sreset_wdg_begin
*/
u_int32_t sreset_wdg_end;
u_int32_t sreset_wdg_in_place;
u_int32_t sreset_wdg_tx_beacon_hang;
/**
* \internal
*
* The number of transmit hangs causing soft reset.
*
* Transmit hang is between 400 to 900ms from the time of sending a packet to the hardware
* without receiving a tx done interrupt.
*/
u_int32_t sreset_wdg_tx_hang;
/**
* \internal
*
* The number of packet memory corruption causing soft reset.
*
* For unknown reason, packet memory may be corrupted. When packet memory corruption is detected,
* soft reset is triggered, and this counter incremented once.
*/
u_int32_t sreset_wdg_pm_corrupt;
/**
* \internal
*
* The number of packet transmit control memory corruption causing soft reset.
*
* For unknown reason, transmit control memory may be corrupted. When transmit control memory corruption is detected,
* soft reset is triggered, and this counter incremented once.
*/
u_int32_t sreset_wdg_tcm_corrupt;
/**
* \internal
*
* The number of receive hangs causing a soft reset.
*
* Receive hang is > 70s without receiving a single packet.
*
* Note that this can trigger in idle situations, but should not affect anything because
* the link is idle.
*/
u_int32_t sreset_wdg_rx_done;
u_int32_t sreset_wdg_in_place_try;
u_int32_t sreset_wdg_tasklet_sched_1;
u_int32_t sreset_wdg_tasklet_sched_2;
u_int32_t sreset_tasklet_sched;
u_int32_t sreset_tasklet_begin;
u_int32_t sreset_tasklet_end;
/**
* \internal
*
* This counter is incremented when a BB hard reset is requested
* to occur in the middle of a soft reset sequence
*/
u_int32_t hreset_req;
/**
* \internal
*
* This counter is incremented at the start of a soft reset.
*
* There should always be a corresponding increment in the sreset_end
* counter, or there is a problem.
*
* \sa sreset_end
*/
u_int32_t sreset_begin;
/**
* \internal
*
* This counter is incremented at the end of a soft reset.
*
* The should always being a corresponding increment in the sreset_begin
* counter, or there is a problem.
*
* \sa sreset_begin
*/
u_int32_t sreset_end;
/**
* \internal
*
* This counter is incremented each time DMA RX is in progress when a
* soft reset is triggered.
*/
u_int32_t sreset_dma_rx_inprog;
/**
* \internal
*
* This counter is incremented each time DMA TX is in progress when a
* soft reset is triggered.
*/
u_int32_t sreset_dma_tx_inprog;
u_int32_t sreset_dma_rx_max_wait;
u_int32_t sreset_dma_tx_max_wait;
u_int32_t sreset_dma_tx_hang;
u_int32_t sreset_dma_rx_hang;
u_int32_t sreset_dma_rx_wait_timeout;
u_int32_t sreset_dma_tx_wait_timeout;
u_int32_t sreset_drop_not_valid;
u_int32_t sreset_drop_bad_addr;
u_int32_t rf_cmpvtune_out;
u_int32_t rf_cal_freq;
u_int32_t ac_max;
u_int32_t ac_min;
u_int32_t ac_cur;
u_int32_t ac_adj;
u_int32_t rx_gain;
u_int32_t rd_cache_indx;
u_int32_t logger_sreset_wmac1_dma_rx_inprog;
u_int32_t logger_sreset_wmac1_dma_tx_inprog;
u_int32_t logger_sreset_wmac1_dma_rx_max_wait;
u_int32_t logger_sreset_wmac1_dma_tx_max_wait;
u_int32_t logger_sreset_wmac1_dma_tx_hang;
u_int32_t logger_sreset_wmac1_dma_rx_hang;
u_int32_t logger_sreset_wmac1_dma_rx_wait_timeout;
u_int32_t logger_sreset_wmac1_dma_tx_wait_timeout;
/**
* These counter show the information of MU frames.
*/
u_int32_t mu_rx_pkt;
/**
* \internal
*
* These counters monitor power duty cycling
*/
u_int32_t pduty_sleep;
u_int32_t pduty_rxoff;
u_int32_t pduty_period;
u_int32_t pduty_pct;
/**
* \internal
*
* These counter are incremented when a soft-ring operation is triggered
*/
u_int32_t soft_ring_push_to_tqe;
u_int32_t soft_ring_empty;
u_int32_t soft_ring_not_empty;
u_int32_t soft_ring_add_force;
u_int32_t soft_ring_add_to_head;
u_int32_t soft_ring_add_continue;
u_int32_t soft_ring_free_pool_empty;
u_int32_t mimo_ps_mode_switch; /* times STA switch MIMO power-save mode by HT action */
u_int32_t rx_vlan_drop;
u_int32_t auto_cca_state;
u_int32_t auto_cca_th;
u_int32_t auto_cca_spre;
u_int32_t auto_cca_intf;
/**
* \internal
*
* These counters are monitor memory allocation.
*/
u_int32_t total_dmem_alloc;
u_int32_t total_dram_alloc;
u_int32_t dmem_alloc_fails;
u_int32_t dram_alloc_fails;
u_int32_t total_dmem_free;
u_int32_t total_dram_free;
/* RX frames BW mode*/
u_int32_t rx_bw_80;
u_int32_t rx_bw_40;
u_int32_t rx_bw_20;
/* U-APSD rx stats */
uint32_t rx_wmm_ps_trigger;
uint32_t rx_wmm_ps_set;
uint32_t rx_wmm_ps_reset;
uint32_t rx_intr_next_ptr_0;
uint32_t rx_hbm_pool_depleted;
uint32_t rxq_intr[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_fill[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_nobuf[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_stop[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_pkt[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_bad_status[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_pkt_oversize[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_pkt_delivered[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_status_hole_chk_num[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_status_hole_chk_step_sum[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_status_hole_chk_step_max[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_status_hole[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_status_hole_max_size[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_process_max[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_process_sum[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_process_num[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_process_limited[QTN_FW_WMAC_RX_QNUM];
uint32_t rxq_desc_chain_empty[QTN_FW_WMAC_RX_QNUM];
uint32_t rx_data_last_seqfrag;
uint32_t rx_data_last_ip_id;
/**
* This counter is incremented once per packet which is sent via the
* external filter (HotSpot functionality).
*/
uint32_t accel_l2_ext_filter;
uint32_t accel_mc_send_l2_ext_filter;
/**
* This counter is incremented once per multicast packet dropped without
* forwording to the external filter (HotSpot functionality).
*/
uint32_t accel_mc_drop_l2_ext_filter;
/**
* The number of Rx frames dropped because the WPA2 Packet Number (PN) was not incrementing.
* This condition indicates a possible replay attack.
*/
uint32_t rx_replay_attack_drop;
};
#define MUC_HT_NUM_RATES 77
#define MUC_VHT_NUM_RATES 40
struct muc_rx_rates {
u_int32_t rx_mcs[MUC_HT_NUM_RATES];
u_int32_t rx_mcs_11ac[MUC_VHT_NUM_RATES];
};
#define QTN_STATS_NUM_BF_SLOTS 10
struct muc_rx_bf_stats {
u_int32_t rx_bf_valid[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_aid[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_ng[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_11n_ndp[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_11ac_ndp[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_11n_act[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_11ac_act[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_11ac_grp_sel[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_11ac_prec[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_11ac_su[QTN_STATS_NUM_BF_SLOTS];
u_int32_t rx_bf_11ac_dsp_fail[QTN_STATS_NUM_BF_SLOTS];
u_int32_t mu_grp_add[QTN_STATS_NUM_BF_SLOTS];
u_int32_t mu_grp_del[QTN_STATS_NUM_BF_SLOTS];
u_int32_t msg_buf_alloc_fail;
};
/** @} */
extern struct muc_rx_stats uc_rx_stats;
extern struct muc_rx_rates uc_rx_rates;
extern struct muc_rx_bf_stats uc_rx_bf_stats;
extern struct muc_tx_stats uc_tx_stats;
extern struct qtn_rate_tx_stats_per_sec uc_tx_rates;
extern uint32_t uc_su_rate_stats_read;
extern uint32_t uc_mu_rate_stats_read;
/*
* Rate adaption data collected for packet logger
* NOTE: Any changes to these definitions will require changes to stat_parser.pl
*/
#define RATES_STATS_NUM_ADAPTATIONS 16
#define RATES_STATS_NUM_TX_RATES 6
#define RATES_STATS_NUM_RX_RATES 8 /* Must be a multiple of word size */
#define RATES_STATS_EVM_CNT 4
/*
* Currently only two user positions are supported for MU group
* the following define should be aligned
* with IEEE80211_MU_GRP_NODES_MAX (4) in future.
* for now we don't want to take care about 2x extra zero-filled
* huge arrays in rate stats
*/
#define RATES_STATS_MAX_USER_IN_GROUP 2
/**
* \addtogroup MUCSTATS
*/
/** @{ */
struct qtn_rate_stats_mcs_data {
uint16_t mcs_rate;
uint16_t rate_index;
uint16_t state;
uint16_t pkt_total;
uint16_t pkt_error;
uint16_t pkt_hw_retry;
uint16_t pkt_sample;
uint16_t avg_per;
} __attribute__((packed));
struct qtn_rate_su_tx_stats {
uint32_t seq_no;
uint32_t timestamp;
uint32_t flags;
uint16_t sampling_index;
uint16_t sampling_rate;
struct qtn_rate_stats_mcs_data mcs_data[RATES_STATS_NUM_TX_RATES];
} __attribute__((packed));
struct qtn_rate_mu_tx_stats {
struct qtn_rate_su_tx_stats group_stats[RATES_STATS_MAX_USER_IN_GROUP];
} __attribute__((packed));
struct qtn_rate_gen_stats {
u_int16_t rx_mcs_rates[RATES_STATS_NUM_RX_RATES];
u_int32_t rx_mcs[RATES_STATS_NUM_RX_RATES];
u_int32_t rx_crc;
u_int32_t rx_sp_errors;
u_int32_t rx_lp_errors;
u_int32_t rx_evm[RATES_STATS_EVM_CNT];
u_int32_t tx_subframe_success;
u_int32_t tx_subframe_fail;
u_int32_t tx_mgmt_success;
u_int32_t tx_hw_retry;
u_int32_t tx_sw_retry;
} __attribute__((packed));
struct qtn_rate_tx_stats_per_sec {
struct qtn_rate_su_tx_stats stats_su[RATES_STATS_NUM_ADAPTATIONS];
struct qtn_rate_mu_tx_stats stats_mu[RATES_STATS_NUM_ADAPTATIONS];
};
/** @} */
#endif /* _STATS_H_ */

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2011 Quantenna Communications, Inc.
*
* Shared datastructure between lhost, MuC and ADM module for CCA measurement
*/
#ifndef _QTN_CCA_H
#define _QTN_CCA_H
struct out_cca_info {
u_int64_t start_tsf;
u_int64_t end_tsf;
u_int32_t cnt_pri_cca;
u_int32_t cnt_sec_cca;
u_int32_t cca_sample_cnt;
};
#endif // _QTN_CCA_H

View File

@ -0,0 +1,52 @@
/*SH1
*******************************************************************************
** **
** Copyright (c) 2012 Quantenna Communications, Inc **
** All Rights Reserved **
** **
** Author : Quantenna Communications Inc **
** File : qtn_config.h **
** Description : **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#ifndef _QTN_CONFIG_H_
#define _QTN_CONFIG_H_
#define TXBF_6_STA_BF
#endif /* _QTN_CONFIG_H_ */

View File

@ -0,0 +1,244 @@
/*SH1
*******************************************************************************
** **
** Copyright (c) 2008 - 2012 Quantenna Communications, Inc **
** All Rights Reserved **
** **
** Date : 21/03/12 **
** File : qtn_debug.c **
** Description : **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#ifndef QTN_DEBUG_H_
#define QTN_DEBUG_H_
/* When set to 1 LHOST formats AuC print output. It is not possible to use %s and %pM
conversion specifiers. Also the number of arguments printed are limited to 8 and therefore
stack size is limited to 32.
When set to 0 AuC formats the output, pass the formatted line to the LHOST that
prints it. */
#ifdef TOPAZ_PLATFORM
#define AUC_LHOST_PRINT_FORMAT 1
#else
#define AUC_LHOST_PRINT_FORMAT 0
#endif
#define PRINT_STACK_SIZE 32
#if defined(MUC_BUILD)
#define DBGFN uc_printk
#elif defined(AUC_BUILD)
#define DBGFN auc_os_printf
#else
#define DBGFN printk
#endif
#ifndef __GNUC__
#define __FUNCTION__ ""
#endif
#define DBGFMT "%s: "
#define DBGEFMT "%s: ERROR - "
#define DBGWFMT "%s: WARNING - "
#define DBGARG __func__
#define DBGMACVAR "%02x:%02x:%02x:%02x:%02x:%02x"
#define DBGMACFMT(a) \
(a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define DBGMACFMT_LE(a) \
(a)[5], (a)[4], (a)[3], (a)[2], (a)[1], (a)[0]
#define DBGFMT_BYTEFLD3_P "%u.%u.%u"
#define DBGFMT_BYTEFLD3_V(_v) (_v >> 16) & 0xff, (_v >> 8) & 0xff, _v & 0xff
#define DBGFMT_BYTEFLD4_P "%u.%u.%u.%u"
#define DBGFMT_BYTEFLD4_V(_v) (_v >> 24) & 0xff, (_v >> 16) & 0xff, (_v >> 8) & 0xff, _v & 0xff
#ifndef BIT
#define BIT(x) (1 << (x))
#endif
typedef enum {
DBG_LM_QDRV = 1,
DBG_LM_QPCIE,
DBG_LM_QRADAR,
DBG_LM_QBOOTCFG,
DBG_LM_QADM,
DBG_LM_QWLAN,
DBG_LM_QMACFW,
DBG_LM_MAX
} dbg_log_module;
typedef const struct
{
dbg_log_module dbg_module_id;
const char *dbg_module_name;
} dbg_module_table_t;
extern unsigned int g_dbg_log_module;
#if defined(MUC_BUILD)
extern unsigned int g_dbg_log_level;
extern unsigned int g_dbg_log_func;
#else
extern unsigned int g_dbg_log_level[DBG_LM_MAX];
extern unsigned int g_dbg_log_func[DBG_LM_MAX];
#endif
extern dbg_module_table_t dbg_module_name_entry[];
#define DBG_LL_EMERG 0
#define DBG_LL_ALERT 1
#define DBG_LL_ERR 2
#define DBG_LL_WARNING 3
#define DBG_LL_CRIT 4
#define DBG_LL_NOTICE 5
#define DBG_LL_INFO 6
#define DBG_LL_HIDDEN 7
#define DBG_LL_DEBUG 8
#define DBG_LL_TRIAL 9
#define DBG_LL_ALL 10
#define DBG_LF_00 0x00000001
#define DBG_LF_01 0x00000002
#define DBG_LF_02 0x00000004
#define DBG_LF_03 0x00000008
#define DBG_LF_04 0x00000010
#define DBG_LF_05 0x00000020
#define DBG_LF_06 0x00000040
#define DBG_LF_07 0x00000080
#define DBG_LF_08 0x00000100
#define DBG_LF_09 0x00000200
#define DBG_LF_10 0x00000400
#define DBG_LF_11 0x00000800
#define DBG_LF_12 0x00001000
#define DBG_LF_13 0x00002000
#define DBG_LF_14 0x00004000
#define DBG_LF_15 0x00008000
#define DBG_LF_16 0x00010000
#define DBG_LF_17 0x00020000
#define DBG_LF_18 0x00040000
#define DBG_LF_19 0x00080000
#define DBG_LF_20 0x00100000
#define DBG_LF_21 0x00200000
#define DBG_LF_22 0x00400000
#define DBG_LF_23 0x00800000
#define DBG_LF_24 0x01000000
#define DBG_LF_25 0x02000000
#define DBG_LF_26 0x04000000
#define DBG_LF_27 0x08000000
#define DBG_LF_28 0x10000000
#define DBG_LF_29 0x20000000
#define DBG_LF_30 0x40000000
#define DBG_LF_31 0x80000000
#define DBG_LF_ALL 0xFFFFFFFF
#define DBG_LOG_FUNC (g_dbg_log_func[DBG_LM - 1])
#define DBG_LOG_LEVEL (g_dbg_log_level[DBG_LM - 1])
#define DBG_LOG_FUNC_TEST(flag) (g_dbg_log_func[DBG_LM - 1] & (flag))
#if defined(QTN_DEBUG)
#define DBGPRINTF_RAW(ll, lf, fmt, ...) \
do { \
if((g_dbg_log_module & (BIT(DBG_LM - 1))) && \
(DBG_LOG_LEVEL >= (ll)) && \
(DBG_LOG_FUNC_TEST(lf))) { \
DBGFN(fmt, ##__VA_ARGS__); \
} \
} while(0)
#define DBGPRINTF(ll, lf, fmt, ...) \
do { \
if((g_dbg_log_module & (BIT(DBG_LM - 1))) && \
(DBG_LOG_LEVEL >= (ll)) && \
(DBG_LOG_FUNC_TEST(lf))) { \
DBGFN(DBGFMT fmt, DBGARG, ##__VA_ARGS__); \
} \
} while(0)
#define DBGPRINTF_E(fmt, ...) \
do { \
if (DBG_LOG_LEVEL >= DBG_LL_ERR) \
DBGFN(DBGEFMT fmt, DBGARG, ##__VA_ARGS__); \
} while(0)
#define DBGPRINTF_W(fmt, ...) \
do { \
if (DBG_LOG_LEVEL >= DBG_LL_WARNING) \
DBGFN(DBGWFMT fmt, DBGARG, ##__VA_ARGS__); \
} while(0)
#define DBGPRINTF_N(fmt, ...) \
DBGFN(fmt, ##__VA_ARGS__);
#define DBGPRINTF_LIMIT_E(fmt, ...) \
do { \
if ((DBG_LOG_LEVEL >= DBG_LL_ERR) && (net_ratelimit())) \
DBGFN(DBGEFMT fmt, DBGARG, ##__VA_ARGS__); \
} while(0)
#define DBGPRINTF_LIMIT(ll, lf, fmt, ...) \
do { \
if ((g_dbg_log_module & BIT(DBG_LM - 1)) && \
DBG_LOG_FUNC_TEST(lf) && \
DBG_LOG_LEVEL >= (ll) && (net_ratelimit())) \
DBGFN(DBGFMT fmt, DBGARG, ##__VA_ARGS__); \
} while(0)
#else
#define DBGPRINTF(ll, lf, fmt, args...)
#define DBGPRINTF_E(fmt, args...)
#define DBGPRINTF_W(fmt, args...)
#define DBGPRINTF_LIMIT_E(fmt, args...)
#define DBGPRINTF_LIMIT(ll, lf, fmt, args...)
#endif
#define HERE(x) do { \
DBGFN("%s:%d:%s %s = %d 0x%x\n", \
__FILE__, __LINE__, __FUNCTION__, (#x), \
(int) (x), (unsigned int) (x)); \
} while(0)
#define HERES(x) do { \
DBGFN("%s:%d:%s %s = '%s'\n", \
__FILE__, __LINE__, __FUNCTION__, (#x), (x)); \
} while(0)
#define HERE_REG(addr) do { \
DBGFN("%s:%d:%s reg 0x%08lx = 0x%08lx (%s)\n", \
__FILE__, __LINE__, __FUNCTION__, \
(unsigned long) (addr), \
(unsigned long) readl(addr), (#addr)); \
} while(0)
#endif /* QTN_DEBUG_H_ */

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2012 Quantenna Communications, Inc.
*/
#ifndef _QTN_UC_COMM_H
#define _QTN_UC_COMM_H
#define MAC_UNITS 1
#if defined(TOPAZ_PLATFORM) && defined(TOPAZ_128_NODE_MODE)
#define QTN_NCIDX_MAX 128
#define QTN_NODE_TBL_SIZE_LHOST 118
#define QTN_NODETID_NODE_SHIFT 7
#else
#define QTN_NCIDX_MAX 64
#define QTN_NODE_TBL_SIZE_LHOST 56
#define QTN_NODETID_NODE_SHIFT 6
#endif
#define QTN_MAX_BSS_VAPS 8
#define QTN_MAX_WDS_VAPS 8
#define QTN_MAX_VAPS ((QTN_MAX_BSS_VAPS) + (QTN_MAX_WDS_VAPS))
#define QTN_NODE_TBL_MUC_HEADRM 3 /* Allow for delayed delete on MUC */
#define QTN_NODE_TBL_SIZE_MUC ((QTN_NODE_TBL_SIZE_LHOST) + (QTN_NODE_TBL_MUC_HEADRM))
#define QTN_ASSOC_LIMIT ((QTN_NODE_TBL_SIZE_LHOST) - (QTN_MAX_VAPS))
#endif // #ifndef _QTN_UC_COMM_H

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 2014 Quantenna Communications, Inc.
* All rights reserved.
*/
#ifndef _QTN_VLAN_H_
#define _QTN_VLAN_H_
#include "../common/ruby_mem.h"
#include <qtn/qtn_debug.h>
#include <qtn/qtn_uc_comm.h>
#define QVLAN_MODE_PTHRU 0
#define QVLAN_MODE_MBSS 1
#define QVLAN_MODE_DYNAMIC 2
#define QVLAN_MODE_MAX (QVLAN_MODE_DYNAMIC)
#define QVLAN_SHIFT_MODE 16
#define QVLAN_MASK_MODE 0xffff0000
#define QVLAN_MASK_VID 0x00000fff
#define QVLAN_MODE(x) (uint16_t)((x) >> QVLAN_SHIFT_MODE)
#define QVLAN_VID(x) (uint16_t)((x) & QVLAN_MASK_VID)
#define QVLAN_CMD_PTHRU 0
#define QVLAN_CMD_UNPTHRU 1
#define QVLAN_CMD_PTHRU_ALL 2
#define QVLAN_CMD_UNPTHRU_ALL 3
#define QVLAN_CMD_BIND 4
#define QVLAN_CMD_UNBIND 5
#define QVLAN_CMD_ENABLE 6
#define QVLAN_CMD_DISABLE 7
#define QVLAN_CMD_DYNAMIC 8
#define QVLAN_CMD_UNDYNAMIC 9
#define QVLAN_MODE_STR_BIND "MBSS (Access) mode"
#define QVLAN_MODE_STR_PTHRU "Passthrough (Trunk) mode"
#define QVLAN_MODE_STR_DYNAMIC "Dynamic mode"
/* default port vlan id */
#define QVLAN_DEF_PVID 1
#define QVLAN_VID_MAX 4096
#define QVLAN_VID_MAX_S 12
#define QVLAN_VID_ALL 0xffff
struct qtn_vlan_config {
uint32_t vlan_cfg;
uint8_t vlan_bitmap[QVLAN_VID_MAX / 7 + 1];
};
/*
* VLAN forward/drop table
*| traffic direction | frame | Access(MBSS/Dynamic mode) | Trunk(Passthrough mode)
*|--------------------------------------------------------------------------------------------------------------
*| wifi tx | no vlan | drop | forward
*|--------------------------------------------------------------------------------------------------------------
*| | vlan tagged | compare tag with PVID: | compare tag against VID list
*| | | 1.equal:untag and forward | 1.Found:forward
*| | | 2.not equal:drop | 2.Not found:drop
*|--------------------------------------------------------------------------------------------------------------
*| wifi rx | no vlan | Add PVID tag and forward | forward
*|--------------------------------------------------------------------------------------------------------------
*| | vlan tagged | Compare tag with PVID: | compare tag against VID list
*| | | 1.equal:forward | 1. Found:forward
*| | | 2.not equal:drop | 2. Not found:drop
*|--------------------------------------------------------------------------------------------------------------
*/
#define QVLAN_BYTES_PER_VID ((QTN_MAX_BSS_VAPS + NBBY - 1) / NBBY)
#define QVLAN_BYTES_PER_VID_SHIFT 0
RUBY_INLINE int
qtn_vlan_is_valid(int vid)
{
return (vid >= 0 && vid < QVLAN_VID_MAX);
}
RUBY_INLINE int
qtn_vlan_is_allowed(volatile uint8_t *vlan_bitmap, uint16_t vid, uint8_t vapid)
{
return !!(vlan_bitmap[(vid << QVLAN_BYTES_PER_VID_SHIFT) + (vapid >> 3)] & BIT(vapid & (8 - 1)));
}
RUBY_INLINE void
qtn_vlan_allow(uint8_t *vlan_bitmap, uint16_t vid, uint8_t vapid)
{
vlan_bitmap[(vid << QVLAN_BYTES_PER_VID_SHIFT) + (vapid >> 3)] |= BIT(vapid & (8 - 1));
}
RUBY_INLINE void
qtn_vlan_disallow(uint8_t *vlan_bitmap, uint16_t vid, uint8_t vapid)
{
vlan_bitmap[(vid << QVLAN_BYTES_PER_VID_SHIFT) + (vapid >> 3)] &= ~BIT(vapid & (8 - 1));
}
RUBY_INLINE void
qtn_vlan_gen_group_addr(uint8_t *mac, uint16_t vid, uint8_t vapid)
{
uint16_t encode;
mac[0] = 0xff;
mac[1] = 0xff;
mac[2] = 0xff;
mac[3] = 0xff;
encode = ((uint16_t)vapid << QVLAN_VID_MAX_S) | vid;
mac[4] = encode >> 8;
mac[5] = (uint8_t)(encode & 0xff);
}
RUBY_INLINE int
qtn_vlan_is_group_addr(const uint8_t *mac)
{
return (mac[0] == 0xff && mac[1] == 0xff
&& mac[2] == 0xff && mac[3] == 0xff
&& mac[4] != 0xff);
}
RUBY_INLINE int
qtn_vlancfg_reform(struct qtn_vlan_config *vcfg)
{
/* remove 0,15,16,31 bits to restore vlan_cfg */
vcfg->vlan_cfg &= 0x7ffe7ffe;
vcfg->vlan_cfg >>= 1;
return ((vcfg->vlan_cfg & QVLAN_MASK_MODE) >> QVLAN_SHIFT_MODE);
}
#endif

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2013 Quantenna Communications, Inc.
*/
#ifndef _QTN_WMM_AC_H
#define _QTN_WMM_AC_H
#define WMM_AC_BE 0
#define WMM_AC_BK 1
#define WMM_AC_VI 2
#define WMM_AC_VO 3
#define WMM_AC_NUM 4
#define QTN_AC_MGMT WMM_AC_VO
#define WMM_AC_INVALID WMM_AC_NUM
#define QTN_AC_ORDER { WMM_AC_VO, WMM_AC_VI, WMM_AC_BE, WMM_AC_BK }
#define QTN_TID_BE 0
#define QTN_TID_BK 1
#define QTN_TID_2 2
#define QTN_TID_3 3
#define QTN_TID_WLAN 4 /* 802.11 encap'ed data from wlan driver */
#define QTN_TID_VI 5
#define QTN_TID_VO 6
#define QTN_TID_MGMT 7
#define QTN_TID_IS_80211(tid) ((tid == QTN_TID_MGMT) || (tid == QTN_TID_WLAN))
#define QTN_TID_ORDER { \
QTN_TID_MGMT, \
QTN_TID_WLAN, \
QTN_TID_VO, \
QTN_TID_VI, \
QTN_TID_BE, \
QTN_TID_BK \
}
#define QTN_TID_ORDER_DATA { \
QTN_TID_VO, \
QTN_TID_VI, \
QTN_TID_BE, \
QTN_TID_BK \
}
#define QTN_TID_ORDER_POLL { \
QTN_TID_VO, \
QTN_TID_VI, \
QTN_TID_BE, \
QTN_TID_BK, \
QTN_TID_WLAN, \
QTN_TID_MGMT \
}
#define WMM_AC_TO_TID(_ac) ( \
(_ac == WMM_AC_VO) ? QTN_TID_VO : \
(_ac == WMM_AC_VI) ? QTN_TID_VI : \
(_ac == WMM_AC_BK) ? QTN_TID_BK : \
QTN_TID_BE)
#define TID_TO_WMM_AC(_tid) ( \
(_tid == QTN_TID_BK) ? WMM_AC_BK : \
(_tid == QTN_TID_VI) ? WMM_AC_VI : \
(_tid == QTN_TID_VO) ? WMM_AC_VO : \
(_tid == QTN_TID_WLAN) ? QTN_AC_MGMT : \
(_tid == QTN_TID_MGMT) ? QTN_AC_MGMT : \
WMM_AC_BE)
#define QTN_TID_COLLAPSE(_tid) WMM_AC_TO_TID(TID_TO_WMM_AC(_tid))
#define AC_TO_QTN_QNUM(_ac) \
(((_ac) == WME_AC_BE) ? 1 : \
((_ac) == WME_AC_BK) ? 0 : \
(_ac))
#endif /* _QTN_WMM_AC_H */

View File

@ -0,0 +1,36 @@
/*
*******************************************************************************
** **
** Copyright (c) 2012 Quantenna Communications Inc **
** All Rights Reserved **
** **
** Author : Quantenna Communications, Inc. **
** File : qvsp_common.h **
** Description : Video Screen Protection **
** **
*******************************************************************************
*/
#ifndef _QVSP_COMMON_H_
#define _QVSP_COMMON_H_
/*
* Default stream airtime cost in msec per sec to send or receive at 8 Mbps.
* Constants are binary for efficiency and do not need to be accurate. They only need to
* scale so that stream cost roughly equates to used airtime, in order to estimate the
* affect of disabling or re-enabling a stream.
*/
#define BYTES_PER_KIB (1024) /* Kibibytes */
#define BYTES_PER_MIB (1024 * 1024) /* Mebibytes */
#define QVSP_STRM_COST_UNIT_MIB (8) /* arbitrary (optimised) cost unit */
#define QVSP_STRM_COST_UNIT_BYTES (QVSP_STRM_COST_UNIT_MIB * BYTES_PER_MIB)
#define QVSP_NODE_COST_DFLT (1000)
struct qtn_per_tid_stats {
uint32_t tx_throt_pkts;
uint32_t tx_throt_bytes;
uint32_t tx_sent_pkts;
uint32_t tx_sent_bytes;
};
#endif

View File

@ -0,0 +1,641 @@
/*SH0
*******************************************************************************
** **
** Copyright (c) 2012-2013 Quantenna Communications, Inc. **
** All Rights Reserved **
** **
** File : qvsp_data.h **
** Description : Video Stream Protection **
** **
*******************************************************************************
EH0*/
#ifndef __QTN_QVSP_DATA_H__
#define __QTN_QVSP_DATA_H__
#include <net80211/_ieee80211.h>
#include <qtn/qvsp_common.h>
#if defined(__KERNEL__)
#include "compat.h"
#include <linux/in6.h>
#elif defined(MUC_BUILD)
#else
#include <netinet/in.h>
#include <sys/param.h>
#define MSEC_PER_SEC 1000L
#endif
/*
* Minimum rate at which to calculate node cost.
* If throughput is not sufficiently high, only small aggregates get transmitted which gives an
* artificially high and noisy node cost estimate.
* The threshold should be lower than QVSP_CFG_STRM_DISABLED_MAX, so that node cost continues to
* be updated when streams are disabled.
*/
#define QVSP_MIN_NODE_KBPS_UPDATE_DFLT 480
#define QVSP_STRM_DISABLED_MAX_DFLT (QVSP_MIN_NODE_KBPS_UPDATE_DFLT + 20)
/* Log levels */
#define LL_0 0x00
#define LL_1 0x01
#define LL_2 0x02
#define LL_3 0x03
#define LL_4 0x04
#define LL_5 0x05
#define LL_6 0x06
#define LL_7 0x07
#define LL_8 0x08
#define LL_9 0x09
enum qvsp_ioctl_state {
QVSP_STATE_FAT,
QVSP_STATE_FAT_AVAIL,
QVSP_STATE_FAT_INTF,
QVSP_STATE_STRM_TOT,
QVSP_STATE_STRM_QTN,
QVSP_STATE_STRM_ENA,
QVSP_STATE_STRM_DIS,
QVSP_STATE_STRM_DMT,
QVSP_STATE_READ_MAX,
QVSP_STATE_RESET,
QVSP_STATE_TEST_FAT,
QVSP_STATE_ALL_MAX
};
#ifndef DOXYGEN_EXCLUDE
/*
* Restrictions:
* this structure must be kept in sync with qvsp_cfg_params and qvspdoc_enumstr_cfg
* _AC[0-3] fields must follow the 'global' equivalent (for macro assumptions)
*/
enum qvsp_cfg_param_e {
QVSP_CFG_ENABLED,
QVSP_CFG_ENABLED_ALWAYS,
QVSP_CFG_FAT_MIN,
QVSP_CFG_FAT_MIN_SOFT,
QVSP_CFG_FAT_MIN_SOFT_CONSEC,
QVSP_CFG_FAT_MIN_SAFE,
QVSP_CFG_FAT_MIN_CHECK_INTV,
QVSP_CFG_FAT_MAX_SOFT,
QVSP_CFG_FAT_MAX_SOFT_CONSEC,
QVSP_CFG_FAT_MAX_SAFE,
QVSP_CFG_FAT_MAX_CHECK_INTV,
QVSP_CFG_NODE_DATA_MIN,
QVSP_CFG_DISABLE_DEMOTE,
QVSP_CFG_DISABLE_DEMOTE_FIX_FAT,
QVSP_CFG_DISABLE_WAIT,
QVSP_CFG_DISABLE_PER_EVENT_MAX,
QVSP_CFG_ENABLE_WAIT,
QVSP_CFG_ENABLE_PER_EVENT_MAX,
QVSP_CFG_STRM_RMT_DIS_TCP,
QVSP_CFG_STRM_RMT_DIS_UDP,
QVSP_CFG_STRM_TPUT_MIN,
QVSP_CFG_STRM_DISABLED_MAX,
QVSP_CFG_STRM_ADPT_THROT,
QVSP_CFG_STRM_ADPT_THROT_STEP,
QVSP_CFG_STRM_ADPT_THROT_MARGIN,
QVSP_CFG_STRM_TPUT_SMPL_MIN,
QVSP_CFG_STRM_COST_RC_ADJUST,
QVSP_CFG_STRM_MAX,
QVSP_CFG_STRM_MAX_AC0,
QVSP_CFG_STRM_MAX_AC1,
QVSP_CFG_STRM_MAX_AC2,
QVSP_CFG_STRM_MAX_AC3,
QVSP_CFG_STRM_MIN,
QVSP_CFG_STRM_MIN_AC0,
QVSP_CFG_STRM_MIN_AC1,
QVSP_CFG_STRM_MIN_AC2,
QVSP_CFG_STRM_MIN_AC3,
QVSP_CFG_STRM_TPUT_MAX_TCP,
QVSP_CFG_STRM_TPUT_MAX_FIRST = QVSP_CFG_STRM_TPUT_MAX_TCP,
QVSP_CFG_STRM_TPUT_MAX_TCP_AC0,
QVSP_CFG_STRM_TPUT_MAX_TCP_AC1,
QVSP_CFG_STRM_TPUT_MAX_TCP_AC2,
QVSP_CFG_STRM_TPUT_MAX_TCP_AC3,
QVSP_CFG_STRM_TPUT_MAX_UDP,
QVSP_CFG_STRM_TPUT_MAX_UDP_AC0,
QVSP_CFG_STRM_TPUT_MAX_UDP_AC1,
QVSP_CFG_STRM_TPUT_MAX_UDP_AC2,
QVSP_CFG_STRM_TPUT_MAX_UDP_AC3,
QVSP_CFG_STRM_TPUT_MAX_LAST = QVSP_CFG_STRM_TPUT_MAX_UDP_AC3,
QVSP_CFG_STRM_ENABLE_WAIT,
QVSP_CFG_STRM_AGE_MAX,
QVSP_CFG_AGE_CHK_INTV,
QVSP_CFG_3RDPT_CTL,
QVSP_CFG_3RDPT_LOCAL_THROT,
QVSP_CFG_3RDPT_QTN, /* treat qtn client as 3rd party client, debug use only */
QVSP_CFG_BA_THROT_INTV,
QVSP_CFG_BA_THROT_DUR_MIN,
QVSP_CFG_BA_THROT_DUR_STEP,
QVSP_CFG_BA_THROT_WINSIZE_MIN,
QVSP_CFG_BA_THROT_WINSIZE_MAX,
QVSP_CFG_WME_THROT_AC,
QVSP_CFG_WME_THROT_AIFSN,
QVSP_CFG_WME_THROT_ECWMIN,
QVSP_CFG_WME_THROT_ECWMAX,
QVSP_CFG_WME_THROT_TXOPLIMIT,
QVSP_CFG_WME_THROT_THRSH_DISABLED,
QVSP_CFG_WME_THROT_THRSH_VICTIM,
QVSP_CFG_EVENT_LOG_LVL,
QVSP_CFG_DEBUG_LOG_LVL,
QVSP_CFG_MAX,
};
struct qvsp_cfg_param {
const char *name;
const char *desc;
const char *units;
uint32_t default_val;
uint32_t min_val;
uint32_t max_val;
};
#define QVSP_CFG_PARAMS { \
{ "enabled", "QTM enabled", "number", 0, 0, 1}, \
{ "enabled_always", "QTM enabled when no QTM peers", "number", 0, 0, 1}, \
{ "fat_min", "Min free airtime", "msps", 100, 1, 1000 }, \
{ "fat_min_soft", "Soft min free airtime", "msps", 170, 1, 1000 }, \
{ "fat_min_soft_consec","Consecutive soft min free airtime", "number", 3, 1, 255 }, \
{ "fat_min_safe", "Safe min free airtime", "msps", 200, 1, 1000 }, \
{ "fat_min_check_intv", "Oversubscription check interval", "ms", 2000, 100, 60000 },\
{ "fat_max_soft", "Soft max free airtime", "msps", 350, 1, 1000 }, \
{ "fat_max_soft_consec","Consecutive soft max free airtime", "number", 5, 1, 255 }, \
{ "fat_max_safe", "Safe max free airtime", "msps", 250, 1, 1000 }, \
{ "fat_max_check_intv", "Undersubscription check interval", "ms", 2000, 100, 86400000 },\
{ "node_data_min", "Min data for node cost update", "Kbps", \
QVSP_MIN_NODE_KBPS_UPDATE_DFLT, 1, 10000 },\
{ "disable_demote", "Demote stream to disable", "number", 1, 0, 1 }, \
{ "disable_demote_fat_fix", "Adjust FAT when demoting streams",\
"number", 0, 0, 1 }, \
{ "disable_wait", "Min re-disable wait time", "secs", 3, 1, 86400 },\
{ "disable_event_max", "Max streams disabled per event", "number", 1, 1, 256 }, \
{ "enable_wait", "Min re-enable wait time", "secs", 15, 1, 86400 },\
{ "enable_event_max", "Max streams enabled per event", "number", 1, 1, 256 }, \
{ "rmt_disable_tcp", "Disable Rx TCP streams at STA", "number", 1, 0, 1 }, \
{ "rmt_disable_udp", "Disable Rx UDP streams at STA", "number", 1, 0, 1 }, \
{ "strm_tput_min", "Min throughput for a real stream", "Kbps", 1000, 1, 10000 },\
{ "strm_disabled_max", "Max throughput when disabled", "Kbps", \
QVSP_STRM_DISABLED_MAX_DFLT, 20, 10000 },\
{ "strm_adpt_throt", "Adaptive throttling enabled", "number", 1, 0, 1 }, \
{ "strm_adpt_throt_step", "Adaptive throttling cost step", \
"percent", 40, 1, 100 },\
{ "strm_adpt_throt_margin", "Adaptive throttling margin", \
"Kbps", 10000, 0, 100000 },\
{ "strm_tput_smpl_min", "Min throughput sampling ms", "ms", 20, 1, 1000 },\
{ "strm_cost_rc_adjust","Adjust stream cost for rate change", "number", 1, 0, 1 },\
{ "strm_max", "Max streams", "cnt", 256, 1, 256 }, \
{ "strm_max_ac0", "Max streams for AC 0", "cnt", 0, 0, 256 }, \
{ "strm_max_ac1", "Max streams for AC 1", "cnt", 0, 0, 256 }, \
{ "strm_max_ac2", "Max streams for AC 2", "cnt", 0, 0, 256 }, \
{ "strm_max_ac3", "Max streams for AC 3", "cnt", 0, 0, 256 }, \
{ "strm_min", "Min streams", "cnt", 1, 1, 1000 }, \
{ "strm_min_ac0", "Min streams for AC 0", "cnt", 0, 1, 1000 }, \
{ "strm_min_ac1", "Min streams for AC 1", "cnt", 0, 1, 1000 }, \
{ "strm_min_ac2", "Min streams for AC 2", "cnt", 0, 1, 1000 }, \
{ "strm_min_ac3", "Min streams for AC 3", "cnt", 0, 1, 1000 }, \
{ "strm_tput_max_tcp", "Max stream throughput for TCP", "Mbps", 0, 0, 10000 },\
{ "strm_tput_max_tcp_ac0","Max stream throughput for TCP AC 0", "Mbps", 0, 0, 10000 },\
{ "strm_tput_max_tcp_ac1","Max stream throughput for TCP AC 1", "Mbps", 0, 0, 10000 },\
{ "strm_tput_max_tcp_ac2","Max stream throughput for TCP AC 2", "Mbps", 0, 0, 10000 },\
{ "strm_tput_max_tcp_ac3","Max stream throughput for TCP AC 3", "Mbps", 0, 0, 10000 },\
{ "strm_tput_max_udp", "Max stream throughput for UDP", "Mbps", 0, 0, 10000 },\
{ "strm_tput_max_udp_ac0","Max stream throughput for UDP AC 0", "Mbps", 0, 0, 10000 },\
{ "strm_tput_max_udp_ac1","Max stream throughput for UDP AC 1", "Mbps", 0, 0, 10000 },\
{ "strm_tput_max_udp_ac2","Max stream throughput for UDP AC 2", "Mbps", 0, 0, 10000 },\
{ "strm_tput_max_udp_ac3","Max stream throughput for UDP AC 3", "Mbps", 0, 0, 10000 },\
{ "strm_enable_wait", "Min stream re-enable wait time", "secs", 30, 1, 86400 },\
{ "strm_age_max", "Max stream age", "secs", 5, 1, 86400 },\
{ "age_check_intv", "Age check interval", "secs", 10, 1, 86400 },\
{ "3rd_party_ctl", "Enable 3rd party client control", "number", 0, 0, 1 }, \
{ "3rd_party_local_throt", "Throttling 3rd party client packet also in local",\
"number", 0, 0, 1 }, \
{ "3rd_party_qtn", "Treat qtn client as 3rd party client", "number", 0, 0, 1 }, \
{ "ba_throt_intv", "BA throttling interval", "ms", 1000, 0, 10000 },\
{ "ba_throt_dur_min", "BA throttling min duration", "ms", 50, 0, 10000 },\
{ "ba_throt_dur_step", "BA throttling duration step", "ms", 100, 50, 10000 },\
{ "ba_throt_winsize_min", "BA throttling min winsize", "number", 1, 0, 256 },\
{ "ba_throt_winsize_max", "BA throttling max winsize", "number", 16, 1, 256 },\
{ "wme_throt_ac", "WME throttling AC bitmap", "number", 3, 0, 15 },\
{ "wme_throt_aifsn", "WME throttling AIFSN", "number", 15, 0, 15 },\
{ "wme_throt_ecwmin", "WME throttling encoded cwmin", "number", 14, 1, 14 },\
{ "wme_throt_ecwmax", "WME throttling encoded cwmax", "number", 15, 1, 15 },\
{ "wme_throt_txoplimit","WME throttling TXOP limit", "number", 0, 0, 65535 },\
{ "wme_throt_thrsh_disabled", "WME throttling disabled stream cost threshold",\
"number", 150, 0, 1000 },\
{ "wme_throt_thrsh_victim", "WME throttling victim stream cost threshold",\
"number", 150, 0, 1000 },\
{ "event_level", "Event log level", "number", LL_0, LL_0, LL_9 },\
{ "debug_level", "Debug log level", "number", LL_3, LL_0, LL_9 },\
}
/* Must be in sync with call_qcsapi_vsp_if_desc */
enum qvsp_if_e {
QVSP_IF_ETH_RX,
QVSP_IF_QDRV_TX,
QVSP_IF_QDRV_RX,
QVSP_IF_PCIE_RX,
QVSP_IF_MAX
};
#define QVSP_IF_DESCS { \
"eth_rx", \
"qdrv_tx", \
"qdrv_rx", \
"pcie_rx", \
"invalid" \
}
/*
* These must be kept in sync with QVSP_STRM_THROT_DESCS and QVSP_STRM_THROT_DESCS_ABBR.
*/
enum qvsp_strm_throt_policy {
QVSP_STRM_THROT_NONE = 0,
QVSP_STRM_THROT_BINARY = 1,
QVSP_STRM_THROT_ADPT = 2,
QVSP_STRM_THROT_MAX,
};
#define QVSP_STRM_THROT_DESCS { \
"None", \
"Binary", \
"Adaptive", \
}
#define QVSP_STRM_THROT_DESCS_ABBR { \
"N/A", \
"BIN", \
"ADP", \
}
enum qvsp_rule_dir_e {
QVSP_RULE_DIR_ANY,
QVSP_RULE_DIR_TX,
QVSP_RULE_DIR_RX,
};
#define QVSP_RULE_DIR_DESCS { \
"Any", \
"Tx", \
"Rx", \
}
enum qvsp_rule_param_e {
QVSP_RULE_PARAM_DIR,
QVSP_RULE_PARAM_VAPPRI,
QVSP_RULE_PARAM_AC,
QVSP_RULE_PARAM_PROTOCOL,
QVSP_RULE_PARAM_TPUT_MIN,
QVSP_RULE_PARAM_TPUT_MAX,
QVSP_RULE_PARAM_COST_MIN,
QVSP_RULE_PARAM_COST_MAX,
QVSP_RULE_PARAM_ORDER,
QVSP_RULE_PARAM_THROT_POLICY,
QVSP_RULE_PARAM_DEMOTE,
QVSP_RULE_PARAM_MAX,
};
struct qvsp_rule_param {
const char *name;
const char *desc;
const char *units;
uint32_t min_val;
uint32_t max_val;
};
#define QVSP_RULE_PARAMS { \
{ "dir", "Direction", "val", 0, 2 }, \
{ "vappri", "VAP Priority", "bitmap", 0x1, 0xf }, \
{ "ac", "Access Classes", "bitmap", 0x1, 0xf }, \
{ "protocol", "IP protocol - TCP(6) or UDP(17)", "val", 6, 17 }, \
{ "tp_min", "Min throughput", "Mbps", 1, 10000 }, \
{ "tp_max", "Max throughput", "Mbps", 1, 10000 }, \
{ "cost_min", "Cost min", "msps", 1, 1000 }, \
{ "cost_max", "Cost max", "msps", 1, 1000 }, \
{ "order", "Match order", "val", 0, QVSP_RULE_ORDER_MAX - 1 },\
{ "throt_policy", "Throttling policy - binary(1) or adaptive(2)", \
"val", 1, QVSP_STRM_THROT_MAX - 1 },\
{ "demote", "Demote stream", "val", 0, 1}, \
}
/*
* These must be kept in sync with QVSP_RULE_ORDER_DESCS and QVSP_RULE_ORDER_DESCS_ABBR.
*/
enum qvsp_rule_order_e {
QVSP_RULE_ORDER_GREATEST_COST_NODE,
QVSP_RULE_ORDER_LEAST_COST_NODE,
QVSP_RULE_ORDER_GREATEST_NODE_INV_PHY_RATE,
QVSP_RULE_ORDER_LEAST_NODE_INV_PHY_RATE,
QVSP_RULE_ORDER_GREATEST_COST_STREAM,
QVSP_RULE_ORDER_LEAST_COST_STREAM,
QVSP_RULE_ORDER_NEWEST,
QVSP_RULE_ORDER_OLDEST,
QVSP_RULE_ORDER_LOWEST_TPUT,
QVSP_RULE_ORDER_HIGHEST_TPUT,
QVSP_RULE_ORDER_MAX
};
#define QVSP_RULE_ORDER_DESCS { \
"greatest cost node first", \
"least cost node first", \
"greatest inverse PHY rate node first", \
"least inverse PHY rate node first", \
"greatest cost stream first", \
"least cost stream first", \
"newest first", \
"oldest first", \
"lowest throughput first", \
"highest throughput first", \
}
#define QVSP_RULE_ORDER_DESCS_ABBR { \
"GCN", \
"LCN", \
"GIPR", \
"LIPR", \
"GCS", \
"LCS", \
"NS", \
"OS", \
"LT", \
"HT", \
}
enum qvsp_strm_state_e {
QVSP_STRM_STATE_NONE,
QVSP_STRM_STATE_DISABLED,
QVSP_STRM_STATE_LOW_TPUT,
QVSP_STRM_STATE_PRE_ENABLED,
QVSP_STRM_STATE_ENABLED,
QVSP_STRM_STATE_DELETED,
QVSP_STRM_STATE_MAX
};
enum qvsp_hairpin_e {
QVSP_HAIRPIN_NONE,
QVSP_HAIRPIN_UCAST,
QVSP_HAIRPIN_MCAST,
};
#define QVSP_RULE_DIR_DESCS { \
"Any", \
"Tx", \
"Rx", \
}
/* This definition must be kept in sync with the qvsp_ext_s struct */
#define QVSP_INACTIVE_REASON { \
"Config", \
"WDS", \
"CoC" \
}
#define QVSP_3RDPT_STR "3"
#ifndef MUC_BUILD
/** \addtogroup vsp_group
* @{
*/
/**
* Defines a stream based on source and destination
*/
struct qvsp_hash_flds_ipv4 {
/** IP source address */
__be32 saddr;
/** IP destination address */
__be32 daddr;
/** UDP/TCP source port */
__be16 sport;
/** UDP/TCP destination port */
__be16 dport;
};
struct qvsp_hash_flds_ipv6 {
/** IP source address */
struct in6_addr saddr;
/** IP destination address */
struct in6_addr daddr;
/** UDP/TCP source port */
__be16 sport;
/** UDP/TCP destination port */
__be16 dport;
};
union qvsp_hash_flds {
struct qvsp_hash_flds_ipv4 ipv4;
struct qvsp_hash_flds_ipv6 ipv6;
};
/**
* Whitelist definition. Passing streams are compared with
* the stream defined in 'hflds', ANDed with netmasks
*/
struct qvsp_wl_flds {
union qvsp_hash_flds hflds;
/** IP source CIDR bitcount */
uint8_t s_cidr_bits;
/** IP destination CIDR bitcount */
uint8_t d_cidr_bits;
/** IP version */
uint8_t ip_version;
};
/**
* IPv4 whitelist tricks for netmask; store netmasks in the hashfield union
*/
static inline __be32 * qvsp_wl_ipv4_netmask_src(struct qvsp_wl_flds *wl)
{
struct qvsp_hash_flds_ipv4 *ipv4 = &wl->hflds.ipv4;
return (__be32 *)&ipv4[1];
}
static inline __be32 * qvsp_wl_ipv4_netmask_dst(struct qvsp_wl_flds *wl)
{
return &(qvsp_wl_ipv4_netmask_src(wl))[1];
}
struct qvsp_rule_flds {
uint32_t param[QVSP_RULE_PARAM_MAX];
};
struct qvsp_strm_stats {
unsigned long first_ref;
uint32_t pkts;
uint32_t bytes;
uint32_t bytes_sent;
uint32_t pkts_sent;
};
struct qvsp_stats_if {
uint32_t strm_add;
uint32_t strm_none;
uint32_t pkt_chk;
uint32_t pkt_tcp;
uint32_t pkt_udp;
uint32_t pkt_other;
uint32_t pkt_ignore;
uint32_t pkt_sent;
uint32_t pkt_drop_throttle;
uint32_t pkt_drop_disabled;
uint32_t pkt_demoted;
uint32_t pkt_frag_found;
uint32_t pkt_frag_not_found;
};
struct qvsp_stats {
uint32_t is_qtm; /* 0: VSP or 1: QTM */
uint32_t strm_enable;
uint32_t strm_disable;
uint32_t strm_disable_remote;
uint32_t strm_reenable;
uint32_t fat_over;
uint32_t fat_under;
uint32_t fat_chk_disable;
uint32_t fat_chk_reenable;
uint32_t fat_chk_squeeze;
uint32_t fat_chk_loosen;
struct qvsp_stats_if stats_if[QVSP_IF_MAX];
};
struct qvsp_strm_info {
union qvsp_hash_flds hash_flds;
uint16_t node_idx;
uint8_t node_mac[6];
uint8_t vap_pri;
uint8_t tid;
uint16_t hairpin_id;
uint16_t hairpin_type;
uint8_t ip_version;
uint8_t ip_proto;
uint8_t ac_in;
uint8_t ac_out;
uint8_t strm_state;
uint8_t disable_remote;
uint8_t is_3rdpt_udp_us;
uint16_t last_ref_secs;
uint32_t ni_inv_phy_rate;
uint32_t phy_rate_disabled;
uint32_t bytes_max;
uint32_t ni_cost;
uint16_t cost_current;
uint16_t cost_max;
uint8_t hash;
uint8_t dir;
uint32_t throt_policy;
uint32_t throt_rate;
uint32_t demote_rule;
/* current state, might be different from demote_rule when recovering */
uint32_t demote_state;
struct qvsp_strm_stats prev_stats;
};
/** @}*/
#endif /* MUC_BUILD */
/*
* Convert kilobits (Kb) to bytes
*/
static __inline__ uint32_t
qvsp_kbit2b(uint32_t kbps)
{
return kbps * 1000 / NBBY;
}
/*
* Convert bytes to kilobits (Kb)
*/
static __inline__ uint32_t
qvsp_b2kbit(uint32_t bytes)
{
return bytes * NBBY / 1000;
}
/*
* Convert bytes over an interval into to kilobits per second
*/
static __inline__ uint32_t
qvsp_b2kbitps(uint32_t bytes, unsigned long interval)
{
/* bytes * NBBY / 1000 / 1000 * interval */
return bytes * NBBY / interval;
}
/*
* Convert bytes to megabits (Mb)
*/
static __inline__ uint32_t
qvsp_b2mbit(uint32_t bytes)
{
return bytes * NBBY / 1000000;
}
/*
* Convert inverse PHY rate to PHY rate
*/
static __inline__ uint32_t
qvsp_inv2phy(uint32_t inv_phy)
{
return 65536 / inv_phy;
}
/*
* Convert faked IP addr to Node/Tid.
* @ip is network/big endian.
*/
static __inline__ void
qvsp_fake_ip2nodetid(const uint32_t *ip, uint8_t *node, uint8_t *tid)
{
*node = ((uint8_t*)ip)[2];
*tid = ((uint8_t*)ip)[3];
}
#define QVSP_TID_FAKE_IP_VERSION 4
#define QVSP_TID_FAKE_IP_PROTO IPPROTO_UDP
/*
* Convert Node/Tid to faked IP addr
* Returned IP addr is network/big endian.
*/
static __inline__ void
qvsp_fake_nodetid2ip(uint32_t *ip, const uint8_t node, const uint8_t tid)
{
((uint8_t*)ip)[0] = 192;
((uint8_t*)ip)[1] = 168;
((uint8_t*)ip)[2] = node;
((uint8_t*)ip)[3] = tid;
}
#ifndef NIPQUAD_FMT
#define NIPQUAD_FMT "%d.%d.%d.%d"
#endif
#ifndef NIPQUAD_LEN
#define NIPQUAD_LEN 15
#endif
#ifndef NIPQUAD
#define NIPQUAD(addr) \
((unsigned char *)&addr)[0], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[3]
#endif
#define QVSP_CFG_SHOW_ANYSTR "Any"
#endif /* DOXYGEN_EXCLUDE */
#endif /* __QTN_QVSP_DATA_H__ */

View File

@ -0,0 +1,674 @@
/*SH1
*******************************************************************************
** **
** Copyright (c) 2010 Quantenna Communications Inc **
** All Rights Reserved **
** **
** Author : Quantenna Communications Inc **
** File : shared_params.h **
** Description : **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#ifndef _SHARED_DEFS_H_
#define _SHARED_DEFS_H_
#include "shared_defs_common.h"
#ifdef TOPAZ_PLATFORM
#define QTN_SWITCH_CHANNEL_TIME_AVG 3750 /* microseconds */
#else
#define QTN_SWITCH_CHANNEL_TIME_AVG 3500 /* microseconds */
#endif
#define IEEE80211_MAX_NAV 32767
/* SCS (ACI/CCI Detection and Mitigation) APIs */
enum qtn_vap_scs_cmds {
IEEE80211_SCS_SET_ENABLE = 1,
IEEE80211_SCS_SET_DEBUG_ENABLE,
IEEE80211_SCS_SET_SAMPLE_ENABLE,
IEEE80211_SCS_SET_SAMPLE_DWELL_TIME,
IEEE80211_SCS_SET_SAMPLE_INTERVAL,
IEEE80211_SCS_SET_THRSHLD_SMPL_PKTNUM,
IEEE80211_SCS_SET_THRSHLD_PRI_CCA,
IEEE80211_SCS_SET_THRSHLD_SEC_CCA,
IEEE80211_SCS_SET_THRSHLD_SMPL_AIRTIME,
IEEE80211_SCS_SET_WF_CCA,
IEEE80211_SCS_SET_WF_RSSI,
IEEE80211_SCS_SET_WF_CRC_ERR,
IEEE80211_SCS_SET_WF_LPRE,
IEEE80211_SCS_SET_WF_SPRE,
IEEE80211_SCS_SET_WF_RETRIES,
IEEE80211_SCS_SET_WF_DFS,
IEEE80211_SCS_SET_WF_MAX_TX_PWR,
IEEE80211_SCS_SET_REPORT_ONLY,
IEEE80211_SCS_SET_CCA_INTF_RATIO,
IEEE80211_SCS_SET_CCA_IDLE_THRSHLD,
IEEE80211_SCS_SET_CCA_INTF_LO_THR,
IEEE80211_SCS_SET_CCA_INTF_HI_THR,
IEEE80211_SCS_SET_CCA_SMPL_DUR,
IEEE80211_SCS_GET_REPORT,
IEEE80211_SCS_GET_INTERNAL_STATS,
IEEE80211_SCS_SET_CCA_INTF_SMTH_FCTR,
IEEE80211_SCS_RESET_RANKING_TABLE,
IEEE80211_SCS_SET_CHAN_MTRC_MRGN,
IEEE80211_SCS_SET_RSSI_SMTH_FCTR,
IEEE80211_SCS_SET_ATTEN_ADJUST,
IEEE80211_SCS_SET_THRSHLD_ATTEN_INC,
IEEE80211_SCS_SET_THRSHLD_DFS_REENTRY,
IEEE80211_SCS_SET_THRSHLD_DFS_REENTRY_MINRATE,
IEEE80211_SCS_SET_PMBL_ERR_SMTH_FCTR,
IEEE80211_SCS_SET_PMBL_ERR_RANGE,
IEEE80211_SCS_SET_PMBL_ERR_MAPPED_INTF_RANGE,
IEEE80211_SCS_SET_THRSHLD_LOAD,
IEEE80211_SCS_SET_PMBL_ERR_WF,
IEEE80211_SCS_SET_THRSHLD_AGING_NOR,
IEEE80211_SCS_SET_THRSHLD_AGING_DFSREENT,
IEEE80211_SCS_SET_THRSHLD_DFS_REENTRY_INTF,
IEEE80211_SCS_SET_PMP_RPT_CCA_SMTH_FCTR,
IEEE80211_SCS_SET_PMP_RX_TIME_SMTH_FCTR,
IEEE80211_SCS_SET_PMP_TX_TIME_SMTH_FCTR,
IEEE80211_SCS_SET_PMP_STATS_STABLE_PERCENT,
IEEE80211_SCS_SET_PMP_STATS_STABLE_RANGE,
IEEE80211_SCS_SET_PMP_STATS_CLEAR_INTERVAL,
IEEE80211_SCS_SET_PMP_TXTIME_COMPENSATION,
IEEE80211_SCS_SET_PMP_RXTIME_COMPENSATION,
IEEE80211_SCS_SET_PMP_TDLSTIME_COMPENSATION,
IEEE80211_SCS_SET_SWITCH_CHANNEL_MANUALLY,
IEEE80211_SCS_SET_AS_RX_TIME_SMTH_FCTR,
IEEE80211_SCS_SET_AS_TX_TIME_SMTH_FCTR,
IEEE80211_SCS_SET_STATS_START,
IEEE80211_SCS_SET_CCA_IDLE_SMTH_FCTR,
IEEE80211_SCS_SET_PMBL_ERR_THRSHLD,
IEEE80211_SCS_SET_CCA_INTF_DFS_MARGIN,
IEEE80211_SCS_SET_MAX
};
#define IEEE80211_SCS_STATE_INIT 0
#define IEEE80211_SCS_STATE_RESET 1
#define IEEE80211_SCS_STATE_CHANNEL_SWITCHING 2
#define IEEE80211_SCS_STATE_MEASUREMENT_CHANGE_CLEAN 3 /* param change */
#define IEEE80211_SCS_STATE_PERIOD_CLEAN 4
#define IEEE80211_SCS_COMPARE_INIT_TIMER 5
#define IEEE80211_SCS_COMPARE_TIMER_INTVAL 2
#define IEEE80211_CCA_SAMPLE_DUR IEEE80211_SCS_COMPARE_TIMER_INTVAL /* seconds */
#define IEEE80211_SCS_CHAN_CURRENT 0
#define IEEE80211_SCS_CHAN_ALL 0xFF
#define IEEE80211_SCS_THRSHLD_MAX 100 /* metric */
#define IEEE80211_SCS_THRSHLD_MIN 1 /* metric */
#define IEEE80211_SCS_SMPL_DWELL_TIME_MAX 24 /* milliseconds, limited by max NAV reservation */
#define IEEE80211_SCS_SMPL_DWELL_TIME_MIN 5 /* milliseconds */
#define IEEE80211_SCS_SMPL_DWELL_TIME_DEFAULT 10 /* milliseconds */
#define IEEE80211_SCS_SMPL_INTV_MAX 3600 /* seconds */
#define IEEE80211_SCS_SMPL_INTV_MIN 1 /* seconds */
#define IEEE80211_SCS_SMPL_INTV_DEFAULT 5 /* seconds */
#define IEEE80211_SCS_THRSHLD_SMPL_PKTNUM_DEFAULT 16 /* packet number */
#define IEEE80211_SCS_THRSHLD_SMPL_PKTNUM_MAX 1000 /* packet number */
#define IEEE80211_SCS_THRSHLD_SMPL_PKTNUM_MIN 1 /* packet number */
#ifdef TOPAZ_PLATFORM
#define IEEE80211_SCS_THRSHLD_SMPL_AIRTIME_DEFAULT 200 /* ms */
#else
#define IEEE80211_SCS_THRSHLD_SMPL_AIRTIME_DEFAULT 300 /* ms */
#endif
#define IEEE80211_SCS_THRSHLD_SMPL_AIRTIME_MAX 1000 /* ms */
#define IEEE80211_SCS_THRSHLD_SMPL_AIRTIME_MIN 1 /* ms */
#define IEEE80211_SCS_THRSHLD_PMBL_ERR_MAX 10000 /* count */
#define IEEE80211_SCS_THRSHLD_PMBL_ERR_MIN 1 /* count */
/*
* Packet rate threshold is determined by how many packets we can hold in buffer without drop
* during off-channel period. It is limited by:
* - sw queue length of each node/tid
* - global resource shared by all node/tid, such as tqew descriptors and msdu headers.
* Current value doesn't apply to the scenario when tqew descriptors are already used up by large
* number of stations.
*/
#define IEEE80211_SCS_THRSHLD_SMPL_TX_PKTRATE (1024 - 128) /* margin = 128 + hw ring size */
#define IEEE80211_SCS_THRSHLD_SMPL_RX_PKTRATE IEEE80211_SCS_THRSHLD_SMPL_TX_PKTRATE /* assume qtn peer */
#define IEEE80211_SCS_THRSHLD_ATTEN_INC_DFT 5 /* db */
#define IEEE80211_SCS_THRSHLD_ATTEN_INC_MIN 0 /* db */
#define IEEE80211_SCS_THRSHLD_ATTEN_INC_MAX 20 /* db */
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_DFT 60 /* seconds */
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_MIN 0 /* seconds */
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_MAX 0xffff /* seconds */
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_INTF_MIN 0
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_INTF_MAX 100
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_INTF_DFT 40
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_MINRATE_UNIT 100 /* kbps */
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_MINRATE_DFT 5 /* unit: 100kbps */
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_MINRATE_MIN 0 /* unit: 100kbps */
#define IEEE80211_SCS_THRSHLD_DFS_REENTRY_MINRATE_MAX 0xffff /* unit: 100kbps */
#define IEEE80211_SCS_THRSHLD_AGING_MIN 0
#define IEEE80211_SCS_THRSHLD_AGING_MAX 0xFFFF
#define IEEE80211_SCS_THRSHLD_AGING_NOR_DFT (60 * 6)
#define IEEE80211_SCS_THRSHLD_AGING_DFSREENT_DFT 5
#define IEEE80211_SCS_CCA_DUR_MAX 10 /* seconds */
#define IEEE80211_SCS_CCA_DUR_MIN 2 /* seconds */
#define IEEE80211_SCS_CCA_INTF_SCALE 1000 /* milliseconds */
#define IEEE80211_SCS_SENDING_QOSNULL_TIME_AVG 1000 /* microseconds */
#define IEEE80211_SCS_SMPL_TIME_MARGIN 2000 /* microseconds */
#define IEEE80211_SCS_SMPL_TIME_OFFSET_SEND_QOSNULL 5000 /* microseconds */
#define IEEE80211_SCS_SMPL_TIME_SENDING_ALL_BEACONS 25000 /* microseconds, the time duration for transmitting all beacons */
#define IEEE80211_CCA_INTF_SMTH_FCTR_NOXP_DFT 75
#define IEEE80211_CCA_INTF_SMTH_FCTR_XPED_DFT 90
#define IEEE80211_CCA_INTF_SMTH_FCTR_MIN 0
#define IEEE80211_CCA_INTF_SMTH_FCTR_MAX 100
#define IEEE80211_SCS_CHAN_MTRC_MRGN_MAX 100
#define IEEE80211_SCS_CHAN_MTRC_MRGN_DFT 5
#define IEEE80211_SCS_RSSI_SMTH_FCTR_UP_DFT 75
#define IEEE80211_SCS_RSSI_SMTH_FCTR_DOWN_DFT 25
#define IEEE80211_SCS_RSSI_SMTH_FCTR_MAX 100
#define IEEE80211_SCS_ATTEN_ADJUST_MIN -20
#define IEEE80211_SCS_ATTEN_ADJUST_MAX 20
#define IEEE80211_SCS_ATTEN_ADJUST_DFT 5
#define IEEE80211_SCS_BRCM_RXGLITCH_THRSHLD_SCALE_DFT 40
#define IEEE80211_SCS_PMBL_ERR_SMTH_FCTR_MIN 0
#define IEEE80211_SCS_PMBL_ERR_SMTH_FCTR_MAX 100
#define IEEE80211_SCS_PMBL_ERR_SMTH_FCTR_DFT 66
#define IEEE80211_SCS_CCA_IDLE_SMTH_FCTR_MIN 0
#define IEEE80211_SCS_CCA_IDLE_SMTH_FCTR_MAX 100
#define IEEE80211_SCS_CCA_IDLE_SMTH_FCTR_DFT 50
#define IEEE80211_SCS_PMP_RPT_CCA_SMTH_FCTR_MAX 100
#define IEEE80211_SCS_PMP_RPT_CCA_SMTH_FCTR_DFT 66
#define IEEE80211_SCS_PMP_RX_TIME_SMTH_FCTR_MAX 100
#define IEEE80211_SCS_PMP_RX_TIME_SMTH_FCTR_DFT 66
#define IEEE80211_SCS_PMP_TX_TIME_SMTH_FCTR_MAX 100
#define IEEE80211_SCS_PMP_TX_TIME_SMTH_FCTR_DFT 66
#define IEEE80211_SCS_PMP_STATS_STABLE_PERCENT_MAX 100
#define IEEE80211_SCS_PMP_STATS_STABLE_PERCENT_DFT 30
#define IEEE80211_SCS_PMP_STATS_STABLE_RANGE_MAX 1000
#define IEEE80211_SCS_PMP_STATS_STABLE_RANGE_DFT 50
#define IEEE80211_SCS_PMP_STATS_CLEAR_INTERVAL_MAX 3600 /* seconds */
#define IEEE80211_SCS_PMP_STATS_CLEAR_INTERVAL_DFT 60 /* seconds */
#define IEEE80211_SCS_AS_RX_TIME_SMTH_FCTR_MAX 100
#define IEEE80211_SCS_AS_RX_TIME_SMTH_FCTR_DFT 50
#define IEEE80211_SCS_AS_TX_TIME_SMTH_FCTR_MAX 100
#define IEEE80211_SCS_AS_TX_TIME_SMTH_FCTR_DFT 50
#define IEEE80211_SCS_SMTH_RBS_TIME 80
#define IEEE80211_SCS_PMBL_ERR_RANGE_MIN 1000
#define IEEE80211_SCS_PMBL_ERR_RANGE_MAX 0xFFFF
#define IEEE80211_SCS_PMBL_ERR_RANGE_DFT 5000
#define IEEE80211_SCS_PMBL_ERR_MAPPED_INTF_RANGE_MIN 0
#define IEEE80211_SCS_PMBL_ERR_MAPPED_INTF_RANGE_MAX 100
#define IEEE80211_SCS_PMBL_ERR_MAPPED_INTF_RANGE_DFT 40
#define IEEE80211_SCS_PMBL_ERR_WF_MIN 0
#define IEEE80211_SCS_PMBL_ERR_WF_MAX 100
#define IEEE80211_SCS_PMBL_SHORT_WF_DFT 0
#define IEEE80211_SCS_PMBL_LONG_WF_DFT 100
#define IEEE80211_SCS_THRSHLD_LOADED_MIN 0
#define IEEE80211_SCS_THRSHLD_LOADED_MAX 1000
#define IEEE80211_SCS_THRSHLD_LOADED_DFT 20
#define IEEE80211_SCS_CHAN_POWER_CUTPOINT 15
#define IEEE80211_SCS_NORMALIZE(_v, _duration) (((_v) < (0xFFFFFFFF / IEEE80211_SCS_CCA_INTF_SCALE)) ? \
((_v) * IEEE80211_SCS_CCA_INTF_SCALE / (_duration)) : \
((_v) / (_duration) * IEEE80211_SCS_CCA_INTF_SCALE))
#define IEEE80211_SCS_SMOOTH(_old, _new, _fctr) (((_old) * (_fctr) + (_new) * (100 - (_fctr))) / 100)
#define IEEE80211_SCS_OFFCHAN_WHOLE_DUR(_dwell_us) ((_dwell_us) + \
(2 * QTN_SWITCH_CHANNEL_TIME_AVG) + \
IEEE80211_SCS_SENDING_QOSNULL_TIME_AVG + \
IEEE80211_SCS_SMPL_TIME_MARGIN)
#define IEEE80211_SCS_VALUE_S 0
#define IEEE80211_SCS_VALUE_M 0xffff
#define IEEE80211_SCS_WF_VALUE_M 0xff
#define IEEE80211_SCS_COMMAND_S 16
#define IEEE80211_SCS_COMMAND_M 0xffff
#define IEEE80211_SCS_STA_CCA_REQ_CC 0x1
#define IEEE80211_SCS_SELF_CCA_CC 0x2
#define IEEE80211_SCS_ATTEN_INC_CC 0x4
#define IEEE80211_SCS_BRCM_STA_TRIGGER_CC 0x8
#define IEEE80211_SCS_CCA_INTF_CC (IEEE80211_SCS_STA_CCA_REQ_CC | IEEE80211_SCS_SELF_CCA_CC)
#define IEEE80211_SCS_INTF_CC (IEEE80211_SCS_CCA_INTF_CC | IEEE80211_SCS_BRCM_STA_TRIGGER_CC)
#define IEEE80211_REMAIN_CHAN_MIN_RSV_PERD 2
enum ieee80211_scs_update_mode {
IEEE80211_SCS_OFFCHAN, /* off-channel, use smoothing and omit current channel */
IEEE80211_SCS_COCHAN, /* co-channel mode */
IEEE80211_SCS_INIT_SCAN, /* like off-channel but include current channel */
};
#define SCSLOG_CRIT 0
#define SCSLOG_NOTICE 1
#define SCSLOG_INFO 2
#define SCSLOG_VERBOSE 3
#define SCSLOG_LEVEL_MAX 3
#if !defined(MUC_BUILD) && !defined(DSP_BUILD) && !defined(AUC_BUILD)
#define SCSDBG(_level, _fmt, ...) do { \
if (ic->ic_scs.scs_debug_enable >= (_level)) { \
DBGFN("SCS: " _fmt, ##__VA_ARGS__); \
} \
} while (0)
#endif
/* OCAC (Off-channel CAC) APIs */
enum qtn_ocac_cmds {
IEEE80211_OCAC_SET_ENABLE = 1,
IEEE80211_OCAC_SET_DISABLE,
IEEE80211_OCAC_SET_DEBUG_LEVEL,
IEEE80211_OCAC_SET_DWELL_TIME,
IEEE80211_OCAC_SET_DURATION,
IEEE80211_OCAC_SET_THRESHOLD_FAT,
IEEE80211_OCAC_SET_DUMP_COUNTS,
IEEE80211_OCAC_SET_CAC_TIME,
IEEE80211_OCAC_SET_THRESHOLD_TRAFFIC,
IEEE80211_OCAC_SET_TIMER_INTERVAL,
IEEE80211_OCAC_SET_DUMP_TSFLOG,
IEEE80211_OCAC_SET_DUMP_CFG,
IEEE80211_OCAC_SET_TRAFFIC_CONTROL,
IEEE80211_OCAC_SET_THRESHOLD_CCA_INTF,
IEEE80211_OCAC_SET_REPORT_ONLY,
IEEE80211_OCAC_SET_DUMP_CCA_COUNTS,
IEEE80211_OCAC_SET_OFFSET_TXHALT,
IEEE80211_OCAC_SET_OFFSET_OFFCHAN,
IEEE80211_OCAC_SET_THRESHOLD_FAT_DEC,
IEEE80211_OCAC_SET_TIMER_EXPIRE_INIT,
IEEE80211_OCAC_SET_SECURE_DWELL_TIME,
IEEE80211_OCAC_SET_BEACON_INTERVAL,
IEEE80211_OCAC_SET_WEATHER_DURATION,
IEEE80211_OCAC_SET_WEATHER_CAC_TIME,
IEEE80211_OCAC_SET_MAX
};
enum qtn_ocac_get_cmds {
IEEE80211_OCAC_GET_STATUS = 1,
IEEE80211_OCAC_GET_AVAILABILITY,
};
#define IEEE80211_OCAC_CLEAN_STATS_STOP 0
#define IEEE80211_OCAC_CLEAN_STATS_START 1
#define IEEE80211_OCAC_CLEAN_STATS_RESET 2
#define IEEE80211_OCAC_DWELL_TIME_MIN 5 /* milliseconds */
#define IEEE80211_OCAC_DWELL_TIME_MAX 200 /* milliseconds */
#define IEEE80211_OCAC_DWELL_TIME_DEFAULT 50 /* milliseconds */
#define IEEE80211_OCAC_SECURE_DWELL_TIME_MIN 5 /* milliseconds */
#define IEEE80211_OCAC_SECURE_DWELL_TIME_MAX 23 /* milliseconds */
#define IEEE80211_OCAC_SECURE_DWELL_TIME_DEFAULT 23 /* milliseconds */
#define IEEE80211_OCAC_DURATION_MIN 1 /* seconds */
#define IEEE80211_OCAC_DURATION_MAX 64800 /* seconds */
#define IEEE80211_OCAC_DURATION_DEFAULT 360 /* seconds */
#define IEEE80211_OCAC_CAC_TIME_MIN 1 /* seconds */
#define IEEE80211_OCAC_CAC_TIME_MAX 64800 /* seconds */
#define IEEE80211_OCAC_CAC_TIME_DEFAULT 145 /* seconds */
#define IEEE80211_OCAC_WEA_DURATION_MIN 60 /* seconds */
#define IEEE80211_OCAC_WEA_DURATION_MAX 86400 /* seconds */
#define IEEE80211_OCAC_WEA_CAC_TIME_MIN 1 /* seconds */
#define IEEE80211_OCAC_WEA_CAC_TIME_MAX 86400 /* seconds */
#define IEEE80211_OCAC_THRESHOLD_FAT_MIN 1 /* percent */
#define IEEE80211_OCAC_THRESHOLD_FAT_MAX 100 /* percent */
#define IEEE80211_OCAC_THRESHOLD_FAT_DEFAULT 65 /* percent */
#define IEEE80211_OCAC_THRESHOLD_TRAFFIC_MIN 1 /* percent */
#define IEEE80211_OCAC_THRESHOLD_TRAFFIC_MAX 100 /* percent */
#define IEEE80211_OCAC_THRESHOLD_TRAFFIC_DEFAULT 35 /* percent */
#define IEEE80211_OCAC_OFFSET_TXHALT_MIN 2 /* milliseconds */
#define IEEE80211_OCAC_OFFSET_TXHALT_MAX 80 /* milliseconds */
#define IEEE80211_OCAC_OFFSET_TXHALT_DEFAULT 10 /* milliseconds */
#define IEEE80211_OCAC_OFFSET_OFFCHAN_MIN 2 /* milliseconds */
#define IEEE80211_OCAC_OFFSET_OFFCHAN_MAX 80 /* milliseconds */
#define IEEE80211_OCAC_OFFSET_OFFCHAN_DEFAULT 5 /* milliseconds */
#define IEEE80211_OCAC_TRAFFIC_CTRL_DEFAULT 1 /* on */
#define IEEE80211_OCAC_THRESHOLD_CCA_INTF_MIN 1 /* percent */
#define IEEE80211_OCAC_THRESHOLD_CCA_INTF_MAX 100 /* percent */
#define IEEE80211_OCAC_THRESHOLD_CCA_INTF_DEFAULT 20 /* percent */
#define IEEE80211_OCAC_THRESHOLD_FAT_DEC_MIN 1 /* percent */
#define IEEE80211_OCAC_THRESHOLD_FAT_DEC_MAX 100 /* percent */
#define IEEE80211_OCAC_THRESHOLD_FAT_DEC_DEFAULT 10 /* percent */
#define IEEE80211_OCAC_TIMER_INTERVAL_MIN 1 /* seconds */
#define IEEE80211_OCAC_TIMER_INTERVAL_MAX 100 /* seconds */
#define IEEE80211_OCAC_TIMER_INTERVAL_DEFAULT 2 /* seconds */
#define IEEE80211_OCAC_BEACON_INTERVAL_MIN 100 /* TUs */
#define IEEE80211_OCAC_BEACON_INTERVAL_MAX 1000 /* TUs */
#define IEEE80211_OCAC_BEACON_INTERVAL_DEFAULT 100 /* TUs */
#define IEEE80211_OCAC_TIMER_EXPIRE_INIT_MIN 1 /* seconds */
#define IEEE80211_OCAC_TIMER_EXPIRE_INIT_MAX 65000 /* seconds */
#define IEEE80211_OCAC_TIMER_EXPIRE_INIT_DEFAULT 2 /* seconds */
#define IEEE80211_OCAC_VALUE_S 0
#define IEEE80211_OCAC_VALUE_M 0xffff
#define IEEE80211_OCAC_COMMAND_S 16
#define IEEE80211_OCAC_COMMAND_M 0xffff
#define IEEE80211_OCAC_COMPRESS_VALUE_F 0x8000
#define IEEE80211_OCAC_COMPRESS_VALUE_M 0x7fff
#define IEEE80211_OCAC_TIME_MARGIN 2000 /* microseconds */
#define OCACLOG_CRIT 0
#define OCACLOG_WARNING 1
#define OCACLOG_NOTICE 2
#define OCACLOG_INFO 3
#define OCACLOG_VERBOSE 4
#define OCACLOG_LEVEL_MAX 4
#if !defined(MUC_BUILD) && !defined(DSP_BUILD) && !defined(AUC_BUILD)
#define OCACDBG(_level, _fmt, ...) do { \
if (ic->ic_ocac.ocac_cfg.ocac_debug_level >= (_level)) { \
DBGFN("DFS_s_radio: " _fmt, ##__VA_ARGS__); \
} \
} while (0)
#endif
#define QTN_M2A_EVENT_TYPE_DTIM 1
#define QTN_M2A_PS_EVENT_PM_ENABLE 2 /* enable power management */
#define QTN_M2A_PS_EVENT_PM_DISABLE 3 /* disable power management */
#define QTN_M2A_PS_EVENT_PS_POLL 4 /* ps poll */
#define QTN_M2A_EVENT_TYPE_UAPSD_SP 5 /* U-APSD SP */
#define QTN_M2A_EVENT_PTID_FLAG_SET 6 /* Set per-TID flag(muc) */
/* Common definitions for flags used to indicate ieee80211_node's states */
#define IEEE80211_NODE_AUTH 0x0001 /* authorized for data */
#define IEEE80211_NODE_QOS 0x0002 /* QoS enabled */
#define IEEE80211_NODE_ERP 0x0004 /* ERP enabled */
#define IEEE80211_NODE_HT 0x0008 /* HT enabled */
/* NB: this must have the same value as IEEE80211_FC1_PWR_MGT */
#define IEEE80211_NODE_PWR_MGT 0x0010 /* power save mode enabled */
#define IEEE80211_NODE_PS_DELIVERING 0x0040 /* STA out of PS, getting delivery */
#define IEEE80211_NODE_PS_POLL 0x0080 /* power save ps poll mode */
#define IEEE80211_NODE_AREF 0x0020 /* authentication ref held */
#define IEEE80211_NODE_2_TX_CHAINS 0x0400 /* this node needs to use 2 TX chain only, for IOT purpose */
#define IEEE80211_NODE_UAPSD 0x1000
#define IEEE80211_NODE_WDS_PEER 0x2000 /* this node is the wds peer in a wds vap */
#define IEEE80211_NODE_VHT 0x4000 /* VHT enabled */
#define IEEE80211_NODE_TPC 0x8000 /* indicate tpc capability */
/* Common definitions for ext_flags */
#define IEEE80211_NODE_TDLS_PTI_REQ 0x0001 /* Should sending PTI request to peer */
#define IEEE80211_NODE_TDLS_PTI_PENDING 0x0002 /* PTI request xmit to peer but not responsed */
#define IEEE80211_NODE_UAPSD_SP_IN_PROGRESS 0x0004 /* U-APSD SP in progress */
#define IEEE80211_NODE_TDLS_PTI_RESP 0x0008 /* PTI response frame received */
#define IEEE80211_NODE_TDLS_MASK 0x000B /* Mask for TDLS bits */
#define QTN_VAP_PRIORITY_RESERVED 2 /* reserve the low values for internal use */
#define QTN_VAP_PRIORITY_NUM 4
#define QTN_VAP_PRIORITY_MGMT (QTN_VAP_PRIORITY_RESERVED + QTN_VAP_PRIORITY_NUM)
#define QTN_TACMAP_HW_PRI_NUM 8 /* hw limitation for 128 node mode */
#define QTN_TACMAP_PRI_PER_VAP 8 /* for maximum 8 TIDs */
#define QTN_TACMAP_SW_PRI_BASE 64 /* values below this are used for "bad apple" nodes */
/* Quantenna specific flags (ni_qtn_flags), do not modify in Auc */
#define QTN_IS_BCM_NODE 0x0000001
#define QTN_IS_IPAD_NODE 0x0000002
#define QTN_IS_IPHONE5_NODE 0x0000004
#define QTN_IS_IPAD3_NODE 0x0000008
#define QTN_IS_INTEL_5100_NODE 0x0000010
#define QTN_IS_INTEL_5300_NODE 0x0000020
#define QTN_IS_SAMSUNG_GALAXY_NODE 0x0000040
#define QTN_IS_NOT_4ADDR_CAPABLE_NODE 0x0000080
#define QTN_AC_BE_INHERITANCE_UPTO_VO 0x0000100
#define QTN_AC_BE_INHERITANCE_UPTO_VI 0x0000200
#define QTN_IS_INTEL_NODE 0x0000400
#define QTN_IS_IPAD_AIR_NODE 0x0000800
#define QTN_IS_IPAD4_NODE 0x0001000
#define QTN_IS_REALTEK_NODE 0x0004000
#define QTN_NODE_TX_RESTRICTED 0x0008000 /* restricted tx enabled */
#define QTN_NODE_TX_RESTRICT_RTS 0x0010000 /* use RTS to confirm node is lost */
#define QTN_IS_NO_RXAMSDU_NO_BF_NODE 0x0020000
#define QTN_NODE_RXAMSDU_SUPPORT 0x0040000 /* node support TX amsdu */
#define QTN_NODE_11N_TXAMSDU_OFF 0x0080000
#define QTN_NODE_TXOP_RESTRICTED 0x0100000
/*
* Bits that can be updated again by Lhost after association creation. Explicit definition helps
* avoid overwriting bits maintained by MuC itself.
*/
#define QTN_FLAGS_UPDATABLE_BITS (QTN_IS_INTEL_NODE)
/* QTN bandwidth definition */
#define QTN_BW_20M 0
#define QTN_BW_40M 1
#define QTN_BW_80M 2
#define QTN_BW_MAX QTN_BW_80M
#define QTN_MAILBOX_INVALID 0xffffffff /* Invalid value to indicate mailbox is disabled */
enum ni_tdls_status {
IEEE80211_TDLS_NODE_STATUS_NONE = 0,
IEEE80211_TDLS_NODE_STATUS_INACTIVE = 1,
IEEE80211_TDLS_NODE_STATUS_STARTING = 2,
IEEE80211_TDLS_NODE_STATUS_ACTIVE = 3,
IEEE80211_TDLS_NODE_STATUS_IDLE = 4
};
/* WoWLAN APIs */
enum qtn_vap_wowlan_cmds {
IEEE80211_WOWLAN_HOST_POWER_SAVE = 1,
IEEE80211_WOWLAN_MATCH_TYPE,
IEEE80211_WOWLAN_L2_ETHER_TYPE,
IEEE80211_WOWLAN_L3_UDP_PORT,
IEEE80211_WOWLAN_MAGIC_PATTERN,
IEEE80211_WOWLAN_MAGIC_PATTERN_GET,
IEEE80211_WOWLAN_SET_MAX
};
/*
* Definitions relating to individual fields from phy_stats,
* shared between the Q driver and the APIs.
*/
/*
* Error Sum needs to be reported together with the corresponding Number of
* Symbols; getting them in separate operations would introduce a race condition
* where the Error Sum and the Number of Symbols came from different
* PHY stat blocks.
*/
#define QTN_PHY_AVG_ERROR_SUM_NSYM_NAME "avg_error_sum_nsym"
#define QTN_PHY_EVM_MANTISSA_SHIFT 5
#define QTN_PHY_EVM_EXPONENT_MASK 0x1f
enum qtn_phy_stat_field {
QTN_PHY_NOSUCH_FIELD = -1,
QTN_PHY_AVG_ERROR_SUM_NSYM_FIELD,
};
#define QTN_M2A_TX_SCALE_BITS 4
#define QTN_M2A_TX_SCALE_MASK ((1 << QTN_M2A_TX_SCALE_BITS) - 1)
/* only for little endian */
#if defined(AUC_BUILD)
#define U64_LOW32(_v) ((uint32_t)(_v))
#define U64_HIGH32(_v) ((uint32_t)((_v) >> 32))
#else
#define U64_LOW32(_v) (((uint32_t*)&(_v))[0])
#define U64_HIGH32(_v) (((uint32_t*)&(_v))[1])
#endif
#define U64_COMPARE_GE(_a, _b) ((U64_HIGH32(_a) > U64_HIGH32(_b)) || \
((U64_HIGH32(_a) == U64_HIGH32(_b)) && (U64_LOW32(_a) >= U64_LOW32(_b))))
#define U64_COMPARE_GT(_a, _b) ((U64_HIGH32(_a) > U64_HIGH32(_b)) || \
((U64_HIGH32(_a) == U64_HIGH32(_b)) && (U64_LOW32(_a) > U64_LOW32(_b))))
#define U64_COMPARE_LE(_a, _b) ((U64_HIGH32(_a) < U64_HIGH32(_b)) || \
((U64_HIGH32(_a) == U64_HIGH32(_b)) && (U64_LOW32(_a) <= U64_LOW32(_b))))
#define U64_COMPARE_LT(_a, _b) ((U64_HIGH32(_a) < U64_HIGH32(_b)) || \
((U64_HIGH32(_a) == U64_HIGH32(_b)) && (U64_LOW32(_a) < U64_LOW32(_b))))
#ifndef MAC2STR
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X"
#define MACSTRL "%02x:%02x:%02x:%02x:%02x:%02x" /* for MuC and Auc which don't support "X" */
#endif
/*
* VSP/QTM
* Macro TOPAZ_QTM is used to help identify changes between original VSP and QTM.
* In Lhost kernel driver, it must be used within CONFIG_QVSP(in kernel .config).
* CONFIG_QVSP TOPAZ_QTM ruby topaz
* Y 1 invalid *QTM works
* Y 0 *VSP works VSP alive but doesn't work for HDP
* N 1 invalid *no VSP/QTM
* N 0 *no VSP no VSP/QTM, and no QTM changes in MuC and AuC
* So generally, sololy changing CONFIG_QVSP works for both ruby and topaz as indicated by *.
* But to throughly clean QTM code in AuC and MuC, disable TOPAZ_QTM in topaz below.
*/
#ifdef TOPAZ_PLATFORM
#define TOPAZ_QTM 1
#else
#define TOPAZ_QTM 0
#endif
#define COMPILE_TIME_ASSERT(constant_expr) \
do { \
switch(0) { \
case 0: \
case constant_expr: \
; \
} \
} while(0)
/**@addtogroup DFSAPIs
*@{*/
/**
* Reason for channel change
*/
enum ieee80211_csw_reason {
/**
* Reason is unknown
*/
IEEE80211_CSW_REASON_UNKNOWN,
/**
* Smart channel selection
*/
IEEE80211_CSW_REASON_SCS,
/**
* Radar detection
*/
IEEE80211_CSW_REASON_DFS,
/**
* Channel set by user
*/
IEEE80211_CSW_REASON_MANUAL,
/**
* Configuration change
*/
IEEE80211_CSW_REASON_CONFIG,
/**
* Scan initiated by user
*/
IEEE80211_CSW_REASON_SCAN,
/**
* Off-channel CAC
*/
IEEE80211_CSW_REASON_OCAC,
/**
* Channel switch announcement
*/
IEEE80211_CSW_REASON_CSA,
/**
* TDLS Channel switch announcement
*/
IEEE80211_CSW_REASON_TDLS_CS,
/**
* Number of values
*/
IEEE80211_CSW_REASON_MAX
};
/**@}*/
/*
* Reasons for channel switches that are not recorded and therefore
* should not be listed in QCSAPI documentation
*/
enum ieee80211_csw_reason_private {
IEEE80211_CSW_REASON_SAMPLING = IEEE80211_CSW_REASON_MAX,
IEEE80211_CSW_REASON_OCAC_RUN,
IEEE80211_CSW_REASON_BGSCAN,
};
/* Keep this in sync with swfeat_desc */
enum swfeat {
SWFEAT_ID_MODE_AP,
SWFEAT_ID_MODE_STA,
SWFEAT_ID_MODE_REPEATER,
SWFEAT_ID_PCIE_RC,
SWFEAT_ID_VHT,
SWFEAT_ID_2X2,
SWFEAT_ID_2X4,
SWFEAT_ID_4X4,
SWFEAT_ID_HS20,
SWFEAT_ID_WPA2_ENT,
SWFEAT_ID_MESH,
SWFEAT_ID_TDLS,
SWFEAT_ID_OCAC,
SWFEAT_ID_QHOP,
SWFEAT_ID_QSV,
SWFEAT_ID_QSV_NEIGH,
SWFEAT_ID_MU_MIMO,
SWFEAT_ID_DUAL_CHAN_VIRT,
SWFEAT_ID_DUAL_CHAN,
SWFEAT_ID_DUAL_BAND_VIRT,
SWFEAT_ID_DUAL_BAND,
SWFEAT_ID_QTM_PRIO,
SWFEAT_ID_QTM,
SWFEAT_ID_SPEC_ANALYZER,
SWFEAT_ID_MAX
};
#define SWFEAT_MAP_SIZE (SWFEAT_ID_MAX / 8 + 1)
/* Used to scale temperature measurements */
#define QDRV_TEMPSENS_COEFF 100000
#define QDRV_TEMPSENS_COEFF10 (10 * QDRV_TEMPSENS_COEFF)
#endif /* _SHARED_DEFS_H_ */

View File

@ -0,0 +1,149 @@
/*SH1
*******************************************************************************
** **
** Copyright (c) 2014 Quantenna Communications Inc **
** All Rights Reserved **
** **
** Author : Quantenna Communications Inc **
** File : shared_defs.h **
** Description : **
** **
*******************************************************************************
** **
** Redistribution and use in source and binary forms, with or without **
** modification, are permitted provided that the following conditions **
** are met: **
** 1. Redistributions of source code must retain the above copyright **
** notice, this list of conditions and the following disclaimer. **
** 2. Redistributions in binary form must reproduce the above copyright **
** notice, this list of conditions and the following disclaimer in the **
** documentation and/or other materials provided with the distribution. **
** 3. The name of the author may not be used to endorse or promote products **
** derived from this software without specific prior written permission. **
** **
** Alternatively, this software may be distributed under the terms of the **
** GNU General Public License ("GPL") version 2, or (at your option) any **
** later version as published by the Free Software Foundation. **
** **
** In the case this software is distributed under the GPL license, **
** you should have received a copy of the GNU General Public License **
** along with this software; if not, write to the Free Software **
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **
** **
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR **
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES**
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. **
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, **
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT **
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,**
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY **
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT **
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF **
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **
** **
*******************************************************************************
EH1*/
#ifndef _SHARED_DEFS_COMMON_H_
#define _SHARED_DEFS_COMMON_H_
/*
* Default board type is 0 to match the default (fallback) from get_bootval.
* Script returns 0 if the parameter is not defined.
*/
#define QTN_RUBY_BOARD_TYPE_DEFAULT 0
#define QTN_RUBY_BRINGUP_BOARD 0
#define QTN_RUBY_BRINGUP_BOARD_32_320 1
#define QTN_RUBY_BRINGUP_BOARD_16_320 2
#define QTN_RUBY_BRINGUP_BOARD_16_160 3
#define QTN_RUBY_BRINGUP_BOARD_ETRON 4
#define QTN_RUBY_BRINGUP_BOARD_ETRON_320 5
#define QTN_RUBY_BRINGUP_BOARD_ETRON_160 6
#define QTN_RUBY_BRINGUP_BOARD_16_200 7
#define QTN_RUBY_BRINGUP_BOARD_32_200 8
#define QTN_RUBY_BRINGUP_BOARD_PCIE 9
/* diag board ids */
#define QTN_RUBY_BRINGUP_BOARD_32_160_ARB 10
#define QTN_RUBY_BRINGUP_BOARD_32_160_ARB_1 11
#define QTN_RUBY_BRINGUP_BOARD_16_160_ARB_1 12
#define QTN_RUBY_BRINGUP_BOARD_32_160_ARB_0 13
#define QTN_RUBY_BRINGUP_BOARD_ETRON_160_EMAC1 14
#define QTN_RUBY_BRINGUP_BOARD_ETRON_250_EMAC1 15
#define QTN_RUBY_BRINGUP_BOARD_ETRON_32_320_EMAC1 16
#define QTN_RUBY_BRINGUP_ETRON32_160 17
#define QTN_RUBY_BRINGUP_ETRON32_320 18
#define QTN_RUBY_BRINGUP_BOARD_MICRON_DUALEMAC 19
#define QTN_RUBY_BRINGUP_BOARD_MICRON_DUALEMAC_MII 20
#define QTN_RUBY_BRINGUP_BOARD_MICRON_DUALEMAC_LOOPBACK 21
#define QTN_RUBY_BRINGUP_BOARD_16_160_DUALEMAC 22
#define QTN_RUBY_REFERENCE_DESIGN_BOARD 1000
#define QTN_RUBY_REFERENCE_DESIGN_BOARD_250 1001
#define QTN_RUBY_REF_BOARD_DUAL_CON 1002
#define QTN_RUBY_REFERENCE_DESIGN_BOARD_320 1003
#define QTN_RUBY_ETRON_32_320_EMAC1 1004
#define QTN_RUBY_ETRON_32_250_EMAC1 1005
#define QTN_RUBY_REFERENCE_DESIGN_BOARD_RGMII_DLL 1006
#define QTN_RUBY_QHS710_5S5_SIGE_DDR250 1007
#define QTN_RUBY_QHS710_5S5_SIGE_DDR320 1008
#define QTN_RUBY_OHS711_PCIE_320DDR 1009
/* pcie reference ids */
#define QTN_RUBY_QHS713_5S1_PCIERC_DDR160 1170
#define QTN_RUBY_OHS711_5S13_PCIE_DDR320 1171 /* duplicate of 1009 */
#define QTN_RUBY_QHS713_5S1_PCIERC_DDR320 1172
#define QTN_RUBY_ODM_BOARD_0 1200
#define QTN_RUBY_ODM_BOARD_1 1201
#define QTN_RUBY_ODM_BOARD_2 1202
#define QTN_RUBY_ODM_BOARD_3 1203
#define QTN_RUBY_ODM_BOARD_4 1204
#define QTN_RUBY_ODM_BOARD_5 1205
#define QTN_RUBY_ODM_BOARD_6 1206
#define QTN_RUBY_ODM_BOARD_7 1207
#define QTN_RUBY_ODM_BOARD_8 1208
#define QTN_RUBY_ODM_BOARD_9 1209
#define QTN_RUBY_ODM_BOARD_10 1210
#define QTN_RUBY_ODM_BOARD_11 1211
#define QTN_RUBY_ODM_BOARD_12 1212
#define QTN_RUBY_ODM_BOARD_13 1213
#define QTN_RUBY_ODM_BOARD_14 1214
#define QTN_RUBY_ODM_BOARD_15 1215
#define QTN_RUBY_ODM_BOARD_16 1216
#define QTN_RUBY_ODM_BOARD_17 1217
#define QTN_RUBY_ODM_BOARD_18 1218
#define QTN_RUBY_ODM_BOARD_19 1219
#define QTN_RUBY_ODM_BOARD_20 1220
#define QTN_RUBY_ODM_BOARD_21 1221
#define QTN_RUBY_ODM_BOARD_22 1222
#define QTN_TOPAZ_FPGAA_BOARD 1223
#define QTN_TOPAZ_FPGAB_BOARD 1224
#define QTN_TOPAZ_DUAL_EMAC_FPGAA_BOARD 1225
#define QTN_TOPAZ_DUAL_EMAC_FPGAB_BOARD 1226
#define QTN_TOPAZ_RC_BOARD 1227
#define QTN_TOPAZ_EP_BOARD 1228
#define QTN_TOPAZ_BB_BOARD 1229
#define QTN_TOPAZ_RF_BOARD 1230
#define QTN_TOPAZ_QHS840_5S1 1231
#define QTN_RUBY_AUTOCONFIG_ID 32768
#define QTN_RUBY_UNIVERSAL_BOARD_ID 65535
#define QTN_RUBY_NOSUCH_BOARD_TYPE -1
#define QTN_RUBY_BRINGUP_RWPA 0
#define QTN_RUBY_REF_RWPA 1
#define QTN_RUBY_SIGE 2
#define QTN_RUBY_UNDEFINED 3
#define QTN_RUBY_WIFI_NONE 4
#define QTN_TPZ_SE5003L1 5
#define QTN_TPZ_SE5003L1_INV 6
#define QTN_TPZ_SKY85703 7
#define QTN_TPZ_SKY85405_BPF840 8
#define QTN_TPZ_DBS 9 /* BBIC4 + RFIC6 */
#define QTN_TPZ_SE5502L 10 /* BBIC4 + RFIC5 */
#define QTN_TPZ_SKY85710_NG 11
#endif /* _SHARED_DEFS_COMMON_H_ */

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2014 Quantenna Communications, Inc.
* All rights reserved.
*/
#ifndef __WLAN_IOCTL_H__
#define __WLAN_IOCTL_H__
enum ieee80211_wifi_mode {
IEEE80211_WIFI_MODE_NONE = 0,
IEEE80211_WIFI_MODE_A,
IEEE80211_WIFI_MODE_B,
IEEE80211_WIFI_MODE_G,
IEEE80211_WIFI_MODE_NA,
IEEE80211_WIFI_MODE_NG,
IEEE80211_WIFI_MODE_AC,
IEEE80211_WIFI_MODE_MAX,
};
#define WLAN_WIFI_MODES_STRINGS { \
[IEEE80211_WIFI_MODE_NONE] = "-", \
[IEEE80211_WIFI_MODE_A] = "a", \
[IEEE80211_WIFI_MODE_B] = "b", \
[IEEE80211_WIFI_MODE_G] = "g", \
[IEEE80211_WIFI_MODE_NA] = "na", \
[IEEE80211_WIFI_MODE_NG] = "ng", \
[IEEE80211_WIFI_MODE_AC] = "ac", \
}
#define IEEE80211_HTCAP_IE_LENGTH 28
#define IEEE80211_VHTCAP_IE_LENGTH 14
struct ieee8011req_sta_tput_caps {
uint8_t macaddr[ETH_ALEN];
uint8_t mode;
uint8_t htcap_ie[IEEE80211_HTCAP_IE_LENGTH];
uint8_t vhtcap_ie[IEEE80211_VHTCAP_IE_LENGTH];
};
#endif /* __WLAN_IOCTL_H__ */

View File

@ -0,0 +1,163 @@
diff --git a/Makefile b/Makefile
index 690da51..478cfa7 100644
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,19 @@ ifneq ($(filter qcawifi,$(IWINFO_BACKENDS)),)
IWINFO_LIB_OBJ += iwinfo_qcawifi.o
endif
+ifneq ($(filter qtnawifi,$(IWINFO_BACKENDS)),)
+ IWINFO_CFLAGS += -DUSE_QTNAWIFI -DATH_SUPPORT_EXT_STAT
+ IWINFO_CFLAGS += -I./libqcsapi_client -DPCIE_RPC_TYPE=RPC_TYPE_QCSAPI_PCIE
+ IWINFO_CLI_LDFLAGS += -ltirpc
+ IWINFO_LIB_LDFLAGS += -ltirpc
+ IWINFO_LIB_OBJ += iwinfo_qtnawifi.o \
+ libqcsapi_client/qcsapi_rpc/generated/qcsapi_rpc_xdr.o \
+ libqcsapi_client/qcsapi_rpc/generated/qcsapi_rpc_clnt_adapter.o \
+ libqcsapi_client/qcsapi_rpc_common/client/rpc_pci_clnt.o
+
+endif
+
+
ifneq ($(filter nl80211,$(IWINFO_BACKENDS)),)
IWINFO_CFLAGS += -DUSE_NL80211
IWINFO_CLI_LDFLAGS += -lnl-tiny
diff --git a/include/iwinfo.h b/include/iwinfo.h
index f98203a..1cfe70b 100644
--- a/include/iwinfo.h
+++ b/include/iwinfo.h
@@ -227,6 +227,7 @@ void sort_by_signal(char *buf, int *len);
void iwinfo_finish(void);
extern const struct iwinfo_ops wext_ops;
+extern const struct iwinfo_ops qtnawifi_ops;
extern const struct iwinfo_ops madwifi_ops;
extern const struct iwinfo_ops wl_ops;
extern const struct iwinfo_ops ra_ops;
diff --git a/include/iwinfo/lua.h b/include/iwinfo/lua.h
index 917e18b..ebb4079 100644
--- a/include/iwinfo/lua.h
+++ b/include/iwinfo/lua.h
@@ -45,6 +45,10 @@
#define IWINFO_QCAWIFI_META "iwinfo.qcawifi"
#endif
+#ifdef USE_QTNAWIFI
+#define IWINFO_QTNAWIFI_META "iwinfo.qtnawifi"
+#endif
+
#ifdef USE_NL80211
#define IWINFO_NL80211_META "iwinfo.nl80211"
#endif
diff --git a/iwinfo_lib.c b/iwinfo_lib.c
index c226a76..1f94bb6 100644
--- a/iwinfo_lib.c
+++ b/iwinfo_lib.c
@@ -333,6 +333,9 @@ static const struct iwinfo_ops *backends[] = {
#ifdef USE_QCAWIFI
&qcawifi_ops,
#endif
+#ifdef USE_QTNAWIFI
+ &qtnawifi_ops,
+#endif
#ifdef USE_WL
&wl_ops,
#endif
diff --git a/iwinfo_lua.c b/iwinfo_lua.c
index 3ab1e19..55001c7 100644
--- a/iwinfo_lua.c
+++ b/iwinfo_lua.c
@@ -769,6 +769,36 @@ LUA_WRAP_STRUCT_OP(qcawifi,mbssid_support)
LUA_WRAP_STRUCT_OP(qcawifi,hardware_id)
#endif
+#ifdef USE_QTNAWIFI
+/* QCAwifi */
+LUA_WRAP_INT_OP(qtnawifi,channel)
+LUA_WRAP_INT_OP(qtnawifi,frequency)
+LUA_WRAP_INT_OP(qtnawifi,frequency_offset)
+LUA_WRAP_INT_OP(qtnawifi,txpower)
+LUA_WRAP_INT_OP(qtnawifi,txpower_offset)
+LUA_WRAP_INT_OP(qtnawifi,bitrate)
+LUA_WRAP_INT_OP(qtnawifi,signal)
+LUA_WRAP_INT_OP(qtnawifi,noise)
+LUA_WRAP_INT_OP(qtnawifi,quality)
+LUA_WRAP_INT_OP(qtnawifi,quality_max)
+LUA_WRAP_STRING_OP(qtnawifi,ssid)
+LUA_WRAP_STRING_OP(qtnawifi,bssid)
+LUA_WRAP_STRING_OP(qtnawifi,country)
+LUA_WRAP_STRING_OP(qtnawifi,hardware_name)
+LUA_WRAP_STRING_OP(qtnawifi,phyname)
+LUA_WRAP_STRUCT_OP(qtnawifi,mode)
+LUA_WRAP_STRUCT_OP(qtnawifi,assoclist)
+LUA_WRAP_STRUCT_OP(qtnawifi,txpwrlist)
+LUA_WRAP_STRUCT_OP(qtnawifi,scanlist)
+LUA_WRAP_STRUCT_OP(qtnawifi,freqlist)
+LUA_WRAP_STRUCT_OP(qtnawifi,countrylist)
+LUA_WRAP_STRUCT_OP(qtnawifi,hwmodelist)
+LUA_WRAP_STRUCT_OP(qtnawifi,htmodelist)
+LUA_WRAP_STRUCT_OP(qtnawifi,encryption)
+LUA_WRAP_STRUCT_OP(qtnawifi,mbssid_support)
+LUA_WRAP_STRUCT_OP(qtnawifi,hardware_id)
+#endif
+
#ifdef USE_NL80211
/* NL80211 */
LUA_WRAP_INT_OP(nl80211,channel)
@@ -959,6 +989,39 @@ static const luaL_reg R_qcawifi[] = {
};
#endif
+#ifdef USE_QTNAWIFI
+/* QCAwifi table */
+static const luaL_reg R_qtnawifi[] = {
+ LUA_REG(qtnawifi,channel),
+ LUA_REG(qtnawifi,frequency),
+ LUA_REG(qtnawifi,frequency_offset),
+ LUA_REG(qtnawifi,txpower),
+ LUA_REG(qtnawifi,txpower_offset),
+ LUA_REG(qtnawifi,bitrate),
+ LUA_REG(qtnawifi,signal),
+ LUA_REG(qtnawifi,noise),
+ LUA_REG(qtnawifi,quality),
+ LUA_REG(qtnawifi,quality_max),
+ LUA_REG(qtnawifi,mode),
+ LUA_REG(qtnawifi,ssid),
+ LUA_REG(qtnawifi,bssid),
+ LUA_REG(qtnawifi,country),
+ LUA_REG(qtnawifi,assoclist),
+ LUA_REG(qtnawifi,txpwrlist),
+ LUA_REG(qtnawifi,scanlist),
+ LUA_REG(qtnawifi,freqlist),
+ LUA_REG(qtnawifi,countrylist),
+ LUA_REG(qtnawifi,hwmodelist),
+ LUA_REG(qtnawifi,htmodelist),
+ LUA_REG(qtnawifi,encryption),
+ LUA_REG(qtnawifi,mbssid_support),
+ LUA_REG(qtnawifi,hardware_id),
+ LUA_REG(qtnawifi,hardware_name),
+ LUA_REG(qtnawifi,phyname),
+ { NULL, NULL }
+};
+#endif
+
#ifdef USE_NL80211
/* NL80211 table */
static const luaL_reg R_nl80211[] = {
@@ -1070,6 +1133,16 @@ LUALIB_API int luaopen_iwinfo(lua_State *L) {
lua_setfield(L, -2, "qcawifi");
#endif
+#ifdef USE_QTNAWIFI
+ luaL_newmetatable(L, IWINFO_QTNAWIFI_META);
+ luaL_register(L, NULL, R_common);
+ luaL_register(L, NULL, R_qtnawifi);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+ lua_setfield(L, -2, "qtnawifi");
+#endif
+
+
#ifdef USE_NL80211
luaL_newmetatable(L, IWINFO_NL80211_META);
luaL_register(L, NULL, R_common);

View File

@ -0,0 +1,28 @@
diff --git a/include/iwinfo.h b/include/iwinfo.h
index a8f8c56..f523ed2 100644
--- a/include/iwinfo.h
+++ b/include/iwinfo.h
@@ -16,7 +16,9 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
+#ifndef _LINUX_IF_H
#include <net/if.h>
+#endif
#include <errno.h>
diff --git a/include/iwinfo/utils.h b/include/iwinfo/utils.h
index 159fd49..ecac6d5 100644
--- a/include/iwinfo/utils.h
+++ b/include/iwinfo/utils.h
@@ -20,7 +20,9 @@
#define __IWINFO_UTILS_H_
#include <sys/socket.h>
+#ifndef _LINUX_IF_H
#include <net/if.h>
+#endif
#include <uci.h>
#include "iwinfo.h"

View File

@ -68,7 +68,12 @@
partition@0 { partition@0 {
label = "ubi"; label = "ubi";
reg = <0 0x8000000>; reg = <0 0x4000000>;
};
partition@4000000 {
label = "extra";
reg = <0x4000000 0x4000000>;
}; };
}; };