/* variables defined in struct mwifiex_adapter */
{"cmd_pending", adapter_item_size(cmd_pending),
adapter_item_addr(cmd_pending), 1},
{"tx_pending", adapter_item_size(tx_pending),
adapter_item_addr(tx_pending), 1},
{"rx_pending", adapter_item_size(rx_pending),
adapter_item_addr(rx_pending), 1},
};
staticint num_of_items = ARRAY_SIZE(items);
/* * This function sends init/shutdown command * to firmware.
*/ int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
u32 func_init_shutdown)
{
u16 cmd;
/* * IOCTL request handler to set/get debug information. * * This function collates/sets the information from/to different driver * structures.
*/ int mwifiex_get_debug_info(struct mwifiex_private *priv, struct mwifiex_debug_info *info)
{ struct mwifiex_adapter *adapter = priv->adapter;
int mwifiex_debug_info_to_buffer(struct mwifiex_private *priv, char *buf, struct mwifiex_debug_info *info)
{ char *p = buf; struct mwifiex_debug_data *d = &items[0];
size_t size, addr; long val; int i, j;
if (!info) return 0;
for (i = 0; i < num_of_items; i++) {
p += sprintf(p, "%s=", d[i].name);
size = d[i].size / d[i].num;
if (i < (num_of_items - 3))
addr = d[i].addr + (size_t)info; else/* The last 3 items are struct mwifiex_adapter variables */
addr = d[i].addr + (size_t)priv->adapter;
for (j = 0; j < d[i].num; j++) { switch (size) { case 1:
val = *((u8 *)addr); break; case 2:
val = get_unaligned((u16 *)addr); break; case 4:
val = get_unaligned((u32 *)addr); break; case 8:
val = get_unaligned((longlong *)addr); break; default:
val = -1; break;
}
p += sprintf(p, "%#lx ", val);
addr += size;
}
p += sprintf(p, "\n");
}
if (info->tx_tbl_num) {
p += sprintf(p, "Tx BA stream table:\n"); for (i = 0; i < info->tx_tbl_num; i++)
p += sprintf(p, "tid = %d, ra = %pM\n",
info->tx_tbl[i].tid, info->tx_tbl[i].ra);
}
if (info->rx_tbl_num) {
p += sprintf(p, "Rx reorder table:\n"); for (i = 0; i < info->rx_tbl_num; i++) {
p += sprintf(p, "tid = %d, ta = %pM, ",
info->rx_tbl[i].tid,
info->rx_tbl[i].ta);
p += sprintf(p, "start_win = %d, ",
info->rx_tbl[i].start_win);
p += sprintf(p, "win_size = %d, buffer: ",
info->rx_tbl[i].win_size);
for (j = 0; j < info->rx_tbl[i].win_size; j++)
p += sprintf(p, "%c ",
info->rx_tbl[i].buffer[j] ? '1' : '0');
p += sprintf(p, "\n");
}
}
if (info->tdls_peer_num) {
p += sprintf(p, "TDLS peer table:\n"); for (i = 0; i < info->tdls_peer_num; i++) {
p += sprintf(p, "peer = %pM",
info->tdls_list[i].peer_addr);
p += sprintf(p, "\n");
}
}
/* * This function processes the received management packet and send it * to the kernel.
*/ int
mwifiex_process_mgmt_packet(struct mwifiex_private *priv, struct sk_buff *skb)
{ struct rxpd *rx_pd;
u16 pkt_len; struct ieee80211_hdr *ieee_hdr;
if (!skb) return -1;
if (!priv->mgmt_frame_mask ||
priv->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) {
mwifiex_dbg(priv->adapter, ERROR, "do not receive mgmt frames on uninitialized intf"); return -1;
}
/* * This function processes the received packet before sending it to the * kernel. * * It extracts the SKB from the received buffer and sends it to kernel. * In case the received buffer does not contain the data in SKB format, * the function creates a blank SKB, fills it with the data from the * received buffer and then sends this new SKB to the kernel.
*/ int mwifiex_recv_packet(struct mwifiex_private *priv, struct sk_buff *skb)
{ struct mwifiex_sta_node *src_node; struct ethhdr *p_ethhdr;
/* This is required only in case of 11n and USB/PCIE as we alloc * a buffer of 4K only if its 11N (to be able to receive 4K * AMSDU packets). In case of SD we allocate buffers based * on the size of packet and hence this is not needed. * * Modifying the truesize here as our allocation for each * skb is 4K but we only receive 2K packets and this cause * the kernel to start dropping packets in case where * application has allocated buffer based on 2K size i.e. * if there a 64K packet received (in IP fragments and * application allocates 64K to receive this packet but * this packet would almost double up because we allocate * each 1.5K fragment in 4K and pass it up. As soon as the * 64K limit hits kernel will start to drop rest of the * fragments. Currently we fail the Filesndl-ht.scr script * for UDP, hence this fix
*/ if ((priv->adapter->iface_type == MWIFIEX_USB ||
priv->adapter->iface_type == MWIFIEX_PCIE) &&
(skb->truesize > MWIFIEX_RX_DATA_BUF_SIZE))
skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE);
netif_rx(skb); return 0;
}
/* * IOCTL completion callback handler. * * This function is called when a pending IOCTL is completed. * * If work queue support is enabled, the function wakes up the * corresponding waiting function. Otherwise, it processes the * IOCTL response and frees the response buffer.
*/ int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_node)
{
WARN_ON(!cmd_node->wait_q_enabled);
mwifiex_dbg(adapter, CMD, "cmd completed: status=%d\n",
adapter->cmd_wait_q.status);
/* This function will return the pointer to station entry in station list * table which matches specified mac address. * This function should be called after acquiring RA list spinlock. * NULL is returned if station entry is not found in associated STA list.
*/ struct mwifiex_sta_node *
mwifiex_get_sta_entry(struct mwifiex_private *priv, const u8 *mac)
{ struct mwifiex_sta_node *node;
/* If tdls channel switching is on-going, tx data traffic should be * blocked until the switching stage completed.
*/
u8 mwifiex_is_tdls_chan_switching(struct mwifiex_private *priv)
{ struct mwifiex_sta_node *sta_ptr;
if (!priv || !ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) returnfalse;
sta_ptr = mwifiex_get_tdls_sta_entry(priv, TDLS_CHAN_SWITCHING); if (sta_ptr) returntrue;
if (!priv || !ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) returnfalse;
sta_ptr = mwifiex_get_tdls_sta_entry(priv, TDLS_IN_OFF_CHAN); if (sta_ptr) returntrue;
returnfalse;
}
/* If tdls channel switching is on-going or tdls operate on off-channel, * cmd path should be blocked until tdls switched to base-channel.
*/
u8 mwifiex_is_send_cmd_allowed(struct mwifiex_private *priv)
{ if (!priv || !ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info)) returntrue;
if (mwifiex_is_tdls_chan_switching(priv) ||
mwifiex_is_tdls_off_chan(priv)) returnfalse;
returntrue;
}
/* This function will add a sta_node entry to associated station list * table with the given mac address. * If entry exist already, existing entry is returned. * If received mac address is NULL, NULL is returned.
*/ struct mwifiex_sta_node *
mwifiex_add_sta_entry(struct mwifiex_private *priv, const u8 *mac)
{ struct mwifiex_sta_node *node;
if (!mac) return NULL;
spin_lock_bh(&priv->sta_list_spinlock);
node = mwifiex_get_sta_entry(priv, mac); if (node) goto done;
node = kzalloc(sizeof(*node), GFP_ATOMIC); if (!node) goto done;
/* This function will search for HT IE in association request IEs * and set station HT parameters accordingly.
*/ void
mwifiex_set_sta_ht_cap(struct mwifiex_private *priv, const u8 *ies, int ies_len, struct mwifiex_sta_node *node)
{ struct ieee_types_header *ht_cap_ie; conststruct ieee80211_ht_cap *ht_cap;
/* This function will delete a station entry from station list */ void mwifiex_del_sta_entry(struct mwifiex_private *priv, const u8 *mac)
{ struct mwifiex_sta_node *node;
spin_lock_bh(&priv->sta_list_spinlock);
node = mwifiex_get_sta_entry(priv, mac); if (node) {
list_del(&node->list);
kfree(node);
}
/* This function will delete all stations from associated station list. */ void mwifiex_del_all_sta_list(struct mwifiex_private *priv)
{ struct mwifiex_sta_node *node, *tmp;
/* function to reset histogram data during init/reset */ void mwifiex_hist_data_reset(struct mwifiex_private *priv)
{ int ix; struct mwifiex_histogram_data *phist_data = priv->hist_data;
atomic_set(&phist_data->num_samples, 0); for (ix = 0; ix < MWIFIEX_MAX_AC_RX_RATES; ix++)
atomic_set(&phist_data->rx_rate[ix], 0); for (ix = 0; ix < MWIFIEX_MAX_SNR; ix++)
atomic_set(&phist_data->snr[ix], 0); for (ix = 0; ix < MWIFIEX_MAX_NOISE_FLR; ix++)
atomic_set(&phist_data->noise_flr[ix], 0); for (ix = 0; ix < MWIFIEX_MAX_SIG_STRENGTH; ix++)
atomic_set(&phist_data->sig_str[ix], 0);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.