| .. | .. |
|---|
| 219 | 219 | skb->dev = master->dev; |
|---|
| 220 | 220 | skb_reset_mac_header(skb); |
|---|
| 221 | 221 | skb_reset_mac_len(skb); |
|---|
| 222 | + spin_lock_bh(&hsr->seqnr_lock); |
|---|
| 222 | 223 | hsr_forward_skb(skb, master); |
|---|
| 224 | + spin_unlock_bh(&hsr->seqnr_lock); |
|---|
| 223 | 225 | } else { |
|---|
| 224 | 226 | atomic_long_inc(&dev->tx_dropped); |
|---|
| 225 | 227 | dev_kfree_skb_any(skb); |
|---|
| .. | .. |
|---|
| 232 | 234 | .parse = eth_header_parse, |
|---|
| 233 | 235 | }; |
|---|
| 234 | 236 | |
|---|
| 235 | | -static struct sk_buff *hsr_init_skb(struct hsr_port *master, u16 proto) |
|---|
| 237 | +static struct sk_buff *hsr_init_skb(struct hsr_port *master) |
|---|
| 236 | 238 | { |
|---|
| 237 | 239 | struct hsr_priv *hsr = master->hsr; |
|---|
| 238 | 240 | struct sk_buff *skb; |
|---|
| .. | .. |
|---|
| 244 | 246 | * being, for PRP it is a trailer and for HSR it is a |
|---|
| 245 | 247 | * header |
|---|
| 246 | 248 | */ |
|---|
| 247 | | - skb = dev_alloc_skb(sizeof(struct hsr_tag) + |
|---|
| 248 | | - sizeof(struct hsr_sup_tag) + |
|---|
| 249 | + skb = dev_alloc_skb(sizeof(struct hsr_sup_tag) + |
|---|
| 249 | 250 | sizeof(struct hsr_sup_payload) + hlen + tlen); |
|---|
| 250 | 251 | |
|---|
| 251 | 252 | if (!skb) |
|---|
| .. | .. |
|---|
| 253 | 254 | |
|---|
| 254 | 255 | skb_reserve(skb, hlen); |
|---|
| 255 | 256 | skb->dev = master->dev; |
|---|
| 256 | | - skb->protocol = htons(proto); |
|---|
| 257 | 257 | skb->priority = TC_PRIO_CONTROL; |
|---|
| 258 | 258 | |
|---|
| 259 | | - if (dev_hard_header(skb, skb->dev, proto, |
|---|
| 259 | + if (dev_hard_header(skb, skb->dev, ETH_P_PRP, |
|---|
| 260 | 260 | hsr->sup_multicast_addr, |
|---|
| 261 | 261 | skb->dev->dev_addr, skb->len) <= 0) |
|---|
| 262 | 262 | goto out; |
|---|
| .. | .. |
|---|
| 278 | 278 | { |
|---|
| 279 | 279 | struct hsr_priv *hsr = master->hsr; |
|---|
| 280 | 280 | __u8 type = HSR_TLV_LIFE_CHECK; |
|---|
| 281 | | - struct hsr_tag *hsr_tag = NULL; |
|---|
| 282 | 281 | struct hsr_sup_payload *hsr_sp; |
|---|
| 283 | 282 | struct hsr_sup_tag *hsr_stag; |
|---|
| 284 | | - unsigned long irqflags; |
|---|
| 285 | 283 | struct sk_buff *skb; |
|---|
| 286 | | - u16 proto; |
|---|
| 287 | 284 | |
|---|
| 288 | 285 | *interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL); |
|---|
| 289 | 286 | if (hsr->announce_count < 3 && hsr->prot_version == 0) { |
|---|
| .. | .. |
|---|
| 292 | 289 | hsr->announce_count++; |
|---|
| 293 | 290 | } |
|---|
| 294 | 291 | |
|---|
| 295 | | - if (!hsr->prot_version) |
|---|
| 296 | | - proto = ETH_P_PRP; |
|---|
| 297 | | - else |
|---|
| 298 | | - proto = ETH_P_HSR; |
|---|
| 299 | | - |
|---|
| 300 | | - skb = hsr_init_skb(master, proto); |
|---|
| 292 | + skb = hsr_init_skb(master); |
|---|
| 301 | 293 | if (!skb) { |
|---|
| 302 | 294 | WARN_ONCE(1, "HSR: Could not send supervision frame\n"); |
|---|
| 303 | 295 | return; |
|---|
| 304 | | - } |
|---|
| 305 | | - |
|---|
| 306 | | - if (hsr->prot_version > 0) { |
|---|
| 307 | | - hsr_tag = skb_put(skb, sizeof(struct hsr_tag)); |
|---|
| 308 | | - hsr_tag->encap_proto = htons(ETH_P_PRP); |
|---|
| 309 | | - set_hsr_tag_LSDU_size(hsr_tag, HSR_V1_SUP_LSDUSIZE); |
|---|
| 310 | 296 | } |
|---|
| 311 | 297 | |
|---|
| 312 | 298 | hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag)); |
|---|
| .. | .. |
|---|
| 314 | 300 | set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version); |
|---|
| 315 | 301 | |
|---|
| 316 | 302 | /* From HSRv1 on we have separate supervision sequence numbers. */ |
|---|
| 317 | | - spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags); |
|---|
| 303 | + spin_lock_bh(&hsr->seqnr_lock); |
|---|
| 318 | 304 | if (hsr->prot_version > 0) { |
|---|
| 319 | 305 | hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr); |
|---|
| 320 | 306 | hsr->sup_sequence_nr++; |
|---|
| 321 | | - hsr_tag->sequence_nr = htons(hsr->sequence_nr); |
|---|
| 322 | | - hsr->sequence_nr++; |
|---|
| 323 | 307 | } else { |
|---|
| 324 | 308 | hsr_stag->sequence_nr = htons(hsr->sequence_nr); |
|---|
| 325 | 309 | hsr->sequence_nr++; |
|---|
| 326 | 310 | } |
|---|
| 327 | | - spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags); |
|---|
| 328 | 311 | |
|---|
| 329 | 312 | hsr_stag->HSR_TLV_type = type; |
|---|
| 330 | 313 | /* TODO: Why 12 in HSRv0? */ |
|---|
| .. | .. |
|---|
| 335 | 318 | hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload)); |
|---|
| 336 | 319 | ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr); |
|---|
| 337 | 320 | |
|---|
| 338 | | - if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN)) |
|---|
| 321 | + if (skb_put_padto(skb, ETH_ZLEN)) { |
|---|
| 322 | + spin_unlock_bh(&hsr->seqnr_lock); |
|---|
| 339 | 323 | return; |
|---|
| 324 | + } |
|---|
| 340 | 325 | |
|---|
| 341 | 326 | hsr_forward_skb(skb, master); |
|---|
| 342 | | - |
|---|
| 327 | + spin_unlock_bh(&hsr->seqnr_lock); |
|---|
| 343 | 328 | return; |
|---|
| 344 | 329 | } |
|---|
| 345 | 330 | |
|---|
| .. | .. |
|---|
| 349 | 334 | struct hsr_priv *hsr = master->hsr; |
|---|
| 350 | 335 | struct hsr_sup_payload *hsr_sp; |
|---|
| 351 | 336 | struct hsr_sup_tag *hsr_stag; |
|---|
| 352 | | - unsigned long irqflags; |
|---|
| 353 | 337 | struct sk_buff *skb; |
|---|
| 354 | | - struct prp_rct *rct; |
|---|
| 355 | | - u8 *tail; |
|---|
| 356 | 338 | |
|---|
| 357 | | - skb = hsr_init_skb(master, ETH_P_PRP); |
|---|
| 339 | + skb = hsr_init_skb(master); |
|---|
| 358 | 340 | if (!skb) { |
|---|
| 359 | 341 | WARN_ONCE(1, "PRP: Could not send supervision frame\n"); |
|---|
| 360 | 342 | return; |
|---|
| .. | .. |
|---|
| 366 | 348 | set_hsr_stag_HSR_ver(hsr_stag, (hsr->prot_version ? 1 : 0)); |
|---|
| 367 | 349 | |
|---|
| 368 | 350 | /* From HSRv1 on we have separate supervision sequence numbers. */ |
|---|
| 369 | | - spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags); |
|---|
| 351 | + spin_lock_bh(&hsr->seqnr_lock); |
|---|
| 370 | 352 | hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr); |
|---|
| 371 | 353 | hsr->sup_sequence_nr++; |
|---|
| 372 | 354 | hsr_stag->HSR_TLV_type = PRP_TLV_LIFE_CHECK_DD; |
|---|
| .. | .. |
|---|
| 376 | 358 | hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload)); |
|---|
| 377 | 359 | ether_addr_copy(hsr_sp->macaddress_A, master->dev->dev_addr); |
|---|
| 378 | 360 | |
|---|
| 379 | | - if (skb_put_padto(skb, ETH_ZLEN + HSR_HLEN)) { |
|---|
| 380 | | - spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags); |
|---|
| 361 | + if (skb_put_padto(skb, ETH_ZLEN)) { |
|---|
| 362 | + spin_unlock_bh(&hsr->seqnr_lock); |
|---|
| 381 | 363 | return; |
|---|
| 382 | 364 | } |
|---|
| 383 | 365 | |
|---|
| 384 | | - tail = skb_tail_pointer(skb) - HSR_HLEN; |
|---|
| 385 | | - rct = (struct prp_rct *)tail; |
|---|
| 386 | | - rct->PRP_suffix = htons(ETH_P_PRP); |
|---|
| 387 | | - set_prp_LSDU_size(rct, HSR_V1_SUP_LSDUSIZE); |
|---|
| 388 | | - rct->sequence_nr = htons(hsr->sequence_nr); |
|---|
| 389 | | - hsr->sequence_nr++; |
|---|
| 390 | | - spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags); |
|---|
| 391 | | - |
|---|
| 392 | 366 | hsr_forward_skb(skb, master); |
|---|
| 367 | + spin_unlock_bh(&hsr->seqnr_lock); |
|---|
| 393 | 368 | } |
|---|
| 394 | 369 | |
|---|
| 395 | 370 | /* Announce (supervision frame) timer function |
|---|
| .. | .. |
|---|
| 468 | 443 | dev->header_ops = &hsr_header_ops; |
|---|
| 469 | 444 | dev->netdev_ops = &hsr_device_ops; |
|---|
| 470 | 445 | SET_NETDEV_DEVTYPE(dev, &hsr_type); |
|---|
| 471 | | - dev->priv_flags |= IFF_NO_QUEUE; |
|---|
| 446 | + dev->priv_flags |= IFF_NO_QUEUE | IFF_DISABLE_NETPOLL; |
|---|
| 472 | 447 | |
|---|
| 473 | 448 | dev->needs_free_netdev = true; |
|---|
| 474 | 449 | |
|---|