int mgt_set_varlen(islpci_private *priv, enum oid_num_t n, void *data, int extra_len) { int ret = 0; struct islpci_mgmtframe *response; int response_op = PIMFOR_OP_ERROR; int dlen; u32 oid; BUG_ON(OID_NUM_LAST <= n); dlen = isl_oid[n].size; oid = isl_oid[n].oid; mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, data); if (islpci_get_state(priv) >= PRV_STATE_READY) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, data, dlen + extra_len, &response); if (!ret) { response_op = response->header->operation; islpci_mgt_release(response); } if (ret || response_op == PIMFOR_OP_ERROR) ret = -EIO; } else ret = -EIO; if (data) mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data); return ret; }
int mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) { int ret = 0; struct islpci_mgmtframe *response = NULL; int response_op = PIMFOR_OP_ERROR; int dlen; void *cache, *_data = data; u32 oid; BUG_ON(OID_NUM_LAST <= n); BUG_ON(extra > isl_oid[n].range); if (!priv->mib) /* memory has been freed */ return -1; dlen = isl_oid[n].size; cache = priv->mib[n]; cache += (cache ? extra * dlen : 0); oid = isl_oid[n].oid + extra; if (_data == NULL) /* we are requested to re-set a cached value */ _data = cache; else mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, _data); /* If we are going to write to the cache, we don't want anyone to read * it -> acquire write lock. * Else we could acquire a read lock to be sure we don't bother the * commit process (which takes a write lock). But I'm not sure if it's * needed. */ if (cache) down_write(&priv->mib_sem); if (islpci_get_state(priv) >= PRV_STATE_READY) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, _data, dlen, &response); if (!ret) { response_op = response->header->operation; islpci_mgt_release(response); } if (ret || response_op == PIMFOR_OP_ERROR) ret = -EIO; } else if (!cache) ret = -EIO; if (cache) { if (!ret && data) memcpy(cache, _data, dlen); up_write(&priv->mib_sem); } /* re-set given data to what it was */ if (data) mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data); return ret; }
void mgt_set(islpci_private *priv, enum oid_num_t n, void *data) { BUG_ON(OID_NUM_LAST <= n); BUG_ON(priv->mib[n] == NULL); memcpy(priv->mib[n], data, isl_oid[n].size); mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, priv->mib[n]); }
int mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data) { int ret = 0; struct islpci_mgmtframe *response = NULL; int response_op = PIMFOR_OP_ERROR; int dlen; void *cache, *_data = data; u32 oid; BUG_ON(OID_NUM_LAST <= n); BUG_ON(extra > isl_oid[n].range); if (!priv->mib) return -1; dlen = isl_oid[n].size; cache = priv->mib[n]; cache += (cache ? extra * dlen : 0); oid = isl_oid[n].oid + extra; if (_data == NULL) _data = cache; else mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, _data); if (cache) down_write(&priv->mib_sem); if (islpci_get_state(priv) >= PRV_STATE_READY) { ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid, _data, dlen, &response); if (!ret) { response_op = response->header->operation; islpci_mgt_release(response); } if (ret || response_op == PIMFOR_OP_ERROR) ret = -EIO; } else if (!cache) ret = -EIO; if (cache) { if (!ret && data) memcpy(cache, _data, dlen); up_write(&priv->mib_sem); } if (data) mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data); return ret; }
static void mgt_cpu_to_le(int type, void *data) { switch (type) { case OID_TYPE_U32: *(u32 *) data = cpu_to_le32(*(u32 *) data); break; case OID_TYPE_BUFFER:{ struct obj_buffer *buff = data; buff->size = cpu_to_le32(buff->size); buff->addr = cpu_to_le32(buff->addr); break; } case OID_TYPE_BSS:{ struct obj_bss *bss = data; bss->age = cpu_to_le16(bss->age); bss->channel = cpu_to_le16(bss->channel); bss->capinfo = cpu_to_le16(bss->capinfo); bss->rates = cpu_to_le16(bss->rates); bss->basic_rates = cpu_to_le16(bss->basic_rates); break; } case OID_TYPE_BSSLIST:{ struct obj_bsslist *list = data; int i; list->nr = cpu_to_le32(list->nr); for (i = 0; i < list->nr; i++) mgt_cpu_to_le(OID_TYPE_BSS, &list->bsslist[i]); break; } case OID_TYPE_FREQUENCIES:{ struct obj_frequencies *freq = data; int i; freq->nr = cpu_to_le16(freq->nr); for (i = 0; i < freq->nr; i++) freq->mhz[i] = cpu_to_le16(freq->mhz[i]); break; } case OID_TYPE_MLME:{ struct obj_mlme *mlme = data; mlme->id = cpu_to_le16(mlme->id); mlme->state = cpu_to_le16(mlme->state); mlme->code = cpu_to_le16(mlme->code); break; } case OID_TYPE_MLMEEX:{ struct obj_mlmeex *mlme = data; mlme->id = cpu_to_le16(mlme->id); mlme->state = cpu_to_le16(mlme->state); mlme->code = cpu_to_le16(mlme->code); mlme->size = cpu_to_le16(mlme->size); break; } case OID_TYPE_ATTACH:{ struct obj_attachment *attach = data; attach->id = cpu_to_le16(attach->id); attach->size = cpu_to_le16(attach->size); break; } case OID_TYPE_SSID: case OID_TYPE_KEY: case OID_TYPE_ADDR: case OID_TYPE_RAW: break; default: BUG(); } }