@@ -96,6 +96,7 @@ static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
96
96
static void ibmveth_proc_unregister_adapter (struct ibmveth_adapter * adapter );
97
97
static irqreturn_t ibmveth_interrupt (int irq , void * dev_instance , struct pt_regs * regs );
98
98
static inline void ibmveth_rxq_harvest_buffer (struct ibmveth_adapter * adapter );
99
+ static struct kobj_type ktype_veth_pool ;
99
100
100
101
#ifdef CONFIG_PROC_FS
101
102
#define IBMVETH_PROC_DIR "net/ibmveth"
@@ -133,12 +134,13 @@ static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter)
133
134
}
134
135
135
136
/* 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 )
137
138
{
138
139
pool -> size = pool_size ;
139
140
pool -> index = pool_index ;
140
141
pool -> buff_size = buff_size ;
141
142
pool -> threshold = pool_size / 2 ;
143
+ pool -> active = pool_active ;
142
144
}
143
145
144
146
/* allocate and setup an buffer pool - called during open */
@@ -180,7 +182,6 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool)
180
182
atomic_set (& pool -> available , 0 );
181
183
pool -> producer_index = 0 ;
182
184
pool -> consumer_index = 0 ;
183
- pool -> active = 0 ;
184
185
185
186
return 0 ;
186
187
}
@@ -301,7 +302,6 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm
301
302
kfree (pool -> skbuff );
302
303
pool -> skbuff = NULL ;
303
304
}
304
- pool -> active = 0 ;
305
305
}
306
306
307
307
/* remove a buffer from a pool */
@@ -433,7 +433,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
433
433
}
434
434
435
435
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 ]);
437
439
}
438
440
439
441
static int ibmveth_open (struct net_device * netdev )
@@ -489,9 +491,6 @@ static int ibmveth_open(struct net_device *netdev)
489
491
adapter -> rx_queue .num_slots = rxq_entries ;
490
492
adapter -> rx_queue .toggle = 1 ;
491
493
492
- /* call change_mtu to init the buffer pools based in initial mtu */
493
- ibmveth_change_mtu (netdev , netdev -> mtu );
494
-
495
494
memcpy (& mac_address , netdev -> dev_addr , netdev -> addr_len );
496
495
mac_address = mac_address >> 16 ;
497
496
@@ -522,6 +521,17 @@ static int ibmveth_open(struct net_device *netdev)
522
521
return - ENONET ;
523
522
}
524
523
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
+
525
535
ibmveth_debug_printk ("registering irq 0x%x\n" , netdev -> irq );
526
536
if ((rc = request_irq (netdev -> irq , & ibmveth_interrupt , 0 , netdev -> name , netdev )) != 0 ) {
527
537
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)
550
560
551
561
ibmveth_debug_printk ("close starting\n" );
552
562
553
- netif_stop_queue (netdev );
563
+ if (!adapter -> pool_config )
564
+ netif_stop_queue (netdev );
554
565
555
566
free_irq (netdev -> irq , netdev );
556
567
@@ -876,46 +887,22 @@ static void ibmveth_set_multicast_list(struct net_device *netdev)
876
887
static int ibmveth_change_mtu (struct net_device * dev , int new_mtu )
877
888
{
878
889
struct ibmveth_adapter * adapter = dev -> priv ;
890
+ int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH ;
879
891
int i ;
880
- int prev_smaller = 1 ;
881
892
882
- if ((new_mtu < 68 ) ||
883
- (new_mtu > (pool_size [IbmVethNumBufferPools - 1 ]) - IBMVETH_BUFF_OH ))
893
+ if (new_mtu < IBMVETH_MAX_MTU )
884
894
return - EINVAL ;
885
895
896
+ /* Look for an active buffer pool that can hold the new MTU */
886
897
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 ;
895
903
}
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
-
911
904
}
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 ;
919
906
}
920
907
921
908
static 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_
960
947
adapter -> vdev = dev ;
961
948
adapter -> netdev = netdev ;
962
949
adapter -> mcastFilterSize = * mcastFilterSize_p ;
950
+ adapter -> pool_config = 0 ;
963
951
964
952
/* Some older boxes running PHYP non-natively have an OF that
965
953
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_
994
982
995
983
memcpy (& netdev -> dev_addr , & adapter -> mac_addr , netdev -> addr_len );
996
984
997
- for (i = 0 ; i < IbmVethNumBufferPools ; i ++ )
985
+ for (i = 0 ; i < IbmVethNumBufferPools ; i ++ ) {
986
+ struct kobject * kobj = & adapter -> rx_buff_pool [i ].kobj ;
998
987
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
+ }
1000
995
1001
996
ibmveth_debug_printk ("adapter @ 0x%p\n" , adapter );
1002
997
@@ -1025,6 +1020,10 @@ static int __devexit ibmveth_remove(struct vio_dev *dev)
1025
1020
{
1026
1021
struct net_device * netdev = dev -> dev .driver_data ;
1027
1022
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 );
1028
1027
1029
1028
unregister_netdev (netdev );
1030
1029
@@ -1169,6 +1168,132 @@ static void ibmveth_proc_unregister_driver(void)
1169
1168
}
1170
1169
#endif /* CONFIG_PROC_FS */
1171
1170
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
+
1172
1297
static struct vio_device_id ibmveth_device_table [] __devinitdata = {
1173
1298
{ "network" , "IBM,l-lan" },
1174
1299
{ "" , "" }
0 commit comments