12e759738SNishad Kamdar /* SPDX-License-Identifier: GPL-2.0 */ 200a2430fSAndrzej Pietrasiewicz /* 300a2430fSAndrzej Pietrasiewicz * u_ether_configfs.h 400a2430fSAndrzej Pietrasiewicz * 500a2430fSAndrzej Pietrasiewicz * Utility definitions for configfs support in USB Ethernet functions 600a2430fSAndrzej Pietrasiewicz * 700a2430fSAndrzej Pietrasiewicz * Copyright (c) 2013 Samsung Electronics Co., Ltd. 800a2430fSAndrzej Pietrasiewicz * http://www.samsung.com 900a2430fSAndrzej Pietrasiewicz * 101b4a3b51SAndrzej Pietrasiewicz * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com> 1100a2430fSAndrzej Pietrasiewicz */ 1200a2430fSAndrzej Pietrasiewicz 1300a2430fSAndrzej Pietrasiewicz #ifndef __U_ETHER_CONFIGFS_H 1400a2430fSAndrzej Pietrasiewicz #define __U_ETHER_CONFIGFS_H 1500a2430fSAndrzej Pietrasiewicz 1600a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM(_f_) \ 1700a2430fSAndrzej Pietrasiewicz static void _f_##_attr_release(struct config_item *item) \ 1800a2430fSAndrzej Pietrasiewicz { \ 1900a2430fSAndrzej Pietrasiewicz struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 2000a2430fSAndrzej Pietrasiewicz \ 2100a2430fSAndrzej Pietrasiewicz usb_put_function_instance(&opts->func_inst); \ 2200a2430fSAndrzej Pietrasiewicz } \ 2300a2430fSAndrzej Pietrasiewicz \ 2400a2430fSAndrzej Pietrasiewicz static struct configfs_item_operations _f_##_item_ops = { \ 2500a2430fSAndrzej Pietrasiewicz .release = _f_##_attr_release, \ 2600a2430fSAndrzej Pietrasiewicz } 2700a2430fSAndrzej Pietrasiewicz 2800a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_) \ 29f9a63da3SChristoph Hellwig static ssize_t _f_##_opts_dev_addr_show(struct config_item *item, \ 3000a2430fSAndrzej Pietrasiewicz char *page) \ 3100a2430fSAndrzej Pietrasiewicz { \ 32f9a63da3SChristoph Hellwig struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 3300a2430fSAndrzej Pietrasiewicz int result; \ 3400a2430fSAndrzej Pietrasiewicz \ 3500a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 3600a2430fSAndrzej Pietrasiewicz result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \ 3700a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 3800a2430fSAndrzej Pietrasiewicz \ 3900a2430fSAndrzej Pietrasiewicz return result; \ 4000a2430fSAndrzej Pietrasiewicz } \ 4100a2430fSAndrzej Pietrasiewicz \ 42f9a63da3SChristoph Hellwig static ssize_t _f_##_opts_dev_addr_store(struct config_item *item, \ 4300a2430fSAndrzej Pietrasiewicz const char *page, size_t len)\ 4400a2430fSAndrzej Pietrasiewicz { \ 45f9a63da3SChristoph Hellwig struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 4600a2430fSAndrzej Pietrasiewicz int ret; \ 4700a2430fSAndrzej Pietrasiewicz \ 4800a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 4900a2430fSAndrzej Pietrasiewicz if (opts->refcnt) { \ 5000a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 5100a2430fSAndrzej Pietrasiewicz return -EBUSY; \ 5200a2430fSAndrzej Pietrasiewicz } \ 5300a2430fSAndrzej Pietrasiewicz \ 5400a2430fSAndrzej Pietrasiewicz ret = gether_set_dev_addr(opts->net, page); \ 5500a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 5600a2430fSAndrzej Pietrasiewicz if (!ret) \ 5700a2430fSAndrzej Pietrasiewicz ret = len; \ 5800a2430fSAndrzej Pietrasiewicz return ret; \ 5900a2430fSAndrzej Pietrasiewicz } \ 6000a2430fSAndrzej Pietrasiewicz \ 61f9a63da3SChristoph Hellwig CONFIGFS_ATTR(_f_##_opts_, dev_addr) 6200a2430fSAndrzej Pietrasiewicz 6300a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_) \ 64f9a63da3SChristoph Hellwig static ssize_t _f_##_opts_host_addr_show(struct config_item *item, \ 6500a2430fSAndrzej Pietrasiewicz char *page) \ 6600a2430fSAndrzej Pietrasiewicz { \ 67f9a63da3SChristoph Hellwig struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 6800a2430fSAndrzej Pietrasiewicz int result; \ 6900a2430fSAndrzej Pietrasiewicz \ 7000a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 7100a2430fSAndrzej Pietrasiewicz result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \ 7200a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 7300a2430fSAndrzej Pietrasiewicz \ 7400a2430fSAndrzej Pietrasiewicz return result; \ 7500a2430fSAndrzej Pietrasiewicz } \ 7600a2430fSAndrzej Pietrasiewicz \ 77f9a63da3SChristoph Hellwig static ssize_t _f_##_opts_host_addr_store(struct config_item *item, \ 7800a2430fSAndrzej Pietrasiewicz const char *page, size_t len)\ 7900a2430fSAndrzej Pietrasiewicz { \ 80f9a63da3SChristoph Hellwig struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 8100a2430fSAndrzej Pietrasiewicz int ret; \ 8200a2430fSAndrzej Pietrasiewicz \ 8300a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 8400a2430fSAndrzej Pietrasiewicz if (opts->refcnt) { \ 8500a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 8600a2430fSAndrzej Pietrasiewicz return -EBUSY; \ 8700a2430fSAndrzej Pietrasiewicz } \ 8800a2430fSAndrzej Pietrasiewicz \ 8900a2430fSAndrzej Pietrasiewicz ret = gether_set_host_addr(opts->net, page); \ 9000a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 9100a2430fSAndrzej Pietrasiewicz if (!ret) \ 9200a2430fSAndrzej Pietrasiewicz ret = len; \ 9300a2430fSAndrzej Pietrasiewicz return ret; \ 9400a2430fSAndrzej Pietrasiewicz } \ 9500a2430fSAndrzej Pietrasiewicz \ 96f9a63da3SChristoph Hellwig CONFIGFS_ATTR(_f_##_opts_, host_addr) 9700a2430fSAndrzej Pietrasiewicz 9800a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_) \ 99f9a63da3SChristoph Hellwig static ssize_t _f_##_opts_qmult_show(struct config_item *item, \ 10000a2430fSAndrzej Pietrasiewicz char *page) \ 10100a2430fSAndrzej Pietrasiewicz { \ 102f9a63da3SChristoph Hellwig struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 10300a2430fSAndrzej Pietrasiewicz unsigned qmult; \ 10400a2430fSAndrzej Pietrasiewicz \ 10500a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 10600a2430fSAndrzej Pietrasiewicz qmult = gether_get_qmult(opts->net); \ 10700a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 10800b6c62eSKrzysztof Opasiak return sprintf(page, "%d\n", qmult); \ 10900a2430fSAndrzej Pietrasiewicz } \ 11000a2430fSAndrzej Pietrasiewicz \ 111f9a63da3SChristoph Hellwig static ssize_t _f_##_opts_qmult_store(struct config_item *item, \ 11200a2430fSAndrzej Pietrasiewicz const char *page, size_t len)\ 11300a2430fSAndrzej Pietrasiewicz { \ 114f9a63da3SChristoph Hellwig struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 11500a2430fSAndrzej Pietrasiewicz u8 val; \ 11600a2430fSAndrzej Pietrasiewicz int ret; \ 11700a2430fSAndrzej Pietrasiewicz \ 11800a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 11900a2430fSAndrzej Pietrasiewicz if (opts->refcnt) { \ 12000a2430fSAndrzej Pietrasiewicz ret = -EBUSY; \ 12100a2430fSAndrzej Pietrasiewicz goto out; \ 12200a2430fSAndrzej Pietrasiewicz } \ 12300a2430fSAndrzej Pietrasiewicz \ 12400a2430fSAndrzej Pietrasiewicz ret = kstrtou8(page, 0, &val); \ 12500a2430fSAndrzej Pietrasiewicz if (ret) \ 12600a2430fSAndrzej Pietrasiewicz goto out; \ 12700a2430fSAndrzej Pietrasiewicz \ 12800a2430fSAndrzej Pietrasiewicz gether_set_qmult(opts->net, val); \ 12900a2430fSAndrzej Pietrasiewicz ret = len; \ 13000a2430fSAndrzej Pietrasiewicz out: \ 13100a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 13200a2430fSAndrzej Pietrasiewicz return ret; \ 13300a2430fSAndrzej Pietrasiewicz } \ 13400a2430fSAndrzej Pietrasiewicz \ 135f9a63da3SChristoph Hellwig CONFIGFS_ATTR(_f_##_opts_, qmult) 13600a2430fSAndrzej Pietrasiewicz 13700a2430fSAndrzej Pietrasiewicz #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_) \ 138f9a63da3SChristoph Hellwig static ssize_t _f_##_opts_ifname_show(struct config_item *item, \ 13900a2430fSAndrzej Pietrasiewicz char *page) \ 14000a2430fSAndrzej Pietrasiewicz { \ 141f9a63da3SChristoph Hellwig struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 14200a2430fSAndrzej Pietrasiewicz int ret; \ 14300a2430fSAndrzej Pietrasiewicz \ 14400a2430fSAndrzej Pietrasiewicz mutex_lock(&opts->lock); \ 14500a2430fSAndrzej Pietrasiewicz ret = gether_get_ifname(opts->net, page, PAGE_SIZE); \ 14600a2430fSAndrzej Pietrasiewicz mutex_unlock(&opts->lock); \ 14700a2430fSAndrzej Pietrasiewicz \ 14800a2430fSAndrzej Pietrasiewicz return ret; \ 14900a2430fSAndrzej Pietrasiewicz } \ 15000a2430fSAndrzej Pietrasiewicz \ 15163d15214SLorenzo Colitti static ssize_t _f_##_opts_ifname_store(struct config_item *item, \ 15263d15214SLorenzo Colitti const char *page, size_t len)\ 15363d15214SLorenzo Colitti { \ 15463d15214SLorenzo Colitti struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 15563d15214SLorenzo Colitti int ret = -EBUSY; \ 15663d15214SLorenzo Colitti \ 15763d15214SLorenzo Colitti mutex_lock(&opts->lock); \ 15863d15214SLorenzo Colitti if (!opts->refcnt) \ 15963d15214SLorenzo Colitti ret = gether_set_ifname(opts->net, page, len); \ 16063d15214SLorenzo Colitti mutex_unlock(&opts->lock); \ 16163d15214SLorenzo Colitti return ret ?: len; \ 16263d15214SLorenzo Colitti } \ 16363d15214SLorenzo Colitti \ 16463d15214SLorenzo Colitti CONFIGFS_ATTR(_f_##_opts_, ifname) 16500a2430fSAndrzej Pietrasiewicz 16673517cf4SDavid Lechner #define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_) \ 16773517cf4SDavid Lechner static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\ 16873517cf4SDavid Lechner char *page) \ 16973517cf4SDavid Lechner { \ 17073517cf4SDavid Lechner struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 17173517cf4SDavid Lechner int ret; \ 17273517cf4SDavid Lechner \ 17373517cf4SDavid Lechner mutex_lock(&opts->lock); \ 17473517cf4SDavid Lechner ret = sprintf(page, "%02x\n", opts->_n_); \ 17573517cf4SDavid Lechner mutex_unlock(&opts->lock); \ 17673517cf4SDavid Lechner \ 17773517cf4SDavid Lechner return ret; \ 17873517cf4SDavid Lechner } \ 17973517cf4SDavid Lechner \ 18073517cf4SDavid Lechner static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\ 18173517cf4SDavid Lechner const char *page, \ 18273517cf4SDavid Lechner size_t len) \ 18373517cf4SDavid Lechner { \ 18473517cf4SDavid Lechner struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ 185*650bf522SDan Carpenter int ret = -EINVAL; \ 18673517cf4SDavid Lechner u8 val; \ 18773517cf4SDavid Lechner \ 18873517cf4SDavid Lechner mutex_lock(&opts->lock); \ 189*650bf522SDan Carpenter if (sscanf(page, "%02hhx", &val) > 0) { \ 19073517cf4SDavid Lechner opts->_n_ = val; \ 19173517cf4SDavid Lechner ret = len; \ 19273517cf4SDavid Lechner } \ 19373517cf4SDavid Lechner mutex_unlock(&opts->lock); \ 19473517cf4SDavid Lechner \ 19573517cf4SDavid Lechner return ret; \ 19673517cf4SDavid Lechner } \ 19773517cf4SDavid Lechner \ 19873517cf4SDavid Lechner CONFIGFS_ATTR(_f_##_opts_, _n_) 19973517cf4SDavid Lechner 20000a2430fSAndrzej Pietrasiewicz #endif /* __U_ETHER_CONFIGFS_H */ 201