mirror of https://gitee.com/openkylin/linux.git
brcmfmac: handle firmware signalling destination entry state
Firmware can signal whether the host driver may sent packets for a specific destination or interface. This can happen when a destination is sleeping or when going off-channel. Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
a2ffc5668e
commit
33753d47d3
|
@ -143,6 +143,8 @@ ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
|
||||||
"tlv_parse_failed: %u\n"
|
"tlv_parse_failed: %u\n"
|
||||||
"tlv_invalid_type: %u\n"
|
"tlv_invalid_type: %u\n"
|
||||||
"mac_update_fails: %u\n"
|
"mac_update_fails: %u\n"
|
||||||
|
"ps_update_fails: %u\n"
|
||||||
|
"if_update_fails: %u\n"
|
||||||
"pkt2bus: %u\n"
|
"pkt2bus: %u\n"
|
||||||
"generic_error: %u\n"
|
"generic_error: %u\n"
|
||||||
"rollback_success: %u\n"
|
"rollback_success: %u\n"
|
||||||
|
@ -161,6 +163,8 @@ ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
|
||||||
fwstats->tlv_parse_failed,
|
fwstats->tlv_parse_failed,
|
||||||
fwstats->tlv_invalid_type,
|
fwstats->tlv_invalid_type,
|
||||||
fwstats->mac_update_failed,
|
fwstats->mac_update_failed,
|
||||||
|
fwstats->mac_ps_update_failed,
|
||||||
|
fwstats->if_update_failed,
|
||||||
fwstats->pkt2bus,
|
fwstats->pkt2bus,
|
||||||
fwstats->generic_error,
|
fwstats->generic_error,
|
||||||
fwstats->rollback_success,
|
fwstats->rollback_success,
|
||||||
|
|
|
@ -144,6 +144,8 @@ struct brcmf_fws_stats {
|
||||||
u32 fifo_credits_back[6];
|
u32 fifo_credits_back[6];
|
||||||
u32 generic_error;
|
u32 generic_error;
|
||||||
u32 mac_update_failed;
|
u32 mac_update_failed;
|
||||||
|
u32 mac_ps_update_failed;
|
||||||
|
u32 if_update_failed;
|
||||||
u32 rollback_success;
|
u32 rollback_success;
|
||||||
u32 rollback_failed;
|
u32 rollback_failed;
|
||||||
u32 delayq_full_error;
|
u32 delayq_full_error;
|
||||||
|
|
|
@ -896,6 +896,69 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
|
||||||
|
u8 type, u8 *data)
|
||||||
|
{
|
||||||
|
struct brcmf_fws_mac_descriptor *entry;
|
||||||
|
u8 mac_handle;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
mac_handle = data[0];
|
||||||
|
entry = &fws->desc.nodes[mac_handle & 0x1F];
|
||||||
|
if (!entry->occupied) {
|
||||||
|
fws->stats.mac_ps_update_failed++;
|
||||||
|
return -ESRCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a state update should wipe old credits? */
|
||||||
|
entry->requested_credit = 0;
|
||||||
|
if (type == BRCMF_FWS_TYPE_MAC_OPEN) {
|
||||||
|
entry->state = BRCMF_FWS_STATE_OPEN;
|
||||||
|
} else {
|
||||||
|
entry->state = BRCMF_FWS_STATE_CLOSE;
|
||||||
|
for (i = BRCMF_FWS_FIFO_AC_BE; i < NL80211_NUM_ACS; i++)
|
||||||
|
brcmf_fws_tim_update(fws, entry, i);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
|
||||||
|
u8 type, u8 *data)
|
||||||
|
{
|
||||||
|
struct brcmf_fws_mac_descriptor *entry;
|
||||||
|
u8 ifidx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ifidx = data[0];
|
||||||
|
|
||||||
|
brcmf_dbg(TRACE, "enter: ifidx=%d\n", ifidx);
|
||||||
|
if (ifidx >= BRCMF_MAX_IFS) {
|
||||||
|
ret = -ERANGE;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = &fws->desc.iface[ifidx];
|
||||||
|
if (!entry->occupied) {
|
||||||
|
ret = -ESRCH;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case BRCMF_FWS_TYPE_INTERFACE_OPEN:
|
||||||
|
entry->state = BRCMF_FWS_STATE_OPEN;
|
||||||
|
return 0;
|
||||||
|
case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
|
||||||
|
entry->state = BRCMF_FWS_STATE_CLOSE;
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fail:
|
||||||
|
fws->stats.if_update_failed++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
|
static void brcmf_fws_return_credits(struct brcmf_fws_info *fws,
|
||||||
u8 fifo, u8 credits)
|
u8 fifo, u8 credits)
|
||||||
{
|
{
|
||||||
|
@ -1111,8 +1174,6 @@ brcmf_fws_txstatus_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
struct brcmf_fws_mac_descriptor *entry = NULL;
|
struct brcmf_fws_mac_descriptor *entry = NULL;
|
||||||
|
|
||||||
fws->stats.txs_indicate++;
|
|
||||||
|
|
||||||
brcmf_dbg(TRACE, "status: flags=0x%X, hslot=%d\n",
|
brcmf_dbg(TRACE, "status: flags=0x%X, hslot=%d\n",
|
||||||
flags, hslot);
|
flags, hslot);
|
||||||
|
|
||||||
|
@ -1305,11 +1366,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BRCMF_FWS_TYPE_MAC_OPEN:
|
|
||||||
case BRCMF_FWS_TYPE_MAC_CLOSE:
|
|
||||||
case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT:
|
case BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT:
|
||||||
case BRCMF_FWS_TYPE_INTERFACE_OPEN:
|
|
||||||
case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
|
|
||||||
case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET:
|
case BRCMF_FWS_TYPE_MAC_REQUEST_PACKET:
|
||||||
case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
|
case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
|
||||||
case BRCMF_FWS_TYPE_COMP_TXSTATUS:
|
case BRCMF_FWS_TYPE_COMP_TXSTATUS:
|
||||||
|
@ -1318,6 +1375,14 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
|
||||||
case BRCMF_FWS_TYPE_MACDESC_DEL:
|
case BRCMF_FWS_TYPE_MACDESC_DEL:
|
||||||
brcmf_fws_macdesc_indicate(fws, type, data);
|
brcmf_fws_macdesc_indicate(fws, type, data);
|
||||||
break;
|
break;
|
||||||
|
case BRCMF_FWS_TYPE_MAC_OPEN:
|
||||||
|
case BRCMF_FWS_TYPE_MAC_CLOSE:
|
||||||
|
brcmf_fws_macdesc_state_indicate(fws, type, data);
|
||||||
|
break;
|
||||||
|
case BRCMF_FWS_TYPE_INTERFACE_OPEN:
|
||||||
|
case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
|
||||||
|
brcmf_fws_interface_state_indicate(fws, type, data);
|
||||||
|
break;
|
||||||
case BRCMF_FWS_TYPE_TXSTATUS:
|
case BRCMF_FWS_TYPE_TXSTATUS:
|
||||||
brcmf_fws_txstatus_indicate(fws, data);
|
brcmf_fws_txstatus_indicate(fws, data);
|
||||||
break;
|
break;
|
||||||
|
@ -1779,7 +1844,8 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
|
||||||
/* enable firmware signalling if fcmode active */
|
/* enable firmware signalling if fcmode active */
|
||||||
if (drvr->fws->fcmode != BRCMF_FWS_FCMODE_NONE)
|
if (drvr->fws->fcmode != BRCMF_FWS_FCMODE_NONE)
|
||||||
tlv |= BRCMF_FWS_FLAGS_XONXOFF_SIGNALS |
|
tlv |= BRCMF_FWS_FLAGS_XONXOFF_SIGNALS |
|
||||||
BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS;
|
BRCMF_FWS_FLAGS_CREDIT_STATUS_SIGNALS |
|
||||||
|
BRCMF_FWS_FLAGS_HOST_PROPTXSTATUS_ACTIVE;
|
||||||
|
|
||||||
rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv);
|
rc = brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
|
Loading…
Reference in New Issue