isl_ioctl.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,270 行 · 第 1/5 页
C
2,270 行
{ islpci_private *priv = netdev_priv(ndev); return mgt_set_request(priv, DOT11_OID_RTSTHRESH, 0, &vwrq->value);}static intprism54_get_rts(struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); union oid_res_t r; int rvalue; /* get the rts threshold */ rvalue = mgt_get_request(priv, DOT11_OID_RTSTHRESH, 0, NULL, &r); vwrq->value = r.u; return rvalue;}static intprism54_set_frag(struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); return mgt_set_request(priv, DOT11_OID_FRAGTHRESH, 0, &vwrq->value);}static intprism54_get_frag(struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); union oid_res_t r; int rvalue; rvalue = mgt_get_request(priv, DOT11_OID_FRAGTHRESH, 0, NULL, &r); vwrq->value = r.u; return rvalue;}/* Here we have (min,max) = max retries for (small frames, big frames). Where * big frame <=> bigger than the rts threshold * small frame <=> smaller than the rts threshold * This is not really the behavior expected by the wireless tool but it seems * to be a common behavior in other drivers. */static intprism54_set_retry(struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); u32 slimit = 0, llimit = 0; /* short and long limit */ u32 lifetime = 0; int rvalue = 0; if (vwrq->disabled) /* we cannot disable this feature */ return -EINVAL; if (vwrq->flags & IW_RETRY_LIMIT) { if (vwrq->flags & IW_RETRY_MIN) slimit = vwrq->value; else if (vwrq->flags & IW_RETRY_MAX) llimit = vwrq->value; else { /* we are asked to set both */ slimit = vwrq->value; llimit = vwrq->value; } } if (vwrq->flags & IW_RETRY_LIFETIME) /* Wireless tools use us unit while the device uses 1024 us unit */ lifetime = vwrq->value / 1024; /* now set what is requested */ if (slimit) rvalue = mgt_set_request(priv, DOT11_OID_SHORTRETRIES, 0, &slimit); if (llimit) rvalue |= mgt_set_request(priv, DOT11_OID_LONGRETRIES, 0, &llimit); if (lifetime) rvalue |= mgt_set_request(priv, DOT11_OID_MAXTXLIFETIME, 0, &lifetime); return rvalue;}static intprism54_get_retry(struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); union oid_res_t r; int rvalue = 0; vwrq->disabled = 0; /* It cannot be disabled */ if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { /* we are asked for the life time */ rvalue = mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r); vwrq->value = r.u * 1024; vwrq->flags = IW_RETRY_LIFETIME; } else if ((vwrq->flags & IW_RETRY_MAX)) { /* we are asked for the long retry limit */ rvalue |= mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r); vwrq->value = r.u; vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; } else { /* default. get the short retry limit */ rvalue |= mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r); vwrq->value = r.u; vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN; } return rvalue;}static intprism54_set_encode(struct net_device *ndev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); int rvalue = 0, force = 0; int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0; union oid_res_t r; /* with the new API, it's impossible to get a NULL pointer. * New version of iwconfig set the IW_ENCODE_NOKEY flag * when no key is given, but older versions don't. */ if (dwrq->length > 0) { /* we have a key to set */ int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; int current_index; struct obj_key key = { DOT11_PRIV_WEP, 0, "" }; /* get the current key index */ rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r); current_index = r.u; /* Verify that the key is not marked as invalid */ if (!(dwrq->flags & IW_ENCODE_NOKEY)) { key.length = dwrq->length > sizeof (key.key) ? sizeof (key.key) : dwrq->length; memcpy(key.key, extra, key.length); if (key.length == 32) /* we want WPA-PSK */ key.type = DOT11_PRIV_TKIP; if ((index < 0) || (index > 3)) /* no index provided use the current one */ index = current_index; /* now send the key to the card */ rvalue |= mgt_set_request(priv, DOT11_OID_DEFKEYX, index, &key); } /* * If a valid key is set, encryption should be enabled * (user may turn it off later). * This is also how "iwconfig ethX key on" works */ if ((index == current_index) && (key.length > 0)) force = 1; } else { int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; if ((index >= 0) && (index <= 3)) { /* we want to set the key index */ rvalue |= mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &index); } else { if (!dwrq->flags & IW_ENCODE_MODE) { /* we cannot do anything. Complain. */ return -EINVAL; } } } /* now read the flags */ if (dwrq->flags & IW_ENCODE_DISABLED) { /* Encoding disabled, * authen = DOT11_AUTH_OS; * invoke = 0; * exunencrypt = 0; */ } if (dwrq->flags & IW_ENCODE_OPEN) /* Encode but accept non-encoded packets. No auth */ invoke = 1; if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) { /* Refuse non-encoded packets. Auth */ authen = DOT11_AUTH_BOTH; invoke = 1; exunencrypt = 1; } /* do the change if requested */ if ((dwrq->flags & IW_ENCODE_MODE) || force) { rvalue |= mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen); rvalue |= mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke); rvalue |= mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &exunencrypt); } return rvalue;}static intprism54_get_encode(struct net_device *ndev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); struct obj_key *key; u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1; u32 authen = 0, invoke = 0, exunencrypt = 0; int rvalue; union oid_res_t r; /* first get the flags */ rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r); authen = r.u; rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r); invoke = r.u; rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r); exunencrypt = r.u; if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt) dwrq->flags = IW_ENCODE_RESTRICTED; else if ((authen == DOT11_AUTH_OS) && !exunencrypt) { if (invoke) dwrq->flags = IW_ENCODE_OPEN; else dwrq->flags = IW_ENCODE_DISABLED; } else /* The card should not work in this state */ dwrq->flags = 0; /* get the current device key index */ rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r); devindex = r.u; /* Now get the key, return it */ if ((index < 0) || (index > 3)) /* no index provided, use the current one */ index = devindex; rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r); key = r.ptr; dwrq->length = key->length; memcpy(extra, key->key, dwrq->length); kfree(key); /* return the used key index */ dwrq->flags |= devindex + 1; return rvalue;}static intprism54_get_txpower(struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); union oid_res_t r; int rvalue; rvalue = mgt_get_request(priv, OID_INL_OUTPUTPOWER, 0, NULL, &r); /* intersil firmware operates in 0.25 dBm (1/4 dBm) */ vwrq->value = (s32) r.u / 4; vwrq->fixed = 1; /* radio is not turned of * btw: how is possible to turn off only the radio */ vwrq->disabled = 0; return rvalue;}static intprism54_set_txpower(struct net_device *ndev, struct iw_request_info *info, struct iw_param *vwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); s32 u = vwrq->value; /* intersil firmware operates in 0.25 dBm (1/4) */ u *= 4; if (vwrq->disabled) { /* don't know how to disable radio */ printk(KERN_DEBUG "%s: %s() disabling radio is not yet supported.\n", priv->ndev->name, __FUNCTION__); return -ENOTSUPP; } else if (vwrq->fixed) /* currently only fixed value is supported */ return mgt_set_request(priv, OID_INL_OUTPUTPOWER, 0, &u); else { printk(KERN_DEBUG "%s: %s() auto power will be implemented later.\n", priv->ndev->name, __FUNCTION__); return -ENOTSUPP; }}static intprism54_reset(struct net_device *ndev, struct iw_request_info *info, __u32 * uwrq, char *extra){ islpci_reset(netdev_priv(ndev), 0); return 0;}static intprism54_get_oid(struct net_device *ndev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ union oid_res_t r; int rvalue; enum oid_num_t n = dwrq->flags; rvalue = mgt_get_request((islpci_private *) ndev->priv, n, 0, NULL, &r); dwrq->length = mgt_response_to_str(n, &r, extra); if ((isl_oid[n].flags & OID_FLAG_TYPE) != OID_TYPE_U32) kfree(r.ptr); return rvalue;}static intprism54_set_u32(struct net_device *ndev, struct iw_request_info *info, __u32 * uwrq, char *extra){ u32 oid = uwrq[0], u = uwrq[1]; return mgt_set_request((islpci_private *) ndev->priv, oid, 0, &u);}static intprism54_set_raw(struct net_device *ndev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ u32 oid = dwrq->flags; return mgt_set_request((islpci_private *) ndev->priv, oid, 0, extra);}voidprism54_acl_init(struct islpci_acl *acl){ sema_init(&acl->sem, 1); INIT_LIST_HEAD(&acl->mac_list); acl->size = 0; acl->policy = MAC_POLICY_OPEN;}static voidprism54_clear_mac(struct islpci_acl *acl){ struct list_head *ptr, *next; struct mac_entry *entry; if (down_interruptible(&acl->sem)) return; if (acl->size == 0) { up(&acl->sem); return; } for (ptr = acl->mac_list.next, next = ptr->next; ptr != &acl->mac_list; ptr = next, next = ptr->next) { entry = list_entry(ptr, struct mac_entry, _list); list_del(ptr); kfree(entry); } acl->size = 0; up(&acl->sem);}voidprism54_acl_clean(struct islpci_acl *acl){ prism54_clear_mac(acl);}static intprism54_add_mac(struct net_device *ndev, struct iw_request_info *info, struct sockaddr *awrq, char *extra){ islpci_private *priv = netdev_priv(ndev); struct islpci_acl *acl = &priv->acl; struct mac_entry *entry; struct sockaddr *addr = (struct sockaddr *) extra; if (addr->sa_family != ARPHRD_ETHER) return -EOPNOTSUPP; entry = kmalloc(sizeof (struct mac_entry), GFP_KERNEL); if (entry == NULL) return -ENOMEM; memcpy(entry->addr, addr->sa_data, ETH_ALEN); if (down_interruptible(&acl->sem)) { kfree(entry); return -ERESTARTSYS; } list_add_tail(&entry->_list, &acl->mac_list); acl->size++; up(&acl->sem); return 0;}static intprism54_del_mac(struct net_device *ndev, struct iw_request_info *info, struct sockaddr *awrq, char *extra){ islpci_private *priv = netdev_priv(ndev); struct islpci_acl *acl = &priv->acl; struct mac_entry *entry; struct list_head *ptr; struct sockaddr *addr = (struct sockaddr *) extra; if (addr->sa_family != ARPHRD_ETHER) return -EOPNOTSUPP; if (down_interruptible(&acl->sem)) return -ERESTARTSYS; for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) { entry = list_entry(ptr, struct mac_entry, _list); if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) { list_del(ptr); acl->size--; kfree(entry); up(&acl->sem); return 0; } } up(&acl->sem); return -EINVAL;}static intprism54_get_mac(struct net_device *ndev, struct iw_request_info *info, struct iw_point *dwrq, char *extra){ islpci_private *priv = netdev_priv(ndev); struct islpci_acl *acl = &priv->acl;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?