Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: hsr: introduce protocol specific function pointers

As a preparatory patch to introduce support for PRP protocol, add a
protocol ops ptr in the private hsr structure to hold function
pointers as some of the functions at protocol level packet
handling is different for HSR vs PRP. It is expected that PRP will
add its of set of functions for protocol handling. Modify existing
hsr_announce() function to call proto_ops->send_sv_frame() to send
supervision frame for HSR. This is expected to be different for PRP.
So introduce a ops function ptr, send_sv_frame() for the same and
initialize it to send_hsr_supervsion_frame(). Modify hsr_announce()
to call proto_ops->send_sv_frame().

Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Murali Karicheri and committed by
David S. Miller
28e458e0 121c33b0

+45 -31
+39 -31
net/hsr/hsr_device.c
··· 230 230 .parse = eth_header_parse, 231 231 }; 232 232 233 - static struct sk_buff *hsr_init_skb(struct hsr_port *master, u8 hsr_ver) 233 + static struct sk_buff *hsr_init_skb(struct hsr_port *master, u16 proto) 234 234 { 235 235 struct hsr_priv *hsr = master->hsr; 236 236 struct sk_buff *skb; ··· 247 247 248 248 skb_reserve(skb, hlen); 249 249 skb->dev = master->dev; 250 - skb->protocol = htons(hsr_ver ? ETH_P_HSR : ETH_P_PRP); 250 + skb->protocol = htons(proto); 251 251 skb->priority = TC_PRIO_CONTROL; 252 252 253 - if (dev_hard_header(skb, skb->dev, (hsr_ver ? ETH_P_HSR : ETH_P_PRP), 253 + if (dev_hard_header(skb, skb->dev, proto, 254 254 hsr->sup_multicast_addr, 255 255 skb->dev->dev_addr, skb->len) <= 0) 256 256 goto out; ··· 267 267 } 268 268 269 269 static void send_hsr_supervision_frame(struct hsr_port *master, 270 - u8 type, u8 hsr_ver) 270 + unsigned long *interval) 271 271 { 272 + struct hsr_priv *hsr = master->hsr; 273 + __u8 type = HSR_TLV_LIFE_CHECK; 274 + struct hsr_tag *hsr_tag = NULL; 272 275 struct hsr_sup_payload *hsr_sp; 273 276 struct hsr_sup_tag *hsr_stag; 274 - struct hsr_tag *hsr_tag; 275 277 unsigned long irqflags; 276 278 struct sk_buff *skb; 279 + u16 proto; 277 280 278 - skb = hsr_init_skb(master, hsr_ver); 281 + *interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL); 282 + if (hsr->announce_count < 3 && hsr->prot_version == 0) { 283 + type = HSR_TLV_ANNOUNCE; 284 + *interval = msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL); 285 + hsr->announce_count++; 286 + } 287 + 288 + if (!hsr->prot_version) 289 + proto = ETH_P_PRP; 290 + else 291 + proto = ETH_P_HSR; 292 + 293 + skb = hsr_init_skb(master, proto); 279 294 if (!skb) { 280 295 WARN_ONCE(1, "HSR: Could not send supervision frame\n"); 281 296 return; 282 297 } 283 298 284 - if (hsr_ver > 0) { 299 + if (hsr->prot_version > 0) { 285 300 hsr_tag = skb_put(skb, sizeof(struct hsr_tag)); 286 301 hsr_tag->encap_proto = htons(ETH_P_PRP); 287 302 set_hsr_tag_LSDU_size(hsr_tag, HSR_V1_SUP_LSDUSIZE); 288 303 } 289 304 290 305 hsr_stag = skb_put(skb, sizeof(struct hsr_sup_tag)); 291 - set_hsr_stag_path(hsr_stag, (hsr_ver ? 0x0 : 0xf)); 292 - set_hsr_stag_HSR_ver(hsr_stag, hsr_ver); 306 + set_hsr_stag_path(hsr_stag, (hsr->prot_version ? 0x0 : 0xf)); 307 + set_hsr_stag_HSR_ver(hsr_stag, hsr->prot_version); 293 308 294 309 /* From HSRv1 on we have separate supervision sequence numbers. */ 295 310 spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags); 296 - if (hsr_ver > 0) { 297 - hsr_stag->sequence_nr = htons(master->hsr->sup_sequence_nr); 298 - hsr_tag->sequence_nr = htons(master->hsr->sequence_nr); 299 - master->hsr->sup_sequence_nr++; 300 - master->hsr->sequence_nr++; 311 + if (hsr->prot_version > 0) { 312 + hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr); 313 + hsr->sup_sequence_nr++; 314 + hsr_tag->sequence_nr = htons(hsr->sequence_nr); 315 + hsr->sequence_nr++; 301 316 } else { 302 - hsr_stag->sequence_nr = htons(master->hsr->sequence_nr); 303 - master->hsr->sequence_nr++; 317 + hsr_stag->sequence_nr = htons(hsr->sequence_nr); 318 + hsr->sequence_nr++; 304 319 } 305 320 spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags); 306 321 307 322 hsr_stag->HSR_TLV_type = type; 308 323 /* TODO: Why 12 in HSRv0? */ 309 - hsr_stag->HSR_TLV_length = 310 - hsr_ver ? sizeof(struct hsr_sup_payload) : 12; 324 + hsr_stag->HSR_TLV_length = hsr->prot_version ? 325 + sizeof(struct hsr_sup_payload) : 12; 311 326 312 327 /* Payload: MacAddressA */ 313 328 hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload)); ··· 348 333 349 334 rcu_read_lock(); 350 335 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); 351 - 352 - if (hsr->announce_count < 3 && hsr->prot_version == 0) { 353 - send_hsr_supervision_frame(master, HSR_TLV_ANNOUNCE, 354 - hsr->prot_version); 355 - hsr->announce_count++; 356 - 357 - interval = msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL); 358 - } else { 359 - send_hsr_supervision_frame(master, HSR_TLV_LIFE_CHECK, 360 - hsr->prot_version); 361 - 362 - interval = msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL); 363 - } 336 + hsr->proto_ops->send_sv_frame(master, &interval); 364 337 365 338 if (is_admin_up(master->dev)) 366 339 mod_timer(&hsr->announce_timer, jiffies + interval); ··· 383 380 384 381 static struct device_type hsr_type = { 385 382 .name = "hsr", 383 + }; 384 + 385 + static struct hsr_proto_ops hsr_ops = { 386 + .send_sv_frame = send_hsr_supervision_frame, 386 387 }; 387 388 388 389 void hsr_dev_setup(struct net_device *dev) ··· 452 445 if (protocol_version == PRP_V1) 453 446 return -EPROTONOSUPPORT; 454 447 448 + hsr->proto_ops = &hsr_ops; 455 449 /* Make sure we recognize frames from ourselves in hsr_rcv() */ 456 450 res = hsr_create_self_node(hsr, hsr_dev->dev_addr, 457 451 slave[1]->dev_addr);
+6
net/hsr/hsr_main.h
··· 140 140 PRP_V1, 141 141 }; 142 142 143 + struct hsr_proto_ops { 144 + /* format and send supervision frame */ 145 + void (*send_sv_frame)(struct hsr_port *port, unsigned long *interval); 146 + }; 147 + 143 148 struct hsr_priv { 144 149 struct rcu_head rcu_head; 145 150 struct list_head ports; ··· 158 153 enum hsr_version prot_version; /* Indicate if HSRv0, HSRv1 or PRPv1 */ 159 154 spinlock_t seqnr_lock; /* locking for sequence_nr */ 160 155 spinlock_t list_lock; /* locking for node list */ 156 + struct hsr_proto_ops *proto_ops; 161 157 unsigned char sup_multicast_addr[ETH_ALEN]; 162 158 #ifdef CONFIG_DEBUG_FS 163 159 struct dentry *node_tbl_root;