[linux] porting cvitek asic chips.
1. update cv182x/cv183x configuration file 2. update cv181x/cv180x configuration file 3. update clk driver for cvitek 4. update dma driver for cvitek 5. update soc driver for cvitek 6. porting cvitek ion driver from kernel-4.19 7. compatible with riscv Change-Id: Icff9fafe0ebe7d6bab824bbadb952e08bdc66c19
This commit is contained in:
committed by
sam.xiang
parent
4bc998a131
commit
4f810186ab
@ -1041,6 +1041,8 @@ EXPORT_SYMBOL(dlci_ioctl_set);
|
||||
static long sock_do_ioctl(struct net *net, struct socket *sock,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
bool need_copyout;
|
||||
int err;
|
||||
void __user *argp = (void __user *)arg;
|
||||
|
||||
@ -1053,25 +1055,13 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,
|
||||
if (err != -ENOIOCTLCMD)
|
||||
return err;
|
||||
|
||||
if (cmd == SIOCGIFCONF) {
|
||||
struct ifconf ifc;
|
||||
if (copy_from_user(&ifc, argp, sizeof(struct ifconf)))
|
||||
if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
|
||||
return -EFAULT;
|
||||
err = dev_ioctl(net, cmd, &ifr, &need_copyout);
|
||||
if (!err && need_copyout)
|
||||
if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
|
||||
return -EFAULT;
|
||||
rtnl_lock();
|
||||
err = dev_ifconf(net, &ifc, sizeof(struct ifreq));
|
||||
rtnl_unlock();
|
||||
if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf)))
|
||||
err = -EFAULT;
|
||||
} else {
|
||||
struct ifreq ifr;
|
||||
bool need_copyout;
|
||||
if (copy_from_user(&ifr, argp, sizeof(struct ifreq)))
|
||||
return -EFAULT;
|
||||
err = dev_ioctl(net, cmd, &ifr, &need_copyout);
|
||||
if (!err && need_copyout)
|
||||
if (copy_to_user(argp, &ifr, sizeof(struct ifreq)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1194,6 +1184,11 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
cmd == SIOCGSTAMP_NEW,
|
||||
false);
|
||||
break;
|
||||
|
||||
case SIOCGIFCONF:
|
||||
err = dev_ifconf(net, argp);
|
||||
break;
|
||||
|
||||
default:
|
||||
err = sock_do_ioctl(net, sock, cmd, arg);
|
||||
break;
|
||||
@ -3097,154 +3092,56 @@ void socket_seq_show(struct seq_file *seq)
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
/* Handle the fact that while struct ifreq has the same *layout* on
|
||||
* 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
|
||||
* which are handled elsewhere, it still has different *size* due to
|
||||
* ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
|
||||
* resulting in struct ifreq being 32 and 40 bytes respectively).
|
||||
* As a result, if the struct happens to be at the end of a page and
|
||||
* the next page isn't readable/writable, we get a fault. To prevent
|
||||
* that, copy back and forth to the full size.
|
||||
*/
|
||||
int get_user_ifreq(struct ifreq *ifr, void __user **ifrdata, void __user *arg)
|
||||
{
|
||||
#ifdef CONFIG_COMPAT
|
||||
static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32)
|
||||
{
|
||||
struct compat_ifconf ifc32;
|
||||
struct ifconf ifc;
|
||||
int err;
|
||||
if (in_compat_syscall()) {
|
||||
struct compat_ifreq *ifr32 = (struct compat_ifreq *)ifr;
|
||||
|
||||
if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf)))
|
||||
memset(ifr, 0, sizeof(*ifr));
|
||||
if (copy_from_user(ifr32, arg, sizeof(*ifr32)))
|
||||
return -EFAULT;
|
||||
|
||||
if (ifrdata)
|
||||
*ifrdata = compat_ptr(ifr32->ifr_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (copy_from_user(ifr, arg, sizeof(*ifr)))
|
||||
return -EFAULT;
|
||||
|
||||
ifc.ifc_len = ifc32.ifc_len;
|
||||
ifc.ifc_req = compat_ptr(ifc32.ifcbuf);
|
||||
if (ifrdata)
|
||||
*ifrdata = ifr->ifr_data;
|
||||
|
||||
rtnl_lock();
|
||||
err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq));
|
||||
rtnl_unlock();
|
||||
if (err)
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(get_user_ifreq);
|
||||
|
||||
ifc32.ifc_len = ifc.ifc_len;
|
||||
if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf)))
|
||||
int put_user_ifreq(struct ifreq *ifr, void __user *arg)
|
||||
{
|
||||
size_t size = sizeof(*ifr);
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (in_compat_syscall())
|
||||
size = sizeof(struct compat_ifreq);
|
||||
#endif
|
||||
if (copy_to_user(arg, ifr, size))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(put_user_ifreq);
|
||||
|
||||
static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
|
||||
{
|
||||
struct compat_ethtool_rxnfc __user *compat_rxnfc;
|
||||
bool convert_in = false, convert_out = false;
|
||||
size_t buf_size = 0;
|
||||
struct ethtool_rxnfc __user *rxnfc = NULL;
|
||||
struct ifreq ifr;
|
||||
u32 rule_cnt = 0, actual_rule_cnt;
|
||||
u32 ethcmd;
|
||||
u32 data;
|
||||
int ret;
|
||||
|
||||
if (get_user(data, &ifr32->ifr_ifru.ifru_data))
|
||||
return -EFAULT;
|
||||
|
||||
compat_rxnfc = compat_ptr(data);
|
||||
|
||||
if (get_user(ethcmd, &compat_rxnfc->cmd))
|
||||
return -EFAULT;
|
||||
|
||||
/* Most ethtool structures are defined without padding.
|
||||
* Unfortunately struct ethtool_rxnfc is an exception.
|
||||
*/
|
||||
switch (ethcmd) {
|
||||
default:
|
||||
break;
|
||||
case ETHTOOL_GRXCLSRLALL:
|
||||
/* Buffer size is variable */
|
||||
if (get_user(rule_cnt, &compat_rxnfc->rule_cnt))
|
||||
return -EFAULT;
|
||||
if (rule_cnt > KMALLOC_MAX_SIZE / sizeof(u32))
|
||||
return -ENOMEM;
|
||||
buf_size += rule_cnt * sizeof(u32);
|
||||
fallthrough;
|
||||
case ETHTOOL_GRXRINGS:
|
||||
case ETHTOOL_GRXCLSRLCNT:
|
||||
case ETHTOOL_GRXCLSRULE:
|
||||
case ETHTOOL_SRXCLSRLINS:
|
||||
convert_out = true;
|
||||
fallthrough;
|
||||
case ETHTOOL_SRXCLSRLDEL:
|
||||
buf_size += sizeof(struct ethtool_rxnfc);
|
||||
convert_in = true;
|
||||
rxnfc = compat_alloc_user_space(buf_size);
|
||||
break;
|
||||
}
|
||||
|
||||
if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ))
|
||||
return -EFAULT;
|
||||
|
||||
ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc;
|
||||
|
||||
if (convert_in) {
|
||||
/* We expect there to be holes between fs.m_ext and
|
||||
* fs.ring_cookie and at the end of fs, but nowhere else.
|
||||
*/
|
||||
BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) +
|
||||
sizeof(compat_rxnfc->fs.m_ext) !=
|
||||
offsetof(struct ethtool_rxnfc, fs.m_ext) +
|
||||
sizeof(rxnfc->fs.m_ext));
|
||||
BUILD_BUG_ON(
|
||||
offsetof(struct compat_ethtool_rxnfc, fs.location) -
|
||||
offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) !=
|
||||
offsetof(struct ethtool_rxnfc, fs.location) -
|
||||
offsetof(struct ethtool_rxnfc, fs.ring_cookie));
|
||||
|
||||
if (copy_in_user(rxnfc, compat_rxnfc,
|
||||
(void __user *)(&rxnfc->fs.m_ext + 1) -
|
||||
(void __user *)rxnfc) ||
|
||||
copy_in_user(&rxnfc->fs.ring_cookie,
|
||||
&compat_rxnfc->fs.ring_cookie,
|
||||
(void __user *)(&rxnfc->fs.location + 1) -
|
||||
(void __user *)&rxnfc->fs.ring_cookie))
|
||||
return -EFAULT;
|
||||
if (ethcmd == ETHTOOL_GRXCLSRLALL) {
|
||||
if (put_user(rule_cnt, &rxnfc->rule_cnt))
|
||||
return -EFAULT;
|
||||
} else if (copy_in_user(&rxnfc->rule_cnt,
|
||||
&compat_rxnfc->rule_cnt,
|
||||
sizeof(rxnfc->rule_cnt)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (convert_out) {
|
||||
if (copy_in_user(compat_rxnfc, rxnfc,
|
||||
(const void __user *)(&rxnfc->fs.m_ext + 1) -
|
||||
(const void __user *)rxnfc) ||
|
||||
copy_in_user(&compat_rxnfc->fs.ring_cookie,
|
||||
&rxnfc->fs.ring_cookie,
|
||||
(const void __user *)(&rxnfc->fs.location + 1) -
|
||||
(const void __user *)&rxnfc->fs.ring_cookie) ||
|
||||
copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt,
|
||||
sizeof(rxnfc->rule_cnt)))
|
||||
return -EFAULT;
|
||||
|
||||
if (ethcmd == ETHTOOL_GRXCLSRLALL) {
|
||||
/* As an optimisation, we only copy the actual
|
||||
* number of rules that the underlying
|
||||
* function returned. Since Mallory might
|
||||
* change the rule count in user memory, we
|
||||
* check that it is less than the rule count
|
||||
* originally given (as the user buffer size),
|
||||
* which has been range-checked.
|
||||
*/
|
||||
if (get_user(actual_rule_cnt, &rxnfc->rule_cnt))
|
||||
return -EFAULT;
|
||||
if (actual_rule_cnt < rule_cnt)
|
||||
rule_cnt = actual_rule_cnt;
|
||||
if (copy_in_user(&compat_rxnfc->rule_locs[0],
|
||||
&rxnfc->rule_locs[0],
|
||||
rule_cnt * sizeof(u32)))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32)
|
||||
{
|
||||
compat_uptr_t uptr32;
|
||||
@ -3252,7 +3149,7 @@ static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32
|
||||
void __user *saved;
|
||||
int err;
|
||||
|
||||
if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq)))
|
||||
if (get_user_ifreq(&ifr, NULL, uifr32))
|
||||
return -EFAULT;
|
||||
|
||||
if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu))
|
||||
@ -3264,7 +3161,7 @@ static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32
|
||||
err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL);
|
||||
if (!err) {
|
||||
ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved;
|
||||
if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq)))
|
||||
if (put_user_ifreq(&ifr, uifr32))
|
||||
err = -EFAULT;
|
||||
}
|
||||
return err;
|
||||
@ -3288,83 +3185,28 @@ static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd,
|
||||
|
||||
static int compat_ifreq_ioctl(struct net *net, struct socket *sock,
|
||||
unsigned int cmd,
|
||||
unsigned long arg,
|
||||
struct compat_ifreq __user *uifr32)
|
||||
{
|
||||
struct ifreq __user *uifr;
|
||||
int err;
|
||||
|
||||
/* Handle the fact that while struct ifreq has the same *layout* on
|
||||
* 32/64 for everything but ifreq::ifru_ifmap and ifreq::ifru_data,
|
||||
* which are handled elsewhere, it still has different *size* due to
|
||||
* ifreq::ifru_ifmap (which is 16 bytes on 32 bit, 24 bytes on 64-bit,
|
||||
* resulting in struct ifreq being 32 and 40 bytes respectively).
|
||||
* As a result, if the struct happens to be at the end of a page and
|
||||
* the next page isn't readable/writable, we get a fault. To prevent
|
||||
* that, copy back and forth to the full size.
|
||||
*/
|
||||
|
||||
uifr = compat_alloc_user_space(sizeof(*uifr));
|
||||
if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
|
||||
return -EFAULT;
|
||||
|
||||
err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
|
||||
|
||||
if (!err) {
|
||||
switch (cmd) {
|
||||
case SIOCGIFFLAGS:
|
||||
case SIOCGIFMETRIC:
|
||||
case SIOCGIFMTU:
|
||||
case SIOCGIFMEM:
|
||||
case SIOCGIFHWADDR:
|
||||
case SIOCGIFINDEX:
|
||||
case SIOCGIFADDR:
|
||||
case SIOCGIFBRDADDR:
|
||||
case SIOCGIFDSTADDR:
|
||||
case SIOCGIFNETMASK:
|
||||
case SIOCGIFPFLAGS:
|
||||
case SIOCGIFTXQLEN:
|
||||
case SIOCGMIIPHY:
|
||||
case SIOCGMIIREG:
|
||||
case SIOCGIFNAME:
|
||||
if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
|
||||
err = -EFAULT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
|
||||
struct compat_ifreq __user *uifr32)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct compat_ifmap __user *uifmap32;
|
||||
bool need_copyout;
|
||||
int err;
|
||||
|
||||
uifmap32 = &uifr32->ifr_ifru.ifru_map;
|
||||
err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
|
||||
err |= get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
|
||||
err |= get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
|
||||
err |= get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
|
||||
err |= get_user(ifr.ifr_map.irq, &uifmap32->irq);
|
||||
err |= get_user(ifr.ifr_map.dma, &uifmap32->dma);
|
||||
err |= get_user(ifr.ifr_map.port, &uifmap32->port);
|
||||
if (err)
|
||||
err = sock->ops->ioctl(sock, cmd, arg);
|
||||
|
||||
/* If this ioctl is unknown try to hand it down
|
||||
* to the NIC driver.
|
||||
*/
|
||||
if (err != -ENOIOCTLCMD)
|
||||
return err;
|
||||
|
||||
if (get_user_ifreq(&ifr, NULL, uifr32))
|
||||
return -EFAULT;
|
||||
err = dev_ioctl(net, cmd, &ifr, &need_copyout);
|
||||
if (!err && need_copyout)
|
||||
if (put_user_ifreq(&ifr, uifr32))
|
||||
return -EFAULT;
|
||||
|
||||
err = dev_ioctl(net, cmd, &ifr, NULL);
|
||||
|
||||
if (cmd == SIOCGIFMAP && !err) {
|
||||
err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
|
||||
err |= put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
|
||||
err |= put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
|
||||
err |= put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
|
||||
err |= put_user(ifr.ifr_map.irq, &uifmap32->irq);
|
||||
err |= put_user(ifr.ifr_map.dma, &uifmap32->dma);
|
||||
err |= put_user(ifr.ifr_map.port, &uifmap32->port);
|
||||
if (err)
|
||||
err = -EFAULT;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3397,15 +3239,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
case SIOCSIFBR:
|
||||
case SIOCGIFBR:
|
||||
return old_bridge_ioctl(argp);
|
||||
case SIOCGIFCONF:
|
||||
return compat_dev_ifconf(net, argp);
|
||||
case SIOCETHTOOL:
|
||||
return ethtool_ioctl(net, argp);
|
||||
case SIOCWANDEV:
|
||||
return compat_siocwandev(net, argp);
|
||||
case SIOCGIFMAP:
|
||||
case SIOCSIFMAP:
|
||||
return compat_sioc_ifmap(net, cmd, argp);
|
||||
case SIOCGSTAMP_OLD:
|
||||
case SIOCGSTAMPNS_OLD:
|
||||
if (!sock->ops->gettstamp)
|
||||
@ -3413,6 +3248,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP_OLD,
|
||||
!COMPAT_USE_64BIT_TIME);
|
||||
|
||||
case SIOCETHTOOL:
|
||||
case SIOCBONDSLAVEINFOQUERY:
|
||||
case SIOCBONDINFOQUERY:
|
||||
case SIOCSHWTSTAMP:
|
||||
@ -3432,10 +3268,13 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
case SIOCGSKNS:
|
||||
case SIOCGSTAMP_NEW:
|
||||
case SIOCGSTAMPNS_NEW:
|
||||
case SIOCGIFCONF:
|
||||
return sock_ioctl(file, cmd, arg);
|
||||
|
||||
case SIOCGIFFLAGS:
|
||||
case SIOCSIFFLAGS:
|
||||
case SIOCGIFMAP:
|
||||
case SIOCSIFMAP:
|
||||
case SIOCGIFMETRIC:
|
||||
case SIOCSIFMETRIC:
|
||||
case SIOCGIFMTU:
|
||||
@ -3472,7 +3311,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
|
||||
case SIOCBONDRELEASE:
|
||||
case SIOCBONDSETHWADDR:
|
||||
case SIOCBONDCHANGEACTIVE:
|
||||
return compat_ifreq_ioctl(net, sock, cmd, argp);
|
||||
return compat_ifreq_ioctl(net, sock, cmd, arg, argp);
|
||||
|
||||
case SIOCSARP:
|
||||
case SIOCGARP:
|
||||
|
||||
Reference in New Issue
Block a user