@@ -96,6 +96,7 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
9696static void ibmveth_proc_unregister_adapter (struct ibmveth_adapter * adapter );
9797static irqreturn_t ibmveth_interrupt (int irq , void * dev_instance , struct pt_regs * regs );
9898static inline void ibmveth_rxq_harvest_buffer (struct ibmveth_adapter * adapter );
99+ static struct kobj_type ktype_veth_pool ;
99100
100101#ifdef CONFIG_PROC_FS
101102#define IBMVETH_PROC_DIR "net/ibmveth"
@@ -133,12 +134,13 @@ static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter)
133134}
134135
135136/* setup the initial settings for a buffer pool */
136- static void ibmveth_init_buffer_pool (struct ibmveth_buff_pool * pool , u32 pool_index , u32 pool_size , u32 buff_size )
137+ static void ibmveth_init_buffer_pool (struct ibmveth_buff_pool * pool , u32 pool_index , u32 pool_size , u32 buff_size , u32 pool_active )
137138{
138139 pool -> size = pool_size ;
139140 pool -> index = pool_index ;
140141 pool -> buff_size = buff_size ;
141142 pool -> threshold = pool_size / 2 ;
143+ pool -> active = pool_active ;
142144}
143145
144146/* allocate and setup an buffer pool - called during open */
@@ -180,7 +182,6 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
180182 atomic_set (& pool -> available , 0 );
181183 pool -> producer_index = 0 ;
182184 pool -> consumer_index = 0 ;
183- pool -> active = 0 ;
184185
185186 return 0 ;
186187}
@@ -301,7 +302,6 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm
301302 kfree (pool -> skbuff );
302303 pool -> skbuff = NULL ;
303304 }
304- pool -> active = 0 ;
305305}
306306
307307/* remove a buffer from a pool */
@@ -433,7 +433,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
433433 }
434434
435435 for (i = 0 ; i < IbmVethNumBufferPools ; i ++ )
436- ibmveth_free_buffer_pool (adapter , & adapter -> rx_buff_pool [i ]);
436+ if (adapter -> rx_buff_pool [i ].active )
437+ ibmveth_free_buffer_pool (adapter ,
438+ & adapter -> rx_buff_pool [i ]);
437439}
438440
439441static int ibmveth_open (struct net_device * netdev )
@@ -489,9 +491,6 @@ static int ibmveth_open(struct net_device *netdev)
489491 adapter -> rx_queue .num_slots = rxq_entries ;
490492 adapter -> rx_queue .toggle = 1 ;
491493
492- /* call change_mtu to init the buffer pools based in initial mtu */
493- ibmveth_change_mtu (netdev , netdev -> mtu );
494-
495494 memcpy (& mac_address , netdev -> dev_addr , netdev -> addr_len );
496495 mac_address = mac_address >> 16 ;
497496
@@ -522,6 +521,17 @@ static int ibmveth_open(struct net_device *netdev)
522521 return - ENONET ;
523522 }
524523
524+ for (i = 0 ; i < IbmVethNumBufferPools ; i ++ ) {
525+ if (!adapter -> rx_buff_pool [i ].active )
526+ continue ;
527+ if (ibmveth_alloc_buffer_pool (& adapter -> rx_buff_pool [i ])) {
528+ ibmveth_error_printk ("unable to alloc pool\n" );
529+ adapter -> rx_buff_pool [i ].active = 0 ;
530+ ibmveth_cleanup (adapter );
531+ return - ENOMEM ;
532+ }
533+ }
534+
525535 ibmveth_debug_printk ("registering irq 0x%x\n" , netdev -> irq );
526536 if ((rc = request_irq (netdev -> irq , & ibmveth_interrupt , 0 , netdev -> name , netdev )) != 0 ) {
527537 ibmveth_error_printk ("unable to request irq 0x%x, rc %d\n" , netdev -> irq , rc );
@@ -550,7 +560,8 @@ static int ibmveth_close(struct net_device *netdev)
550560
551561 ibmveth_debug_printk ("close starting\n" );
552562
553- netif_stop_queue (netdev );
563+ if (!adapter -> pool_config )
564+ netif_stop_queue (netdev );
554565
555566 free_irq (netdev -> irq , netdev );
556567
@@ -876,46 +887,22 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
876887static int ibmveth_change_mtu (struct net_device * dev , int new_mtu )
877888{
878889 struct ibmveth_adapter * adapter = dev -> priv ;
890+ int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH ;
879891 int i ;
880- int prev_smaller = 1 ;
881892
882- if ((new_mtu < 68 ) ||
883- (new_mtu > (pool_size [IbmVethNumBufferPools - 1 ]) - IBMVETH_BUFF_OH ))
893+ if (new_mtu < IBMVETH_MAX_MTU )
884894 return - EINVAL ;
885895
896+ /* Look for an active buffer pool that can hold the new MTU */
886897 for (i = 0 ; i < IbmVethNumBufferPools ; i ++ ) {
887- int activate = 0 ;
888- if (new_mtu > (pool_size [i ] - IBMVETH_BUFF_OH )) {
889- activate = 1 ;
890- prev_smaller = 1 ;
891- } else {
892- if (prev_smaller )
893- activate = 1 ;
894- prev_smaller = 0 ;
898+ if (!adapter -> rx_buff_pool [i ].active )
899+ continue ;
900+ if (new_mtu_oh < adapter -> rx_buff_pool [i ].buff_size ) {
901+ dev -> mtu = new_mtu ;
902+ return 0 ;
895903 }
896-
897- if (activate && !adapter -> rx_buff_pool [i ].active ) {
898- struct ibmveth_buff_pool * pool =
899- & adapter -> rx_buff_pool [i ];
900- if (ibmveth_alloc_buffer_pool (pool )) {
901- ibmveth_error_printk ("unable to alloc pool\n" );
902- return - ENOMEM ;
903- }
904- adapter -> rx_buff_pool [i ].active = 1 ;
905- } else if (!activate && adapter -> rx_buff_pool [i ].active ) {
906- adapter -> rx_buff_pool [i ].active = 0 ;
907- h_free_logical_lan_buffer (adapter -> vdev -> unit_address ,
908- (u64 )pool_size [i ]);
909- }
910-
911904 }
912-
913- /* kick the interrupt handler so that the new buffer pools get
914- replenished or deallocated */
915- ibmveth_interrupt (dev -> irq , dev , NULL );
916-
917- dev -> mtu = new_mtu ;
918- return 0 ;
905+ return - EINVAL ;
919906}
920907
921908static int __devinit ibmveth_probe (struct vio_dev * dev , const struct vio_device_id * id )
@@ -960,6 +947,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
960947 adapter -> vdev = dev ;
961948 adapter -> netdev = netdev ;
962949 adapter -> mcastFilterSize = * mcastFilterSize_p ;
950+ adapter -> pool_config = 0 ;
963951
964952 /* Some older boxes running PHYP non-natively have an OF that
965953 returns a 8-byte local-mac-address field (and the first
@@ -994,9 +982,16 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
994982
995983 memcpy (& netdev -> dev_addr , & adapter -> mac_addr , netdev -> addr_len );
996984
997- for (i = 0 ; i < IbmVethNumBufferPools ; i ++ )
985+ for (i = 0 ; i < IbmVethNumBufferPools ; i ++ ) {
986+ struct kobject * kobj = & adapter -> rx_buff_pool [i ].kobj ;
998987 ibmveth_init_buffer_pool (& adapter -> rx_buff_pool [i ], i ,
999- pool_count [i ], pool_size [i ]);
988+ pool_count [i ], pool_size [i ],
989+ pool_active [i ]);
990+ kobj -> parent = & dev -> dev .kobj ;
991+ sprintf (kobj -> name , "pool%d" , i );
992+ kobj -> ktype = & ktype_veth_pool ;
993+ kobject_register (kobj );
994+ }
1000995
1001996 ibmveth_debug_printk ("adapter @ 0x%p\n" , adapter );
1002997
@@ -1025,6 +1020,10 @@ static int __devexit ibmveth_remove(struct vio_dev *dev)
10251020{
10261021 struct net_device * netdev = dev -> dev .driver_data ;
10271022 struct ibmveth_adapter * adapter = netdev -> priv ;
1023+ int i ;
1024+
1025+ for (i = 0 ; i < IbmVethNumBufferPools ; i ++ )
1026+ kobject_unregister (& adapter -> rx_buff_pool [i ].kobj );
10281027
10291028 unregister_netdev (netdev );
10301029
@@ -1169,6 +1168,132 @@ static void ibmveth_proc_unregister_driver(void)
11691168}
11701169#endif /* CONFIG_PROC_FS */
11711170
1171+ static struct attribute veth_active_attr ;
1172+ static struct attribute veth_num_attr ;
1173+ static struct attribute veth_size_attr ;
1174+
1175+ static ssize_t veth_pool_show (struct kobject * kobj ,
1176+ struct attribute * attr , char * buf )
1177+ {
1178+ struct ibmveth_buff_pool * pool = container_of (kobj ,
1179+ struct ibmveth_buff_pool ,
1180+ kobj );
1181+
1182+ if (attr == & veth_active_attr )
1183+ return sprintf (buf , "%d\n" , pool -> active );
1184+ else if (attr == & veth_num_attr )
1185+ return sprintf (buf , "%d\n" , pool -> size );
1186+ else if (attr == & veth_size_attr )
1187+ return sprintf (buf , "%d\n" , pool -> buff_size );
1188+ return 0 ;
1189+ }
1190+
1191+ static ssize_t veth_pool_store (struct kobject * kobj , struct attribute * attr ,
1192+ const char * buf , size_t count )
1193+ {
1194+ struct ibmveth_buff_pool * pool = container_of (kobj ,
1195+ struct ibmveth_buff_pool ,
1196+ kobj );
1197+ struct net_device * netdev =
1198+ container_of (kobj -> parent , struct device , kobj )-> driver_data ;
1199+ struct ibmveth_adapter * adapter = netdev -> priv ;
1200+ long value = simple_strtol (buf , NULL , 10 );
1201+ long rc ;
1202+
1203+ if (attr == & veth_active_attr ) {
1204+ if (value && !pool -> active ) {
1205+ if (ibmveth_alloc_buffer_pool (pool )) {
1206+ ibmveth_error_printk ("unable to alloc pool\n" );
1207+ return - ENOMEM ;
1208+ }
1209+ pool -> active = 1 ;
1210+ adapter -> pool_config = 1 ;
1211+ ibmveth_close (netdev );
1212+ adapter -> pool_config = 0 ;
1213+ if ((rc = ibmveth_open (netdev )))
1214+ return rc ;
1215+ } else if (!value && pool -> active ) {
1216+ int mtu = netdev -> mtu + IBMVETH_BUFF_OH ;
1217+ int i ;
1218+ /* Make sure there is a buffer pool with buffers that
1219+ can hold a packet of the size of the MTU */
1220+ for (i = 0 ; i < IbmVethNumBufferPools ; i ++ ) {
1221+ if (pool == & adapter -> rx_buff_pool [i ])
1222+ continue ;
1223+ if (!adapter -> rx_buff_pool [i ].active )
1224+ continue ;
1225+ if (mtu < adapter -> rx_buff_pool [i ].buff_size ) {
1226+ pool -> active = 0 ;
1227+ h_free_logical_lan_buffer (adapter ->
1228+ vdev ->
1229+ unit_address ,
1230+ pool ->
1231+ buff_size );
1232+ }
1233+ }
1234+ if (pool -> active ) {
1235+ ibmveth_error_printk ("no active pool >= MTU\n" );
1236+ return - EPERM ;
1237+ }
1238+ }
1239+ } else if (attr == & veth_num_attr ) {
1240+ if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT )
1241+ return - EINVAL ;
1242+ else {
1243+ adapter -> pool_config = 1 ;
1244+ ibmveth_close (netdev );
1245+ adapter -> pool_config = 0 ;
1246+ pool -> size = value ;
1247+ if ((rc = ibmveth_open (netdev )))
1248+ return rc ;
1249+ }
1250+ } else if (attr == & veth_size_attr ) {
1251+ if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE )
1252+ return - EINVAL ;
1253+ else {
1254+ adapter -> pool_config = 1 ;
1255+ ibmveth_close (netdev );
1256+ adapter -> pool_config = 0 ;
1257+ pool -> buff_size = value ;
1258+ if ((rc = ibmveth_open (netdev )))
1259+ return rc ;
1260+ }
1261+ }
1262+
1263+ /* kick the interrupt handler to allocate/deallocate pools */
1264+ ibmveth_interrupt (netdev -> irq , netdev , NULL );
1265+ return count ;
1266+ }
1267+
1268+
1269+ #define ATTR (_name , _mode ) \
1270+ struct attribute veth_##_name##_attr = { \
1271+ .name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE \
1272+ };
1273+
1274+ static ATTR (active , 0644 ) ;
1275+ static ATTR (num , 0644 ) ;
1276+ static ATTR (size , 0644 ) ;
1277+
1278+ static struct attribute * veth_pool_attrs [] = {
1279+ & veth_active_attr ,
1280+ & veth_num_attr ,
1281+ & veth_size_attr ,
1282+ NULL ,
1283+ };
1284+
1285+ static struct sysfs_ops veth_pool_ops = {
1286+ .show = veth_pool_show ,
1287+ .store = veth_pool_store ,
1288+ };
1289+
1290+ static struct kobj_type ktype_veth_pool = {
1291+ .release = NULL ,
1292+ .sysfs_ops = & veth_pool_ops ,
1293+ .default_attrs = veth_pool_attrs ,
1294+ };
1295+
1296+
11721297static struct vio_device_id ibmveth_device_table [] __devinitdata = {
11731298 { "network" , "IBM,l-lan" },
11741299 { "" , "" }
0 commit comments