File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -375,6 +375,32 @@ void can_set_default_mtu(struct net_device *dev)
375375 }
376376}
377377
378+ void can_set_cap_info (struct net_device * dev )
379+ {
380+ struct can_priv * priv = netdev_priv (dev );
381+ u32 can_cap ;
382+
383+ if (can_dev_in_xl_only_mode (priv )) {
384+ /* XL only mode => no CC/FD capability */
385+ can_cap = CAN_CAP_XL ;
386+ } else {
387+ /* mixed mode => CC + FD/XL capability */
388+ can_cap = CAN_CAP_CC ;
389+
390+ if (priv -> ctrlmode & CAN_CTRLMODE_FD )
391+ can_cap |= CAN_CAP_FD ;
392+
393+ if (priv -> ctrlmode & CAN_CTRLMODE_XL )
394+ can_cap |= CAN_CAP_XL ;
395+ }
396+
397+ if (priv -> ctrlmode & (CAN_CTRLMODE_LISTENONLY |
398+ CAN_CTRLMODE_RESTRICTED ))
399+ can_cap |= CAN_CAP_RO ;
400+
401+ can_set_cap (dev , can_cap );
402+ }
403+
378404/* helper to define static CAN controller features at device creation time */
379405int can_set_static_ctrlmode (struct net_device * dev , u32 static_mode )
380406{
@@ -390,6 +416,7 @@ int can_set_static_ctrlmode(struct net_device *dev, u32 static_mode)
390416
391417 /* override MTU which was set by default in can_setup()? */
392418 can_set_default_mtu (dev );
419+ can_set_cap_info (dev );
393420
394421 return 0 ;
395422}
Original file line number Diff line number Diff line change @@ -377,6 +377,7 @@ static int can_ctrlmode_changelink(struct net_device *dev,
377377 }
378378
379379 can_set_default_mtu (dev );
380+ can_set_cap_info (dev );
380381
381382 return 0 ;
382383}
Original file line number Diff line number Diff line change @@ -130,6 +130,19 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
130130 return NETDEV_TX_OK ;
131131}
132132
133+ static void vcan_set_cap_info (struct net_device * dev )
134+ {
135+ u32 can_cap = CAN_CAP_CC ;
136+
137+ if (dev -> mtu > CAN_MTU )
138+ can_cap |= CAN_CAP_FD ;
139+
140+ if (dev -> mtu >= CANXL_MIN_MTU )
141+ can_cap |= CAN_CAP_XL ;
142+
143+ can_set_cap (dev , can_cap );
144+ }
145+
133146static int vcan_change_mtu (struct net_device * dev , int new_mtu )
134147{
135148 /* Do not allow changing the MTU while running */
@@ -141,6 +154,7 @@ static int vcan_change_mtu(struct net_device *dev, int new_mtu)
141154 return - EINVAL ;
142155
143156 WRITE_ONCE (dev -> mtu , new_mtu );
157+ vcan_set_cap_info (dev );
144158 return 0 ;
145159}
146160
@@ -162,6 +176,7 @@ static void vcan_setup(struct net_device *dev)
162176 dev -> tx_queue_len = 0 ;
163177 dev -> flags = IFF_NOARP ;
164178 can_set_ml_priv (dev , netdev_priv (dev ));
179+ vcan_set_cap_info (dev );
165180
166181 /* set flags according to driver capabilities */
167182 if (echo )
Original file line number Diff line number Diff line change @@ -125,6 +125,19 @@ static int vxcan_get_iflink(const struct net_device *dev)
125125 return iflink ;
126126}
127127
128+ static void vxcan_set_cap_info (struct net_device * dev )
129+ {
130+ u32 can_cap = CAN_CAP_CC ;
131+
132+ if (dev -> mtu > CAN_MTU )
133+ can_cap |= CAN_CAP_FD ;
134+
135+ if (dev -> mtu >= CANXL_MIN_MTU )
136+ can_cap |= CAN_CAP_XL ;
137+
138+ can_set_cap (dev , can_cap );
139+ }
140+
128141static int vxcan_change_mtu (struct net_device * dev , int new_mtu )
129142{
130143 /* Do not allow changing the MTU while running */
@@ -136,6 +149,7 @@ static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
136149 return - EINVAL ;
137150
138151 WRITE_ONCE (dev -> mtu , new_mtu );
152+ vxcan_set_cap_info (dev );
139153 return 0 ;
140154}
141155
@@ -167,6 +181,7 @@ static void vxcan_setup(struct net_device *dev)
167181
168182 can_ml = netdev_priv (dev ) + ALIGN (sizeof (struct vxcan_priv ), NETDEV_ALIGN );
169183 can_set_ml_priv (dev , can_ml );
184+ vxcan_set_cap_info (dev );
170185}
171186
172187/* forward declaration for rtnl_create_link() */
Original file line number Diff line number Diff line change 4646#include <linux/list.h>
4747#include <linux/netdevice.h>
4848
49+ /* exposed CAN device capabilities for network layer */
50+ #define CAN_CAP_CC BIT(0) /* CAN CC aka Classical CAN */
51+ #define CAN_CAP_FD BIT(1) /* CAN FD */
52+ #define CAN_CAP_XL BIT(2) /* CAN XL */
53+ #define CAN_CAP_RO BIT(3) /* read-only mode (LISTEN/RESTRICTED) */
54+
4955#define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS)
5056#define CAN_EFF_RCV_HASH_BITS 10
5157#define CAN_EFF_RCV_ARRAY_SZ (1 << CAN_EFF_RCV_HASH_BITS)
@@ -64,6 +70,7 @@ struct can_ml_priv {
6470#ifdef CAN_J1939
6571 struct j1939_priv * j1939_priv ;
6672#endif
73+ u32 can_cap ;
6774};
6875
6976static inline struct can_ml_priv * can_get_ml_priv (struct net_device * dev )
@@ -77,4 +84,21 @@ static inline void can_set_ml_priv(struct net_device *dev,
7784 netdev_set_ml_priv (dev , ml_priv , ML_PRIV_CAN );
7885}
7986
87+ static inline bool can_cap_enabled (struct net_device * dev , u32 cap )
88+ {
89+ struct can_ml_priv * can_ml = can_get_ml_priv (dev );
90+
91+ if (!can_ml )
92+ return false;
93+
94+ return (can_ml -> can_cap & cap );
95+ }
96+
97+ static inline void can_set_cap (struct net_device * dev , u32 cap )
98+ {
99+ struct can_ml_priv * can_ml = can_get_ml_priv (dev );
100+
101+ can_ml -> can_cap = cap ;
102+ }
103+
80104#endif /* CAN_ML_H */
Original file line number Diff line number Diff line change @@ -116,6 +116,7 @@ struct can_priv *safe_candev_priv(struct net_device *dev);
116116int open_candev (struct net_device * dev );
117117void close_candev (struct net_device * dev );
118118void can_set_default_mtu (struct net_device * dev );
119+ void can_set_cap_info (struct net_device * dev );
119120int __must_check can_set_static_ctrlmode (struct net_device * dev ,
120121 u32 static_mode );
121122int can_hwtstamp_get (struct net_device * netdev ,
You can’t perform that action at this time.
0 commit comments